From ec7500d9f8b3f66a8d09a9597a7ae9b61bb4ed24 Mon Sep 17 00:00:00 2001 From: Gaudenz Steinlin Date: Thu, 22 Dec 2016 07:55:05 +0000 Subject: [PATCH] Import openorienteering-mapper_0.6.7.orig.tar.gz [dgit import orig openorienteering-mapper_0.6.7.orig.tar.gz] --- .github/ISSUE_TEMPLATE.md | 14 + 3rd-party/clipper/CMakeLists.txt | 121 + 3rd-party/clipper/License.txt | 26 + 3rd-party/clipper/clipper.pro | 54 + 3rd-party/clipper/download/README.txt | 1 + 3rd-party/doxygen/CMakeLists.txt | 100 + 3rd-party/doxygen/LICENSE | 340 + 3rd-party/doxygen/download/README.txt | 1 + 3rd-party/doxygen/doxygen.pro | 51 + 3rd-party/gcc-mxe/README | 20 + 3rd-party/gcc-mxe/make-source.sh | 93 + 3rd-party/gdal/CMakeLists.txt | 209 + 3rd-party/gdal/LICENSE.TXT | 263 + 3rd-party/gdal/download/README.txt | 1 + 3rd-party/gdal/gdal.pro | 69 + 3rd-party/gdal/patches/config.guess | 1558 + 3rd-party/gdal/patches/config.sub | 1791 + 3rd-party/gdal/patches/gdal-2.0.1.patch | 24 + 3rd-party/gnu-libstdc++/INSTALL.txt.in | 26 + 3rd-party/gnu-libstdc++/README.txt | 20 + 3rd-party/gnu-libstdc++/build.sh | 56 + 3rd-party/gnu-libstdc++/gnu-libstdc++.pro | 94 + 3rd-party/gnu-libstdc++/init.sh | 145 + 3rd-party/proj/CMakeLists.txt | 151 + 3rd-party/proj/COPYING | 34 + 3rd-party/proj/download/README.txt | 1 + 3rd-party/proj/patches/README.txt | 16 + 3rd-party/proj/patches/configure.patch | 29 + 3rd-party/proj/proj-config.in | 45 + 3rd-party/proj/proj-make.in | 30 + 3rd-party/proj/proj-patch.in | 25 + 3rd-party/proj/proj-postinstall.in | 34 + 3rd-party/proj/proj.pro | 73 + 3rd-party/qbezier/CMakeLists.txt | 38 + 3rd-party/qbezier/LICENSE.GPL | 674 + 3rd-party/qbezier/README.txt | 8 + 3rd-party/qbezier/qbezier.pro | 38 + 3rd-party/qbezier/src/mapper_qbezier.cpp | 5 + 3rd-party/qbezier/src/private/qbezier_p.h | 276 + 3rd-party/qbezier/src/private/qdatabuffer_p.h | 147 + 3rd-party/qbezier/src/private/qmath_p.h | 73 + 3rd-party/qbezier/src/private/qnumeric_p.h | 201 + 3rd-party/qt5/CMakeLists.txt | 354 + 3rd-party/qt5/download/README.txt | 1 + .../patches/5.4.0/qtbase-qandroidstyle.patch | 27 + ...qtbase-qtbug-39874-qnetworkproxy_win.patch | 45 + .../qtbase-qtbug-43124-qprintengine_win.patch | 15 + .../patches/5.4.2/qtbase-qandroidstyle.patch | 27 + .../5.4.2/qttools-qtbug-45095-qdbus.patch | 12 + .../5.4/qtbase-android-motionEvent.patch | 33 + .../5.4/qtbase-configure-android.patch | 39 + .../qt5/patches/5.4/qtbase-create-cmake.patch | 21 + .../qt5/patches/5.4/qtbase-qdockwidget.patch | 32 + .../5.5/qtbase-QTBUG-48203-print-crash.patch | 36 + .../patches/5.5/qtbase-android-install.patch | 36 + .../qt5/patches/5.5/qtbase-create-cmake.patch | 21 + 3rd-party/qt5/qt.conf.in | 3 + 3rd-party/qt5/qt.conf.qrc.in | 5 + 3rd-party/qt5/qt5-config-host.in | 67 + 3rd-party/qt5/qt5-config.cmd.in | 20 + 3rd-party/qt5/qt5-config.in | 49 + 3rd-party/qt5/qt5-make.in | 28 + 3rd-party/qt5/qt5-patchqt.in | 197 + 3rd-party/qt5/qt5.pro | 60 + 3rd-party/qtsingleapplication/CMakeLists.txt | 46 + .../qtsingleapplication.pro | 47 + .../qtsingleapplication/src/QtLockedFile | 1 + .../src/QtSingleApplication | 1 + .../qtsingleapplication/src/qtlocalpeer.cpp | 204 + .../qtsingleapplication/src/qtlocalpeer.h | 77 + .../qtsingleapplication/src/qtlockedfile.cpp | 193 + .../qtsingleapplication/src/qtlockedfile.h | 97 + .../src/qtlockedfile_unix.cpp | 115 + .../src/qtlockedfile_win.cpp | 211 + .../src/qtsingleapplication.cpp | 347 + .../src/qtsingleapplication.h | 105 + .../src/qtsingleapplication.pri | 17 + .../src/qtsinglecoreapplication.cpp | 149 + .../src/qtsinglecoreapplication.h | 71 + .../src/qtsinglecoreapplication.pri | 10 + CMakeLists.txt | 365 + COPYING | 674 + INSTALL.md | 218 + README.md | 46 + android/AndroidManifest.xml | 64 + android/res/drawable-hdpi/icon.png | Bin 0 -> 11851 bytes android/res/drawable-ldpi/icon.png | Bin 0 -> 3896 bytes android/res/drawable-mdpi/icon.png | Bin 0 -> 5831 bytes android/res/drawable-xhdpi/icon.png | Bin 0 -> 17055 bytes android/res/values/strings.xml | 5 + .../mapper/MapperActivity.java | 210 + cmake/DeployQt5.cmake | 336 + cmake/EnableSanitize.cmake | 39 + cmake/FindPROJ4.cmake | 152 + cmake/FindPolyclipping.cmake | 156 + .../toolchain/arm-linux-android-abi-gcc.cmake | 37 + cmake/toolchain/bundle-test.cmake | 39 + cmake/toolchain/i586-mingw32msvc.cmake | 35 + cmake/toolchain/i686-w64-mingw32.cmake | 42 + doc/api/CMakeLists.txt | 95 + doc/api/Doxyfile.in | 53 + doc/api/api-docs-commit.sh | 38 + doc/api/api-docs-repository.sh | 36 + doc/api/api-docs.sh.in | 39 + doc/api/extra/code_overview.h | 111 + doc/api/extra/mainpage.h | 46 + doc/api/versionfilter.sh.in | 36 + doc/coding-style.xml | 39 + doc/licensing/CMakeLists.txt | 102 + doc/licensing/licensing-html.qdocconf | 28 + doc/licensing/licensing.css | 50 + doc/licensing/licensing.pro | 85 + doc/licensing/licensing.qdocconf | 35 + doc/licensing/licensing.qrc | 11 + doc/licensing/src/apache-2.0.qdoc | 219 + .../src/gcc-runtime-library-exception.qdoc | 86 + doc/licensing/src/gdal-licensing.qdocinc | 268 + doc/licensing/src/gpl-3.0.qdoc | 702 + doc/licensing/src/lgpl-2.1.qdoc | 528 + doc/licensing/src/lgpl-3.0.qdoc | 189 + doc/licensing/src/licensing.qdoc | 265 + doc/licensing/src/qt-licensing.qdocinc | 1587 + doc/licensing/src/trademarks.qdocinc | 29 + doc/man/Mapper.1 | 40 + doc/manual/CMakeLists.txt | 185 + doc/manual/Doxyfile.in | 51 + doc/manual/Manual.qhcp.in | 19 + doc/manual/footer.html | 6 + doc/manual/header.html | 16 + doc/manual/manual.pro | 60 + doc/manual/pages/android-app.md | 96 + doc/manual/pages/android-index.md | 27 + doc/manual/pages/android-pc.md | 96 + doc/manual/pages/android-requirements.md | 55 + doc/manual/pages/android-storage.md | 39 + doc/manual/pages/attachment/scribble_1024.png | Bin 0 -> 5733 bytes doc/manual/pages/attachment/scribble_2048.png | Bin 0 -> 21316 bytes doc/manual/pages/color_dock_widget.md | 57 + doc/manual/pages/colors_symbols.md | 15 + doc/manual/pages/course_design.md | 81 + doc/manual/pages/edit_menu.md | 80 + doc/manual/pages/faq.md | 59 + doc/manual/pages/file_menu.md | 81 + doc/manual/pages/georeferencing.md | 78 + doc/manual/pages/grid.md | 33 + .../pages/images/Android_UI_explanation.png | Bin 0 -> 211085 bytes doc/manual/pages/images/color_dock_widget.png | Bin 0 -> 97165 bytes .../pages/images/color_editor_desktop.png | Bin 0 -> 35336 bytes .../images/color_editor_professional.png | Bin 0 -> 51197 bytes doc/manual/pages/images/course_design.png | Bin 0 -> 138556 bytes doc/manual/pages/images/georeferencing.png | Bin 0 -> 73351 bytes doc/manual/pages/images/grid_settings.png | Bin 0 -> 55073 bytes doc/manual/pages/images/main_window.png | Bin 0 -> 139343 bytes doc/manual/pages/images/new_map.png | Bin 0 -> 37671 bytes .../pages/images/symbol_dock_widget.png | Bin 0 -> 25049 bytes .../pages/images/symbol_dock_widget_menu.png | Bin 0 -> 44031 bytes .../pages/images/symbol_replace_dialog.png | Bin 0 -> 71612 bytes doc/manual/pages/images/template_adjust.png | Bin 0 -> 31360 bytes .../images/template_image_positioning.png | Bin 0 -> 30339 bytes .../pages/images/template_setup_window.png | Bin 0 -> 26243 bytes doc/manual/pages/images/touch_cursor.png | Bin 0 -> 915 bytes doc/manual/pages/index.md | 63 + doc/manual/pages/main_window.md | 21 + doc/manual/pages/map_menu.md | 78 + doc/manual/pages/map_parts.md | 26 + doc/manual/pages/mapping-introduction.md | 104 + doc/manual/pages/new_map.md | 30 + doc/manual/pages/reference.md | 17 + doc/manual/pages/settings.md | 64 + doc/manual/pages/symbol_dock_widget.md | 118 + doc/manual/pages/symbol_replace_dialog.md | 26 + doc/manual/pages/symbols_menu.md | 27 + doc/manual/pages/tag_editor.md | 14 + doc/manual/pages/template_adjust.md | 21 + doc/manual/pages/templates-index.md | 13 + doc/manual/pages/templates.md | 94 + doc/manual/pages/templates_menu.md | 20 + doc/manual/pages/toolbars.md | 360 + doc/manual/pages/tools_menu.md | 11 + doc/manual/pages/view_menu.md | 61 + doc/manual/postprocess-qhp.cmake.in | 31 + doc/manual/preprocess-markdown.cmake.in | 196 + doc/manual/style.css | 27 + doc/openorienteering.png | Bin 0 -> 13651 bytes examples/CMakeLists.txt | 37 + examples/README.md | 5 + examples/autosave-example.qrc | 6 + examples/complete map.omap | 215 + examples/examples.pro | 36 + examples/examples.qrc | 6 + examples/forest sample.omap | 12 + examples/overprinting.omap | 14 + examples/src/complete map.xmap | 74864 ++++++++++++++++ examples/src/forest sample.xmap | 20505 +++++ examples/src/overprinting.xmap | 7126 ++ help/tip-of-the-day/tips_de.txt | 4 + help/tip-of-the-day/tips_en.txt | 16 + help/tip-of-the-day/tips_fr.txt | 16 + help/tip-of-the-day/tips_ru.txt | 14 + help/tip-of-the-day/tips_uk.txt | 16 + images/about.png | Bin 0 -> 1901 bytes images/arrow-down.png | Bin 0 -> 1187 bytes images/arrow-left.png | Bin 0 -> 1200 bytes images/arrow-right.png | Bin 0 -> 1219 bytes images/arrow-thin-downright.png | Bin 0 -> 450 bytes images/arrow-thin-upleft.png | Bin 0 -> 441 bytes images/arrow-up.png | Bin 0 -> 1193 bytes images/close.png | Bin 0 -> 1853 bytes images/colors.png | Bin 0 -> 267 bytes images/compass.png | Bin 0 -> 2033 bytes images/control.png | Bin 0 -> 318 bytes images/copy-coords.png | Bin 0 -> 1306 bytes images/copy.png | Bin 0 -> 723 bytes images/cursor-crosshair.png | Bin 0 -> 148 bytes images/cursor-cut.png | Bin 0 -> 1070 bytes images/cursor-delete.png | Bin 0 -> 814 bytes images/cursor-draw-circle.png | Bin 0 -> 677 bytes images/cursor-draw-path.png | Bin 0 -> 622 bytes images/cursor-draw-point.png | Bin 0 -> 261 bytes images/cursor-draw-rectangle.png | Bin 0 -> 398 bytes images/cursor-draw-text.png | Bin 0 -> 676 bytes images/cursor-fill.png | Bin 0 -> 832 bytes images/cursor-georeferencing-add.png | Bin 0 -> 211 bytes images/cursor-georeferencing-move.png | Bin 0 -> 268 bytes images/cursor-hollow.png | Bin 0 -> 210 bytes images/cursor-invisible.png | Bin 0 -> 81 bytes images/cursor-paint-on-template.png | Bin 0 -> 723 bytes images/cursor-rotate.png | Bin 0 -> 756 bytes images/cursor-scale.png | Bin 0 -> 661 bytes images/cut.png | Bin 0 -> 2087 bytes images/delete.png | Bin 0 -> 1889 bytes images/draw-circle.png | Bin 0 -> 1258 bytes images/draw-freehand.png | Bin 0 -> 1997 bytes images/draw-path.png | Bin 0 -> 1209 bytes images/draw-point-gps.png | Bin 0 -> 1530 bytes images/draw-point.png | Bin 0 -> 362 bytes images/draw-rectangle.png | Bin 0 -> 284 bytes images/draw-text.png | Bin 0 -> 1284 bytes images/georeferencing.png | Bin 0 -> 256 bytes images/gps-distance-rings.png | Bin 0 -> 970 bytes images/gps-temporary-clear.png | Bin 0 -> 834 bytes images/gps-temporary-path.png | Bin 0 -> 896 bytes images/gps-temporary-point.png | Bin 0 -> 1258 bytes images/grid.png | Bin 0 -> 224 bytes images/group.png | Bin 0 -> 1747 bytes images/help.png | Bin 0 -> 2231 bytes images/magnifying-glass.png | Bin 0 -> 2196 bytes images/map-parts.png | Bin 0 -> 1060 bytes images/mapper-help.png | Bin 0 -> 2952 bytes images/mapper-icon/Mapper-128.png | Bin 0 -> 24549 bytes images/mapper-icon/Mapper-16.png | Bin 0 -> 1917 bytes images/mapper-icon/Mapper-24.png | Bin 0 -> 2889 bytes images/mapper-icon/Mapper-256.png | Bin 0 -> 61581 bytes images/mapper-icon/Mapper-32.png | Bin 0 -> 4051 bytes images/mapper-icon/Mapper-48.png | Bin 0 -> 5831 bytes images/mapper-icon/Mapper-512.png | Bin 0 -> 143738 bytes images/mapper-icon/Mapper-96.png | Bin 0 -> 17055 bytes images/mapper-icon/Mapper-large.psd | Bin 0 -> 2932779 bytes images/mapper-icon/Mapper-small.psd | Bin 0 -> 1388453 bytes images/mapper-icon/Mapper.icns | Bin 0 -> 278110 bytes images/mapper-icon/Mapper.ico | Bin 0 -> 323550 bytes images/mapper-icon/README.txt | 4 + images/mapper-icon/mapper-help.xcf | Bin 0 -> 6244 bytes images/mapper.png | Bin 0 -> 3188 bytes images/minus.png | Bin 0 -> 377 bytes images/move.png | Bin 0 -> 1840 bytes images/new.png | Bin 0 -> 1008 bytes images/open-orienteering.png | Bin 0 -> 45070 bytes images/open.png | Bin 0 -> 1176 bytes images/paint-on-template-settings.png | Bin 0 -> 1266 bytes images/paste.png | Bin 0 -> 1027 bytes images/pencil.png | Bin 0 -> 1106 bytes images/plus.png | Bin 0 -> 646 bytes images/point-handles-2x.png | Bin 0 -> 1640 bytes images/point-handles-4x.png | Bin 0 -> 3206 bytes images/point-handles.png | Bin 0 -> 878 bytes images/print-mode-raster.png | Bin 0 -> 1686 bytes images/print-mode-separations.png | Bin 0 -> 1073 bytes images/print-mode-vector.png | Bin 0 -> 2932 bytes images/print.png | Bin 0 -> 917 bytes images/redo.png | Bin 0 -> 1502 bytes images/rotate-map.png | Bin 0 -> 1886 bytes images/save.png | Bin 0 -> 890 bytes images/settings.png | Bin 0 -> 2544 bytes images/svg/map-parts.svg | 143 + images/symbol_point_explanation.png | Bin 0 -> 3441 bytes images/symbols.png | Bin 0 -> 252 bytes images/tag-selector.png | Bin 0 -> 661 bytes images/templates.png | Bin 0 -> 2630 bytes images/text-align-baseline.png | Bin 0 -> 1259 bytes images/text-align-bottom.png | Bin 0 -> 1263 bytes images/text-align-hcenter.png | Bin 0 -> 1336 bytes images/text-align-left.png | Bin 0 -> 1284 bytes images/text-align-right.png | Bin 0 -> 1268 bytes images/text-align-top.png | Bin 0 -> 1272 bytes images/text-align-vcenter.png | Bin 0 -> 1224 bytes images/three-dots.png | Bin 0 -> 347 bytes images/title.png | Bin 0 -> 46905 bytes images/tool-boolean-difference.png | Bin 0 -> 618 bytes images/tool-boolean-intersection.png | Bin 0 -> 549 bytes images/tool-boolean-merge-holes.png | Bin 0 -> 417 bytes images/tool-boolean-union.png | Bin 0 -> 911 bytes images/tool-boolean-xor.png | Bin 0 -> 791 bytes images/tool-connect-paths.png | Bin 0 -> 1191 bytes images/tool-convert-to-curves.png | Bin 0 -> 1557 bytes images/tool-cut-hole.png | Bin 0 -> 2373 bytes images/tool-cut.png | Bin 0 -> 2124 bytes images/tool-cutout-physical-inner.png | Bin 0 -> 1930 bytes images/tool-cutout-physical.png | Bin 0 -> 1928 bytes images/tool-distribute-points.png | Bin 0 -> 331 bytes images/tool-duplicate.png | Bin 0 -> 916 bytes images/tool-edit-line.png | Bin 0 -> 964 bytes images/tool-edit.png | Bin 0 -> 876 bytes images/tool-fill-border.png | Bin 0 -> 1532 bytes images/tool-fill.png | Bin 0 -> 2435 bytes images/tool-gps-display.png | Bin 0 -> 970 bytes images/tool-measure.png | Bin 0 -> 1574 bytes images/tool-rotate-pattern.png | Bin 0 -> 1679 bytes images/tool-rotate.png | Bin 0 -> 1616 bytes images/tool-scale.png | Bin 0 -> 740 bytes images/tool-simplify-path.png | Bin 0 -> 1552 bytes images/tool-switch-dashes.png | Bin 0 -> 348 bytes images/tool-switch-symbol.png | Bin 0 -> 227 bytes images/tool-touch-cursor.png | Bin 0 -> 1167 bytes images/undo.png | Bin 0 -> 1601 bytes images/view-show-all.png | Bin 0 -> 1256 bytes images/view-zoom-in.png | Bin 0 -> 2168 bytes images/view-zoom-out.png | Bin 0 -> 2164 bytes images/window-new.png | Bin 0 -> 671 bytes oo-mapper-version.pri | 4 + oo-mapper.pro | 155 + packaging/CMakeLists.txt | 529 + packaging/linguist/CMakeLists.txt | 238 + packaging/linguist/COPYING | 674 + packaging/linux/Mapper.desktop | 28 + packaging/linux/openorienteering-mapper.xml | 35 + packaging/src/CMakeLists.txt | 36 + packaging/src/Mapper_Source.cmake.in | 64 + packaging/translations.cpp | 14 + packaging/windows/custom.nsi.in | 79 + resources.qrc | 131 + src/CMakeLists.txt | 484 + src/color_dock_widget.cpp | 456 + src/color_dock_widget.h | 91 + src/compass.cpp | 589 + src/compass.h | 77 + src/core/autosave.cpp | 133 + src/core/autosave.h | 84 + src/core/autosave_p.h | 63 + src/core/crs_template.cpp | 123 + src/core/crs_template.h | 304 + src/core/crs_template_implementation.cpp | 286 + src/core/crs_template_implementation.h | 127 + src/core/georeferencing.cpp | 872 + src/core/georeferencing.h | 670 + src/core/image_transparency_fixup.h | 89 + src/core/latlon.cpp | 32 + src/core/latlon.h | 136 + src/core/map_color.cpp | 381 + src/core/map_color.h | 884 + src/core/map_coord.cpp | 449 + src/core/map_coord.h | 1124 + src/core/map_grid.cpp | 219 + src/core/map_grid.h | 167 + src/core/map_printer.cpp | 1285 + src/core/map_printer.h | 543 + src/core/map_view.cpp | 508 + src/core/map_view.h | 519 + src/core/path_coord.cpp | 503 + src/core/path_coord.h | 289 + src/core/storage_location.cpp | 292 + src/core/storage_location.h | 121 + src/core/virtual_coord_vector.cpp | 36 + src/core/virtual_coord_vector.h | 241 + src/core/virtual_path.cpp | 838 + src/core/virtual_path.h | 423 + src/dxfparser.cpp | 600 + src/dxfparser.h | 151 + src/file_format.cpp | 88 + src/file_format.h | 321 + src/file_format_native.cpp | 424 + src/file_format_native.h | 69 + src/file_format_ocad8.cpp | 2722 + src/file_format_ocad8.h | 37 + src/file_format_ocad8_p.h | 229 + src/file_format_registry.cpp | 90 + src/file_format_registry.h | 98 + src/file_format_xml.cpp | 908 + src/file_format_xml.h | 64 + src/file_format_xml_p.h | 87 + src/file_import_export.cpp | 151 + src/file_import_export.h | 267 + src/fileformats/ocd_file_export.cpp | 47 + src/fileformats/ocd_file_export.h | 49 + src/fileformats/ocd_file_format.cpp | 55 + src/fileformats/ocd_file_format.h | 51 + src/fileformats/ocd_file_import.cpp | 2096 + src/fileformats/ocd_file_import.h | 441 + src/fileformats/ocd_types.cpp | 46 + src/fileformats/ocd_types.h | 870 + src/fileformats/ocd_types_v10.h | 33 + src/fileformats/ocd_types_v11.h | 159 + src/fileformats/ocd_types_v12.h | 99 + src/fileformats/ocd_types_v8.h | 447 + src/fileformats/ocd_types_v9.h | 215 + src/gdal/CMakeLists.txt | 55 + src/gdal/gdal_manager.cpp | 267 + src/gdal/gdal_manager.h | 109 + src/gdal/gdal_settings_page.cpp | 221 + src/gdal/gdal_settings_page.h | 58 + src/gdal/ogr_file_format.cpp | 1070 + src/gdal/ogr_file_format.h | 55 + src/gdal/ogr_file_format_p.h | 214 + src/gdal/ogr_template.cpp | 119 + src/gdal/ogr_template.h | 59 + src/global.cpp | 43 + src/global.h | 33 + src/gps_display.cpp | 361 + src/gps_display.h | 136 + src/gps_temporary_markers.cpp | 127 + src/gps_temporary_markers.h | 69 + src/gps_track.cpp | 645 + src/gps_track.h | 178 + src/gps_track_recorder.cpp | 101 + src/gps_track_recorder.h | 55 + src/gui/about_dialog.cpp | 184 + src/gui/about_dialog.h | 56 + src/gui/autosave_dialog.cpp | 192 + src/gui/autosave_dialog.h | 131 + src/gui/color_dialog.cpp | 636 + src/gui/color_dialog.h | 140 + src/gui/configure_grid_dialog.cpp | 265 + src/gui/configure_grid_dialog.h | 95 + src/gui/georeferencing_dialog.cpp | 747 + src/gui/georeferencing_dialog.h | 332 + src/gui/home_screen_controller.cpp | 157 + src/gui/home_screen_controller.h | 79 + src/gui/main_window.cpp | 1189 + src/gui/main_window.h | 561 + src/gui/main_window_controller.cpp | 85 + src/gui/main_window_controller.h | 130 + src/gui/modifier_key.cpp | 97 + src/gui/modifier_key.h | 113 + src/gui/point_handles.cpp | 193 + src/gui/point_handles.h | 152 + src/gui/print_progress_dialog.cpp | 74 + src/gui/print_progress_dialog.h | 83 + src/gui/print_tool.cpp | 377 + src/gui/print_tool.h | 117 + src/gui/print_widget.cpp | 1335 + src/gui/print_widget.h | 326 + src/gui/select_crs_dialog.cpp | 133 + src/gui/select_crs_dialog.h | 91 + src/gui/settings_dialog.cpp | 220 + src/gui/settings_dialog.h | 99 + src/gui/text_browser_dialog.cpp | 132 + src/gui/text_browser_dialog.h | 69 + src/gui/widgets/action_grid_bar.cpp | 274 + src/gui/widgets/action_grid_bar.h | 119 + src/gui/widgets/color_dropdown.cpp | 161 + src/gui/widgets/color_dropdown.h | 69 + src/gui/widgets/compass_display.cpp | 116 + src/gui/widgets/compass_display.h | 69 + src/gui/widgets/crs_param_widgets.cpp | 97 + src/gui/widgets/crs_param_widgets.h | 54 + src/gui/widgets/crs_selector.cpp | 382 + src/gui/widgets/crs_selector.h | 186 + src/gui/widgets/editor_settings_page.cpp | 147 + src/gui/widgets/editor_settings_page.h | 69 + src/gui/widgets/general_settings_page.cpp | 391 + src/gui/widgets/general_settings_page.h | 86 + src/gui/widgets/home_screen_widget.cpp | 570 + src/gui/widgets/home_screen_widget.h | 204 + src/gui/widgets/key_button_bar.cpp | 122 + src/gui/widgets/key_button_bar.h | 80 + src/gui/widgets/mapper_proxystyle.cpp | 177 + src/gui/widgets/mapper_proxystyle.h | 85 + src/gui/widgets/measure_widget.cpp | 162 + src/gui/widgets/measure_widget.h | 54 + src/gui/widgets/pie_menu.cpp | 398 + src/gui/widgets/pie_menu.h | 156 + src/gui/widgets/segmented_button_layout.cpp | 75 + src/gui/widgets/segmented_button_layout.h | 74 + src/gui/widgets/settings_page.cpp | 33 + src/gui/widgets/settings_page.h | 92 + src/gui/widgets/symbol_dropdown.cpp | 157 + src/gui/widgets/symbol_dropdown.h | 96 + src/gui/widgets/symbol_render_widget.cpp | 1216 + src/gui/widgets/symbol_render_widget.h | 359 + src/gui/widgets/symbol_tooltip.cpp | 202 + src/gui/widgets/symbol_tooltip.h | 131 + src/gui/widgets/symbol_widget.cpp | 82 + src/gui/widgets/symbol_widget.h | 126 + src/gui/widgets/tag_select_widget.cpp | 419 + src/gui/widgets/tag_select_widget.h | 91 + src/gui/widgets/tags_widget.cpp | 266 + src/gui/widgets/tags_widget.h | 95 + src/gui/widgets/template_list_widget.cpp | 1313 + src/gui/widgets/template_list_widget.h | 151 + src/gui/widgets/text_alignment_widget.cpp | 183 + src/gui/widgets/text_alignment_widget.h | 70 + src/libocad/CMakeLists.txt | 34 + src/libocad/array.c | 133 + src/libocad/array.h | 113 + src/libocad/color.c | 78 + src/libocad/file.c | 460 + src/libocad/geometry.c | 145 + src/libocad/geometry.h | 111 + src/libocad/libocad.h | 1111 + src/libocad/libocad.pro | 64 + src/libocad/ocad_object.c | 227 + src/libocad/ocad_symbol.c | 153 + src/libocad/path.c | 312 + src/libocad/setup.c | 44 + src/libocad/string.c | 167 + src/libocad/types.c | 90 + src/libocad/types.h | 50 + src/main.cpp | 165 + src/map.cpp | 2503 + src/map.h | 1821 + src/map_dialog_new.cpp | 288 + src/map_dialog_new.h | 128 + src/map_dialog_rotate.cpp | 156 + src/map_dialog_rotate.h | 72 + src/map_dialog_scale.cpp | 139 + src/map_dialog_scale.h | 68 + src/map_editor.cpp | 3940 + src/map_editor.h | 779 + src/map_editor_activity.cpp | 40 + src/map_editor_activity.h | 94 + src/map_editor_p.h | 78 + src/map_part.cpp | 321 + src/map_part.h | 334 + src/map_part_undo.cpp | 173 + src/map_part_undo.h | 93 + src/map_widget.cpp | 1334 + src/map_widget.h | 551 + src/mapper_config.h.in | 47 + src/mapper_resource.cpp | 205 + src/mapper_resource.h | 67 + src/matrix.cpp | 214 + src/matrix.h | 194 + src/mingw/resources.rc.in | 50 + src/object.cpp | 3231 + src/object.h | 1165 + src/object_operations.h | 195 + src/object_query.cpp | 225 + src/object_query.h | 131 + src/object_text.cpp | 504 + src/object_text.h | 373 + src/object_undo.cpp | 769 + src/object_undo.h | 438 + src/printsupport/CMakeLists.txt | 76 + src/printsupport/advanced_pdf_printer.cpp | 50 + src/printsupport/advanced_pdf_printer.h | 50 + src/printsupport/fork.sh | 39 + src/printsupport/patch.sh | 18 + src/printsupport/patches/devicecmyk.diff | 66 + src/printsupport/patches/enginetype.diff | 49 + src/printsupport/patches/headers.sed | 73 + src/printsupport/patches/papersize.diff | 25 + src/printsupport/patches/producer.diff | 19 + src/printsupport/printer_properties.cpp | 47 + src/printsupport/printer_properties.h | 73 + src/printsupport/printer_properties_win.cpp | 219 + src/printsupport/printsupport.pro | 49 + src/printsupport/qt-5.2.1/advanced_pdf.cpp | 2642 + src/printsupport/qt-5.2.1/advanced_pdf_p.h | 337 + .../qt-5.2.1/printengine_advanced_pdf.cpp | 382 + .../qt-5.2.1/printengine_advanced_pdf_p.h | 152 + src/printsupport/qt-5.2.1/qfontsubset.cpp | 1264 + src/printsupport/qt-5.2.1/qfontsubset_agl.cpp | 280 + src/printsupport/qt-5.2.1/qfontsubset_p.h | 90 + src/printsupport/qt-5.5.1/advanced_pdf.cpp | 2693 + src/printsupport/qt-5.5.1/advanced_pdf_p.h | 323 + .../qt-5.5.1/printengine_advanced_pdf.cpp | 402 + .../qt-5.5.1/printengine_advanced_pdf_p.h | 138 + src/printsupport/qt-5.5.1/qfontsubset.cpp | 1259 + src/printsupport/qt-5.5.1/qfontsubset_agl.cpp | 280 + src/printsupport/qt-5.5.1/qfontsubset_p.h | 90 + src/qmake/mapper_config.h | 34 + src/renderable.cpp | 741 + src/renderable.h | 469 + src/renderable_implementation.cpp | 687 + src/renderable_implementation.h | 145 + src/settings.cpp | 260 + src/settings.h | 138 + src/src.pro | 391 + src/src.pro.in | 115 + src/symbol.cpp | 665 + src/symbol.h | 441 + src/symbol_area.cpp | 1194 + src/symbol_area.h | 271 + src/symbol_combined.cpp | 563 + src/symbol_combined.h | 139 + src/symbol_dialog_replace.cpp | 359 + src/symbol_dialog_replace.h | 78 + src/symbol_line.cpp | 2740 + src/symbol_line.h | 496 + src/symbol_point.cpp | 460 + src/symbol_point.h | 160 + src/symbol_point_editor.cpp | 1029 + src/symbol_point_editor.h | 207 + src/symbol_properties_widget.cpp | 196 + src/symbol_properties_widget.h | 91 + src/symbol_setting_dialog.cpp | 491 + src/symbol_setting_dialog.h | 174 + src/symbol_text.cpp | 1109 + src/symbol_text.h | 267 + src/template.cpp | 836 + src/template.h | 459 + src/template_adjust.cpp | 845 + src/template_adjust.h | 221 + src/template_dialog_reopen.cpp | 166 + src/template_dialog_reopen.h | 70 + src/template_image.cpp | 726 + src/template_image.h | 176 + src/template_map.cpp | 194 + src/template_map.h | 82 + src/template_position_dock_widget.cpp | 180 + src/template_position_dock_widget.h | 63 + src/template_tool_move.cpp | 116 + src/template_tool_move.h | 53 + src/template_tool_paint.cpp | 372 + src/template_tool_paint.h | 127 + src/template_track.cpp | 574 + src/template_track.h | 126 + src/tool.cpp | 429 + src/tool.h | 426 + src/tool_base.cpp | 499 + src/tool_base.h | 243 + src/tool_boolean.cpp | 1067 + src/tool_boolean.h | 266 + src/tool_cut.cpp | 694 + src/tool_cut.h | 139 + src/tool_cut_hole.cpp | 243 + src/tool_cut_hole.h | 77 + src/tool_cutout.cpp | 310 + src/tool_cutout.h | 93 + src/tool_distribute_points.cpp | 170 + src/tool_distribute_points.h | 132 + src/tool_draw_circle.cpp | 306 + src/tool_draw_circle.h | 70 + src/tool_draw_freehand.cpp | 279 + src/tool_draw_freehand.h | 63 + src/tool_draw_line_and_area.cpp | 387 + src/tool_draw_line_and_area.h | 128 + src/tool_draw_path.cpp | 1111 + src/tool_draw_path.h | 155 + src/tool_draw_point.cpp | 344 + src/tool_draw_point.h | 89 + src/tool_draw_point_gps.cpp | 209 + src/tool_draw_point_gps.h | 75 + src/tool_draw_rectangle.cpp | 749 + src/tool_draw_rectangle.h | 144 + src/tool_draw_text.cpp | 384 + src/tool_draw_text.h | 89 + src/tool_edit.cpp | 674 + src/tool_edit.h | 241 + src/tool_edit_line.cpp | 572 + src/tool_edit_line.h | 133 + src/tool_edit_point.cpp | 865 + src/tool_edit_point.h | 183 + src/tool_fill.cpp | 498 + src/tool_fill.h | 102 + src/tool_helpers.cpp | 969 + src/tool_helpers.h | 381 + src/tool_pan.cpp | 78 + src/tool_pan.h | 47 + src/tool_rotate.cpp | 212 + src/tool_rotate.h | 63 + src/tool_rotate_pattern.cpp | 231 + src/tool_rotate_pattern.h | 54 + src/tool_scale.cpp | 206 + src/tool_scale.h | 71 + src/touch_cursor.cpp | 218 + src/touch_cursor.h | 105 + src/transformation.cpp | 298 + src/transformation.h | 76 + src/undo.cpp | 300 + src/undo.h | 368 + src/undo_manager.cpp | 455 + src/undo_manager.h | 408 + src/util.cpp | 345 + src/util.h | 350 + src/util/backports.h | 31 + src/util/encoding.cpp | 74 + src/util/encoding.h | 53 + src/util/item_delegates.cpp | 256 + src/util/item_delegates.h | 230 + src/util/memory.h | 51 + src/util/overriding_shortcut.cpp | 67 + src/util/overriding_shortcut.h | 69 + src/util/qasconst.h | 50 + src/util/qoverload.h | 86 + src/util/recording_translator.cpp | 47 + src/util/recording_translator.h | 52 + src/util/scoped_signals_blocker.cpp | 43 + src/util/scoped_signals_blocker.h | 159 + src/util/xml_stream_util.cpp | 218 + src/util/xml_stream_util.h | 725 + src/util_gui.h | 307 + src/util_task_dialog.cpp | 75 + src/util_task_dialog.h | 106 + src/util_translation.cpp | 143 + src/util_translation.h | 147 + suppress.txt.in | 16 + symbol sets/10000/Course_Design_10000.omap | 216 + symbol sets/10000/ISMTBOM_10000.omap | 22 + symbol sets/10000/ISMTBOM_uk_10000.omap | 6 + symbol sets/10000/ISOM_10000.omap | 12 + symbol sets/10000/ISOM_cs_10000.omap | 187 + symbol sets/10000/ISOM_fi_10000.omap | 18 + symbol sets/10000/ISOM_ru_10000.omap | 1 + symbol sets/10000/ISSkiOM_10000.omap | 35 + symbol sets/15000/Course_Design_15000.omap | 216 + symbol sets/15000/ISMTBOM_15000.omap | 22 + symbol sets/15000/ISMTBOM_uk_15000.omap | 6 + symbol sets/15000/ISOM_15000.omap | 12 + symbol sets/15000/ISOM_cs_15000.omap | 187 + symbol sets/15000/ISOM_fi_15000.omap | 18 + symbol sets/15000/ISOM_ru_15000.omap | 1 + symbol sets/15000/ISSkiOM_15000.omap | 35 + symbol sets/20000/ISMTBOM_20000.omap | 22 + symbol sets/20000/ISMTBOM_uk_20000.omap | 6 + symbol sets/4000/Course_Design_4000.omap | 216 + symbol sets/4000/ISSOM_4000.omap | 187 + symbol sets/4000/ISSOM_cs_4000.omap | 534 + symbol sets/4000/ISSOM_fi_4000.omap | 240 + symbol sets/4000/ISSOM_fr_4000.omap | 192 + symbol sets/5000/Course_Design_5000.omap | 216 + symbol sets/5000/ISMTBOM_5000.omap | 22 + symbol sets/5000/ISMTBOM_uk_5000.omap | 6 + symbol sets/5000/ISSOM_5000.omap | 187 + symbol sets/5000/ISSOM_cs_5000.omap | 534 + symbol sets/5000/ISSOM_fi_5000.omap | 240 + symbol sets/5000/ISSOM_fr_5000.omap | 192 + symbol sets/5000/ISSkiOM_5000.omap | 35 + symbol sets/7500/ISMTBOM_7500.omap | 22 + symbol sets/7500/ISMTBOM_uk_7500.omap | 6 + symbol sets/CMakeLists.txt | 84 + symbol sets/README.md | 21 + symbol sets/src/Course_Design_10000.xmap | 10403 +++ symbol sets/src/ISMTBOM_15000.xmap | 7323 ++ symbol sets/src/ISMTBOM_ru_15000.xmap | 7305 ++ symbol sets/src/ISMTBOM_uk_15000.xmap | 7308 ++ symbol sets/src/ISOM_15000.xmap | 7193 ++ symbol sets/src/ISOM_cs_15000.xmap | 6866 ++ symbol sets/src/ISOM_fi_15000.xmap | 6698 ++ symbol sets/src/ISOM_ru_15000.xmap | 7182 ++ symbol sets/src/ISSOM_5000.xmap | 7323 ++ symbol sets/src/ISSOM_cs_5000.xmap | 7156 ++ symbol sets/src/ISSOM_fi_5000.xmap | 6864 ++ symbol sets/src/ISSOM_fr_5000.xmap | 6814 ++ symbol sets/src/ISSkiOM_15000.xmap | 7566 ++ symbol sets/symbol sets.pro | 34 + test/AUTORUN_TESTS.cmake.in | 39 + test/CMakeLists.txt | 181 + test/TESTNAME-RUN.cmake.in | 36 + test/autosave_t.cpp | 240 + test/autosave_t.h | 97 + test/coord_xml_t.cpp | 1066 + test/coord_xml_t.h | 110 + test/data/CMakeLists.txt | 44 + .../issue-513-coords-outside-printable.omap | 115 + .../issue-513-coords-outside-printable.xmap | 117 + .../data/issue-513-coords-outside-qint32.omap | 1 + test/data/spotcolor_overprint.xmap | 2581 + test/data/test_map.omap | Bin 0 -> 150014 bytes test/duplicate_equals_t.cpp | 104 + test/duplicate_equals_t.h | 45 + test/encoding_t.cpp | 66 + test/encoding_t.h | 49 + test/file_format_t.cpp | 471 + test/file_format_t.h | 69 + test/georeferencing_t.cpp | 219 + test/georeferencing_t.h | 75 + test/locale_t.cpp | 73 + test/locale_t.h | 48 + test/map_color_t.cpp | 295 + test/map_color_t.h | 49 + test/map_t.cpp | 154 + test/map_t.h | 50 + test/mapper_t.cpp | 50 + test/object_query_t.cpp | 174 + test/object_query_t.h | 47 + test/path_object_t.cpp | 470 + test/path_object_t.h | 60 + test/qpainter_t.cpp | 134 + test/qpainter_t.h | 93 + test/symbol_set_t.cpp | 381 + test/symbol_set_t.h | 53 + test/tools_t.cpp | 207 + test/tools_t.h | 38 + test/transform_t.cpp | 131 + test/transform_t.h | 62 + test/tst_qglobal.cpp | 158 + test/tst_qglobal.h | 43 + test/undo_manager_t.cpp | 241 + test/undo_manager_t.h | 82 + translations/CMakeLists.txt | 233 + translations/OpenOrienteering_cs.ts | 7822 ++ translations/OpenOrienteering_da.ts | 7288 ++ translations/OpenOrienteering_de.ts | 7578 ++ translations/OpenOrienteering_en.ts | 99 + translations/OpenOrienteering_eo.ts | 7317 ++ translations/OpenOrienteering_es.ts | 7750 ++ translations/OpenOrienteering_et.ts | 8957 ++ translations/OpenOrienteering_fi.ts | 7663 ++ translations/OpenOrienteering_fr.ts | 7689 ++ translations/OpenOrienteering_he.ts | 7288 ++ translations/OpenOrienteering_hu.ts | 7690 ++ translations/OpenOrienteering_id.ts | 9018 ++ translations/OpenOrienteering_it.ts | 7508 ++ translations/OpenOrienteering_ja.ts | 8300 ++ translations/OpenOrienteering_lv.ts | 9742 ++ translations/OpenOrienteering_nb.ts | 9547 ++ translations/OpenOrienteering_nl.ts | 9581 ++ translations/OpenOrienteering_pl.ts | 7796 ++ translations/OpenOrienteering_pt_BR.ts | 7473 ++ translations/OpenOrienteering_ru.ts | 7451 ++ translations/OpenOrienteering_sv.ts | 8343 ++ translations/OpenOrienteering_template.ts | 7279 ++ translations/OpenOrienteering_uk.ts | 7392 ++ translations/OpenOrienteering_zh_CN.ts | 7279 ++ translations/future_translations.cpp | 80 + translations/locversion.plist.in | 14 + translations/qt_template.ts | 1669 + translations/translate_text_files.sh | 66 + translations/translations.pro | 70 + 830 files changed, 541414 insertions(+) create mode 100644 .github/ISSUE_TEMPLATE.md create mode 100644 3rd-party/clipper/CMakeLists.txt create mode 100644 3rd-party/clipper/License.txt create mode 100644 3rd-party/clipper/clipper.pro create mode 100644 3rd-party/clipper/download/README.txt create mode 100644 3rd-party/doxygen/CMakeLists.txt create mode 100644 3rd-party/doxygen/LICENSE create mode 100644 3rd-party/doxygen/download/README.txt create mode 100644 3rd-party/doxygen/doxygen.pro create mode 100644 3rd-party/gcc-mxe/README create mode 100755 3rd-party/gcc-mxe/make-source.sh create mode 100644 3rd-party/gdal/CMakeLists.txt create mode 100644 3rd-party/gdal/LICENSE.TXT create mode 100644 3rd-party/gdal/download/README.txt create mode 100644 3rd-party/gdal/gdal.pro create mode 100755 3rd-party/gdal/patches/config.guess create mode 100755 3rd-party/gdal/patches/config.sub create mode 100644 3rd-party/gdal/patches/gdal-2.0.1.patch create mode 100644 3rd-party/gnu-libstdc++/INSTALL.txt.in create mode 100644 3rd-party/gnu-libstdc++/README.txt create mode 100755 3rd-party/gnu-libstdc++/build.sh create mode 100644 3rd-party/gnu-libstdc++/gnu-libstdc++.pro create mode 100755 3rd-party/gnu-libstdc++/init.sh create mode 100644 3rd-party/proj/CMakeLists.txt create mode 100644 3rd-party/proj/COPYING create mode 100644 3rd-party/proj/download/README.txt create mode 100644 3rd-party/proj/patches/README.txt create mode 100644 3rd-party/proj/patches/configure.patch create mode 100644 3rd-party/proj/proj-config.in create mode 100644 3rd-party/proj/proj-make.in create mode 100644 3rd-party/proj/proj-patch.in create mode 100644 3rd-party/proj/proj-postinstall.in create mode 100644 3rd-party/proj/proj.pro create mode 100644 3rd-party/qbezier/CMakeLists.txt create mode 100644 3rd-party/qbezier/LICENSE.GPL create mode 100644 3rd-party/qbezier/README.txt create mode 100644 3rd-party/qbezier/qbezier.pro create mode 100644 3rd-party/qbezier/src/mapper_qbezier.cpp create mode 100644 3rd-party/qbezier/src/private/qbezier_p.h create mode 100644 3rd-party/qbezier/src/private/qdatabuffer_p.h create mode 100644 3rd-party/qbezier/src/private/qmath_p.h create mode 100644 3rd-party/qbezier/src/private/qnumeric_p.h create mode 100644 3rd-party/qt5/CMakeLists.txt create mode 100644 3rd-party/qt5/download/README.txt create mode 100644 3rd-party/qt5/patches/5.4.0/qtbase-qandroidstyle.patch create mode 100644 3rd-party/qt5/patches/5.4.0/qtbase-qtbug-39874-qnetworkproxy_win.patch create mode 100644 3rd-party/qt5/patches/5.4.0/qtbase-qtbug-43124-qprintengine_win.patch create mode 100644 3rd-party/qt5/patches/5.4.2/qtbase-qandroidstyle.patch create mode 100644 3rd-party/qt5/patches/5.4.2/qttools-qtbug-45095-qdbus.patch create mode 100644 3rd-party/qt5/patches/5.4/qtbase-android-motionEvent.patch create mode 100644 3rd-party/qt5/patches/5.4/qtbase-configure-android.patch create mode 100644 3rd-party/qt5/patches/5.4/qtbase-create-cmake.patch create mode 100644 3rd-party/qt5/patches/5.4/qtbase-qdockwidget.patch create mode 100644 3rd-party/qt5/patches/5.5/qtbase-QTBUG-48203-print-crash.patch create mode 100644 3rd-party/qt5/patches/5.5/qtbase-android-install.patch create mode 100644 3rd-party/qt5/patches/5.5/qtbase-create-cmake.patch create mode 100644 3rd-party/qt5/qt.conf.in create mode 100644 3rd-party/qt5/qt.conf.qrc.in create mode 100644 3rd-party/qt5/qt5-config-host.in create mode 100755 3rd-party/qt5/qt5-config.cmd.in create mode 100644 3rd-party/qt5/qt5-config.in create mode 100644 3rd-party/qt5/qt5-make.in create mode 100644 3rd-party/qt5/qt5-patchqt.in create mode 100644 3rd-party/qt5/qt5.pro create mode 100644 3rd-party/qtsingleapplication/CMakeLists.txt create mode 100644 3rd-party/qtsingleapplication/qtsingleapplication.pro create mode 100644 3rd-party/qtsingleapplication/src/QtLockedFile create mode 100644 3rd-party/qtsingleapplication/src/QtSingleApplication create mode 100644 3rd-party/qtsingleapplication/src/qtlocalpeer.cpp create mode 100644 3rd-party/qtsingleapplication/src/qtlocalpeer.h create mode 100644 3rd-party/qtsingleapplication/src/qtlockedfile.cpp create mode 100644 3rd-party/qtsingleapplication/src/qtlockedfile.h create mode 100644 3rd-party/qtsingleapplication/src/qtlockedfile_unix.cpp create mode 100644 3rd-party/qtsingleapplication/src/qtlockedfile_win.cpp create mode 100644 3rd-party/qtsingleapplication/src/qtsingleapplication.cpp create mode 100644 3rd-party/qtsingleapplication/src/qtsingleapplication.h create mode 100644 3rd-party/qtsingleapplication/src/qtsingleapplication.pri create mode 100644 3rd-party/qtsingleapplication/src/qtsinglecoreapplication.cpp create mode 100644 3rd-party/qtsingleapplication/src/qtsinglecoreapplication.h create mode 100644 3rd-party/qtsingleapplication/src/qtsinglecoreapplication.pri create mode 100644 CMakeLists.txt create mode 100644 COPYING create mode 100644 INSTALL.md create mode 100644 README.md create mode 100644 android/AndroidManifest.xml create mode 100644 android/res/drawable-hdpi/icon.png create mode 100644 android/res/drawable-ldpi/icon.png create mode 100644 android/res/drawable-mdpi/icon.png create mode 100644 android/res/drawable-xhdpi/icon.png create mode 100644 android/res/values/strings.xml create mode 100644 android/src/org/openorienteering/mapper/MapperActivity.java create mode 100644 cmake/DeployQt5.cmake create mode 100644 cmake/EnableSanitize.cmake create mode 100644 cmake/FindPROJ4.cmake create mode 100644 cmake/FindPolyclipping.cmake create mode 100644 cmake/toolchain/arm-linux-android-abi-gcc.cmake create mode 100644 cmake/toolchain/bundle-test.cmake create mode 100644 cmake/toolchain/i586-mingw32msvc.cmake create mode 100644 cmake/toolchain/i686-w64-mingw32.cmake create mode 100644 doc/api/CMakeLists.txt create mode 100644 doc/api/Doxyfile.in create mode 100755 doc/api/api-docs-commit.sh create mode 100755 doc/api/api-docs-repository.sh create mode 100755 doc/api/api-docs.sh.in create mode 100644 doc/api/extra/code_overview.h create mode 100644 doc/api/extra/mainpage.h create mode 100755 doc/api/versionfilter.sh.in create mode 100644 doc/coding-style.xml create mode 100644 doc/licensing/CMakeLists.txt create mode 100644 doc/licensing/licensing-html.qdocconf create mode 100644 doc/licensing/licensing.css create mode 100644 doc/licensing/licensing.pro create mode 100644 doc/licensing/licensing.qdocconf create mode 100644 doc/licensing/licensing.qrc create mode 100644 doc/licensing/src/apache-2.0.qdoc create mode 100644 doc/licensing/src/gcc-runtime-library-exception.qdoc create mode 100644 doc/licensing/src/gdal-licensing.qdocinc create mode 100644 doc/licensing/src/gpl-3.0.qdoc create mode 100644 doc/licensing/src/lgpl-2.1.qdoc create mode 100644 doc/licensing/src/lgpl-3.0.qdoc create mode 100644 doc/licensing/src/licensing.qdoc create mode 100644 doc/licensing/src/qt-licensing.qdocinc create mode 100644 doc/licensing/src/trademarks.qdocinc create mode 100644 doc/man/Mapper.1 create mode 100644 doc/manual/CMakeLists.txt create mode 100644 doc/manual/Doxyfile.in create mode 100644 doc/manual/Manual.qhcp.in create mode 100644 doc/manual/footer.html create mode 100644 doc/manual/header.html create mode 100644 doc/manual/manual.pro create mode 100644 doc/manual/pages/android-app.md create mode 100644 doc/manual/pages/android-index.md create mode 100644 doc/manual/pages/android-pc.md create mode 100644 doc/manual/pages/android-requirements.md create mode 100644 doc/manual/pages/android-storage.md create mode 100644 doc/manual/pages/attachment/scribble_1024.png create mode 100644 doc/manual/pages/attachment/scribble_2048.png create mode 100644 doc/manual/pages/color_dock_widget.md create mode 100644 doc/manual/pages/colors_symbols.md create mode 100644 doc/manual/pages/course_design.md create mode 100644 doc/manual/pages/edit_menu.md create mode 100644 doc/manual/pages/faq.md create mode 100644 doc/manual/pages/file_menu.md create mode 100644 doc/manual/pages/georeferencing.md create mode 100644 doc/manual/pages/grid.md create mode 100644 doc/manual/pages/images/Android_UI_explanation.png create mode 100644 doc/manual/pages/images/color_dock_widget.png create mode 100644 doc/manual/pages/images/color_editor_desktop.png create mode 100644 doc/manual/pages/images/color_editor_professional.png create mode 100644 doc/manual/pages/images/course_design.png create mode 100644 doc/manual/pages/images/georeferencing.png create mode 100644 doc/manual/pages/images/grid_settings.png create mode 100644 doc/manual/pages/images/main_window.png create mode 100644 doc/manual/pages/images/new_map.png create mode 100644 doc/manual/pages/images/symbol_dock_widget.png create mode 100644 doc/manual/pages/images/symbol_dock_widget_menu.png create mode 100644 doc/manual/pages/images/symbol_replace_dialog.png create mode 100644 doc/manual/pages/images/template_adjust.png create mode 100644 doc/manual/pages/images/template_image_positioning.png create mode 100644 doc/manual/pages/images/template_setup_window.png create mode 100644 doc/manual/pages/images/touch_cursor.png create mode 100644 doc/manual/pages/index.md create mode 100644 doc/manual/pages/main_window.md create mode 100644 doc/manual/pages/map_menu.md create mode 100644 doc/manual/pages/map_parts.md create mode 100644 doc/manual/pages/mapping-introduction.md create mode 100644 doc/manual/pages/new_map.md create mode 100644 doc/manual/pages/reference.md create mode 100644 doc/manual/pages/settings.md create mode 100644 doc/manual/pages/symbol_dock_widget.md create mode 100644 doc/manual/pages/symbol_replace_dialog.md create mode 100644 doc/manual/pages/symbols_menu.md create mode 100644 doc/manual/pages/tag_editor.md create mode 100644 doc/manual/pages/template_adjust.md create mode 100644 doc/manual/pages/templates-index.md create mode 100644 doc/manual/pages/templates.md create mode 100644 doc/manual/pages/templates_menu.md create mode 100644 doc/manual/pages/toolbars.md create mode 100644 doc/manual/pages/tools_menu.md create mode 100644 doc/manual/pages/view_menu.md create mode 100644 doc/manual/postprocess-qhp.cmake.in create mode 100644 doc/manual/preprocess-markdown.cmake.in create mode 100644 doc/manual/style.css create mode 100644 doc/openorienteering.png create mode 100644 examples/CMakeLists.txt create mode 100644 examples/README.md create mode 100644 examples/autosave-example.qrc create mode 100644 examples/complete map.omap create mode 100644 examples/examples.pro create mode 100644 examples/examples.qrc create mode 100644 examples/forest sample.omap create mode 100644 examples/overprinting.omap create mode 100644 examples/src/complete map.xmap create mode 100644 examples/src/forest sample.xmap create mode 100644 examples/src/overprinting.xmap create mode 100644 help/tip-of-the-day/tips_de.txt create mode 100644 help/tip-of-the-day/tips_en.txt create mode 100644 help/tip-of-the-day/tips_fr.txt create mode 100644 help/tip-of-the-day/tips_ru.txt create mode 100644 help/tip-of-the-day/tips_uk.txt create mode 100644 images/about.png create mode 100644 images/arrow-down.png create mode 100644 images/arrow-left.png create mode 100644 images/arrow-right.png create mode 100644 images/arrow-thin-downright.png create mode 100644 images/arrow-thin-upleft.png create mode 100644 images/arrow-up.png create mode 100644 images/close.png create mode 100644 images/colors.png create mode 100644 images/compass.png create mode 100644 images/control.png create mode 100644 images/copy-coords.png create mode 100644 images/copy.png create mode 100644 images/cursor-crosshair.png create mode 100644 images/cursor-cut.png create mode 100644 images/cursor-delete.png create mode 100644 images/cursor-draw-circle.png create mode 100644 images/cursor-draw-path.png create mode 100644 images/cursor-draw-point.png create mode 100644 images/cursor-draw-rectangle.png create mode 100644 images/cursor-draw-text.png create mode 100644 images/cursor-fill.png create mode 100644 images/cursor-georeferencing-add.png create mode 100644 images/cursor-georeferencing-move.png create mode 100644 images/cursor-hollow.png create mode 100644 images/cursor-invisible.png create mode 100644 images/cursor-paint-on-template.png create mode 100644 images/cursor-rotate.png create mode 100644 images/cursor-scale.png create mode 100644 images/cut.png create mode 100644 images/delete.png create mode 100644 images/draw-circle.png create mode 100644 images/draw-freehand.png create mode 100644 images/draw-path.png create mode 100644 images/draw-point-gps.png create mode 100644 images/draw-point.png create mode 100644 images/draw-rectangle.png create mode 100644 images/draw-text.png create mode 100644 images/georeferencing.png create mode 100644 images/gps-distance-rings.png create mode 100644 images/gps-temporary-clear.png create mode 100644 images/gps-temporary-path.png create mode 100644 images/gps-temporary-point.png create mode 100644 images/grid.png create mode 100644 images/group.png create mode 100644 images/help.png create mode 100644 images/magnifying-glass.png create mode 100644 images/map-parts.png create mode 100644 images/mapper-help.png create mode 100644 images/mapper-icon/Mapper-128.png create mode 100644 images/mapper-icon/Mapper-16.png create mode 100644 images/mapper-icon/Mapper-24.png create mode 100644 images/mapper-icon/Mapper-256.png create mode 100644 images/mapper-icon/Mapper-32.png create mode 100644 images/mapper-icon/Mapper-48.png create mode 100644 images/mapper-icon/Mapper-512.png create mode 100644 images/mapper-icon/Mapper-96.png create mode 100755 images/mapper-icon/Mapper-large.psd create mode 100755 images/mapper-icon/Mapper-small.psd create mode 100644 images/mapper-icon/Mapper.icns create mode 100644 images/mapper-icon/Mapper.ico create mode 100644 images/mapper-icon/README.txt create mode 100644 images/mapper-icon/mapper-help.xcf create mode 100644 images/mapper.png create mode 100644 images/minus.png create mode 100644 images/move.png create mode 100644 images/new.png create mode 100644 images/open-orienteering.png create mode 100644 images/open.png create mode 100644 images/paint-on-template-settings.png create mode 100644 images/paste.png create mode 100644 images/pencil.png create mode 100644 images/plus.png create mode 100644 images/point-handles-2x.png create mode 100644 images/point-handles-4x.png create mode 100644 images/point-handles.png create mode 100644 images/print-mode-raster.png create mode 100644 images/print-mode-separations.png create mode 100644 images/print-mode-vector.png create mode 100644 images/print.png create mode 100644 images/redo.png create mode 100644 images/rotate-map.png create mode 100644 images/save.png create mode 100644 images/settings.png create mode 100644 images/svg/map-parts.svg create mode 100644 images/symbol_point_explanation.png create mode 100644 images/symbols.png create mode 100644 images/tag-selector.png create mode 100644 images/templates.png create mode 100644 images/text-align-baseline.png create mode 100644 images/text-align-bottom.png create mode 100644 images/text-align-hcenter.png create mode 100644 images/text-align-left.png create mode 100644 images/text-align-right.png create mode 100644 images/text-align-top.png create mode 100644 images/text-align-vcenter.png create mode 100644 images/three-dots.png create mode 100644 images/title.png create mode 100644 images/tool-boolean-difference.png create mode 100644 images/tool-boolean-intersection.png create mode 100644 images/tool-boolean-merge-holes.png create mode 100644 images/tool-boolean-union.png create mode 100644 images/tool-boolean-xor.png create mode 100644 images/tool-connect-paths.png create mode 100644 images/tool-convert-to-curves.png create mode 100644 images/tool-cut-hole.png create mode 100644 images/tool-cut.png create mode 100644 images/tool-cutout-physical-inner.png create mode 100644 images/tool-cutout-physical.png create mode 100644 images/tool-distribute-points.png create mode 100644 images/tool-duplicate.png create mode 100644 images/tool-edit-line.png create mode 100644 images/tool-edit.png create mode 100644 images/tool-fill-border.png create mode 100644 images/tool-fill.png create mode 100644 images/tool-gps-display.png create mode 100644 images/tool-measure.png create mode 100644 images/tool-rotate-pattern.png create mode 100644 images/tool-rotate.png create mode 100644 images/tool-scale.png create mode 100644 images/tool-simplify-path.png create mode 100644 images/tool-switch-dashes.png create mode 100644 images/tool-switch-symbol.png create mode 100644 images/tool-touch-cursor.png create mode 100644 images/undo.png create mode 100644 images/view-show-all.png create mode 100644 images/view-zoom-in.png create mode 100644 images/view-zoom-out.png create mode 100644 images/window-new.png create mode 100644 oo-mapper-version.pri create mode 100644 oo-mapper.pro create mode 100644 packaging/CMakeLists.txt create mode 100644 packaging/linguist/CMakeLists.txt create mode 100644 packaging/linguist/COPYING create mode 100644 packaging/linux/Mapper.desktop create mode 100644 packaging/linux/openorienteering-mapper.xml create mode 100644 packaging/src/CMakeLists.txt create mode 100644 packaging/src/Mapper_Source.cmake.in create mode 100644 packaging/translations.cpp create mode 100644 packaging/windows/custom.nsi.in create mode 100644 resources.qrc create mode 100644 src/CMakeLists.txt create mode 100644 src/color_dock_widget.cpp create mode 100644 src/color_dock_widget.h create mode 100644 src/compass.cpp create mode 100644 src/compass.h create mode 100644 src/core/autosave.cpp create mode 100644 src/core/autosave.h create mode 100644 src/core/autosave_p.h create mode 100644 src/core/crs_template.cpp create mode 100644 src/core/crs_template.h create mode 100644 src/core/crs_template_implementation.cpp create mode 100644 src/core/crs_template_implementation.h create mode 100644 src/core/georeferencing.cpp create mode 100644 src/core/georeferencing.h create mode 100644 src/core/image_transparency_fixup.h create mode 100644 src/core/latlon.cpp create mode 100644 src/core/latlon.h create mode 100644 src/core/map_color.cpp create mode 100644 src/core/map_color.h create mode 100644 src/core/map_coord.cpp create mode 100644 src/core/map_coord.h create mode 100644 src/core/map_grid.cpp create mode 100644 src/core/map_grid.h create mode 100644 src/core/map_printer.cpp create mode 100644 src/core/map_printer.h create mode 100644 src/core/map_view.cpp create mode 100644 src/core/map_view.h create mode 100644 src/core/path_coord.cpp create mode 100644 src/core/path_coord.h create mode 100644 src/core/storage_location.cpp create mode 100644 src/core/storage_location.h create mode 100644 src/core/virtual_coord_vector.cpp create mode 100644 src/core/virtual_coord_vector.h create mode 100644 src/core/virtual_path.cpp create mode 100644 src/core/virtual_path.h create mode 100644 src/dxfparser.cpp create mode 100644 src/dxfparser.h create mode 100644 src/file_format.cpp create mode 100644 src/file_format.h create mode 100644 src/file_format_native.cpp create mode 100644 src/file_format_native.h create mode 100644 src/file_format_ocad8.cpp create mode 100644 src/file_format_ocad8.h create mode 100644 src/file_format_ocad8_p.h create mode 100644 src/file_format_registry.cpp create mode 100644 src/file_format_registry.h create mode 100644 src/file_format_xml.cpp create mode 100644 src/file_format_xml.h create mode 100644 src/file_format_xml_p.h create mode 100644 src/file_import_export.cpp create mode 100644 src/file_import_export.h create mode 100644 src/fileformats/ocd_file_export.cpp create mode 100644 src/fileformats/ocd_file_export.h create mode 100644 src/fileformats/ocd_file_format.cpp create mode 100644 src/fileformats/ocd_file_format.h create mode 100644 src/fileformats/ocd_file_import.cpp create mode 100644 src/fileformats/ocd_file_import.h create mode 100644 src/fileformats/ocd_types.cpp create mode 100644 src/fileformats/ocd_types.h create mode 100644 src/fileformats/ocd_types_v10.h create mode 100644 src/fileformats/ocd_types_v11.h create mode 100644 src/fileformats/ocd_types_v12.h create mode 100644 src/fileformats/ocd_types_v8.h create mode 100644 src/fileformats/ocd_types_v9.h create mode 100644 src/gdal/CMakeLists.txt create mode 100644 src/gdal/gdal_manager.cpp create mode 100644 src/gdal/gdal_manager.h create mode 100644 src/gdal/gdal_settings_page.cpp create mode 100644 src/gdal/gdal_settings_page.h create mode 100644 src/gdal/ogr_file_format.cpp create mode 100644 src/gdal/ogr_file_format.h create mode 100644 src/gdal/ogr_file_format_p.h create mode 100644 src/gdal/ogr_template.cpp create mode 100644 src/gdal/ogr_template.h create mode 100644 src/global.cpp create mode 100644 src/global.h create mode 100644 src/gps_display.cpp create mode 100644 src/gps_display.h create mode 100644 src/gps_temporary_markers.cpp create mode 100644 src/gps_temporary_markers.h create mode 100644 src/gps_track.cpp create mode 100644 src/gps_track.h create mode 100644 src/gps_track_recorder.cpp create mode 100644 src/gps_track_recorder.h create mode 100644 src/gui/about_dialog.cpp create mode 100644 src/gui/about_dialog.h create mode 100644 src/gui/autosave_dialog.cpp create mode 100644 src/gui/autosave_dialog.h create mode 100644 src/gui/color_dialog.cpp create mode 100644 src/gui/color_dialog.h create mode 100644 src/gui/configure_grid_dialog.cpp create mode 100644 src/gui/configure_grid_dialog.h create mode 100644 src/gui/georeferencing_dialog.cpp create mode 100644 src/gui/georeferencing_dialog.h create mode 100644 src/gui/home_screen_controller.cpp create mode 100644 src/gui/home_screen_controller.h create mode 100644 src/gui/main_window.cpp create mode 100644 src/gui/main_window.h create mode 100644 src/gui/main_window_controller.cpp create mode 100644 src/gui/main_window_controller.h create mode 100644 src/gui/modifier_key.cpp create mode 100644 src/gui/modifier_key.h create mode 100644 src/gui/point_handles.cpp create mode 100644 src/gui/point_handles.h create mode 100644 src/gui/print_progress_dialog.cpp create mode 100644 src/gui/print_progress_dialog.h create mode 100644 src/gui/print_tool.cpp create mode 100644 src/gui/print_tool.h create mode 100644 src/gui/print_widget.cpp create mode 100644 src/gui/print_widget.h create mode 100644 src/gui/select_crs_dialog.cpp create mode 100644 src/gui/select_crs_dialog.h create mode 100644 src/gui/settings_dialog.cpp create mode 100644 src/gui/settings_dialog.h create mode 100644 src/gui/text_browser_dialog.cpp create mode 100644 src/gui/text_browser_dialog.h create mode 100644 src/gui/widgets/action_grid_bar.cpp create mode 100644 src/gui/widgets/action_grid_bar.h create mode 100644 src/gui/widgets/color_dropdown.cpp create mode 100644 src/gui/widgets/color_dropdown.h create mode 100644 src/gui/widgets/compass_display.cpp create mode 100644 src/gui/widgets/compass_display.h create mode 100644 src/gui/widgets/crs_param_widgets.cpp create mode 100644 src/gui/widgets/crs_param_widgets.h create mode 100644 src/gui/widgets/crs_selector.cpp create mode 100644 src/gui/widgets/crs_selector.h create mode 100644 src/gui/widgets/editor_settings_page.cpp create mode 100644 src/gui/widgets/editor_settings_page.h create mode 100644 src/gui/widgets/general_settings_page.cpp create mode 100644 src/gui/widgets/general_settings_page.h create mode 100644 src/gui/widgets/home_screen_widget.cpp create mode 100644 src/gui/widgets/home_screen_widget.h create mode 100644 src/gui/widgets/key_button_bar.cpp create mode 100644 src/gui/widgets/key_button_bar.h create mode 100644 src/gui/widgets/mapper_proxystyle.cpp create mode 100644 src/gui/widgets/mapper_proxystyle.h create mode 100644 src/gui/widgets/measure_widget.cpp create mode 100644 src/gui/widgets/measure_widget.h create mode 100644 src/gui/widgets/pie_menu.cpp create mode 100644 src/gui/widgets/pie_menu.h create mode 100644 src/gui/widgets/segmented_button_layout.cpp create mode 100644 src/gui/widgets/segmented_button_layout.h create mode 100644 src/gui/widgets/settings_page.cpp create mode 100644 src/gui/widgets/settings_page.h create mode 100644 src/gui/widgets/symbol_dropdown.cpp create mode 100644 src/gui/widgets/symbol_dropdown.h create mode 100644 src/gui/widgets/symbol_render_widget.cpp create mode 100644 src/gui/widgets/symbol_render_widget.h create mode 100644 src/gui/widgets/symbol_tooltip.cpp create mode 100644 src/gui/widgets/symbol_tooltip.h create mode 100644 src/gui/widgets/symbol_widget.cpp create mode 100644 src/gui/widgets/symbol_widget.h create mode 100644 src/gui/widgets/tag_select_widget.cpp create mode 100644 src/gui/widgets/tag_select_widget.h create mode 100644 src/gui/widgets/tags_widget.cpp create mode 100644 src/gui/widgets/tags_widget.h create mode 100644 src/gui/widgets/template_list_widget.cpp create mode 100644 src/gui/widgets/template_list_widget.h create mode 100644 src/gui/widgets/text_alignment_widget.cpp create mode 100644 src/gui/widgets/text_alignment_widget.h create mode 100644 src/libocad/CMakeLists.txt create mode 100644 src/libocad/array.c create mode 100644 src/libocad/array.h create mode 100644 src/libocad/color.c create mode 100644 src/libocad/file.c create mode 100644 src/libocad/geometry.c create mode 100644 src/libocad/geometry.h create mode 100644 src/libocad/libocad.h create mode 100644 src/libocad/libocad.pro create mode 100644 src/libocad/ocad_object.c create mode 100644 src/libocad/ocad_symbol.c create mode 100644 src/libocad/path.c create mode 100644 src/libocad/setup.c create mode 100644 src/libocad/string.c create mode 100644 src/libocad/types.c create mode 100644 src/libocad/types.h create mode 100644 src/main.cpp create mode 100644 src/map.cpp create mode 100644 src/map.h create mode 100644 src/map_dialog_new.cpp create mode 100644 src/map_dialog_new.h create mode 100644 src/map_dialog_rotate.cpp create mode 100644 src/map_dialog_rotate.h create mode 100644 src/map_dialog_scale.cpp create mode 100644 src/map_dialog_scale.h create mode 100644 src/map_editor.cpp create mode 100644 src/map_editor.h create mode 100644 src/map_editor_activity.cpp create mode 100644 src/map_editor_activity.h create mode 100644 src/map_editor_p.h create mode 100644 src/map_part.cpp create mode 100644 src/map_part.h create mode 100644 src/map_part_undo.cpp create mode 100644 src/map_part_undo.h create mode 100644 src/map_widget.cpp create mode 100644 src/map_widget.h create mode 100644 src/mapper_config.h.in create mode 100644 src/mapper_resource.cpp create mode 100644 src/mapper_resource.h create mode 100644 src/matrix.cpp create mode 100644 src/matrix.h create mode 100644 src/mingw/resources.rc.in create mode 100644 src/object.cpp create mode 100644 src/object.h create mode 100644 src/object_operations.h create mode 100644 src/object_query.cpp create mode 100644 src/object_query.h create mode 100644 src/object_text.cpp create mode 100644 src/object_text.h create mode 100644 src/object_undo.cpp create mode 100644 src/object_undo.h create mode 100644 src/printsupport/CMakeLists.txt create mode 100644 src/printsupport/advanced_pdf_printer.cpp create mode 100644 src/printsupport/advanced_pdf_printer.h create mode 100755 src/printsupport/fork.sh create mode 100755 src/printsupport/patch.sh create mode 100644 src/printsupport/patches/devicecmyk.diff create mode 100644 src/printsupport/patches/enginetype.diff create mode 100644 src/printsupport/patches/headers.sed create mode 100644 src/printsupport/patches/papersize.diff create mode 100644 src/printsupport/patches/producer.diff create mode 100644 src/printsupport/printer_properties.cpp create mode 100644 src/printsupport/printer_properties.h create mode 100644 src/printsupport/printer_properties_win.cpp create mode 100644 src/printsupport/printsupport.pro create mode 100644 src/printsupport/qt-5.2.1/advanced_pdf.cpp create mode 100644 src/printsupport/qt-5.2.1/advanced_pdf_p.h create mode 100644 src/printsupport/qt-5.2.1/printengine_advanced_pdf.cpp create mode 100644 src/printsupport/qt-5.2.1/printengine_advanced_pdf_p.h create mode 100644 src/printsupport/qt-5.2.1/qfontsubset.cpp create mode 100644 src/printsupport/qt-5.2.1/qfontsubset_agl.cpp create mode 100644 src/printsupport/qt-5.2.1/qfontsubset_p.h create mode 100644 src/printsupport/qt-5.5.1/advanced_pdf.cpp create mode 100644 src/printsupport/qt-5.5.1/advanced_pdf_p.h create mode 100644 src/printsupport/qt-5.5.1/printengine_advanced_pdf.cpp create mode 100644 src/printsupport/qt-5.5.1/printengine_advanced_pdf_p.h create mode 100644 src/printsupport/qt-5.5.1/qfontsubset.cpp create mode 100644 src/printsupport/qt-5.5.1/qfontsubset_agl.cpp create mode 100644 src/printsupport/qt-5.5.1/qfontsubset_p.h create mode 100644 src/qmake/mapper_config.h create mode 100644 src/renderable.cpp create mode 100644 src/renderable.h create mode 100644 src/renderable_implementation.cpp create mode 100644 src/renderable_implementation.h create mode 100644 src/settings.cpp create mode 100644 src/settings.h create mode 100644 src/src.pro create mode 100644 src/src.pro.in create mode 100644 src/symbol.cpp create mode 100644 src/symbol.h create mode 100644 src/symbol_area.cpp create mode 100644 src/symbol_area.h create mode 100644 src/symbol_combined.cpp create mode 100644 src/symbol_combined.h create mode 100644 src/symbol_dialog_replace.cpp create mode 100644 src/symbol_dialog_replace.h create mode 100644 src/symbol_line.cpp create mode 100644 src/symbol_line.h create mode 100644 src/symbol_point.cpp create mode 100644 src/symbol_point.h create mode 100644 src/symbol_point_editor.cpp create mode 100644 src/symbol_point_editor.h create mode 100644 src/symbol_properties_widget.cpp create mode 100644 src/symbol_properties_widget.h create mode 100644 src/symbol_setting_dialog.cpp create mode 100644 src/symbol_setting_dialog.h create mode 100644 src/symbol_text.cpp create mode 100644 src/symbol_text.h create mode 100644 src/template.cpp create mode 100644 src/template.h create mode 100644 src/template_adjust.cpp create mode 100644 src/template_adjust.h create mode 100644 src/template_dialog_reopen.cpp create mode 100644 src/template_dialog_reopen.h create mode 100644 src/template_image.cpp create mode 100644 src/template_image.h create mode 100644 src/template_map.cpp create mode 100644 src/template_map.h create mode 100644 src/template_position_dock_widget.cpp create mode 100644 src/template_position_dock_widget.h create mode 100644 src/template_tool_move.cpp create mode 100644 src/template_tool_move.h create mode 100644 src/template_tool_paint.cpp create mode 100644 src/template_tool_paint.h create mode 100644 src/template_track.cpp create mode 100644 src/template_track.h create mode 100644 src/tool.cpp create mode 100644 src/tool.h create mode 100644 src/tool_base.cpp create mode 100644 src/tool_base.h create mode 100644 src/tool_boolean.cpp create mode 100644 src/tool_boolean.h create mode 100644 src/tool_cut.cpp create mode 100644 src/tool_cut.h create mode 100644 src/tool_cut_hole.cpp create mode 100644 src/tool_cut_hole.h create mode 100644 src/tool_cutout.cpp create mode 100644 src/tool_cutout.h create mode 100644 src/tool_distribute_points.cpp create mode 100644 src/tool_distribute_points.h create mode 100644 src/tool_draw_circle.cpp create mode 100644 src/tool_draw_circle.h create mode 100644 src/tool_draw_freehand.cpp create mode 100644 src/tool_draw_freehand.h create mode 100644 src/tool_draw_line_and_area.cpp create mode 100644 src/tool_draw_line_and_area.h create mode 100644 src/tool_draw_path.cpp create mode 100644 src/tool_draw_path.h create mode 100644 src/tool_draw_point.cpp create mode 100644 src/tool_draw_point.h create mode 100644 src/tool_draw_point_gps.cpp create mode 100644 src/tool_draw_point_gps.h create mode 100644 src/tool_draw_rectangle.cpp create mode 100644 src/tool_draw_rectangle.h create mode 100644 src/tool_draw_text.cpp create mode 100644 src/tool_draw_text.h create mode 100644 src/tool_edit.cpp create mode 100644 src/tool_edit.h create mode 100644 src/tool_edit_line.cpp create mode 100644 src/tool_edit_line.h create mode 100644 src/tool_edit_point.cpp create mode 100644 src/tool_edit_point.h create mode 100644 src/tool_fill.cpp create mode 100644 src/tool_fill.h create mode 100644 src/tool_helpers.cpp create mode 100644 src/tool_helpers.h create mode 100644 src/tool_pan.cpp create mode 100644 src/tool_pan.h create mode 100644 src/tool_rotate.cpp create mode 100644 src/tool_rotate.h create mode 100644 src/tool_rotate_pattern.cpp create mode 100644 src/tool_rotate_pattern.h create mode 100644 src/tool_scale.cpp create mode 100644 src/tool_scale.h create mode 100644 src/touch_cursor.cpp create mode 100644 src/touch_cursor.h create mode 100644 src/transformation.cpp create mode 100644 src/transformation.h create mode 100644 src/undo.cpp create mode 100644 src/undo.h create mode 100644 src/undo_manager.cpp create mode 100644 src/undo_manager.h create mode 100644 src/util.cpp create mode 100644 src/util.h create mode 100644 src/util/backports.h create mode 100644 src/util/encoding.cpp create mode 100644 src/util/encoding.h create mode 100644 src/util/item_delegates.cpp create mode 100644 src/util/item_delegates.h create mode 100644 src/util/memory.h create mode 100644 src/util/overriding_shortcut.cpp create mode 100644 src/util/overriding_shortcut.h create mode 100644 src/util/qasconst.h create mode 100644 src/util/qoverload.h create mode 100644 src/util/recording_translator.cpp create mode 100644 src/util/recording_translator.h create mode 100644 src/util/scoped_signals_blocker.cpp create mode 100644 src/util/scoped_signals_blocker.h create mode 100644 src/util/xml_stream_util.cpp create mode 100644 src/util/xml_stream_util.h create mode 100644 src/util_gui.h create mode 100644 src/util_task_dialog.cpp create mode 100644 src/util_task_dialog.h create mode 100644 src/util_translation.cpp create mode 100644 src/util_translation.h create mode 100644 suppress.txt.in create mode 100644 symbol sets/10000/Course_Design_10000.omap create mode 100644 symbol sets/10000/ISMTBOM_10000.omap create mode 100644 symbol sets/10000/ISMTBOM_uk_10000.omap create mode 100644 symbol sets/10000/ISOM_10000.omap create mode 100644 symbol sets/10000/ISOM_cs_10000.omap create mode 100644 symbol sets/10000/ISOM_fi_10000.omap create mode 100644 symbol sets/10000/ISOM_ru_10000.omap create mode 100644 symbol sets/10000/ISSkiOM_10000.omap create mode 100644 symbol sets/15000/Course_Design_15000.omap create mode 100644 symbol sets/15000/ISMTBOM_15000.omap create mode 100644 symbol sets/15000/ISMTBOM_uk_15000.omap create mode 100644 symbol sets/15000/ISOM_15000.omap create mode 100644 symbol sets/15000/ISOM_cs_15000.omap create mode 100644 symbol sets/15000/ISOM_fi_15000.omap create mode 100644 symbol sets/15000/ISOM_ru_15000.omap create mode 100644 symbol sets/15000/ISSkiOM_15000.omap create mode 100644 symbol sets/20000/ISMTBOM_20000.omap create mode 100644 symbol sets/20000/ISMTBOM_uk_20000.omap create mode 100644 symbol sets/4000/Course_Design_4000.omap create mode 100644 symbol sets/4000/ISSOM_4000.omap create mode 100644 symbol sets/4000/ISSOM_cs_4000.omap create mode 100644 symbol sets/4000/ISSOM_fi_4000.omap create mode 100644 symbol sets/4000/ISSOM_fr_4000.omap create mode 100644 symbol sets/5000/Course_Design_5000.omap create mode 100644 symbol sets/5000/ISMTBOM_5000.omap create mode 100644 symbol sets/5000/ISMTBOM_uk_5000.omap create mode 100644 symbol sets/5000/ISSOM_5000.omap create mode 100644 symbol sets/5000/ISSOM_cs_5000.omap create mode 100644 symbol sets/5000/ISSOM_fi_5000.omap create mode 100644 symbol sets/5000/ISSOM_fr_5000.omap create mode 100644 symbol sets/5000/ISSkiOM_5000.omap create mode 100644 symbol sets/7500/ISMTBOM_7500.omap create mode 100644 symbol sets/7500/ISMTBOM_uk_7500.omap create mode 100644 symbol sets/CMakeLists.txt create mode 100644 symbol sets/README.md create mode 100644 symbol sets/src/Course_Design_10000.xmap create mode 100644 symbol sets/src/ISMTBOM_15000.xmap create mode 100644 symbol sets/src/ISMTBOM_ru_15000.xmap create mode 100644 symbol sets/src/ISMTBOM_uk_15000.xmap create mode 100644 symbol sets/src/ISOM_15000.xmap create mode 100644 symbol sets/src/ISOM_cs_15000.xmap create mode 100644 symbol sets/src/ISOM_fi_15000.xmap create mode 100644 symbol sets/src/ISOM_ru_15000.xmap create mode 100644 symbol sets/src/ISSOM_5000.xmap create mode 100644 symbol sets/src/ISSOM_cs_5000.xmap create mode 100644 symbol sets/src/ISSOM_fi_5000.xmap create mode 100644 symbol sets/src/ISSOM_fr_5000.xmap create mode 100644 symbol sets/src/ISSkiOM_15000.xmap create mode 100644 symbol sets/symbol sets.pro create mode 100644 test/AUTORUN_TESTS.cmake.in create mode 100644 test/CMakeLists.txt create mode 100644 test/TESTNAME-RUN.cmake.in create mode 100644 test/autosave_t.cpp create mode 100644 test/autosave_t.h create mode 100644 test/coord_xml_t.cpp create mode 100644 test/coord_xml_t.h create mode 100644 test/data/CMakeLists.txt create mode 100644 test/data/issue-513-coords-outside-printable.omap create mode 100644 test/data/issue-513-coords-outside-printable.xmap create mode 100644 test/data/issue-513-coords-outside-qint32.omap create mode 100644 test/data/spotcolor_overprint.xmap create mode 100644 test/data/test_map.omap create mode 100644 test/duplicate_equals_t.cpp create mode 100644 test/duplicate_equals_t.h create mode 100644 test/encoding_t.cpp create mode 100644 test/encoding_t.h create mode 100644 test/file_format_t.cpp create mode 100644 test/file_format_t.h create mode 100644 test/georeferencing_t.cpp create mode 100644 test/georeferencing_t.h create mode 100644 test/locale_t.cpp create mode 100644 test/locale_t.h create mode 100644 test/map_color_t.cpp create mode 100644 test/map_color_t.h create mode 100644 test/map_t.cpp create mode 100644 test/map_t.h create mode 100644 test/mapper_t.cpp create mode 100644 test/object_query_t.cpp create mode 100644 test/object_query_t.h create mode 100644 test/path_object_t.cpp create mode 100644 test/path_object_t.h create mode 100644 test/qpainter_t.cpp create mode 100644 test/qpainter_t.h create mode 100644 test/symbol_set_t.cpp create mode 100644 test/symbol_set_t.h create mode 100644 test/tools_t.cpp create mode 100644 test/tools_t.h create mode 100644 test/transform_t.cpp create mode 100644 test/transform_t.h create mode 100644 test/tst_qglobal.cpp create mode 100644 test/tst_qglobal.h create mode 100644 test/undo_manager_t.cpp create mode 100644 test/undo_manager_t.h create mode 100644 translations/CMakeLists.txt create mode 100644 translations/OpenOrienteering_cs.ts create mode 100644 translations/OpenOrienteering_da.ts create mode 100644 translations/OpenOrienteering_de.ts create mode 100644 translations/OpenOrienteering_en.ts create mode 100644 translations/OpenOrienteering_eo.ts create mode 100644 translations/OpenOrienteering_es.ts create mode 100644 translations/OpenOrienteering_et.ts create mode 100644 translations/OpenOrienteering_fi.ts create mode 100644 translations/OpenOrienteering_fr.ts create mode 100644 translations/OpenOrienteering_he.ts create mode 100644 translations/OpenOrienteering_hu.ts create mode 100644 translations/OpenOrienteering_id.ts create mode 100644 translations/OpenOrienteering_it.ts create mode 100644 translations/OpenOrienteering_ja.ts create mode 100644 translations/OpenOrienteering_lv.ts create mode 100644 translations/OpenOrienteering_nb.ts create mode 100644 translations/OpenOrienteering_nl.ts create mode 100644 translations/OpenOrienteering_pl.ts create mode 100644 translations/OpenOrienteering_pt_BR.ts create mode 100644 translations/OpenOrienteering_ru.ts create mode 100644 translations/OpenOrienteering_sv.ts create mode 100644 translations/OpenOrienteering_template.ts create mode 100644 translations/OpenOrienteering_uk.ts create mode 100644 translations/OpenOrienteering_zh_CN.ts create mode 100644 translations/future_translations.cpp create mode 100644 translations/locversion.plist.in create mode 100644 translations/qt_template.ts create mode 100755 translations/translate_text_files.sh create mode 100644 translations/translations.pro diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md new file mode 100644 index 0000000..3f386a6 --- /dev/null +++ b/.github/ISSUE_TEMPLATE.md @@ -0,0 +1,14 @@ +### Steps to reproduce +1. +2. +3. + +### Actual behaviour +Tell us what happens + +### Expected behaviour +Tell us what should happen instead + +### Configuration +Mapper Version: +Operating System: diff --git a/3rd-party/clipper/CMakeLists.txt b/3rd-party/clipper/CMakeLists.txt new file mode 100644 index 0000000..68e9f02 --- /dev/null +++ b/3rd-party/clipper/CMakeLists.txt @@ -0,0 +1,121 @@ +# +# Copyright 2013-2015 Kai Pastor +# +# This file is part of OpenOrienteering. +# +# OpenOrienteering is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# OpenOrienteering is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with OpenOrienteering. If not, see . + + +project(Clipper) + +cmake_minimum_required(VERSION 2.8.3) + +# Configuration options + +set(CLIPPER_VERSION_DEFAULT 6.1.3a) +if(CLIPPER_VERSION MATCHES "^5") + unset(CLIPPER_VERSION CACHE) # source incompatible +endif() +set(CLIPPER_VERSION ${CLIPPER_VERSION_DEFAULT} CACHE STRING + "Version number of the Clipper library, recommended value: 6.1.3a") +mark_as_advanced(CLIPPER_VERSION) + + + +message(STATUS "Configuring Clipper library ${CLIPPER_VERSION}") + +if (NOT ${CLIPPER_VERSION} STREQUAL ${CLIPPER_VERSION_DEFAULT}) + message(WARNING + "The Clipper library version is different from the current recommended version " + "(${CLIPPER_VERSION} vs. ${CLIPPER_VERSION_DEFAULT}).") +endif() + +# Optionally use externally provided clipper source dir (e.g. Debian packaging) +set(CLIPPER_SOURCE_DIR_DEFAULT) +set(CLIPPER_SOURCE_DIR "${CLIPPER_SOURCE_DIR_DEFAULT}" CACHE STRING + "The Clipper library source directory to be used instead of a download") +mark_as_advanced(CLIPPER_SOURCE_DIR) + +if(CLIPPER_SOURCE_DIR) + # Expand variables like @PROJECT_SOURCE_DIR@ + string(CONFIGURE "${CLIPPER_SOURCE_DIR}" EXPANDED_SOURCE_DIR @ONLY) + set(CLIPPER_SOURCE + SOURCE_DIR "${EXPANDED_SOURCE_DIR}" + ) +else() + set(CLIPPER_MD5SUMS + # Schema: VERSION:MD5 + 6.1.3a:4dcd043ce48de59714f07bd3ec7ac62b + ) + foreach(line ${CLIPPER_MD5SUMS}) + if(${line} MATCHES "^${CLIPPER_VERSION}:") + string(REPLACE "${CLIPPER_VERSION}:" "" CLIPPER_MD5 ${line}) + break() + endif() + endforeach() + if(NOT CLIPPER_MD5) + message(FATAL_ERROR + "Unknown MD5 sum for Clipper library ${CLIPPER_VERSION}. " + "Edit ${PROJECT_SOURCE_DIR}/CMakeLists.txt, " + "or specify the correct CLIPPER_MD5 value at the command line.") + endif() + set(CLIPPER_SOURCE + DOWNLOAD_DIR ${PROJECT_SOURCE_DIR}/download + URL "http://sourceforge.net/projects/polyclipping/files/clipper_ver${CLIPPER_VERSION}.zip/download" + URL_MD5 ${CLIPPER_MD5} + ) +endif() + +set(CLIPPER_LICENSE_FILE "${PROJECT_SOURCE_DIR}/License.txt") +if(EXISTS "${CLIPPER_LICENSE_FILE}.${CLIPPER_VERSION}") + set(CLIPPER_LICENSE_FILE "${CLIPPER_LICENSE_FILE}.${CLIPPER_VERSION}") +endif() +file(GLOB CLIPPER_LICENSE_FILES License.txt*) +add_custom_target(clipper-licenses + COMMENT "This target makes Qt Creator show all sources in the project tree." + SOURCES ${CLIPPER_LICENSE_FILES} +) + +# External project definition + +include(ExternalProject) +ExternalProject_Add( + Clipper + ${CLIPPER_SOURCE} + CONFIGURE_COMMAND + # Check that the license hasn't changed. + ${CMAKE_COMMAND} -E compare_files /License.txt "${CLIPPER_LICENSE_FILE}" + COMMAND + # Force source file timestamp update. + ${CMAKE_COMMAND} -E copy /cpp/clipper.cpp "${CMAKE_CURRENT_BINARY_DIR}/clipper.cpp" + BUILD_COMMAND "" + INSTALL_COMMAND "" +) +ExternalProject_Get_Property(Clipper SOURCE_DIR) + + +# The actual library build + +if(CMAKE_COMPILER_IS_GNUCXX) + string(REPLACE "-Wpedantic" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}") +endif() + +set(CLIPPER_SOURCES "${CMAKE_CURRENT_BINARY_DIR}/clipper.cpp") +set_source_files_properties(${CLIPPER_SOURCES} PROPERTIES GENERATED TRUE) + +add_library(polyclipping STATIC ${CLIPPER_SOURCES}) + +target_include_directories(polyclipping PUBLIC ${SOURCE_DIR}/cpp) + +add_dependencies(polyclipping Clipper) diff --git a/3rd-party/clipper/License.txt b/3rd-party/clipper/License.txt new file mode 100644 index 0000000..3793cdd --- /dev/null +++ b/3rd-party/clipper/License.txt @@ -0,0 +1,26 @@ +The Clipper Library (including Delphi, C++ & C# source code, other accompanying +code, examples and documentation), hereafter called "the Software", has been +released under the following license, terms and conditions: + +Boost Software License - Version 1.0 - August 17th, 2003 +http://www.boost.org/LICENSE_1_0.txt + +Permission is hereby granted, free of charge, to any person or organization +obtaining a copy of the Software covered by this license to use, reproduce, +display, distribute, execute, and transmit the Software, and to prepare +derivative works of the Software, and to permit third-parties to whom the +Software is furnished to do so, all subject to the following: + +The copyright notices in the Software and this entire statement, including the +above license grant, this restriction and the following disclaimer, must be +included in all copies of the Software, in whole or in part, and all derivative +works of the Software, unless such copies or derivative works are solely in the +form of machine-executable object code generated by a source language processor. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL +THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE FOR ANY +DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/3rd-party/clipper/clipper.pro b/3rd-party/clipper/clipper.pro new file mode 100644 index 0000000..b6705a6 --- /dev/null +++ b/3rd-party/clipper/clipper.pro @@ -0,0 +1,54 @@ +# +# Copyright 2013, 2014 Kai Pastor +# +# This file is part of OpenOrienteering. +# +# OpenOrienteering is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# OpenOrienteering is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with OpenOrienteering. If not, see . + +TEMPLATE = aux +CONFIG += c++11 +CONFIG -= debug_and_release + +CMAKE_TOOLCHAIN_FILE = $$clean_path($$OUT_PWD/../../toolchain.cmake) +if (exists($$CMAKE_TOOLCHAIN_FILE)) { + CMAKE_ARGS += "-DCMAKE_TOOLCHAIN_FILE=\"$$CMAKE_TOOLCHAIN_FILE\"" + clipper.depends += $$CMAKE_TOOLCHAIN_FILE +} + +clipper.dir = $$OUT_PWD/clipper +clipper.target = $$clipper.dir/libpolyclipping.a +win32:!gcc: clipper.target = $$clipper.dir/libpolyclipping.lib +clipper.commands = \ + mkdir -p "$$clipper.dir" && \ + cd "$$clipper.dir" && \ + if [ -d CMakeFiles -o -f CMakeCache.txt ] ; then rm -R CMake*; fi && \ + if [ -d Clipper-prefix ] ; then rm -R Clipper-prefix; fi && \ + cmake "$$PWD" $$CMAKE_ARGS && \ + PATH="$$NDK_TOOLCHAIN_PATH/bin:${PATH}" $(MAKE) VERBOSE=$(VERBOSE) + +QMAKE_EXTRA_TARGETS += clipper +PRE_TARGETDEPS += $$clipper.target +QMAKE_CLEAN += $$clipper.target + +CLIPPER_PRI = \ + "$$LITERAL_HASH Generated by $$_PRO_FILE_" \ + "DEPENDPATH += $$clipper.dir/Clipper-prefix/src/Clipper/cpp" \ + "INCLUDEPATH += $$clipper.dir/Clipper-prefix/src/Clipper/cpp" \ + "LIBS += \"-L$$clipper.dir\"" + +write_file($$OUT_PWD/clipper.pri, CLIPPER_PRI) + +OTHER_FILES += \ + CMakeLists.txt \ + License.txt diff --git a/3rd-party/clipper/download/README.txt b/3rd-party/clipper/download/README.txt new file mode 100644 index 0000000..5703953 --- /dev/null +++ b/3rd-party/clipper/download/README.txt @@ -0,0 +1 @@ +This directory contains downloaded Clipper source archives. diff --git a/3rd-party/doxygen/CMakeLists.txt b/3rd-party/doxygen/CMakeLists.txt new file mode 100644 index 0000000..ad737ac --- /dev/null +++ b/3rd-party/doxygen/CMakeLists.txt @@ -0,0 +1,100 @@ +# +# Copyright 2014 Kai Pastor +# +# This file is part of OpenOrienteering. +# +# OpenOrienteering is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# OpenOrienteering is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with OpenOrienteering. If not, see . + + +project(Doxygen NONE) + +cmake_minimum_required(VERSION 2.8.3) + +# Configuration options + +set(DOXYGEN_VERSION_DEFAULT 1.8.8) +set(DOXYGEN_VERSION ${DOXYGEN_VERSION_DEFAULT} CACHE STRING + "Version number of the doxygen library") +mark_as_advanced(DOXYGEN_VERSION) + +message(STATUS "Configuring doxygen ${DOXYGEN_VERSION}") + +if (NOT ${DOXYGEN_VERSION} STREQUAL ${DOXYGEN_VERSION_DEFAULT}) + message(WARNING + "The doxygen library version is different from the current recommended version " + "(${DOXYGEN_VERSION} vs. ${DOXYGEN_VERSION_DEFAULT}).") +endif() + +set(DOXYGEN_MD5SUMS + # Schema: VERSION:MD5 + 1.8.8:453892def7b378df387585a9358c23d4 +) +foreach(line ${DOXYGEN_MD5SUMS}) + if(${line} MATCHES "^${DOXYGEN_VERSION}:") + string(REPLACE "${DOXYGEN_VERSION}:" "" DOXYGEN_MD5 ${line}) + break() + endif() +endforeach() +if(NOT DOXYGEN_MD5) + message(FATAL_ERROR + "Unknown MD5 sum for doxygen library ${DOXYGEN_VERSION}. " + "Edit ${PROJECT_SOURCE_DIR}/CMakeLists.txt, " + "or specify the correct DOXYGEN_MD5 value at the command line.") +endif() +set(DOXYGEN_SOURCE + DOWNLOAD_DIR ${PROJECT_SOURCE_DIR}/download + URL "http://sourceforge.net/projects/doxygen/files/rel-${DOXYGEN_VERSION}/doxygen-${DOXYGEN_VERSION}.src.tar.gz/download" + URL_MD5 ${DOXYGEN_MD5} +) + +set(DOXYGEN_LICENSE_FILE "${PROJECT_SOURCE_DIR}/LICENSE") +if(EXISTS "${DOXYGEN_LICENSE_FILE}.${DOXYGEN_VERSION}") + set(DOXYGEN_LICENSE_FILE "${DOXYGEN_LICENSE_FILE}.${DOXYGEN_VERSION}") +endif() +file(GLOB DOXYGEN_LICENSE_FILES LICENSE*) +add_custom_target(doxygen-licenses + COMMENT "This target makes Qt Creator show all sources in the project tree." + SOURCES ${DOXYGEN_LICENSE_FILES} +) + +# External project definition + +include(ExternalProject) +ExternalProject_Add( + doxygen-project + ${DOXYGEN_SOURCE} + # Check that the license hasn't changed. + PATCH_COMMAND sed -e "/This version of Mac OS X is unsupported/d" -i.orig qtools/qglobal.h + CONFIGURE_COMMAND + # Check that the license hasn't changed. + ${CMAKE_COMMAND} -E compare_files /LICENSE "${DOXYGEN_LICENSE_FILE}" + COMMAND + "/configure" "--release" "--prefix" "" + BUILD_IN_SOURCE 1 +) +ExternalProject_Get_Property(doxygen-project INSTALL_DIR) + + +# Exported configuration + +add_executable(doxygen IMPORTED GLOBAL) +set_target_properties(doxygen PROPERTIES + IMPORTED_LOCATION "${INSTALL_DIR}/bin/doxygen" +) +add_dependencies(doxygen doxygen-project) +set(DOXYGEN_EXECUTABLE doxygen CACHE PATH + "The path where to find doxygen" + FORCE +) +mark_as_advanced(DOXYGEN_EXECUTABLE) diff --git a/3rd-party/doxygen/LICENSE b/3rd-party/doxygen/LICENSE new file mode 100644 index 0000000..219ec28 --- /dev/null +++ b/3rd-party/doxygen/LICENSE @@ -0,0 +1,340 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) yyyy + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) yyyy name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/3rd-party/doxygen/download/README.txt b/3rd-party/doxygen/download/README.txt new file mode 100644 index 0000000..72c1922 --- /dev/null +++ b/3rd-party/doxygen/download/README.txt @@ -0,0 +1 @@ +This directory contains downloaded doxygen source archives. diff --git a/3rd-party/doxygen/doxygen.pro b/3rd-party/doxygen/doxygen.pro new file mode 100644 index 0000000..caccdd4 --- /dev/null +++ b/3rd-party/doxygen/doxygen.pro @@ -0,0 +1,51 @@ +# +# Copyright 2015 Kai Pastor +# +# This file is part of OpenOrienteering. +# +# OpenOrienteering is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# OpenOrienteering is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with OpenOrienteering. If not, see . + +TEMPLATE = aux +CONFIG -= debug_and_release + +CMAKE_TOOLCHAIN_FILE = $$clean_path($$OUT_PWD/../../toolchain.cmake) +if (exists($$CMAKE_TOOLCHAIN_FILE)) { + CMAKE_ARGS += "-DCMAKE_TOOLCHAIN_FILE=\"$$CMAKE_TOOLCHAIN_FILE\"" + doxygen.depends += $$CMAKE_TOOLCHAIN_FILE +} + +doxygen.dir = $$OUT_PWD/doxygen +doxygen.target = $$doxygen.dir/doxygen-project-prefix/bin/doxygen +win32: doxygen.target = $$doxygen.dir/doxygen-project-prefix/bin/doxygen.exe +doxygen.commands = \ + mkdir -p "$$doxygen.dir" && \ + cd "$$doxygen.dir" && \ + if [ -d CMakeFiles -o -f CMakeCache.txt ] ; then rm -R CMake*; fi && \ + if [ -d doxygen-project-prefix ] ; then rm -R doxygen-project-prefix; fi && \ + cmake "$$PWD" $$CMAKE_ARGS && \ + $(MAKE) all VERBOSE=$(VERBOSE) && \ + $(MAKE) clean VERBOSE=$(VERBOSE) + +QMAKE_EXTRA_TARGETS += doxygen +PRE_TARGETDEPS += $$doxygen.target +QMAKE_CLEAN += $$doxygen.target + +DOXYGEN_PRI = \ + "$$LITERAL_HASH Generated by $$_PRO_FILE_" + +write_file($$OUT_PWD/doxygen.pri, DOXYGEN_PRI) + +OTHER_FILES += \ + CMakeLists.txt \ + LICENSE diff --git a/3rd-party/gcc-mxe/README b/3rd-party/gcc-mxe/README new file mode 100644 index 0000000..e2872d5 --- /dev/null +++ b/3rd-party/gcc-mxe/README @@ -0,0 +1,20 @@ +make-source.sh creates a tarball of MXE.cc and the sources files which are +required to build gcc C/C++ toolchains for +- i686-w64-mingw32.shared +- x86_64-w64-mingw32.shared + +See make-source.sh for modifications which are applied to MXE.cc before +packaging. + +To build gcc and its dependencies from the extracted tarball, run + + make gcc + +This will use the sources which came with this package. + +To build gdb, run + + make gdb + +The sources of gdb and of its dependencies will be downloaded on first build. + diff --git a/3rd-party/gcc-mxe/make-source.sh b/3rd-party/gcc-mxe/make-source.sh new file mode 100755 index 0000000..de7616b --- /dev/null +++ b/3rd-party/gcc-mxe/make-source.sh @@ -0,0 +1,93 @@ +#/bin/sh -e +# +# (C) 2014 Kai Pastor +# +# This file is part of OpenOrienteering. +# +# OpenOrienteering is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# OpenOrienteering is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with OpenOrienteering. If not, see . + +LANG=C +MXE_TARGET="i686-w64-mingw32.shared x86_64-w64-mingw32.shared" +MXE_DIR=gcc-mxe-$(date +%Y%m%d) +PKG_LIST="binutils cloog gcc gcc-cloog gcc-isl gcc-gmp gcc-mpc gcc-mpfr gmp isl mingw-w64 mpc mpfr pkgconf" +PKG_LIST="$PKG_LIST gdb expat libiconv pdcurses readline zlib" + +git clone -b master https://github.com/mxe/mxe.git $MXE_DIR + +( cd $MXE_DIR ; git show-branch --list --reflog=1 ) > $MXE_DIR/GIT_SHOW_BRANCH + +for I in $MXE_DIR/.git* $MXE_DIR/assets $MXE_DIR/doc $MXE_DIR/tools/* src/cmake +do + echo $I + case "$I" in + */tools/compat-init.sh) + ;; # keep it + */tools/make-shared-from-static) + ;; # keep it + */tools/update-*) + ;; # keep it + *) + rm -Rf "$I" + ;; + esac +done + +for I in $(sed -n 's/^.* class="package">\([^<]*\)<.*$/\1/p' "$MXE_DIR/index.html") +do + echo " $PKG_LIST " | grep " $I " > /dev/null && I= + if [ -n "$I" ] + then + rm $MXE_DIR/src/$I.mk $MXE_DIR/src/$I-* 2>/dev/null || true + sed -i -e '//N;/^.* class="package">'"$I"' $MXE_DIR/settings.mk << END_SETTINGS +MXE_TARGETS := $MXE_TARGET +#JOBS := 6 + +END_SETTINGS + +mkdir $MXE_DIR/OpenOrienteering +cp "$0" $MXE_DIR/OpenOrienteering/ +cat > $MXE_DIR/README << END_README +$(LANG=C date) OpenOrienteering + +This is a clone of MXE.cc modified to fulfil the sole purpose of a controlled +build of a $(echo ${MXE_TARGET} | sed -e 's/ /\//') C/C++ toolchain. +See OpenOrienteering/make-source.sh for the modifications. + +To build gcc and its dependencies, run + + make gcc + +This will use existing sources which came with this package. + +To build gdb, run + + make gdb + +The sources of gdb and of its dependencies will be downloaded on first build. + +END_README + +make -C $MXE_DIR download-gcc + +fakeroot tar cvzf $MXE_DIR-src.tar.gz $MXE_DIR + diff --git a/3rd-party/gdal/CMakeLists.txt b/3rd-party/gdal/CMakeLists.txt new file mode 100644 index 0000000..dd1cf1e --- /dev/null +++ b/3rd-party/gdal/CMakeLists.txt @@ -0,0 +1,209 @@ +# +# Copyright 2016 Kai Pastor +# +# This file is part of OpenOrienteering. +# +# OpenOrienteering is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# OpenOrienteering is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with OpenOrienteering. If not, see . + + +project(GDAL) + +cmake_minimum_required(VERSION 2.8.3) + +include(ExternalProject) + +# Configuration options + +set(GDAL_VERSION_DEFAULT 2.0.1+dfsg) +set(GDAL_VERSION ${GDAL_VERSION_DEFAULT} CACHE STRING + "Version number of the GDAL library, recommended value: ${GDAL_VERSION_DEFAULT}") +mark_as_advanced(GDAL_VERSION) + +message(STATUS "Configuring GDAL library ${GDAL_VERSION}") + +string(REGEX MATCH "^[0-9]\\.[0-9]+\\.[0-9]+" GDAL_MAJOR_MINOR_REVISION ${GDAL_VERSION}) +if (NOT "${GDAL_VERSION}" MATCHES "^${GDAL_MAJOR_MINOR_REVISION}") + message(WARNING + "The GDAL library version is different from the current recommended version " + "(${GDAL_VERSION} vs. ${GDAL_VERSION_DEFAULT}).") +endif() + +set(GDAL_MD5SUMS + 2.0.1+dfsg:18e207a12f920e2a40405891eb6168ec:https://github.com/OpenOrienteering/sources/releases/download/3rd-party/gdal_2.0.1.dfsg.orig.tar.gz +) +string(REPLACE "+" "[+]" GDAL_VERSION_REGEX "${GDAL_VERSION}") +foreach(line ${GDAL_MD5SUMS}) + if(${line} MATCHES "^${GDAL_VERSION_REGEX}:") + string(REPLACE "${GDAL_VERSION}:" "" GDAL_MD5 ${line}) + break() + endif() +endforeach() +if(NOT GDAL_MD5) + message(FATAL_ERROR + "Unknown MD5 sum for GDAL library ${GDAL_VERSION}. " + "Edit ${GDALECT_SOURCE_DIR}/CMakeLists.txt, " + "or specify the correct GDAL_MD5 value at the command line.") +endif() +if(GDAL_MD5 MATCHES ":") + message(WARNING "Not using an official release of GDAL.") + string(REGEX REPLACE "^[0-9a-fA-F]*:" "" GDAL_URL "${GDAL_MD5}") + string(REGEX REPLACE ":.*" "" GDAL_MD5 "${GDAL_MD5}") +elseif(GDAL_VERSION MATCHES "-openorienteering-") + set(GDAL_URL "https://github.com/OpenOrienteering/sources/releases/download/3rd-party/gdal-${GDAL_VERSION}.tar.gz") +else() + set(GDAL_URL "http://download.osgeo.org/gdal/${GDAL_VERSION}/gdal-${GDAL_VERSION}.tar.gz") +endif() + +set(GDAL_LICENSE_FILE "${PROJECT_SOURCE_DIR}/LICENSE.TXT") +if(EXISTS "${GDAL_LICENSE_FILE}.${GDAL_VERSION}") + set(GDAL_LICENSE_FILE "${GDAL_LICENSE_FILE}.${GDAL_VERSION}") +endif() + + +# External project definition + +set(GDAL_EXTRA_FLAGS "-Wno-unused-parameter -Wno-ignored-qualifiers -Wno-unused-private-field -Wno-deprecated-register") +string(REGEX REPLACE "-Wpedantic|-Wall" "" GDAL_CFLAGS "${CMAKE_C_FLAGS} ${CMAKE_C_FLAGS_RELEASE} ${GDAL_EXTRA_FLAGS}") +string(REGEX REPLACE "-Wpedantic|-Wall" "" GDAL_CXXFLAGS "${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_RELEASE} ${GDAL_EXTRA_FLAGS}") +if(CMAKE_CROSSCOMPILING AND NOT GNU_SYSTEM_NAME AND MINGW) + set(_env_lang $ENV{LC_ALL}) + set(ENV{LC_ALL} C) + execute_process( + COMMAND ${CMAKE_C_COMPILER} -v + ERROR_VARIABLE GNU_SYSTEM_NAME + ) + set(ENV{LC_ALL} ${_env_lang}) + string(REGEX REPLACE ".*Target: ?([^\n]*).*" \\1 GNU_SYSTEM_NAME ${GNU_SYSTEM_NAME}) +endif() +if(CMAKE_CROSSCOMPILING AND GNU_SYSTEM_NAME) + execute_process( + COMMAND "${CMAKE_CURRENT_SOURCE_DIR}/patches/config.guess" + OUTPUT_VARIABLE build + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + set(GDAL_CONFIG_EXTRA "--host=${GNU_SYSTEM_NAME}" "--build=${build}" --without-expat) + get_directory_property(_include_dirs INCLUDE_DIRECTORIES) + if(_include_dirs) + unset(_cpp_flags) + foreach(_dir ${_include_dirs}) + set(_cpp_flags "${_cpp_flags} -I${_dir}") + endforeach() + list(APPEND GDAL_CONFIG_EXTRA "CPPFLAGS=${_cpp_flags}") + endif() + if(GNU_SYSTEM_NAME STREQUAL "arm-linux-androideabi") + set(STANDALONE_TOOLCHAIN arm-linux-androideabi-4.9) + set(CMAKE_C_COMPILER /toolchain/${STANDALONE_TOOLCHAIN}/bin/arm-linux-androideabi-gcc) + set(CMAKE_CXX_COMPILER /toolchain/${STANDALONE_TOOLCHAIN}/bin/arm-linux-androideabi-g++) + elseif(GNU_SYSTEM_NAME STREQUAL "i686-linux-android") + set(STANDALONE_TOOLCHAIN arm-linux-androideabi-gcc-4.9) + set(CMAKE_C_COMPILER /toolchain/${STANDALONE_TOOLCHAIN}/bin/i686-linux-android-gcc) + set(CMAKE_CXX_COMPILER /toolchain/${STANDALONE_TOOLCHAIN}/bin/i686-linux-android-g++) + elseif(ANDROID) + message(WARNING "Unsupported Android architecture '${GNU_SYSTEM_NAME}'") + endif() +elseif(APPLE) + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -stdlib=libc++") + # Didn't manage to pass the deployment target to all libtool link steps + #string(REGEX REPLACE "(^| )(--?[^W])" "\\1-Wl,\\2" CMAKE_EXE_LINKER_FLAGS ${CMAKE_EXE_LINKER_FLAGS}) + set(GDAL_CONFIG_EXTRA --without-libtool) +else() + unset(GDAL_CONFIG_EXTRA) +endif() + +include(ExternalProject) +ExternalProject_Add( + GDAL + DOWNLOAD_DIR ${PROJECT_SOURCE_DIR}/download + URL ${GDAL_URL} + URL_MD5 ${GDAL_MD5} + PATCH_COMMAND + cp ${PROJECT_SOURCE_DIR}/patches/config.sub ${PROJECT_SOURCE_DIR}/patches/config.guess / + COMMAND + find ${PROJECT_SOURCE_DIR}/patches -name gdal-${GDAL_MAJOR_MINOR_REVISION}*.patch -exec patch -p0 -N -i {} + + CONFIGURE_COMMAND + # Check that the license hasn't changed. + ${CMAKE_COMMAND} -E compare_files /LICENSE.TXT "${GDAL_LICENSE_FILE}" + COMMAND + "/configure" + "--prefix=" + --disable-static + --enable-shared + --with-ogr + --with-hide-internal-symbols + --with-rename-internal-libtiff-symbols + --without-jpeg12 # possible violation of ODR in GDAL < 2.1 + --with-threads=no + --without-pcraster + --without-grib + --without-perl + --without-php + --without-python + --without-java + ${GDAL_CONFIG_EXTRA} + "CC=${CMAKE_C_COMPILER}" + "CFLAGS=${GDAL_CFLAGS}" + "CXX=${CMAKE_CXX_COMPILER}" + "CXXFLAGS=${GDAL_CXXFLAGS}" + "LDFLAGS=${CMAKE_EXE_LINKER_FLAGS}" + BUILD_COMMAND + "\$(MAKE)" + INSTALL_COMMAND + "\$(MAKE)" -j1 install + BUILD_IN_SOURCE 1 +) + +if(ANDROID AND STANDALONE_TOOLCHAIN) + ExternalProject_Add_Step(GDAL toolchain + COMMENT "Creating standalone toolchain" + DEPENDEES update + DEPENDERS configure + COMMAND + bash $(ANDROID_NDK_ROOT)/build/tools/make-standalone-toolchain.sh + --install-dir=/toolchain/${STANDALONE_TOOLCHAIN} + --platform=$(ANDROID_NDK_PLATFORM) + --toolchain=${STANDALONE_TOOLCHAIN} + ) +endif() + + +# Exported configuration + +# The following will not succeed during the initial configuration +# but on repeated configuration after an successful build. + +ExternalProject_Get_Property(GDAL BINARY_DIR) +ExternalProject_Get_Property(GDAL INSTALL_DIR) + +find_path(GDAL_INCLUDE_DIR NAMES gdal.h PATHS + "${INSTALL_DIR}/include" + NO_DEFAULT_PATH + NO_CMAKE_FIND_ROOT_PATH +) +mark_as_advanced(GDAL_INCLUDE_DIR) + +find_library(GDAL_LIBRARY NAMES gdal PATHS + "${INSTALL_DIR}/lib" + NO_DEFAULT_PATH + NO_CMAKE_FIND_ROOT_PATH +) +mark_as_advanced(GDAL_LIBRARY) + +if(GDAL_INCLUDE_DIR AND GDAL_LIBRARY) + set(GDAL_BINARY_DIR "${INSTALL_DIR}/bin" PARENT_SCOPE) + mark_as_advanced(GDAL_BINARY_DIR) + set(GDAL_FOUND TRUE PARENT_SCOPE) +endif() + +# Don't let Xcode re-root the install +set_target_properties(GDAL PROPERTIES XCODE_ATTRIBUTE_INSTALL_ROOT "") diff --git a/3rd-party/gdal/LICENSE.TXT b/3rd-party/gdal/LICENSE.TXT new file mode 100644 index 0000000..d65fdd2 --- /dev/null +++ b/3rd-party/gdal/LICENSE.TXT @@ -0,0 +1,263 @@ + +GDAL/OGR Licensing +================== + +This file attempts to include all licenses that apply within the GDAL/OGR +source tree, in particular any that are supposed to be exposed to the end user +for credit requirements for instance. The contents of this file can be +displayed from GDAL commandline utilities using the --license commandline +switch. + + +GDAL/OGR General +---------------- + +In general GDAL/OGR is licensed under an MIT/X style license with the +following terms: + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, distribute, sublicense, +and/or sell copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. + + +gdal/frmts/gtiff/tif_float.c +---------------------------- + +Copyright (c) 2002, Industrial Light & Magic, a division of Lucas +Digital Ltd. LLC + +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: +* Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. +* Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. +* Neither the name of Industrial Light & Magic nor the names of +its contributors may be used to endorse or promote products derived +from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +gdal/frmts/hdf4/hdf-eos/* +------------------------ + + Copyright (C) 1996 Hughes and Applied Research Corporation + + Permission to use, modify, and distribute this software and its documentation + for any purpose without fee is hereby granted, provided that the above + copyright notice appear in all copies and that both that copyright notice and + this permission notice appear in supporting documentation. + + +gdal/frmts/pcraster/libcsf +-------------------------- + +Copyright (c) 1997-2003, Utrecht University +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + +* Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + +* Neither the name of Utrecht University nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +gdal/frmts/grib/degrib/* +------------------------ + +The degrib and g2clib source code are modified versions of code produced +by NOAA NWS and are in the public domain subject to the following +restrictions: + +http://www.weather.gov/im/softa.htm + +DISCLAIMER The United States Government makes no warranty, expressed or +implied, as to the usefulness of the software and documentation for any +purpose. The U.S. Government, its instrumentalities, officers, employees, +and agents assumes no responsibility (1) for the use of the software and +documentation listed below, or (2) to provide technical support to users. + +http://www.weather.gov/disclaimer.php + + The information on government servers are in the public domain, unless +specifically annotated otherwise, and may be used freely by the public so +long as you do not 1) claim it is your own (e.g. by claiming copyright for +NWS information -- see below), 2) use it in a manner that implies an +endorsement or affiliation with NOAA/NWS, or 3) modify it in content and +then present it as official government material. You also cannot present +information of your own in a way that makes it appear to be official +government information.. + + The user assumes the entire risk related to its use of this data. NWS is +providing this data "as is," and NWS disclaims any and all warranties, +whether express or implied, including (without limitation) any implied +warranties of merchantability or fitness for a particular purpose. In no +event will NWS be liable to you or to any third party for any direct, +indirect, incidental, consequential, special or exemplary damages or lost +profit resulting from any use or misuse of this data. + + As required by 17 U.S.C. 403, third parties producing copyrighted works +consisting predominantly of the material appearing in NWS Web pages must +provide notice with such work(s) identifying the NWS material incorporated +and stating that such material is not subject to copyright protection. + +port/cpl_minizip* +----------------- + +This is version 2005-Feb-10 of the Info-ZIP copyright and license. +The definitive version of this document should be available at +ftp://ftp.info-zip.org/pub/infozip/license.html indefinitely. + + +Copyright (c) 1990-2005 Info-ZIP. All rights reserved. + +For the purposes of this copyright and license, "Info-ZIP" is defined as +the following set of individuals: + + Mark Adler, John Bush, Karl Davis, Harald Denker, Jean-Michel Dubois, + Jean-loup Gailly, Hunter Goatley, Ed Gordon, Ian Gorman, Chris Herborth, + Dirk Haase, Greg Hartwig, Robert Heath, Jonathan Hudson, Paul Kienitz, + David Kirschbaum, Johnny Lee, Onno van der Linden, Igor Mandrichenko, + Steve P. Miller, Sergio Monesi, Keith Owens, George Petrov, Greg Roelofs, + Kai Uwe Rommel, Steve Salisbury, Dave Smith, Steven M. Schweda, + Christian Spieler, Cosmin Truta, Antoine Verheijen, Paul von Behren, + Rich Wales, Mike White + +This software is provided "as is," without warranty of any kind, express +or implied. In no event shall Info-ZIP or its contributors be held liable +for any direct, indirect, incidental, special or consequential damages +arising out of the use of or inability to use this software. + +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it +freely, subject to the following restrictions: + + 1. Redistributions of source code must retain the above copyright notice, + definition, disclaimer, and this list of conditions. + + 2. Redistributions in binary form (compiled executables) must reproduce + the above copyright notice, definition, disclaimer, and this list of + conditions in documentation and/or other materials provided with the + distribution. The sole exception to this condition is redistribution + of a standard UnZipSFX binary (including SFXWiz) as part of a + self-extracting archive; that is permitted without inclusion of this + license, as long as the normal SFX banner has not been removed from + the binary or disabled. + + 3. Altered versions--including, but not limited to, ports to new operating + systems, existing ports with new graphical interfaces, and dynamic, + shared, or static library versions--must be plainly marked as such + and must not be misrepresented as being the original source. Such + altered versions also must not be misrepresented as being Info-ZIP + releases--including, but not limited to, labeling of the altered + versions with the names "Info-ZIP" (or any variation thereof, including, + but not limited to, different capitalizations), "Pocket UnZip," "WiZ" + or "MacZip" without the explicit permission of Info-ZIP. Such altered + versions are further prohibited from misrepresentative use of the + Zip-Bugs or Info-ZIP e-mail addresses or of the Info-ZIP URL(s). + + 4. Info-ZIP retains the right to use the names "Info-ZIP," "Zip," "UnZip," + "UnZipSFX," "WiZ," "Pocket UnZip," "Pocket Zip," and "MacZip" for its + own source and binary releases. + + +gdal/ogr/ogrsf_frmts/dxf/intronurbs.cpp +--------------------------------------- + +This code is derived from the code associated with the book "An Introduction +to NURBS" by David F. Rogers. More information on the book and the code is +available at: + + http://www.nar-associates.com/nurbs/ + + +Copyright (c) 2009, David F. Rogers +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + * Neither the name of the David F. Rogers nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +gdal/alg/thinplatespline.cpp +---------------------------- + +IEEE754 log() code derived from: +@(#)e_log.c 1.3 95/01/18 + +Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + +Developed at SunSoft, a Sun Microsystems, Inc. business. +Permission to use, copy, modify, and distribute this +software is freely granted, provided that this notice +is preserved. diff --git a/3rd-party/gdal/download/README.txt b/3rd-party/gdal/download/README.txt new file mode 100644 index 0000000..dccca35 --- /dev/null +++ b/3rd-party/gdal/download/README.txt @@ -0,0 +1 @@ +This directory contains downloaded GDAL source archives. diff --git a/3rd-party/gdal/gdal.pro b/3rd-party/gdal/gdal.pro new file mode 100644 index 0000000..37aab9e --- /dev/null +++ b/3rd-party/gdal/gdal.pro @@ -0,0 +1,69 @@ +# +# Copyright 2016 Kai Pastor +# +# This file is part of OpenOrienteering. +# +# OpenOrienteering is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# OpenOrienteering is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with OpenOrienteering. If not, see . + +TEMPLATE = aux +CONFIG -= debug_and_release + +CMAKE_TOOLCHAIN_FILE = $$clean_path($$OUT_PWD/../../toolchain.cmake) +if (exists($$CMAKE_TOOLCHAIN_FILE)) { + CMAKE_ARGS += "-DCMAKE_TOOLCHAIN_FILE=\"$$CMAKE_TOOLCHAIN_FILE\"" + gdal.depends += $$CMAKE_TOOLCHAIN_FILE +} + +gdal.dir = $$OUT_PWD/gdal +gdal.target = $$gdal.dir/GDAL-prefix/lib/libgdal.so +osx: gdal.target = $$gdal.dir/GDAL-prefix/lib/libgdal.dylib +win32: gdal.target = $$gdal.dir/GDAL-prefix/bin/libgdal-20.dll +gdal.cflags = $$QMAKE_CFLAGS -Wno-declaration-after-statement -Wno-int-to-pointer-cast +gdal.commands = \ + mkdir -p "$$gdal.dir" && \ + cd "$$gdal.dir" && \ + if [ -d CMakeFiles -o -f CMakeCache.txt ] ; then rm -R CMake*; fi && \ + if [ -d GDAL-prefix ] ; then rm -R GDAL-prefix; fi && \ + cmake "$$PWD" $$CMAKE_ARGS && \ + PATH="$$NDK_TOOLCHAIN_PATH/bin:${PATH}" $(MAKE) VERBOSE=$(VERBOSE) all && \ + $(MAKE) clean VERBOSE=$(VERBOSE) + +QMAKE_EXTRA_TARGETS += gdal +PRE_TARGETDEPS += $$gdal.target +QMAKE_CLEAN += $$gdal.target + +GDAL_PRI = \ + "$$LITERAL_HASH Generated by $$_PRO_FILE_" \ + "DEPENDPATH += $$gdal.dir/GDAL-prefix/include" \ + "INCLUDEPATH += $$gdal.dir/GDAL-prefix/include" +win32: GDAL_PRI += \ + "LIBS += \"-L$$gdal.dir/GDAL-prefix/bin\"" +else: GDAL_PRI += \ + "LIBS += \"-L$$gdal.dir/GDAL-prefix/lib\"" +android: GDAL_PRI += \ + "ANDROID_EXTRA_LIBS += \"$$gdal.target\"" + +write_file($$OUT_PWD/gdal.pri, GDAL_PRI) + +android|win32 { + INSTALLS += gdal_data + gdal_data.prefix = + android: gdal_data.prefix = /assets + gdal_data.path = $$gdal_data.prefix/gdal + gdal_data.files = $$gdal.dir/GDAL-prefix/share/gdal/* +} + +OTHER_FILES += \ + CMakeLists.txt \ + LICENSE.TXT diff --git a/3rd-party/gdal/patches/config.guess b/3rd-party/gdal/patches/config.guess new file mode 100755 index 0000000..b79252d --- /dev/null +++ b/3rd-party/gdal/patches/config.guess @@ -0,0 +1,1558 @@ +#! /bin/sh +# Attempt to guess a canonical system name. +# Copyright 1992-2013 Free Software Foundation, Inc. + +timestamp='2013-06-10' + +# This file is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that +# program. This Exception is an additional permission under section 7 +# of the GNU General Public License, version 3 ("GPLv3"). +# +# Originally written by Per Bothner. +# +# You can get the latest version of this script from: +# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD +# +# Please send patches with a ChangeLog entry to config-patches@gnu.org. + + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] + +Output the configuration name of the system \`$me' is run on. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.guess ($timestamp) + +Originally written by Per Bothner. +Copyright 1992-2013 Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit ;; + --version | -v ) + echo "$version" ; exit ;; + --help | --h* | -h ) + echo "$usage"; exit ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" >&2 + exit 1 ;; + * ) + break ;; + esac +done + +if test $# != 0; then + echo "$me: too many arguments$help" >&2 + exit 1 +fi + +trap 'exit 1' 1 2 15 + +# CC_FOR_BUILD -- compiler used by this script. Note that the use of a +# compiler to aid in system detection is discouraged as it requires +# temporary files to be created and, as you can see below, it is a +# headache to deal with in a portable fashion. + +# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still +# use `HOST_CC' if defined, but it is deprecated. + +# Portable tmp directory creation inspired by the Autoconf team. + +set_cc_for_build=' +trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; +trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; +: ${TMPDIR=/tmp} ; + { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || + { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || + { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || + { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; +dummy=$tmp/dummy ; +tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; +case $CC_FOR_BUILD,$HOST_CC,$CC in + ,,) echo "int x;" > $dummy.c ; + for c in cc gcc c89 c99 ; do + if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then + CC_FOR_BUILD="$c"; break ; + fi ; + done ; + if test x"$CC_FOR_BUILD" = x ; then + CC_FOR_BUILD=no_compiler_found ; + fi + ;; + ,,*) CC_FOR_BUILD=$CC ;; + ,*,*) CC_FOR_BUILD=$HOST_CC ;; +esac ; set_cc_for_build= ;' + +# This is needed to find uname on a Pyramid OSx when run in the BSD universe. +# (ghazi@noc.rutgers.edu 1994-08-24) +if (test -f /.attbin/uname) >/dev/null 2>&1 ; then + PATH=$PATH:/.attbin ; export PATH +fi + +UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown +UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown +UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown +UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown + +case "${UNAME_SYSTEM}" in +Linux|GNU|GNU/*) + # If the system lacks a compiler, then just pick glibc. + # We could probably try harder. + LIBC=gnu + + eval $set_cc_for_build + cat <<-EOF > $dummy.c + #include + #if defined(__UCLIBC__) + LIBC=uclibc + #elif defined(__dietlibc__) + LIBC=dietlibc + #else + LIBC=gnu + #endif + EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'` + ;; +esac + +# Note: order is significant - the case branches are not exclusive. + +case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in + *:NetBSD:*:*) + # NetBSD (nbsd) targets should (where applicable) match one or + # more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*, + # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently + # switched to ELF, *-*-netbsd* would select the old + # object file format. This provides both forward + # compatibility and a consistent mechanism for selecting the + # object file format. + # + # Note: NetBSD doesn't particularly care about the vendor + # portion of the name. We always set it to "unknown". + sysctl="sysctl -n hw.machine_arch" + UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ + /usr/sbin/$sysctl 2>/dev/null || echo unknown)` + case "${UNAME_MACHINE_ARCH}" in + armeb) machine=armeb-unknown ;; + arm*) machine=arm-unknown ;; + sh3el) machine=shl-unknown ;; + sh3eb) machine=sh-unknown ;; + sh5el) machine=sh5le-unknown ;; + *) machine=${UNAME_MACHINE_ARCH}-unknown ;; + esac + # The Operating System including object format, if it has switched + # to ELF recently, or will in the future. + case "${UNAME_MACHINE_ARCH}" in + arm*|i386|m68k|ns32k|sh3*|sparc|vax) + eval $set_cc_for_build + if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ELF__ + then + # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). + # Return netbsd for either. FIX? + os=netbsd + else + os=netbsdelf + fi + ;; + *) + os=netbsd + ;; + esac + # The OS release + # Debian GNU/NetBSD machines have a different userland, and + # thus, need a distinct triplet. However, they do not need + # kernel version information, so it can be replaced with a + # suitable tag, in the style of linux-gnu. + case "${UNAME_VERSION}" in + Debian*) + release='-gnu' + ;; + *) + release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` + ;; + esac + # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: + # contains redundant information, the shorter form: + # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. + echo "${machine}-${os}${release}" + exit ;; + *:Bitrig:*:*) + UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'` + echo ${UNAME_MACHINE_ARCH}-unknown-bitrig${UNAME_RELEASE} + exit ;; + *:OpenBSD:*:*) + UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` + echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE} + exit ;; + *:ekkoBSD:*:*) + echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} + exit ;; + *:SolidBSD:*:*) + echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE} + exit ;; + macppc:MirBSD:*:*) + echo powerpc-unknown-mirbsd${UNAME_RELEASE} + exit ;; + *:MirBSD:*:*) + echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} + exit ;; + alpha:OSF1:*:*) + case $UNAME_RELEASE in + *4.0) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` + ;; + *5.*) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` + ;; + esac + # According to Compaq, /usr/sbin/psrinfo has been available on + # OSF/1 and Tru64 systems produced since 1995. I hope that + # covers most systems running today. This code pipes the CPU + # types through head -n 1, so we only detect the type of CPU 0. + ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` + case "$ALPHA_CPU_TYPE" in + "EV4 (21064)") + UNAME_MACHINE="alpha" ;; + "EV4.5 (21064)") + UNAME_MACHINE="alpha" ;; + "LCA4 (21066/21068)") + UNAME_MACHINE="alpha" ;; + "EV5 (21164)") + UNAME_MACHINE="alphaev5" ;; + "EV5.6 (21164A)") + UNAME_MACHINE="alphaev56" ;; + "EV5.6 (21164PC)") + UNAME_MACHINE="alphapca56" ;; + "EV5.7 (21164PC)") + UNAME_MACHINE="alphapca57" ;; + "EV6 (21264)") + UNAME_MACHINE="alphaev6" ;; + "EV6.7 (21264A)") + UNAME_MACHINE="alphaev67" ;; + "EV6.8CB (21264C)") + UNAME_MACHINE="alphaev68" ;; + "EV6.8AL (21264B)") + UNAME_MACHINE="alphaev68" ;; + "EV6.8CX (21264D)") + UNAME_MACHINE="alphaev68" ;; + "EV6.9A (21264/EV69A)") + UNAME_MACHINE="alphaev69" ;; + "EV7 (21364)") + UNAME_MACHINE="alphaev7" ;; + "EV7.9 (21364A)") + UNAME_MACHINE="alphaev79" ;; + esac + # A Pn.n version is a patched version. + # A Vn.n version is a released version. + # A Tn.n version is a released field test version. + # A Xn.n version is an unreleased experimental baselevel. + # 1.2 uses "1.2" for uname -r. + echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + # Reset EXIT trap before exiting to avoid spurious non-zero exit code. + exitcode=$? + trap '' 0 + exit $exitcode ;; + Alpha\ *:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # Should we change UNAME_MACHINE based on the output of uname instead + # of the specific Alpha model? + echo alpha-pc-interix + exit ;; + 21064:Windows_NT:50:3) + echo alpha-dec-winnt3.5 + exit ;; + Amiga*:UNIX_System_V:4.0:*) + echo m68k-unknown-sysv4 + exit ;; + *:[Aa]miga[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-amigaos + exit ;; + *:[Mm]orph[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-morphos + exit ;; + *:OS/390:*:*) + echo i370-ibm-openedition + exit ;; + *:z/VM:*:*) + echo s390-ibm-zvmoe + exit ;; + *:OS400:*:*) + echo powerpc-ibm-os400 + exit ;; + arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) + echo arm-acorn-riscix${UNAME_RELEASE} + exit ;; + arm*:riscos:*:*|arm*:RISCOS:*:*) + echo arm-unknown-riscos + exit ;; + SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) + echo hppa1.1-hitachi-hiuxmpp + exit ;; + Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) + # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. + if test "`(/bin/universe) 2>/dev/null`" = att ; then + echo pyramid-pyramid-sysv3 + else + echo pyramid-pyramid-bsd + fi + exit ;; + NILE*:*:*:dcosx) + echo pyramid-pyramid-svr4 + exit ;; + DRS?6000:unix:4.0:6*) + echo sparc-icl-nx6 + exit ;; + DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) + case `/usr/bin/uname -p` in + sparc) echo sparc-icl-nx7; exit ;; + esac ;; + s390x:SunOS:*:*) + echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4H:SunOS:5.*:*) + echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) + echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*) + echo i386-pc-auroraux${UNAME_RELEASE} + exit ;; + i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) + eval $set_cc_for_build + SUN_ARCH="i386" + # If there is a compiler, see if it is configured for 64-bit objects. + # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. + # This test works for both compilers. + if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then + if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \ + (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_64BIT_ARCH >/dev/null + then + SUN_ARCH="x86_64" + fi + fi + echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:6*:*) + # According to config.sub, this is the proper way to canonicalize + # SunOS6. Hard to guess exactly what SunOS6 will be like, but + # it's likely to be more like Solaris than SunOS4. + echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:*:*) + case "`/usr/bin/arch -k`" in + Series*|S4*) + UNAME_RELEASE=`uname -v` + ;; + esac + # Japanese Language versions have a version number like `4.1.3-JL'. + echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` + exit ;; + sun3*:SunOS:*:*) + echo m68k-sun-sunos${UNAME_RELEASE} + exit ;; + sun*:*:4.2BSD:*) + UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` + test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 + case "`/bin/arch`" in + sun3) + echo m68k-sun-sunos${UNAME_RELEASE} + ;; + sun4) + echo sparc-sun-sunos${UNAME_RELEASE} + ;; + esac + exit ;; + aushp:SunOS:*:*) + echo sparc-auspex-sunos${UNAME_RELEASE} + exit ;; + # The situation for MiNT is a little confusing. The machine name + # can be virtually everything (everything which is not + # "atarist" or "atariste" at least should have a processor + # > m68000). The system name ranges from "MiNT" over "FreeMiNT" + # to the lowercase version "mint" (or "freemint"). Finally + # the system name "TOS" denotes a system which is actually not + # MiNT. But MiNT is downward compatible to TOS, so this should + # be no problem. + atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) + echo m68k-milan-mint${UNAME_RELEASE} + exit ;; + hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) + echo m68k-hades-mint${UNAME_RELEASE} + exit ;; + *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) + echo m68k-unknown-mint${UNAME_RELEASE} + exit ;; + m68k:machten:*:*) + echo m68k-apple-machten${UNAME_RELEASE} + exit ;; + powerpc:machten:*:*) + echo powerpc-apple-machten${UNAME_RELEASE} + exit ;; + RISC*:Mach:*:*) + echo mips-dec-mach_bsd4.3 + exit ;; + RISC*:ULTRIX:*:*) + echo mips-dec-ultrix${UNAME_RELEASE} + exit ;; + VAX*:ULTRIX*:*:*) + echo vax-dec-ultrix${UNAME_RELEASE} + exit ;; + 2020:CLIX:*:* | 2430:CLIX:*:*) + echo clipper-intergraph-clix${UNAME_RELEASE} + exit ;; + mips:*:*:UMIPS | mips:*:*:RISCos) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c +#ifdef __cplusplus +#include /* for printf() prototype */ + int main (int argc, char *argv[]) { +#else + int main (argc, argv) int argc; char *argv[]; { +#endif + #if defined (host_mips) && defined (MIPSEB) + #if defined (SYSTYPE_SYSV) + printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_SVR4) + printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) + printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); + #endif + #endif + exit (-1); + } +EOF + $CC_FOR_BUILD -o $dummy $dummy.c && + dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` && + SYSTEM_NAME=`$dummy $dummyarg` && + { echo "$SYSTEM_NAME"; exit; } + echo mips-mips-riscos${UNAME_RELEASE} + exit ;; + Motorola:PowerMAX_OS:*:*) + echo powerpc-motorola-powermax + exit ;; + Motorola:*:4.3:PL8-*) + echo powerpc-harris-powermax + exit ;; + Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) + echo powerpc-harris-powermax + exit ;; + Night_Hawk:Power_UNIX:*:*) + echo powerpc-harris-powerunix + exit ;; + m88k:CX/UX:7*:*) + echo m88k-harris-cxux7 + exit ;; + m88k:*:4*:R4*) + echo m88k-motorola-sysv4 + exit ;; + m88k:*:3*:R3*) + echo m88k-motorola-sysv3 + exit ;; + AViiON:dgux:*:*) + # DG/UX returns AViiON for all architectures + UNAME_PROCESSOR=`/usr/bin/uname -p` + if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] + then + if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ + [ ${TARGET_BINARY_INTERFACE}x = x ] + then + echo m88k-dg-dgux${UNAME_RELEASE} + else + echo m88k-dg-dguxbcs${UNAME_RELEASE} + fi + else + echo i586-dg-dgux${UNAME_RELEASE} + fi + exit ;; + M88*:DolphinOS:*:*) # DolphinOS (SVR3) + echo m88k-dolphin-sysv3 + exit ;; + M88*:*:R3*:*) + # Delta 88k system running SVR3 + echo m88k-motorola-sysv3 + exit ;; + XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) + echo m88k-tektronix-sysv3 + exit ;; + Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) + echo m68k-tektronix-bsd + exit ;; + *:IRIX*:*:*) + echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` + exit ;; + ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. + echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id + exit ;; # Note that: echo "'`uname -s`'" gives 'AIX ' + i*86:AIX:*:*) + echo i386-ibm-aix + exit ;; + ia64:AIX:*:*) + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} + exit ;; + *:AIX:2:3) + if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + + main() + { + if (!__power_pc()) + exit(1); + puts("powerpc-ibm-aix3.2.5"); + exit(0); + } +EOF + if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` + then + echo "$SYSTEM_NAME" + else + echo rs6000-ibm-aix3.2.5 + fi + elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then + echo rs6000-ibm-aix3.2.4 + else + echo rs6000-ibm-aix3.2 + fi + exit ;; + *:AIX:*:[4567]) + IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` + if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then + IBM_ARCH=rs6000 + else + IBM_ARCH=powerpc + fi + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${IBM_ARCH}-ibm-aix${IBM_REV} + exit ;; + *:AIX:*:*) + echo rs6000-ibm-aix + exit ;; + ibmrt:4.4BSD:*|romp-ibm:BSD:*) + echo romp-ibm-bsd4.4 + exit ;; + ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and + echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to + exit ;; # report: romp-ibm BSD 4.3 + *:BOSX:*:*) + echo rs6000-bull-bosx + exit ;; + DPX/2?00:B.O.S.:*:*) + echo m68k-bull-sysv3 + exit ;; + 9000/[34]??:4.3bsd:1.*:*) + echo m68k-hp-bsd + exit ;; + hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) + echo m68k-hp-bsd4.4 + exit ;; + 9000/[34678]??:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + case "${UNAME_MACHINE}" in + 9000/31? ) HP_ARCH=m68000 ;; + 9000/[34]?? ) HP_ARCH=m68k ;; + 9000/[678][0-9][0-9]) + if [ -x /usr/bin/getconf ]; then + sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` + sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` + case "${sc_cpu_version}" in + 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 + 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 + 532) # CPU_PA_RISC2_0 + case "${sc_kernel_bits}" in + 32) HP_ARCH="hppa2.0n" ;; + 64) HP_ARCH="hppa2.0w" ;; + '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 + esac ;; + esac + fi + if [ "${HP_ARCH}" = "" ]; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + + #define _HPUX_SOURCE + #include + #include + + int main () + { + #if defined(_SC_KERNEL_BITS) + long bits = sysconf(_SC_KERNEL_BITS); + #endif + long cpu = sysconf (_SC_CPU_VERSION); + + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1"); break; + case CPU_PA_RISC2_0: + #if defined(_SC_KERNEL_BITS) + switch (bits) + { + case 64: puts ("hppa2.0w"); break; + case 32: puts ("hppa2.0n"); break; + default: puts ("hppa2.0"); break; + } break; + #else /* !defined(_SC_KERNEL_BITS) */ + puts ("hppa2.0"); break; + #endif + default: puts ("hppa1.0"); break; + } + exit (0); + } +EOF + (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` + test -z "$HP_ARCH" && HP_ARCH=hppa + fi ;; + esac + if [ ${HP_ARCH} = "hppa2.0w" ] + then + eval $set_cc_for_build + + # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating + # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler + # generating 64-bit code. GNU and HP use different nomenclature: + # + # $ CC_FOR_BUILD=cc ./config.guess + # => hppa2.0w-hp-hpux11.23 + # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess + # => hppa64-hp-hpux11.23 + + if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | + grep -q __LP64__ + then + HP_ARCH="hppa2.0w" + else + HP_ARCH="hppa64" + fi + fi + echo ${HP_ARCH}-hp-hpux${HPUX_REV} + exit ;; + ia64:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + echo ia64-hp-hpux${HPUX_REV} + exit ;; + 3050*:HI-UX:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + int + main () + { + long cpu = sysconf (_SC_CPU_VERSION); + /* The order matters, because CPU_IS_HP_MC68K erroneously returns + true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct + results, however. */ + if (CPU_IS_PA_RISC (cpu)) + { + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; + case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; + default: puts ("hppa-hitachi-hiuxwe2"); break; + } + } + else if (CPU_IS_HP_MC68K (cpu)) + puts ("m68k-hitachi-hiuxwe2"); + else puts ("unknown-hitachi-hiuxwe2"); + exit (0); + } +EOF + $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` && + { echo "$SYSTEM_NAME"; exit; } + echo unknown-hitachi-hiuxwe2 + exit ;; + 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) + echo hppa1.1-hp-bsd + exit ;; + 9000/8??:4.3bsd:*:*) + echo hppa1.0-hp-bsd + exit ;; + *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) + echo hppa1.0-hp-mpeix + exit ;; + hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) + echo hppa1.1-hp-osf + exit ;; + hp8??:OSF1:*:*) + echo hppa1.0-hp-osf + exit ;; + i*86:OSF1:*:*) + if [ -x /usr/sbin/sysversion ] ; then + echo ${UNAME_MACHINE}-unknown-osf1mk + else + echo ${UNAME_MACHINE}-unknown-osf1 + fi + exit ;; + parisc*:Lites*:*:*) + echo hppa1.1-hp-lites + exit ;; + C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) + echo c1-convex-bsd + exit ;; + C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit ;; + C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) + echo c34-convex-bsd + exit ;; + C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) + echo c38-convex-bsd + exit ;; + C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) + echo c4-convex-bsd + exit ;; + CRAY*Y-MP:*:*:*) + echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*[A-Z]90:*:*:*) + echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ + | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ + -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ + -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*TS:*:*:*) + echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*T3E:*:*:*) + echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*SV1:*:*:*) + echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + *:UNICOS/mp:*:*) + echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) + FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` + echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit ;; + 5000:UNIX_System_V:4.*:*) + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'` + echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit ;; + i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) + echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} + exit ;; + sparc*:BSD/OS:*:*) + echo sparc-unknown-bsdi${UNAME_RELEASE} + exit ;; + *:BSD/OS:*:*) + echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} + exit ;; + *:FreeBSD:*:*) + UNAME_PROCESSOR=`/usr/bin/uname -p` + case ${UNAME_PROCESSOR} in + amd64) + echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + *) + echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + esac + exit ;; + i*:CYGWIN*:*) + echo ${UNAME_MACHINE}-pc-cygwin + exit ;; + *:MINGW64*:*) + echo ${UNAME_MACHINE}-pc-mingw64 + exit ;; + *:MINGW*:*) + echo ${UNAME_MACHINE}-pc-mingw32 + exit ;; + i*:MSYS*:*) + echo ${UNAME_MACHINE}-pc-msys + exit ;; + i*:windows32*:*) + # uname -m includes "-pc" on this system. + echo ${UNAME_MACHINE}-mingw32 + exit ;; + i*:PW*:*) + echo ${UNAME_MACHINE}-pc-pw32 + exit ;; + *:Interix*:*) + case ${UNAME_MACHINE} in + x86) + echo i586-pc-interix${UNAME_RELEASE} + exit ;; + authenticamd | genuineintel | EM64T) + echo x86_64-unknown-interix${UNAME_RELEASE} + exit ;; + IA64) + echo ia64-unknown-interix${UNAME_RELEASE} + exit ;; + esac ;; + [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) + echo i${UNAME_MACHINE}-pc-mks + exit ;; + 8664:Windows_NT:*) + echo x86_64-pc-mks + exit ;; + i*:Windows_NT*:* | Pentium*:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we + # UNAME_MACHINE based on the output of uname instead of i386? + echo i586-pc-interix + exit ;; + i*:UWIN*:*) + echo ${UNAME_MACHINE}-pc-uwin + exit ;; + amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) + echo x86_64-unknown-cygwin + exit ;; + p*:CYGWIN*:*) + echo powerpcle-unknown-cygwin + exit ;; + prep*:SunOS:5.*:*) + echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + *:GNU:*:*) + # the GNU system + echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-${LIBC}`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` + exit ;; + *:GNU/*:*:*) + # other systems with GNU libc and userland + echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-${LIBC} + exit ;; + i*86:Minix:*:*) + echo ${UNAME_MACHINE}-pc-minix + exit ;; + aarch64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + aarch64_be:Linux:*:*) + UNAME_MACHINE=aarch64_be + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + alpha:Linux:*:*) + case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in + EV5) UNAME_MACHINE=alphaev5 ;; + EV56) UNAME_MACHINE=alphaev56 ;; + PCA56) UNAME_MACHINE=alphapca56 ;; + PCA57) UNAME_MACHINE=alphapca56 ;; + EV6) UNAME_MACHINE=alphaev6 ;; + EV67) UNAME_MACHINE=alphaev67 ;; + EV68*) UNAME_MACHINE=alphaev68 ;; + esac + objdump --private-headers /bin/sh | grep -q ld.so.1 + if test "$?" = 0 ; then LIBC="gnulibc1" ; fi + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + arc:Linux:*:* | arceb:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + arm*:Linux:*:*) + eval $set_cc_for_build + if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ARM_EABI__ + then + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + else + if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ARM_PCS_VFP + then + echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabi + else + echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabihf + fi + fi + exit ;; + avr32*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + cris:Linux:*:*) + echo ${UNAME_MACHINE}-axis-linux-${LIBC} + exit ;; + crisv32:Linux:*:*) + echo ${UNAME_MACHINE}-axis-linux-${LIBC} + exit ;; + frv:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + hexagon:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + i*86:Linux:*:*) + echo ${UNAME_MACHINE}-pc-linux-${LIBC} + exit ;; + ia64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + m32r*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + m68*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + mips:Linux:*:* | mips64:Linux:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #undef CPU + #undef ${UNAME_MACHINE} + #undef ${UNAME_MACHINE}el + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) + CPU=${UNAME_MACHINE}el + #else + #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) + CPU=${UNAME_MACHINE} + #else + CPU= + #endif + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'` + test x"${CPU}" != x && { echo "${CPU}-unknown-linux-${LIBC}"; exit; } + ;; + or1k:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + or32:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + padre:Linux:*:*) + echo sparc-unknown-linux-${LIBC} + exit ;; + parisc64:Linux:*:* | hppa64:Linux:*:*) + echo hppa64-unknown-linux-${LIBC} + exit ;; + parisc:Linux:*:* | hppa:Linux:*:*) + # Look for CPU level + case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in + PA7*) echo hppa1.1-unknown-linux-${LIBC} ;; + PA8*) echo hppa2.0-unknown-linux-${LIBC} ;; + *) echo hppa-unknown-linux-${LIBC} ;; + esac + exit ;; + ppc64:Linux:*:*) + echo powerpc64-unknown-linux-${LIBC} + exit ;; + ppc:Linux:*:*) + echo powerpc-unknown-linux-${LIBC} + exit ;; + ppc64le:Linux:*:*) + echo powerpc64le-unknown-linux-${LIBC} + exit ;; + ppcle:Linux:*:*) + echo powerpcle-unknown-linux-${LIBC} + exit ;; + s390:Linux:*:* | s390x:Linux:*:*) + echo ${UNAME_MACHINE}-ibm-linux-${LIBC} + exit ;; + sh64*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + sh*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + sparc:Linux:*:* | sparc64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + tile*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + vax:Linux:*:*) + echo ${UNAME_MACHINE}-dec-linux-${LIBC} + exit ;; + x86_64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + xtensa*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + i*86:DYNIX/ptx:4*:*) + # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. + # earlier versions are messed up and put the nodename in both + # sysname and nodename. + echo i386-sequent-sysv4 + exit ;; + i*86:UNIX_SV:4.2MP:2.*) + # Unixware is an offshoot of SVR4, but it has its own version + # number series starting with 2... + # I am not positive that other SVR4 systems won't match this, + # I just have to hope. -- rms. + # Use sysv4.2uw... so that sysv4* matches it. + echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} + exit ;; + i*86:OS/2:*:*) + # If we were able to find `uname', then EMX Unix compatibility + # is probably installed. + echo ${UNAME_MACHINE}-pc-os2-emx + exit ;; + i*86:XTS-300:*:STOP) + echo ${UNAME_MACHINE}-unknown-stop + exit ;; + i*86:atheos:*:*) + echo ${UNAME_MACHINE}-unknown-atheos + exit ;; + i*86:syllable:*:*) + echo ${UNAME_MACHINE}-pc-syllable + exit ;; + i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*) + echo i386-unknown-lynxos${UNAME_RELEASE} + exit ;; + i*86:*DOS:*:*) + echo ${UNAME_MACHINE}-pc-msdosdjgpp + exit ;; + i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) + UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` + if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then + echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} + else + echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} + fi + exit ;; + i*86:*:5:[678]*) + # UnixWare 7.x, OpenUNIX and OpenServer 6. + case `/bin/uname -X | grep "^Machine"` in + *486*) UNAME_MACHINE=i486 ;; + *Pentium) UNAME_MACHINE=i586 ;; + *Pent*|*Celeron) UNAME_MACHINE=i686 ;; + esac + echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} + exit ;; + i*86:*:3.2:*) + if test -f /usr/options/cb.name; then + UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then + UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` + (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 + (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ + && UNAME_MACHINE=i586 + (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ + && UNAME_MACHINE=i686 + (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ + && UNAME_MACHINE=i686 + echo ${UNAME_MACHINE}-pc-sco$UNAME_REL + else + echo ${UNAME_MACHINE}-pc-sysv32 + fi + exit ;; + pc:*:*:*) + # Left here for compatibility: + # uname -m prints for DJGPP always 'pc', but it prints nothing about + # the processor, so we play safe by assuming i586. + # Note: whatever this is, it MUST be the same as what config.sub + # prints for the "djgpp" host, or else GDB configury will decide that + # this is a cross-build. + echo i586-pc-msdosdjgpp + exit ;; + Intel:Mach:3*:*) + echo i386-pc-mach3 + exit ;; + paragon:*:*:*) + echo i860-intel-osf1 + exit ;; + i860:*:4.*:*) # i860-SVR4 + if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then + echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 + else # Add other i860-SVR4 vendors below as they are discovered. + echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 + fi + exit ;; + mini*:CTIX:SYS*5:*) + # "miniframe" + echo m68010-convergent-sysv + exit ;; + mc68k:UNIX:SYSTEM5:3.51m) + echo m68k-convergent-sysv + exit ;; + M680?0:D-NIX:5.3:*) + echo m68k-diab-dnix + exit ;; + M68*:*:R3V[5678]*:*) + test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; + 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) + OS_REL='' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4.3${OS_REL}; exit; } + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; + 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4; exit; } ;; + NCR*:*:4.2:* | MPRAS*:*:4.2:*) + OS_REL='.3' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4.3${OS_REL}; exit; } + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && { echo i586-ncr-sysv4.3${OS_REL}; exit; } + /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \ + && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; + m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) + echo m68k-unknown-lynxos${UNAME_RELEASE} + exit ;; + mc68030:UNIX_System_V:4.*:*) + echo m68k-atari-sysv4 + exit ;; + TSUNAMI:LynxOS:2.*:*) + echo sparc-unknown-lynxos${UNAME_RELEASE} + exit ;; + rs6000:LynxOS:2.*:*) + echo rs6000-unknown-lynxos${UNAME_RELEASE} + exit ;; + PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*) + echo powerpc-unknown-lynxos${UNAME_RELEASE} + exit ;; + SM[BE]S:UNIX_SV:*:*) + echo mips-dde-sysv${UNAME_RELEASE} + exit ;; + RM*:ReliantUNIX-*:*:*) + echo mips-sni-sysv4 + exit ;; + RM*:SINIX-*:*:*) + echo mips-sni-sysv4 + exit ;; + *:SINIX-*:*:*) + if uname -p 2>/dev/null >/dev/null ; then + UNAME_MACHINE=`(uname -p) 2>/dev/null` + echo ${UNAME_MACHINE}-sni-sysv4 + else + echo ns32k-sni-sysv + fi + exit ;; + PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort + # says + echo i586-unisys-sysv4 + exit ;; + *:UNIX_System_V:4*:FTX*) + # From Gerald Hewes . + # How about differentiating between stratus architectures? -djm + echo hppa1.1-stratus-sysv4 + exit ;; + *:*:*:FTX*) + # From seanf@swdc.stratus.com. + echo i860-stratus-sysv4 + exit ;; + i*86:VOS:*:*) + # From Paul.Green@stratus.com. + echo ${UNAME_MACHINE}-stratus-vos + exit ;; + *:VOS:*:*) + # From Paul.Green@stratus.com. + echo hppa1.1-stratus-vos + exit ;; + mc68*:A/UX:*:*) + echo m68k-apple-aux${UNAME_RELEASE} + exit ;; + news*:NEWS-OS:6*:*) + echo mips-sony-newsos6 + exit ;; + R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) + if [ -d /usr/nec ]; then + echo mips-nec-sysv${UNAME_RELEASE} + else + echo mips-unknown-sysv${UNAME_RELEASE} + fi + exit ;; + BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. + echo powerpc-be-beos + exit ;; + BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. + echo powerpc-apple-beos + exit ;; + BePC:BeOS:*:*) # BeOS running on Intel PC compatible. + echo i586-pc-beos + exit ;; + BePC:Haiku:*:*) # Haiku running on Intel PC compatible. + echo i586-pc-haiku + exit ;; + x86_64:Haiku:*:*) + echo x86_64-unknown-haiku + exit ;; + SX-4:SUPER-UX:*:*) + echo sx4-nec-superux${UNAME_RELEASE} + exit ;; + SX-5:SUPER-UX:*:*) + echo sx5-nec-superux${UNAME_RELEASE} + exit ;; + SX-6:SUPER-UX:*:*) + echo sx6-nec-superux${UNAME_RELEASE} + exit ;; + SX-7:SUPER-UX:*:*) + echo sx7-nec-superux${UNAME_RELEASE} + exit ;; + SX-8:SUPER-UX:*:*) + echo sx8-nec-superux${UNAME_RELEASE} + exit ;; + SX-8R:SUPER-UX:*:*) + echo sx8r-nec-superux${UNAME_RELEASE} + exit ;; + Power*:Rhapsody:*:*) + echo powerpc-apple-rhapsody${UNAME_RELEASE} + exit ;; + *:Rhapsody:*:*) + echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} + exit ;; + *:Darwin:*:*) + UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown + eval $set_cc_for_build + if test "$UNAME_PROCESSOR" = unknown ; then + UNAME_PROCESSOR=powerpc + fi + if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then + if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ + (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_64BIT_ARCH >/dev/null + then + case $UNAME_PROCESSOR in + i386) UNAME_PROCESSOR=x86_64 ;; + powerpc) UNAME_PROCESSOR=powerpc64 ;; + esac + fi + fi + echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} + exit ;; + *:procnto*:*:* | *:QNX:[0123456789]*:*) + UNAME_PROCESSOR=`uname -p` + if test "$UNAME_PROCESSOR" = "x86"; then + UNAME_PROCESSOR=i386 + UNAME_MACHINE=pc + fi + echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} + exit ;; + *:QNX:*:4*) + echo i386-pc-qnx + exit ;; + NEO-?:NONSTOP_KERNEL:*:*) + echo neo-tandem-nsk${UNAME_RELEASE} + exit ;; + NSE-*:NONSTOP_KERNEL:*:*) + echo nse-tandem-nsk${UNAME_RELEASE} + exit ;; + NSR-?:NONSTOP_KERNEL:*:*) + echo nsr-tandem-nsk${UNAME_RELEASE} + exit ;; + *:NonStop-UX:*:*) + echo mips-compaq-nonstopux + exit ;; + BS2000:POSIX*:*:*) + echo bs2000-siemens-sysv + exit ;; + DS/*:UNIX_System_V:*:*) + echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} + exit ;; + *:Plan9:*:*) + # "uname -m" is not consistent, so use $cputype instead. 386 + # is converted to i386 for consistency with other x86 + # operating systems. + if test "$cputype" = "386"; then + UNAME_MACHINE=i386 + else + UNAME_MACHINE="$cputype" + fi + echo ${UNAME_MACHINE}-unknown-plan9 + exit ;; + *:TOPS-10:*:*) + echo pdp10-unknown-tops10 + exit ;; + *:TENEX:*:*) + echo pdp10-unknown-tenex + exit ;; + KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) + echo pdp10-dec-tops20 + exit ;; + XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) + echo pdp10-xkl-tops20 + exit ;; + *:TOPS-20:*:*) + echo pdp10-unknown-tops20 + exit ;; + *:ITS:*:*) + echo pdp10-unknown-its + exit ;; + SEI:*:*:SEIUX) + echo mips-sei-seiux${UNAME_RELEASE} + exit ;; + *:DragonFly:*:*) + echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` + exit ;; + *:*VMS:*:*) + UNAME_MACHINE=`(uname -p) 2>/dev/null` + case "${UNAME_MACHINE}" in + A*) echo alpha-dec-vms ; exit ;; + I*) echo ia64-dec-vms ; exit ;; + V*) echo vax-dec-vms ; exit ;; + esac ;; + *:XENIX:*:SysV) + echo i386-pc-xenix + exit ;; + i*86:skyos:*:*) + echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//' + exit ;; + i*86:rdos:*:*) + echo ${UNAME_MACHINE}-pc-rdos + exit ;; + i*86:AROS:*:*) + echo ${UNAME_MACHINE}-pc-aros + exit ;; + x86_64:VMkernel:*:*) + echo ${UNAME_MACHINE}-unknown-esx + exit ;; +esac + +eval $set_cc_for_build +cat >$dummy.c < +# include +#endif +main () +{ +#if defined (sony) +#if defined (MIPSEB) + /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, + I don't know.... */ + printf ("mips-sony-bsd\n"); exit (0); +#else +#include + printf ("m68k-sony-newsos%s\n", +#ifdef NEWSOS4 + "4" +#else + "" +#endif + ); exit (0); +#endif +#endif + +#if defined (__arm) && defined (__acorn) && defined (__unix) + printf ("arm-acorn-riscix\n"); exit (0); +#endif + +#if defined (hp300) && !defined (hpux) + printf ("m68k-hp-bsd\n"); exit (0); +#endif + +#if defined (NeXT) +#if !defined (__ARCHITECTURE__) +#define __ARCHITECTURE__ "m68k" +#endif + int version; + version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; + if (version < 4) + printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); + else + printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); + exit (0); +#endif + +#if defined (MULTIMAX) || defined (n16) +#if defined (UMAXV) + printf ("ns32k-encore-sysv\n"); exit (0); +#else +#if defined (CMU) + printf ("ns32k-encore-mach\n"); exit (0); +#else + printf ("ns32k-encore-bsd\n"); exit (0); +#endif +#endif +#endif + +#if defined (__386BSD__) + printf ("i386-pc-bsd\n"); exit (0); +#endif + +#if defined (sequent) +#if defined (i386) + printf ("i386-sequent-dynix\n"); exit (0); +#endif +#if defined (ns32000) + printf ("ns32k-sequent-dynix\n"); exit (0); +#endif +#endif + +#if defined (_SEQUENT_) + struct utsname un; + + uname(&un); + + if (strncmp(un.version, "V2", 2) == 0) { + printf ("i386-sequent-ptx2\n"); exit (0); + } + if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ + printf ("i386-sequent-ptx1\n"); exit (0); + } + printf ("i386-sequent-ptx\n"); exit (0); + +#endif + +#if defined (vax) +# if !defined (ultrix) +# include +# if defined (BSD) +# if BSD == 43 + printf ("vax-dec-bsd4.3\n"); exit (0); +# else +# if BSD == 199006 + printf ("vax-dec-bsd4.3reno\n"); exit (0); +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# endif +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# else + printf ("vax-dec-ultrix\n"); exit (0); +# endif +#endif + +#if defined (alliant) && defined (i860) + printf ("i860-alliant-bsd\n"); exit (0); +#endif + + exit (1); +} +EOF + +$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` && + { echo "$SYSTEM_NAME"; exit; } + +# Apollos put the system type in the environment. + +test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; } + +# Convex versions that predate uname can use getsysinfo(1) + +if [ -x /usr/convex/getsysinfo ] +then + case `getsysinfo -f cpu_type` in + c1*) + echo c1-convex-bsd + exit ;; + c2*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit ;; + c34*) + echo c34-convex-bsd + exit ;; + c38*) + echo c38-convex-bsd + exit ;; + c4*) + echo c4-convex-bsd + exit ;; + esac +fi + +cat >&2 < in order to provide the needed +information to handle your system. + +config.guess timestamp = $timestamp + +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null` + +hostinfo = `(hostinfo) 2>/dev/null` +/bin/universe = `(/bin/universe) 2>/dev/null` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` +/bin/arch = `(/bin/arch) 2>/dev/null` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` + +UNAME_MACHINE = ${UNAME_MACHINE} +UNAME_RELEASE = ${UNAME_RELEASE} +UNAME_SYSTEM = ${UNAME_SYSTEM} +UNAME_VERSION = ${UNAME_VERSION} +EOF + +exit 1 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/3rd-party/gdal/patches/config.sub b/3rd-party/gdal/patches/config.sub new file mode 100755 index 0000000..9633db7 --- /dev/null +++ b/3rd-party/gdal/patches/config.sub @@ -0,0 +1,1791 @@ +#! /bin/sh +# Configuration validation subroutine script. +# Copyright 1992-2013 Free Software Foundation, Inc. + +timestamp='2013-08-10' + +# This file is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that +# program. This Exception is an additional permission under section 7 +# of the GNU General Public License, version 3 ("GPLv3"). + + +# Please send patches with a ChangeLog entry to config-patches@gnu.org. +# +# Configuration subroutine to validate and canonicalize a configuration type. +# Supply the specified configuration type as an argument. +# If it is invalid, we print an error message on stderr and exit with code 1. +# Otherwise, we print the canonical config type on stdout and succeed. + +# You can get the latest version of this script from: +# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD + +# This file is supposed to be the same for all GNU packages +# and recognize all the CPU types, system types and aliases +# that are meaningful with *any* GNU software. +# Each package is responsible for reporting which valid configurations +# it does not support. The user should be able to distinguish +# a failure to support a valid configuration from a meaningless +# configuration. + +# The goal of this file is to map all the various variations of a given +# machine specification into a single specification in the form: +# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM +# or in some cases, the newer four-part form: +# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM +# It is wrong to echo any other type of specification. + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] CPU-MFR-OPSYS + $0 [OPTION] ALIAS + +Canonicalize a configuration name. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.sub ($timestamp) + +Copyright 1992-2013 Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit ;; + --version | -v ) + echo "$version" ; exit ;; + --help | --h* | -h ) + echo "$usage"; exit ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" + exit 1 ;; + + *local*) + # First pass through any local machine types. + echo $1 + exit ;; + + * ) + break ;; + esac +done + +case $# in + 0) echo "$me: missing argument$help" >&2 + exit 1;; + 1) ;; + *) echo "$me: too many arguments$help" >&2 + exit 1;; +esac + +# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). +# Here we must recognize all the valid KERNEL-OS combinations. +maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` +case $maybe_os in + nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \ + linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \ + knetbsd*-gnu* | netbsd*-gnu* | \ + kopensolaris*-gnu* | \ + storm-chaos* | os2-emx* | rtmk-nova*) + os=-$maybe_os + basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` + ;; + android-linux) + os=-linux-android + basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown + ;; + *) + basic_machine=`echo $1 | sed 's/-[^-]*$//'` + if [ $basic_machine != $1 ] + then os=`echo $1 | sed 's/.*-/-/'` + else os=; fi + ;; +esac + +### Let's recognize common machines as not being operating systems so +### that things like config.sub decstation-3100 work. We also +### recognize some manufacturers as not being operating systems, so we +### can provide default operating systems below. +case $os in + -sun*os*) + # Prevent following clause from handling this invalid input. + ;; + -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ + -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ + -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ + -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ + -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ + -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ + -apple | -axis | -knuth | -cray | -microblaze*) + os= + basic_machine=$1 + ;; + -bluegene*) + os=-cnk + ;; + -sim | -cisco | -oki | -wec | -winbond) + os= + basic_machine=$1 + ;; + -scout) + ;; + -wrs) + os=-vxworks + basic_machine=$1 + ;; + -chorusos*) + os=-chorusos + basic_machine=$1 + ;; + -chorusrdb) + os=-chorusrdb + basic_machine=$1 + ;; + -hiux*) + os=-hiuxwe2 + ;; + -sco6) + os=-sco5v6 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco5) + os=-sco3.2v5 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco4) + os=-sco3.2v4 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2.[4-9]*) + os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2v[4-9]*) + # Don't forget version if it is 3.2v4 or newer. + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco5v6*) + # Don't forget version if it is 3.2v4 or newer. + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco*) + os=-sco3.2v2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -udk*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -isc) + os=-isc2.2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -clix*) + basic_machine=clipper-intergraph + ;; + -isc*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -lynx*178) + os=-lynxos178 + ;; + -lynx*5) + os=-lynxos5 + ;; + -lynx*) + os=-lynxos + ;; + -ptx*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` + ;; + -windowsnt*) + os=`echo $os | sed -e 's/windowsnt/winnt/'` + ;; + -psos*) + os=-psos + ;; + -mint | -mint[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; +esac + +# Decode aliases for certain CPU-COMPANY combinations. +case $basic_machine in + # Recognize the basic CPU types without company name. + # Some are omitted here because they have special meanings below. + 1750a | 580 \ + | a29k \ + | aarch64 | aarch64_be \ + | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ + | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ + | am33_2.0 \ + | arc | arceb \ + | arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \ + | avr | avr32 \ + | be32 | be64 \ + | bfin \ + | c4x | c8051 | clipper \ + | d10v | d30v | dlx | dsp16xx \ + | epiphany \ + | fido | fr30 | frv \ + | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ + | hexagon \ + | i370 | i860 | i960 | ia64 \ + | ip2k | iq2000 \ + | le32 | le64 \ + | lm32 \ + | m32c | m32r | m32rle | m68000 | m68k | m88k \ + | maxq | mb | microblaze | microblazeel | mcore | mep | metag \ + | mips | mipsbe | mipseb | mipsel | mipsle \ + | mips16 \ + | mips64 | mips64el \ + | mips64octeon | mips64octeonel \ + | mips64orion | mips64orionel \ + | mips64r5900 | mips64r5900el \ + | mips64vr | mips64vrel \ + | mips64vr4100 | mips64vr4100el \ + | mips64vr4300 | mips64vr4300el \ + | mips64vr5000 | mips64vr5000el \ + | mips64vr5900 | mips64vr5900el \ + | mipsisa32 | mipsisa32el \ + | mipsisa32r2 | mipsisa32r2el \ + | mipsisa64 | mipsisa64el \ + | mipsisa64r2 | mipsisa64r2el \ + | mipsisa64sb1 | mipsisa64sb1el \ + | mipsisa64sr71k | mipsisa64sr71kel \ + | mipsr5900 | mipsr5900el \ + | mipstx39 | mipstx39el \ + | mn10200 | mn10300 \ + | moxie \ + | mt \ + | msp430 \ + | nds32 | nds32le | nds32be \ + | nios | nios2 | nios2eb | nios2el \ + | ns16k | ns32k \ + | open8 \ + | or1k | or32 \ + | pdp10 | pdp11 | pj | pjl \ + | powerpc | powerpc64 | powerpc64le | powerpcle \ + | pyramid \ + | rl78 | rx \ + | score \ + | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ + | sh64 | sh64le \ + | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \ + | sparcv8 | sparcv9 | sparcv9b | sparcv9v \ + | spu \ + | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \ + | ubicom32 \ + | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \ + | we32k \ + | x86 | xc16x | xstormy16 | xtensa \ + | z8k | z80) + basic_machine=$basic_machine-unknown + ;; + c54x) + basic_machine=tic54x-unknown + ;; + c55x) + basic_machine=tic55x-unknown + ;; + c6x) + basic_machine=tic6x-unknown + ;; + m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | picochip) + basic_machine=$basic_machine-unknown + os=-none + ;; + m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) + ;; + ms1) + basic_machine=mt-unknown + ;; + + strongarm | thumb | xscale) + basic_machine=arm-unknown + ;; + xgate) + basic_machine=$basic_machine-unknown + os=-none + ;; + xscaleeb) + basic_machine=armeb-unknown + ;; + + xscaleel) + basic_machine=armel-unknown + ;; + + # We use `pc' rather than `unknown' + # because (1) that's what they normally are, and + # (2) the word "unknown" tends to confuse beginning users. + i*86 | x86_64) + basic_machine=$basic_machine-pc + ;; + # Object if more than one company name word. + *-*-*) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; + # Recognize the basic CPU types with company name. + 580-* \ + | a29k-* \ + | aarch64-* | aarch64_be-* \ + | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ + | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ + | alphapca5[67]-* | alpha64pca5[67]-* | arc-* | arceb-* \ + | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ + | avr-* | avr32-* \ + | be32-* | be64-* \ + | bfin-* | bs2000-* \ + | c[123]* | c30-* | [cjt]90-* | c4x-* \ + | c8051-* | clipper-* | craynv-* | cydra-* \ + | d10v-* | d30v-* | dlx-* \ + | elxsi-* \ + | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \ + | h8300-* | h8500-* \ + | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ + | hexagon-* \ + | i*86-* | i860-* | i960-* | ia64-* \ + | ip2k-* | iq2000-* \ + | le32-* | le64-* \ + | lm32-* \ + | m32c-* | m32r-* | m32rle-* \ + | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ + | m88110-* | m88k-* | maxq-* | mcore-* | metag-* \ + | microblaze-* | microblazeel-* \ + | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ + | mips16-* \ + | mips64-* | mips64el-* \ + | mips64octeon-* | mips64octeonel-* \ + | mips64orion-* | mips64orionel-* \ + | mips64r5900-* | mips64r5900el-* \ + | mips64vr-* | mips64vrel-* \ + | mips64vr4100-* | mips64vr4100el-* \ + | mips64vr4300-* | mips64vr4300el-* \ + | mips64vr5000-* | mips64vr5000el-* \ + | mips64vr5900-* | mips64vr5900el-* \ + | mipsisa32-* | mipsisa32el-* \ + | mipsisa32r2-* | mipsisa32r2el-* \ + | mipsisa64-* | mipsisa64el-* \ + | mipsisa64r2-* | mipsisa64r2el-* \ + | mipsisa64sb1-* | mipsisa64sb1el-* \ + | mipsisa64sr71k-* | mipsisa64sr71kel-* \ + | mipsr5900-* | mipsr5900el-* \ + | mipstx39-* | mipstx39el-* \ + | mmix-* \ + | mt-* \ + | msp430-* \ + | nds32-* | nds32le-* | nds32be-* \ + | nios-* | nios2-* | nios2eb-* | nios2el-* \ + | none-* | np1-* | ns16k-* | ns32k-* \ + | open8-* \ + | orion-* \ + | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ + | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \ + | pyramid-* \ + | rl78-* | romp-* | rs6000-* | rx-* \ + | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \ + | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ + | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \ + | sparclite-* \ + | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx?-* \ + | tahoe-* \ + | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ + | tile*-* \ + | tron-* \ + | ubicom32-* \ + | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \ + | vax-* \ + | we32k-* \ + | x86-* | x86_64-* | xc16x-* | xps100-* \ + | xstormy16-* | xtensa*-* \ + | ymp-* \ + | z8k-* | z80-*) + ;; + # Recognize the basic CPU types without company name, with glob match. + xtensa*) + basic_machine=$basic_machine-unknown + ;; + # Recognize the various machine names and aliases which stand + # for a CPU type and a company and sometimes even an OS. + 386bsd) + basic_machine=i386-unknown + os=-bsd + ;; + 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) + basic_machine=m68000-att + ;; + 3b*) + basic_machine=we32k-att + ;; + a29khif) + basic_machine=a29k-amd + os=-udi + ;; + abacus) + basic_machine=abacus-unknown + ;; + adobe68k) + basic_machine=m68010-adobe + os=-scout + ;; + alliant | fx80) + basic_machine=fx80-alliant + ;; + altos | altos3068) + basic_machine=m68k-altos + ;; + am29k) + basic_machine=a29k-none + os=-bsd + ;; + amd64) + basic_machine=x86_64-pc + ;; + amd64-*) + basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + amdahl) + basic_machine=580-amdahl + os=-sysv + ;; + amiga | amiga-*) + basic_machine=m68k-unknown + ;; + amigaos | amigados) + basic_machine=m68k-unknown + os=-amigaos + ;; + amigaunix | amix) + basic_machine=m68k-unknown + os=-sysv4 + ;; + apollo68) + basic_machine=m68k-apollo + os=-sysv + ;; + apollo68bsd) + basic_machine=m68k-apollo + os=-bsd + ;; + aros) + basic_machine=i386-pc + os=-aros + ;; + aux) + basic_machine=m68k-apple + os=-aux + ;; + balance) + basic_machine=ns32k-sequent + os=-dynix + ;; + blackfin) + basic_machine=bfin-unknown + os=-linux + ;; + blackfin-*) + basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'` + os=-linux + ;; + bluegene*) + basic_machine=powerpc-ibm + os=-cnk + ;; + c54x-*) + basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + c55x-*) + basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + c6x-*) + basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + c90) + basic_machine=c90-cray + os=-unicos + ;; + cegcc) + basic_machine=arm-unknown + os=-cegcc + ;; + convex-c1) + basic_machine=c1-convex + os=-bsd + ;; + convex-c2) + basic_machine=c2-convex + os=-bsd + ;; + convex-c32) + basic_machine=c32-convex + os=-bsd + ;; + convex-c34) + basic_machine=c34-convex + os=-bsd + ;; + convex-c38) + basic_machine=c38-convex + os=-bsd + ;; + cray | j90) + basic_machine=j90-cray + os=-unicos + ;; + craynv) + basic_machine=craynv-cray + os=-unicosmp + ;; + cr16 | cr16-*) + basic_machine=cr16-unknown + os=-elf + ;; + crds | unos) + basic_machine=m68k-crds + ;; + crisv32 | crisv32-* | etraxfs*) + basic_machine=crisv32-axis + ;; + cris | cris-* | etrax*) + basic_machine=cris-axis + ;; + crx) + basic_machine=crx-unknown + os=-elf + ;; + da30 | da30-*) + basic_machine=m68k-da30 + ;; + decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) + basic_machine=mips-dec + ;; + decsystem10* | dec10*) + basic_machine=pdp10-dec + os=-tops10 + ;; + decsystem20* | dec20*) + basic_machine=pdp10-dec + os=-tops20 + ;; + delta | 3300 | motorola-3300 | motorola-delta \ + | 3300-motorola | delta-motorola) + basic_machine=m68k-motorola + ;; + delta88) + basic_machine=m88k-motorola + os=-sysv3 + ;; + dicos) + basic_machine=i686-pc + os=-dicos + ;; + djgpp) + basic_machine=i586-pc + os=-msdosdjgpp + ;; + dpx20 | dpx20-*) + basic_machine=rs6000-bull + os=-bosx + ;; + dpx2* | dpx2*-bull) + basic_machine=m68k-bull + os=-sysv3 + ;; + ebmon29k) + basic_machine=a29k-amd + os=-ebmon + ;; + elxsi) + basic_machine=elxsi-elxsi + os=-bsd + ;; + encore | umax | mmax) + basic_machine=ns32k-encore + ;; + es1800 | OSE68k | ose68k | ose | OSE) + basic_machine=m68k-ericsson + os=-ose + ;; + fx2800) + basic_machine=i860-alliant + ;; + genix) + basic_machine=ns32k-ns + ;; + gmicro) + basic_machine=tron-gmicro + os=-sysv + ;; + go32) + basic_machine=i386-pc + os=-go32 + ;; + h3050r* | hiux*) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + h8300hms) + basic_machine=h8300-hitachi + os=-hms + ;; + h8300xray) + basic_machine=h8300-hitachi + os=-xray + ;; + h8500hms) + basic_machine=h8500-hitachi + os=-hms + ;; + harris) + basic_machine=m88k-harris + os=-sysv3 + ;; + hp300-*) + basic_machine=m68k-hp + ;; + hp300bsd) + basic_machine=m68k-hp + os=-bsd + ;; + hp300hpux) + basic_machine=m68k-hp + os=-hpux + ;; + hp3k9[0-9][0-9] | hp9[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k2[0-9][0-9] | hp9k31[0-9]) + basic_machine=m68000-hp + ;; + hp9k3[2-9][0-9]) + basic_machine=m68k-hp + ;; + hp9k6[0-9][0-9] | hp6[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k7[0-79][0-9] | hp7[0-79][0-9]) + basic_machine=hppa1.1-hp + ;; + hp9k78[0-9] | hp78[0-9]) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][13679] | hp8[0-9][13679]) + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][0-9] | hp8[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hppa-next) + os=-nextstep3 + ;; + hppaosf) + basic_machine=hppa1.1-hp + os=-osf + ;; + hppro) + basic_machine=hppa1.1-hp + os=-proelf + ;; + i370-ibm* | ibm*) + basic_machine=i370-ibm + ;; + i*86v32) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv32 + ;; + i*86v4*) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv4 + ;; + i*86v) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv + ;; + i*86sol2) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-solaris2 + ;; + i386mach) + basic_machine=i386-mach + os=-mach + ;; + i386-vsta | vsta) + basic_machine=i386-unknown + os=-vsta + ;; + iris | iris4d) + basic_machine=mips-sgi + case $os in + -irix*) + ;; + *) + os=-irix4 + ;; + esac + ;; + isi68 | isi) + basic_machine=m68k-isi + os=-sysv + ;; + m68knommu) + basic_machine=m68k-unknown + os=-linux + ;; + m68knommu-*) + basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'` + os=-linux + ;; + m88k-omron*) + basic_machine=m88k-omron + ;; + magnum | m3230) + basic_machine=mips-mips + os=-sysv + ;; + merlin) + basic_machine=ns32k-utek + os=-sysv + ;; + microblaze*) + basic_machine=microblaze-xilinx + ;; + mingw64) + basic_machine=x86_64-pc + os=-mingw64 + ;; + mingw32) + basic_machine=i686-pc + os=-mingw32 + ;; + mingw32ce) + basic_machine=arm-unknown + os=-mingw32ce + ;; + miniframe) + basic_machine=m68000-convergent + ;; + *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; + mips3*-*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` + ;; + mips3*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown + ;; + monitor) + basic_machine=m68k-rom68k + os=-coff + ;; + morphos) + basic_machine=powerpc-unknown + os=-morphos + ;; + msdos) + basic_machine=i386-pc + os=-msdos + ;; + ms1-*) + basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'` + ;; + msys) + basic_machine=i686-pc + os=-msys + ;; + mvs) + basic_machine=i370-ibm + os=-mvs + ;; + nacl) + basic_machine=le32-unknown + os=-nacl + ;; + ncr3000) + basic_machine=i486-ncr + os=-sysv4 + ;; + netbsd386) + basic_machine=i386-unknown + os=-netbsd + ;; + netwinder) + basic_machine=armv4l-rebel + os=-linux + ;; + news | news700 | news800 | news900) + basic_machine=m68k-sony + os=-newsos + ;; + news1000) + basic_machine=m68030-sony + os=-newsos + ;; + news-3600 | risc-news) + basic_machine=mips-sony + os=-newsos + ;; + necv70) + basic_machine=v70-nec + os=-sysv + ;; + next | m*-next ) + basic_machine=m68k-next + case $os in + -nextstep* ) + ;; + -ns2*) + os=-nextstep2 + ;; + *) + os=-nextstep3 + ;; + esac + ;; + nh3000) + basic_machine=m68k-harris + os=-cxux + ;; + nh[45]000) + basic_machine=m88k-harris + os=-cxux + ;; + nindy960) + basic_machine=i960-intel + os=-nindy + ;; + mon960) + basic_machine=i960-intel + os=-mon960 + ;; + nonstopux) + basic_machine=mips-compaq + os=-nonstopux + ;; + np1) + basic_machine=np1-gould + ;; + neo-tandem) + basic_machine=neo-tandem + ;; + nse-tandem) + basic_machine=nse-tandem + ;; + nsr-tandem) + basic_machine=nsr-tandem + ;; + op50n-* | op60c-*) + basic_machine=hppa1.1-oki + os=-proelf + ;; + openrisc | openrisc-*) + basic_machine=or32-unknown + ;; + os400) + basic_machine=powerpc-ibm + os=-os400 + ;; + OSE68000 | ose68000) + basic_machine=m68000-ericsson + os=-ose + ;; + os68k) + basic_machine=m68k-none + os=-os68k + ;; + pa-hitachi) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + paragon) + basic_machine=i860-intel + os=-osf + ;; + parisc) + basic_machine=hppa-unknown + os=-linux + ;; + parisc-*) + basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'` + os=-linux + ;; + pbd) + basic_machine=sparc-tti + ;; + pbb) + basic_machine=m68k-tti + ;; + pc532 | pc532-*) + basic_machine=ns32k-pc532 + ;; + pc98) + basic_machine=i386-pc + ;; + pc98-*) + basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentium | p5 | k5 | k6 | nexgen | viac3) + basic_machine=i586-pc + ;; + pentiumpro | p6 | 6x86 | athlon | athlon_*) + basic_machine=i686-pc + ;; + pentiumii | pentium2 | pentiumiii | pentium3) + basic_machine=i686-pc + ;; + pentium4) + basic_machine=i786-pc + ;; + pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) + basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumpro-* | p6-* | 6x86-* | athlon-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentium4-*) + basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pn) + basic_machine=pn-gould + ;; + power) basic_machine=power-ibm + ;; + ppc | ppcbe) basic_machine=powerpc-unknown + ;; + ppc-* | ppcbe-*) + basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppcle | powerpclittle | ppc-le | powerpc-little) + basic_machine=powerpcle-unknown + ;; + ppcle-* | powerpclittle-*) + basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64) basic_machine=powerpc64-unknown + ;; + ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64le | powerpc64little | ppc64-le | powerpc64-little) + basic_machine=powerpc64le-unknown + ;; + ppc64le-* | powerpc64little-*) + basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ps2) + basic_machine=i386-ibm + ;; + pw32) + basic_machine=i586-unknown + os=-pw32 + ;; + rdos | rdos64) + basic_machine=x86_64-pc + os=-rdos + ;; + rdos32) + basic_machine=i386-pc + os=-rdos + ;; + rom68k) + basic_machine=m68k-rom68k + os=-coff + ;; + rm[46]00) + basic_machine=mips-siemens + ;; + rtpc | rtpc-*) + basic_machine=romp-ibm + ;; + s390 | s390-*) + basic_machine=s390-ibm + ;; + s390x | s390x-*) + basic_machine=s390x-ibm + ;; + sa29200) + basic_machine=a29k-amd + os=-udi + ;; + sb1) + basic_machine=mipsisa64sb1-unknown + ;; + sb1el) + basic_machine=mipsisa64sb1el-unknown + ;; + sde) + basic_machine=mipsisa32-sde + os=-elf + ;; + sei) + basic_machine=mips-sei + os=-seiux + ;; + sequent) + basic_machine=i386-sequent + ;; + sh) + basic_machine=sh-hitachi + os=-hms + ;; + sh5el) + basic_machine=sh5le-unknown + ;; + sh64) + basic_machine=sh64-unknown + ;; + sparclite-wrs | simso-wrs) + basic_machine=sparclite-wrs + os=-vxworks + ;; + sps7) + basic_machine=m68k-bull + os=-sysv2 + ;; + spur) + basic_machine=spur-unknown + ;; + st2000) + basic_machine=m68k-tandem + ;; + stratus) + basic_machine=i860-stratus + os=-sysv4 + ;; + strongarm-* | thumb-*) + basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + sun2) + basic_machine=m68000-sun + ;; + sun2os3) + basic_machine=m68000-sun + os=-sunos3 + ;; + sun2os4) + basic_machine=m68000-sun + os=-sunos4 + ;; + sun3os3) + basic_machine=m68k-sun + os=-sunos3 + ;; + sun3os4) + basic_machine=m68k-sun + os=-sunos4 + ;; + sun4os3) + basic_machine=sparc-sun + os=-sunos3 + ;; + sun4os4) + basic_machine=sparc-sun + os=-sunos4 + ;; + sun4sol2) + basic_machine=sparc-sun + os=-solaris2 + ;; + sun3 | sun3-*) + basic_machine=m68k-sun + ;; + sun4) + basic_machine=sparc-sun + ;; + sun386 | sun386i | roadrunner) + basic_machine=i386-sun + ;; + sv1) + basic_machine=sv1-cray + os=-unicos + ;; + symmetry) + basic_machine=i386-sequent + os=-dynix + ;; + t3e) + basic_machine=alphaev5-cray + os=-unicos + ;; + t90) + basic_machine=t90-cray + os=-unicos + ;; + tile*) + basic_machine=$basic_machine-unknown + os=-linux-gnu + ;; + tx39) + basic_machine=mipstx39-unknown + ;; + tx39el) + basic_machine=mipstx39el-unknown + ;; + toad1) + basic_machine=pdp10-xkl + os=-tops20 + ;; + tower | tower-32) + basic_machine=m68k-ncr + ;; + tpf) + basic_machine=s390x-ibm + os=-tpf + ;; + udi29k) + basic_machine=a29k-amd + os=-udi + ;; + ultra3) + basic_machine=a29k-nyu + os=-sym1 + ;; + v810 | necv810) + basic_machine=v810-nec + os=-none + ;; + vaxv) + basic_machine=vax-dec + os=-sysv + ;; + vms) + basic_machine=vax-dec + os=-vms + ;; + vpp*|vx|vx-*) + basic_machine=f301-fujitsu + ;; + vxworks960) + basic_machine=i960-wrs + os=-vxworks + ;; + vxworks68) + basic_machine=m68k-wrs + os=-vxworks + ;; + vxworks29k) + basic_machine=a29k-wrs + os=-vxworks + ;; + w65*) + basic_machine=w65-wdc + os=-none + ;; + w89k-*) + basic_machine=hppa1.1-winbond + os=-proelf + ;; + xbox) + basic_machine=i686-pc + os=-mingw32 + ;; + xps | xps100) + basic_machine=xps100-honeywell + ;; + xscale-* | xscalee[bl]-*) + basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'` + ;; + ymp) + basic_machine=ymp-cray + os=-unicos + ;; + z8k-*-coff) + basic_machine=z8k-unknown + os=-sim + ;; + z80-*-coff) + basic_machine=z80-unknown + os=-sim + ;; + none) + basic_machine=none-none + os=-none + ;; + +# Here we handle the default manufacturer of certain CPU types. It is in +# some cases the only manufacturer, in others, it is the most popular. + w89k) + basic_machine=hppa1.1-winbond + ;; + op50n) + basic_machine=hppa1.1-oki + ;; + op60c) + basic_machine=hppa1.1-oki + ;; + romp) + basic_machine=romp-ibm + ;; + mmix) + basic_machine=mmix-knuth + ;; + rs6000) + basic_machine=rs6000-ibm + ;; + vax) + basic_machine=vax-dec + ;; + pdp10) + # there are many clones, so DEC is not a safe bet + basic_machine=pdp10-unknown + ;; + pdp11) + basic_machine=pdp11-dec + ;; + we32k) + basic_machine=we32k-att + ;; + sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele) + basic_machine=sh-unknown + ;; + sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v) + basic_machine=sparc-sun + ;; + cydra) + basic_machine=cydra-cydrome + ;; + orion) + basic_machine=orion-highlevel + ;; + orion105) + basic_machine=clipper-highlevel + ;; + mac | mpw | mac-mpw) + basic_machine=m68k-apple + ;; + pmac | pmac-mpw) + basic_machine=powerpc-apple + ;; + *-unknown) + # Make sure to match an already-canonicalized machine name. + ;; + *) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; +esac + +# Here we canonicalize certain aliases for manufacturers. +case $basic_machine in + *-digital*) + basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` + ;; + *-commodore*) + basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` + ;; + *) + ;; +esac + +# Decode manufacturer-specific aliases for certain operating systems. + +if [ x"$os" != x"" ] +then +case $os in + # First match some system type aliases + # that might get confused with valid system types. + # -solaris* is a basic system type, with this one exception. + -auroraux) + os=-auroraux + ;; + -solaris1 | -solaris1.*) + os=`echo $os | sed -e 's|solaris1|sunos4|'` + ;; + -solaris) + os=-solaris2 + ;; + -svr4*) + os=-sysv4 + ;; + -unixware*) + os=-sysv4.2uw + ;; + -gnu/linux*) + os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` + ;; + # First accept the basic system types. + # The portable systems comes first. + # Each alternative MUST END IN A *, to match a version number. + # -sysv* is not here because it comes later, after sysvr4. + -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ + | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\ + | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \ + | -sym* | -kopensolaris* | -plan9* \ + | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ + | -aos* | -aros* \ + | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ + | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ + | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ + | -bitrig* | -openbsd* | -solidbsd* \ + | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ + | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ + | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ + | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ + | -chorusos* | -chorusrdb* | -cegcc* \ + | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ + | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \ + | -linux-newlib* | -linux-musl* | -linux-uclibc* \ + | -uxpv* | -beos* | -mpeix* | -udk* \ + | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ + | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ + | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ + | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ + | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ + | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ + | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es*) + # Remember, each alternative MUST END IN *, to match a version number. + ;; + -qnx*) + case $basic_machine in + x86-* | i*86-*) + ;; + *) + os=-nto$os + ;; + esac + ;; + -nto-qnx*) + ;; + -nto*) + os=`echo $os | sed -e 's|nto|nto-qnx|'` + ;; + -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ + | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \ + | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) + ;; + -mac*) + os=`echo $os | sed -e 's|mac|macos|'` + ;; + -linux-dietlibc) + os=-linux-dietlibc + ;; + -linux*) + os=`echo $os | sed -e 's|linux|linux-gnu|'` + ;; + -sunos5*) + os=`echo $os | sed -e 's|sunos5|solaris2|'` + ;; + -sunos6*) + os=`echo $os | sed -e 's|sunos6|solaris3|'` + ;; + -opened*) + os=-openedition + ;; + -os400*) + os=-os400 + ;; + -wince*) + os=-wince + ;; + -osfrose*) + os=-osfrose + ;; + -osf*) + os=-osf + ;; + -utek*) + os=-bsd + ;; + -dynix*) + os=-bsd + ;; + -acis*) + os=-aos + ;; + -atheos*) + os=-atheos + ;; + -syllable*) + os=-syllable + ;; + -386bsd) + os=-bsd + ;; + -ctix* | -uts*) + os=-sysv + ;; + -nova*) + os=-rtmk-nova + ;; + -ns2 ) + os=-nextstep2 + ;; + -nsk*) + os=-nsk + ;; + # Preserve the version number of sinix5. + -sinix5.*) + os=`echo $os | sed -e 's|sinix|sysv|'` + ;; + -sinix*) + os=-sysv4 + ;; + -tpf*) + os=-tpf + ;; + -triton*) + os=-sysv3 + ;; + -oss*) + os=-sysv3 + ;; + -svr4) + os=-sysv4 + ;; + -svr3) + os=-sysv3 + ;; + -sysvr4) + os=-sysv4 + ;; + # This must come after -sysvr4. + -sysv*) + ;; + -ose*) + os=-ose + ;; + -es1800*) + os=-ose + ;; + -xenix) + os=-xenix + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + os=-mint + ;; + -aros*) + os=-aros + ;; + -zvmoe) + os=-zvmoe + ;; + -dicos*) + os=-dicos + ;; + -nacl*) + ;; + -none) + ;; + *) + # Get rid of the `-' at the beginning of $os. + os=`echo $os | sed 's/[^-]*-//'` + echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 + exit 1 + ;; +esac +else + +# Here we handle the default operating systems that come with various machines. +# The value should be what the vendor currently ships out the door with their +# machine or put another way, the most popular os provided with the machine. + +# Note that if you're going to try to match "-MANUFACTURER" here (say, +# "-sun"), then you have to tell the case statement up towards the top +# that MANUFACTURER isn't an operating system. Otherwise, code above +# will signal an error saying that MANUFACTURER isn't an operating +# system, and we'll never get to this point. + +case $basic_machine in + score-*) + os=-elf + ;; + spu-*) + os=-elf + ;; + *-acorn) + os=-riscix1.2 + ;; + arm*-rebel) + os=-linux + ;; + arm*-semi) + os=-aout + ;; + c4x-* | tic4x-*) + os=-coff + ;; + c8051-*) + os=-elf + ;; + hexagon-*) + os=-elf + ;; + tic54x-*) + os=-coff + ;; + tic55x-*) + os=-coff + ;; + tic6x-*) + os=-coff + ;; + # This must come before the *-dec entry. + pdp10-*) + os=-tops20 + ;; + pdp11-*) + os=-none + ;; + *-dec | vax-*) + os=-ultrix4.2 + ;; + m68*-apollo) + os=-domain + ;; + i386-sun) + os=-sunos4.0.2 + ;; + m68000-sun) + os=-sunos3 + ;; + m68*-cisco) + os=-aout + ;; + mep-*) + os=-elf + ;; + mips*-cisco) + os=-elf + ;; + mips*-*) + os=-elf + ;; + or1k-*) + os=-elf + ;; + or32-*) + os=-coff + ;; + *-tti) # must be before sparc entry or we get the wrong os. + os=-sysv3 + ;; + sparc-* | *-sun) + os=-sunos4.1.1 + ;; + *-be) + os=-beos + ;; + *-haiku) + os=-haiku + ;; + *-ibm) + os=-aix + ;; + *-knuth) + os=-mmixware + ;; + *-wec) + os=-proelf + ;; + *-winbond) + os=-proelf + ;; + *-oki) + os=-proelf + ;; + *-hp) + os=-hpux + ;; + *-hitachi) + os=-hiux + ;; + i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) + os=-sysv + ;; + *-cbm) + os=-amigaos + ;; + *-dg) + os=-dgux + ;; + *-dolphin) + os=-sysv3 + ;; + m68k-ccur) + os=-rtu + ;; + m88k-omron*) + os=-luna + ;; + *-next ) + os=-nextstep + ;; + *-sequent) + os=-ptx + ;; + *-crds) + os=-unos + ;; + *-ns) + os=-genix + ;; + i370-*) + os=-mvs + ;; + *-next) + os=-nextstep3 + ;; + *-gould) + os=-sysv + ;; + *-highlevel) + os=-bsd + ;; + *-encore) + os=-bsd + ;; + *-sgi) + os=-irix + ;; + *-siemens) + os=-sysv4 + ;; + *-masscomp) + os=-rtu + ;; + f30[01]-fujitsu | f700-fujitsu) + os=-uxpv + ;; + *-rom68k) + os=-coff + ;; + *-*bug) + os=-coff + ;; + *-apple) + os=-macos + ;; + *-atari*) + os=-mint + ;; + *) + os=-none + ;; +esac +fi + +# Here we handle the case where we know the os, and the CPU type, but not the +# manufacturer. We pick the logical manufacturer. +vendor=unknown +case $basic_machine in + *-unknown) + case $os in + -riscix*) + vendor=acorn + ;; + -sunos*) + vendor=sun + ;; + -cnk*|-aix*) + vendor=ibm + ;; + -beos*) + vendor=be + ;; + -hpux*) + vendor=hp + ;; + -mpeix*) + vendor=hp + ;; + -hiux*) + vendor=hitachi + ;; + -unos*) + vendor=crds + ;; + -dgux*) + vendor=dg + ;; + -luna*) + vendor=omron + ;; + -genix*) + vendor=ns + ;; + -mvs* | -opened*) + vendor=ibm + ;; + -os400*) + vendor=ibm + ;; + -ptx*) + vendor=sequent + ;; + -tpf*) + vendor=ibm + ;; + -vxsim* | -vxworks* | -windiss*) + vendor=wrs + ;; + -aux*) + vendor=apple + ;; + -hms*) + vendor=hitachi + ;; + -mpw* | -macos*) + vendor=apple + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + vendor=atari + ;; + -vos*) + vendor=stratus + ;; + esac + basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` + ;; +esac + +echo $basic_machine$os +exit + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/3rd-party/gdal/patches/gdal-2.0.1.patch b/3rd-party/gdal/patches/gdal-2.0.1.patch new file mode 100644 index 0000000..dc69ccb --- /dev/null +++ b/3rd-party/gdal/patches/gdal-2.0.1.patch @@ -0,0 +1,24 @@ +diff -up ./frmts/GNUmakefile.orig ./frmts/GNUmakefile +--- ./frmts/GNUmakefile.orig 2016-01-01 22:53:27.597434480 +0100 ++++ ./frmts/GNUmakefile 2016-01-01 22:54:29.020540683 +0100 +@@ -16,7 +16,7 @@ clean: $(foreach d,$(GDAL_FORMATS),$(d)- + $(RM) o/*.lo + + o/gdalallregister.$(OBJ_EXT): gdalallregister.cpp ../GDALmake.opt +- $(CXX) -c $(GDAL_INCLUDE) $(CXXFLAGS) $(FRMT_FLAGS) \ ++ $(CXX) -c $(GDAL_INCLUDE) $(CPPFLAGS) $(CXXFLAGS) $(FRMT_FLAGS) \ + -DGDAL_FORMATS="$(GDAL_FORMATS)" \ + gdalallregister.cpp -o o/gdalallregister.$(OBJ_EXT) + +diff -up ./gcore/GNUmakefile.orig ./gcore/GNUmakefile +--- ./gcore/GNUmakefile.orig 2016-01-01 22:53:17.541580806 +0100 ++++ ./gcore/GNUmakefile 2016-01-01 22:54:06.292871404 +0100 +@@ -48,7 +48,7 @@ docs: + gdal_misc.$(OBJ_EXT): gdal_misc.cpp gdal_version.h + + gdaldrivermanager.$(OBJ_EXT): gdaldrivermanager.cpp ../GDALmake.opt +- $(CXX) -c $(GDAL_INCLUDE) $(CXXFLAGS) -DINST_DATA=\"$(INST_DATA)\" \ ++ $(CXX) -c $(GDAL_INCLUDE) $(CPPFLAGS) $(CXXFLAGS) -DINST_DATA=\"$(INST_DATA)\" \ + $< -o $@ + + install: diff --git a/3rd-party/gnu-libstdc++/INSTALL.txt.in b/3rd-party/gnu-libstdc++/INSTALL.txt.in new file mode 100644 index 0000000..2a8b5cd --- /dev/null +++ b/3rd-party/gnu-libstdc++/INSTALL.txt.in @@ -0,0 +1,26 @@ +For building and installing libstdc++ and for creating the source package, you +need to have installed the matching Android NDK release (cf. NDK-Release.txt) +and run: + + ./build.sh /PATH/TO/NDK + +You may add options as understood by the NDK's build-gnu-libstdc++.sh, e.g. +--verbose or -j6. + + +ATTENTION: +Before running build.sh, you need to backup (if desired) and remove +/PATH/TO/NDK/sources/cxx-stl/gnu-libstdc++/4.9 which come with the NDK. +The build process will write new libstdc++ files to this directory! + + +The source code in the src subdirectory was taken from + + https://android.googlesource.com/toolchain/gcc.git + +The selected git revision is documented in the file REVISION. + +The build scripts and patches in the build/tools/ directory were taken from the +Android NDK release's directory build/tools/. The gcc patches in +build/tools/toolchain-patches/ were already applied to the source code in src +and are included in this distribution for reference diff --git a/3rd-party/gnu-libstdc++/README.txt b/3rd-party/gnu-libstdc++/README.txt new file mode 100644 index 0000000..1b8914a --- /dev/null +++ b/3rd-party/gnu-libstdc++/README.txt @@ -0,0 +1,20 @@ +This package is for building and installing GNU libstdc++ for the Android +NDK and for providing the corresponding source code. + +It is to be used by doing an out-of-source build configured by qmake from the +supplied gnu-libstdc++.pro. You need to set ANDROID_NDK_ROOT, e.g. by choosing +an Android kit in Qt Creator. + +The GCC 4.9 libstdc++ source code will be taken from + + https://android.googlesource.com/toolchain/gcc.git + +The selected git revision will be documented in the file REVISION. + +Build scripts and gcc patches will be taken from + + /PATH/TO/NDK/build/tools/ + +If it exists, a patch file build-tools-[NDK_REVISION].patch will be applied to +the build scripts and patches. Than, the gcc patches are applied to the source +code. diff --git a/3rd-party/gnu-libstdc++/build.sh b/3rd-party/gnu-libstdc++/build.sh new file mode 100755 index 0000000..13d5ff7 --- /dev/null +++ b/3rd-party/gnu-libstdc++/build.sh @@ -0,0 +1,56 @@ +#!/bin/bash -e +# +# Copyright 2014, 2015 Kai Pastor +# +# This file is part of OpenOrienteering. +# +# OpenOrienteering is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# OpenOrienteering is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with OpenOrienteering. If not, see . + +NDK_DIR="$1" +if [ -z "$NDK_DIR" -o ! -d "$NDK_DIR" ] +then + echo "$0: Error: missing parameter" >&2 + echo "Usage:" >&2 + echo " $0 /PATH/TO/NDK-DIR" >&2 + exit 1 +fi + +if [ -d "$NDK_DIR/sources/cxx-stl/gnu-libstdc++/4.9" ] +then + echo -n "$0: Error: Before running $0, you must (backup! and) remove " >&2 + echo "$NDK_DIR/sources/cxx-stl/gnu-libstdc++/4.9." >&2 + exit 3 +fi + +shift + +TRY64= +if [ -d "$NDK_DIR/toolchains/x86-4.9/prebuilt/linux-x86_64" ] +then + TRY64=--try-64 +fi + +echo "Building GNU libstdc++..." +ANDROID_NDK_ROOT="$NDK_DIR" bash "$(pwd)/build/tools/build-gnu-libstdc++.sh" \ + "$(pwd)/src" \ + --gcc-version-list=4.9 \ + --ndk-dir="$NDK_DIR" \ + $TRY64 \ + $* + +echo "Creating source code archiv..." +ARCHIVE_NAME=$(basename "$(pwd)") +( cd .. && tar cJf "$ARCHIVE_NAME.tar.xz" --exclude="$ARCHIVE_NAME/gcc" --exclude="*~" "$ARCHIVE_NAME" ) + +echo "*** $ARCHIVE_NAME.tar.xz: done" diff --git a/3rd-party/gnu-libstdc++/gnu-libstdc++.pro b/3rd-party/gnu-libstdc++/gnu-libstdc++.pro new file mode 100644 index 0000000..9549f14 --- /dev/null +++ b/3rd-party/gnu-libstdc++/gnu-libstdc++.pro @@ -0,0 +1,94 @@ +# +# Copyright 2014, 2015 Kai Pastor +# +# This file is part of OpenOrienteering. +# +# OpenOrienteering is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# OpenOrienteering is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with OpenOrienteering. If not, see . + +# This .pro file shall be used with a mkspec/kit for Android + +TEMPLATE = aux + +# Files to be listed in Qt Creator project tree +OTHER_FILES = \ + build.sh \ + init.sh \ + INSTALL.txt.in \ + README.txt + +# Determine Android NDK root and release +ANDROID_NDK_ROOT = $$(ANDROID_NDK_ROOT) +isEmpty(ANDROID_NDK_ROOT) { + ANDROID_NDK_ROOT = $$cat("$$OUT_PWD/ANDROID_NDK_ROOT.cache", true) + ANDROID_NDK_ROOT = $$first(ANDROID_NDK_ROOT) +} + +RELEASE_FILE = "$$ANDROID_NDK_ROOT/RELEASE.TXT" +RELEASE_FULL = $$cat("$$RELEASE_FILE", true) +RELEASE = $$split(RELEASE_FULL, " ") +RELEASE = $$split(RELEASE, "-") +RELEASE = $$first(RELEASE) + +isEmpty(RELEASE) { + warning("Unable to determine Android NDK release.") + warning(" (ANDROID_NDK_ROOT: $$ANDROID_NDK_ROOT)") + error("Building GNU libstdc++ library not supported for other systems.") +} + +# Verify that init and build script exist for this release +init.script = $$PWD/init.sh +exists($$init.script) { + message("Android NDK Release: $$RELEASE_FULL") +} else { + warning("Unsupported Android NDK Release: $$RELEASE_FULL") +} + +# Save ANDROID_NDK_ROOT for reconfiguration +write_file($$OUT_PWD/ANDROID_NDK_ROOT.cache, ANDROID_NDK_ROOT) + +# Download/src directory +GNU_LIBSTDCPP_DIR = gnu-libstdc++-android-ndk-$$RELEASE-src + +# Target "init" +init.target = $$GNU_LIBSTDCPP_DIR/build.sh +init.depends = \ + $$ANDROID_NDK_ROOT/RELEASE.TXT \ + $$PWD/build.sh \ + $$PWD/INSTALL.txt.in \ + $$init.script +exists($$PWD/build-tools-$${RELEASE}.patch): init.depends += $$PWD/build-tools-$${RELEASE}.patch +init.commands = @ \ + mkdir -p "$$GNU_LIBSTDCPP_DIR" && \ + echo "$$RELEASE" > "$$GNU_LIBSTDCPP_DIR/NDK-Release.txt" && \ + if [ -f "$$PWD/build-tools-$${RELEASE}.patch" ]; then \ + cp "$$PWD/build-tools-$${RELEASE}.patch" "$$GNU_LIBSTDCPP_DIR/build-tools.patch"; \ + fi && \ + cp "$$PWD/INSTALL.txt.in" "$$GNU_LIBSTDCPP_DIR/INSTALL.txt" && \ + ( test ! -f "$$init.target" || \ + rm "$$init.target" ) && \ + ( cd "$$GNU_LIBSTDCPP_DIR" && \ + "$$init.script" "$$ANDROID_NDK_ROOT" ) && \ + cp "$$PWD/build.sh" "$$init.target" + +# Target "build" +build.target = android-ndk-$$RELEASE-gnu-libstdc++.tgz +build.script = $$init.target +build.depends = $$build.script +build.commands = @ \ + ( cd "$$GNU_LIBSTDCPP_DIR" && \ + "../$$build.script" "$$ANDROID_NDK_ROOT" --package-dir="$$OUT_PWD" ) + +QMAKE_EXTRA_TARGETS += build init +PRE_TARGETDEPS += $$build.target +QMAKE_CLEAN += $$init.target $$build.target $$GNU_LIBSTDCPP_DIR/build/tools/toolchain-patches/gcc/* diff --git a/3rd-party/gnu-libstdc++/init.sh b/3rd-party/gnu-libstdc++/init.sh new file mode 100755 index 0000000..f74176f --- /dev/null +++ b/3rd-party/gnu-libstdc++/init.sh @@ -0,0 +1,145 @@ +#!/bin/sh -e +# +# Copyright 2015 Kai Pastor +# +# This file is part of OpenOrienteering. +# +# OpenOrienteering is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# OpenOrienteering is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with OpenOrienteering. If not, see . + +NDK_DIR="$1" +if [ -z "$NDK_DIR" -o ! -d "$NDK_DIR" ] +then + echo "Usage:" + echo " $0 /PATH/TO/NDK-DIR" + exit 1 +fi + +PATCHES_DIR="$NDK_DIR/build/tools/toolchain-patches/gcc" +if [ ! -d "$PATCHES_DIR" ] +then + echo "Error: No build/tools/toolchain-patches/gcc in $NDK_DIR" + exit 2 +fi + +mkdir -p src/build && touch src/build/configure + +#rm -Rf $(pwd)/gcc/.git +export GIT_DIR="$(pwd)/gcc/.git" +if [ ! -d "$GIT_DIR" ] +then + echo "Creating local git repository..." + git clone --no-checkout https://android.googlesource.com/toolchain/gcc.git +else + echo "Updating local git repository..." + git fetch +fi + +REVISION=$(sed -e '/gcc.git/!d;s/^[^ ]* *\|([^ ]* *\| .*//g' "$NDK_DIR/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/SOURCES") +echo $REVISION > REVISION +echo "Checking out revision $REVISION..." +( + mkdir -p src/gcc && + cd src/gcc && + git checkout -f $REVISION -- \ + gcc-4.9/libstdc++-v3 \ + \ + gcc-4.9/ChangeLog* \ + gcc-4.9/config\* \ + gcc-4.9/COPYING* \ + gcc-4.9/gcc/DATESTAMP \ + gcc-4.9/include \ + gcc-4.9/install-sh \ + gcc-4.9/libgcc \ + gcc-4.9/libiberty \ + gcc-4.9/libtool* \ + gcc-4.9/lt* \ + gcc-4.9/MAINTAINERS* \ + gcc-4.9/mkinstalldirs \ + gcc-4.9/README* \ + \ + gcc-4.8/gcc/config/linux-android.h \ + gcc-4.9/gcc/config/linux-android.h \ + \ + gcc-4.8/libgcc/gthr-posix.h \ + gcc-4.9/libgcc/gthr-posix.h \ + \ + gcc-4.8/libstdc++-v3/src/Makefile.in \ + gcc-4.9/libstdc++-v3/src/Makefile.in \ + \ + gcc-4.9/gcc/BASE-VER \ + \ + gcc-4.9/gcc/ChangeLog \ + gcc-4.9/gcc/config/arm/arm.md \ + gcc-4.9/gcc/testsuite/ChangeLog \ + \ + gcc-4.8/gcc/config/i386/arm_neon.h \ + gcc-4.9/gcc/config/i386/arm_neon.h \ + \ + # End. Covers libstdc++ sources, build dependencies, and extra files touched by patches. +) + +echo "Copying build scripts and patches..." + +NDK_SCRIPTS=" \ + build/tools/build-gnu-libstdc++.sh \ + build/tools/dev-defaults.sh \ + build/tools/ndk-common.sh \ + build/tools/prebuilt-common.sh " + +mkdir -p build/tools +for I in $NDK_SCRIPTS +do + cp "$NDK_DIR/$I" build/tools/ +done + +PATCHES=$(find "$PATCHES_DIR" -name '*.patch' | sort) +if [ -n "$PATCHES" ] +then + mkdir -p build/tools/toolchain-patches/gcc + for PATCH in $PATCHES + do + grep -q gcc-4.9 "$PATCH" && + cp "$PATCH" build/tools/toolchain-patches/gcc/ + done +fi + +echo "Applying patches..." + +CHANGE_FILE=CHANGES.txt +echo "*** CHANGE NOTICE: ***" > $CHANGE_FILE +echo "\n$(date +%F) OpenOrienteering (http://www.openorienteering.org)" >> $CHANGE_FILE +echo " Patches from build/tools/toolchain-patches/gcc applied to src/:\n" >> $CHANGE_FILE +PATCHES=$(find "$(pwd)/build/tools/toolchain-patches/gcc" -name '*.patch' | sort) +if [ -n "$PATCHES" ] +then + for PATCH in $PATCHES; do + echo "*** $(basename $PATCH)" + ( cd src/gcc && patch -p1 < $PATCH ) || exit 1 + done | tee -a $CHANGE_FILE +fi + +echo "Cleanup..." +for I in src/gcc/gcc-4.8 src/gcc/gcc-4.9/lto-plugin src/gcc/gcc-4.9/libgcc/config/* +do + case $(basename "$I") in + aarch64|arm|mips|i386) + ;; + *) + if [ -d "$I" ] + then + rm -R "$I" + fi + ;; + esac +done diff --git a/3rd-party/proj/CMakeLists.txt b/3rd-party/proj/CMakeLists.txt new file mode 100644 index 0000000..e1520ec --- /dev/null +++ b/3rd-party/proj/CMakeLists.txt @@ -0,0 +1,151 @@ +# +# Copyright 2012-2015 Kai Pastor +# +# This file is part of OpenOrienteering. +# +# OpenOrienteering is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# OpenOrienteering is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with OpenOrienteering. If not, see . + + +project(Proj C) + +cmake_minimum_required(VERSION 2.8.3) + +if(${CMAKE_CURRENT_BINARY_DIR} MATCHES " ") + # Note: autotools don't allow whitespace and some other special characters. + message(FATAL_ERROR "The build directory must not contain whitespace.") +endif() + +# Configuration options + +set(PROJ_VERSION_DEFAULT 4.9.2) +set(PROJ_VERSION ${PROJ_VERSION_DEFAULT} CACHE STRING + "Version number of the Proj library, recommended value: ${PROJ_VERSION_DEFAULT}") +mark_as_advanced(PROJ_VERSION) + +message(STATUS "Configuring Proj library ${PROJ_VERSION}") + +if (NOT ${PROJ_VERSION} STREQUAL ${PROJ_VERSION_DEFAULT}) + message(WARNING + "The Proj library version is different from the current recommended version " + "(${PROJ_VERSION} vs. ${PROJ_VERSION_DEFAULT}).") +endif() + +set(PROJ_MD5SUMS + 4.9.2:9843131676e31bbd903d60ae7dc76cf9 +) +foreach(line ${PROJ_MD5SUMS}) + if(${line} MATCHES "^${PROJ_VERSION}:") + string(REPLACE "${PROJ_VERSION}:" "" PROJ_MD5 ${line}) + break() + endif() +endforeach() +if(NOT PROJ_MD5) + message(FATAL_ERROR + "Unknown MD5 sum for Proj library ${PROJ_VERSION}. " + "Edit ${PROJECT_SOURCE_DIR}/CMakeLists.txt, " + "or specify the correct PROJ_MD5 value at the command line.") +endif() + +set(PROJ_LICENSE_FILE "${PROJECT_SOURCE_DIR}/COPYING") +if(EXISTS "${PROJ_LICENSE_FILE}.${PROJ_VERSION}") + set(PROJ_LICENSE_FILE "${PROJ_LICENSE_FILE}.${PROJ_VERSION}") +endif() + +find_program(SH_PROGRAM sh + PATHS + "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\MSYS-1.0_is1;Inno Setup: App Path]/bin" + "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\MinGW;InstallLocation]/bin" + C: + C:/MinGW + PATH_SUFFIXES msys/1.0/bin) +mark_as_advanced(SH_PROGRAM) + +if("${CMAKE_GENERATOR} ${CMAKE_EXTRA_GENERATOR}" MATCHES "Unix Makefiles" OR + "${CMAKE_GENERATOR}" STREQUAL "MSYS Makefiles") + # use magic MAKE macro + set(PROJ_MAKE_COMMAND "\$(MAKE)") +else() + # use wrapper + set(PROJ_MAKE_COMMAND "${SH_PROGRAM}" -l -e ${CMAKE_CURRENT_BINARY_DIR}/proj-make) +endif() + +# External project definition + +include(ExternalProject) +ExternalProject_Add( + Proj + DOWNLOAD_DIR ${PROJECT_SOURCE_DIR}/download + URL "http://download.osgeo.org/proj/proj-${PROJ_VERSION}.tar.gz" + URL_MD5 ${PROJ_MD5} + PATCH_COMMAND "${SH_PROGRAM}" -l -e ${CMAKE_CURRENT_BINARY_DIR}/proj-patch + CONFIGURE_COMMAND + # Check that the license hasn't changed. + ${CMAKE_COMMAND} -E compare_files /COPYING "${PROJ_LICENSE_FILE}" + COMMAND + "${SH_PROGRAM}" -l -e ${CMAKE_CURRENT_BINARY_DIR}/proj-config + BUILD_COMMAND ${PROJ_MAKE_COMMAND} + INSTALL_COMMAND ${PROJ_MAKE_COMMAND} -j1 install + && "${SH_PROGRAM}" -l -e ${CMAKE_CURRENT_BINARY_DIR}/proj-postinstall +) +ExternalProject_Get_Property(Proj SOURCE_DIR) +ExternalProject_Get_Property(Proj BINARY_DIR) +ExternalProject_Get_Property(Proj INSTALL_DIR) + +if(CMAKE_CROSSCOMPILING AND NOT GNU_SYSTEM_NAME AND MINGW) + set(_env_lang $ENV{LC_ALL}) + set(ENV{LC_ALL} C) + execute_process( + COMMAND ${CMAKE_C_COMPILER} -v + ERROR_VARIABLE GNU_SYSTEM_NAME + ) + set(ENV{LC_ALL} ${_env_lang}) + string(REGEX REPLACE ".*Target: ?([^\n]*).*" \\1 GNU_SYSTEM_NAME ${GNU_SYSTEM_NAME}) +endif() +if(CMAKE_CROSSCOMPILING AND GNU_SYSTEM_NAME) + set(_proj_cfg_cross "--build=$(sh ${SOURCE_DIR}/config.guess) --host=${GNU_SYSTEM_NAME}") + get_directory_property(_include_dirs INCLUDE_DIRECTORIES) + if(_include_dirs) + unset(_cpp_flags) + foreach(_dir ${_include_dirs}) + set(_cpp_flags "${_cpp_flags} -I${_dir}") + endforeach() + set(_proj_cfg_cross "${_proj_cfg_cross} CPPFLAGS=\"${_cpp_flags}\"") + endif() +else() + unset(_proj_cfg_cross) +endif() + +configure_file(proj-patch.in ${CMAKE_CURRENT_BINARY_DIR}/proj-patch) +configure_file(proj-config.in ${CMAKE_CURRENT_BINARY_DIR}/proj-config) +configure_file(proj-make.in ${CMAKE_CURRENT_BINARY_DIR}/proj-make) +configure_file(proj-postinstall.in ${CMAKE_CURRENT_BINARY_DIR}/proj-postinstall) + +# Exported configuration + +set(PROJ4_ROOT "${INSTALL_DIR}" PARENT_SCOPE) + +# Remove any left-over cache entries +unset(PROJ4_ROOT CACHE) +unset(PROJ4_INCLUDE_DIR CACHE) +unset(PROJ4_LIBRARY CACHE) +unset(PROJ4_LIBRARY_DEBUG CACHE) +unset(PROJ4_LIBRARY_RELEASE CACHE) + + +# Don't let Xcode re-root the install +set_target_properties(Proj PROPERTIES XCODE_ATTRIBUTE_INSTALL_ROOT "") + + +message(STATUS "Configuring Proj library ${PROJ_VERSION} - done") + diff --git a/3rd-party/proj/COPYING b/3rd-party/proj/COPYING new file mode 100644 index 0000000..fa37174 --- /dev/null +++ b/3rd-party/proj/COPYING @@ -0,0 +1,34 @@ + +All source, data files and other contents of the PROJ.4 package are +available under the following terms. Note that the PROJ 4.3 and earlier +was "public domain" as is common with US government work, but apparently +this is not a well defined legal term in many countries. I am placing +everything under the following MIT style license because I believe it is +effectively the same as public domain, allowing anyone to use the code as +they wish, including making proprietary derivatives. + +Though I have put my own name as copyright holder, I don't mean to imply +I did the work. Essentially all work was done by Gerald Evenden. + + -------------- + + Copyright (c) 2000, Frank Warmerdam + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. + diff --git a/3rd-party/proj/download/README.txt b/3rd-party/proj/download/README.txt new file mode 100644 index 0000000..c6fdbd3 --- /dev/null +++ b/3rd-party/proj/download/README.txt @@ -0,0 +1 @@ +This directory contains downloaded Proj.4 source archives. diff --git a/3rd-party/proj/patches/README.txt b/3rd-party/proj/patches/README.txt new file mode 100644 index 0000000..962a748 --- /dev/null +++ b/3rd-party/proj/patches/README.txt @@ -0,0 +1,16 @@ +proj-4.8.0 is quite old, and it needs modifications for Android support. + +config.guess and config.sub were taken from +http://git.savannah.gnu.org/gitweb/?p=config.git;a=tree;h=3bfabc1475612c4425af0358c101f85f1b97fe64;hb=3bfabc1475612c4425af0358c101f85f1b97fe64 +(Wed, 1 Jan 2014 00:37:33 +0000, commit 3bfabc1475612c4425af0358c101f85f1b97fe64). +Both files are under the GPL3v3. + +configure.patch was created manually by applying the changes from +http://git.savannah.gnu.org/cgit/libtool.git/commit/?id=8eeeb00daef8c4f720c9b79a0cdb89225d9909b6 +(2013-10-08 21:42:07, commit 8eeeb00daef8c4f720c9b79a0cdb89225d9909b6). +The original change modified a file named libtool.m4 which is part of GNU libtool +which is under GPLv2 or any later version. + +pj_init.c.patch was taken from +http://trac.osgeo.org/proj/attachment/ticket/204/ +The patch modified a file named pj_init.c which is part of PROJ.4. diff --git a/3rd-party/proj/patches/configure.patch b/3rd-party/proj/patches/configure.patch new file mode 100644 index 0000000..b677f06 --- /dev/null +++ b/3rd-party/proj/patches/configure.patch @@ -0,0 +1,29 @@ +diff -up Proj/configure.orig Proj/configure +--- Proj/configure.orig 2015-11-17 09:19:22.915735180 +0100 ++++ Proj/configure 2015-11-17 09:25:42.834099078 +0100 +@@ -11317,6 +11317,25 @@ linux*oldld* | linux*aout* | linux*coff* + dynamic_linker=no + ;; + ++# From libtool commit 8eeeb00daef8c4f720c9b79a0cdb89225d9909b6 ++linux*android*) ++ version_type=none # Android doesn't support versioned libraries. ++ need_lib_prefix=no ++ need_version=no ++ library_names_spec='$libname$release$shared_ext' ++ soname_spec='$libname$release$shared_ext' ++ finish_cmds= ++ shlibpath_var=LD_LIBRARY_PATH ++ shlibpath_overrides_runpath=yes ++ ++ # This implies no fast_install, which is unacceptable. ++ # Some rework will be needed to allow for fast_install ++ # before this can be enabled. ++ hardcode_into_libs=yes ++ ++ dynamic_linker='Android linker' ++ ;; ++ + # This must be glibc/ELF. + linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) + version_type=linux # correct to gnu/linux during the next big refactor diff --git a/3rd-party/proj/proj-config.in b/3rd-party/proj/proj-config.in new file mode 100644 index 0000000..5e27978 --- /dev/null +++ b/3rd-party/proj/proj-config.in @@ -0,0 +1,45 @@ +#!/bin/sh -e +# +# Copyright 2012, 2014-2015 Kai Pastor +# +# This file is part of OpenOrienteering. +# +# OpenOrienteering is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# OpenOrienteering is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with OpenOrienteering. If not, see . + +# sh wrapping: +# Especially MSYS needs -l so that it reads /etc/profile and sets up a proper +# environment. But /etc/profile will cd to the home directory. The wrapper needs +# to cd back to the BINARY_DIR. [2] +# In addition, configure must be called from its proper /[DRIVER_LETTER]/... +# path in MSYS, while CMAKE provides a [DRIVE_LETTER]:/... path. [1] + +# [1] Get rid of DOS-style paths in MSYS +cd "@SOURCE_DIR@" +SOURCE_DIR=$(pwd) + +# [2] Go to build directory +cd "@BINARY_DIR@" + +# [3] Put msys-bundled gcc at the end of the PATH +export PATH=$(echo "$PATH" | sed -e 's/\(^\|:\)\([/]mingw[/]bin\):\(.*\)/\1\3:\2/') + +"$SOURCE_DIR/configure" \ + --enable-static=no \ + --without-mutex \ + --without-jni \ + --prefix="@INSTALL_DIR@" \ + @_proj_cfg_cross@ \ + CC=@CMAKE_C_COMPILER@ \ + CFLAGS="@CMAKE_C_FLAGS@ @CMAKE_C_FLAGS_RELEASE@" \ + LDFLAGS="@CMAKE_EXE_LINKER_FLAGS@" diff --git a/3rd-party/proj/proj-make.in b/3rd-party/proj/proj-make.in new file mode 100644 index 0000000..4891d8e --- /dev/null +++ b/3rd-party/proj/proj-make.in @@ -0,0 +1,30 @@ +#!/bin/sh -e +# +# Copyright 2012 Kai Pastor +# +# This file is part of OpenOrienteering. +# +# OpenOrienteering is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# OpenOrienteering is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with OpenOrienteering. If not, see . + +# sh wrapping: +# Especially MSYS needs -l so that it reads /etc/profile and sets up a proper +# environment. But /etc/profile will cd to the home directory. The wrapper needs +# to cd back to the BINARY_DIR. + +cd "@BINARY_DIR@" + +unset MAKE +unset MAKEFLAGS +make "$@" + diff --git a/3rd-party/proj/proj-patch.in b/3rd-party/proj/proj-patch.in new file mode 100644 index 0000000..91a2439 --- /dev/null +++ b/3rd-party/proj/proj-patch.in @@ -0,0 +1,25 @@ +#!/bin/sh -e +# +# Copyright 2014, 2015 Kai Pastor +# +# This file is part of OpenOrienteering. +# +# OpenOrienteering is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# OpenOrienteering is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with OpenOrienteering. If not, see . + +cd "@SOURCE_DIR@" + +if [ "@PROJ_VERSION@" = "4.9.2" ] +then + patch -p1 < "@PROJECT_SOURCE_DIR@/patches/configure.patch" +fi diff --git a/3rd-party/proj/proj-postinstall.in b/3rd-party/proj/proj-postinstall.in new file mode 100644 index 0000000..03b66f3 --- /dev/null +++ b/3rd-party/proj/proj-postinstall.in @@ -0,0 +1,34 @@ +#!/bin/sh -e +# +# Copyright 2012, 2015 Kai Pastor +# +# This file is part of OpenOrienteering. +# +# OpenOrienteering is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# OpenOrienteering is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with OpenOrienteering. If not, see . + +if test -n "@CMAKE_RUNTIME_OUTPUT_DIRECTORY@"; then + + cd "@INSTALL_DIR@" + + if test -n "@WIN32@"; then + test -n "$VERBOSE" && echo "cp -a bin/libproj-0.dll \"@CMAKE_RUNTIME_OUTPUT_DIRECTORY@/\"" + cp -a bin/libproj-9.dll "@CMAKE_RUNTIME_OUTPUT_DIRECTORY@/" + # else + # Libtool will already have generated a message on how to set + # LD_LIBRARY_PATH in order to use the library. + fi + + test -n "$VERBOSE" && echo "cp -a share/proj \"@CMAKE_RUNTIME_OUTPUT_DIRECTORY@/\"" + cp -a share/proj "@CMAKE_RUNTIME_OUTPUT_DIRECTORY@/" +fi diff --git a/3rd-party/proj/proj.pro b/3rd-party/proj/proj.pro new file mode 100644 index 0000000..2cc3fdb --- /dev/null +++ b/3rd-party/proj/proj.pro @@ -0,0 +1,73 @@ +# +# Copyright 2014-2015 Kai Pastor +# +# This file is part of OpenOrienteering. +# +# OpenOrienteering is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# OpenOrienteering is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with OpenOrienteering. If not, see . + +TEMPLATE = aux +CONFIG -= debug_and_release + +CMAKE_TOOLCHAIN_FILE = $$clean_path($$OUT_PWD/../../toolchain.cmake) +if (exists($$CMAKE_TOOLCHAIN_FILE)) { + CMAKE_ARGS += "-DCMAKE_TOOLCHAIN_FILE=\"$$CMAKE_TOOLCHAIN_FILE\"" + proj.depends += $$CMAKE_TOOLCHAIN_FILE +} + +proj.dir = $$OUT_PWD/proj +proj.target = $$proj.dir/Proj-prefix/lib/libproj.so +osx: proj.target = $$proj.dir/Proj-prefix/lib/libproj.9.dylib +win32: proj.target = $$proj.dir/Proj-prefix/bin/libproj-9.dll +proj.cflags = $$QMAKE_CFLAGS -Wno-declaration-after-statement -Wno-int-to-pointer-cast +proj.commands = \ + mkdir -p "$$proj.dir" && \ + cd "$$proj.dir" && \ + if [ -d CMakeFiles -o -f CMakeCache.txt ] ; then rm -R CMake*; fi && \ + if [ -d Proj-prefix ] ; then rm -R Proj-prefix; fi && \ + cmake "$$PWD" $$CMAKE_ARGS && \ + PATH="$$NDK_TOOLCHAIN_PATH/bin:${PATH}" $(MAKE) VERBOSE=$(VERBOSE) all && \ + $(MAKE) clean VERBOSE=$(VERBOSE) + +QMAKE_EXTRA_TARGETS += proj +PRE_TARGETDEPS += $$proj.target +QMAKE_CLEAN += $$proj.target + +PROJ_PRI = \ + "$$LITERAL_HASH Generated by $$_PRO_FILE_" \ + "DEPENDPATH += $$proj.dir/Proj-prefix/include" \ + "INCLUDEPATH += $$proj.dir/Proj-prefix/include" +win32: PROJ_PRI += \ + "LIBS += \"-L$$proj.dir/Proj-prefix/bin\"" +else: PROJ_PRI += \ + "LIBS += \"-L$$proj.dir/Proj-prefix/lib\"" +android: PROJ_PRI += \ + "ANDROID_EXTRA_LIBS += \"$$proj.target\"" + +write_file($$OUT_PWD/proj.pri, PROJ_PRI) + +android|win32 { + INSTALLS += proj_data + proj_data.prefix = + android: proj_data.prefix = /assets + proj_data.extra = $(MAKE) -C proj/Proj-prefix/src/Proj-build/nad install-data DESTDIR=$(INSTALL_ROOT) prefix= datarootdir=$$proj_data.prefix + proj_data.path = $$proj_data.prefix/proj +} + +OTHER_FILES += \ + CMakeLists.txt \ + COPYING \ + proj-config.in \ + proj-make.in \ + proj-patch.in \ + proj-postinstall.in diff --git a/3rd-party/qbezier/CMakeLists.txt b/3rd-party/qbezier/CMakeLists.txt new file mode 100644 index 0000000..5a75cc4 --- /dev/null +++ b/3rd-party/qbezier/CMakeLists.txt @@ -0,0 +1,38 @@ +# +# Copyright 2014 Kai Pastor +# +# This file is part of OpenOrienteering. +# +# OpenOrienteering is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# OpenOrienteering is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with OpenOrienteering. If not, see . + +# qbezier_p.h and the private headers it depends on may be missing +# in some installations of Qt. +# +# The implementation of the functions declared in qbezier_p.h are available in +# the QtGui library. +# +# The headers need to be reviewed when switching to newer versions of Qt. +# (Last review: Qt 5.3.0 beta.) + + +set(QBEZIER_SRCS + src/private/qbezier_p.h # from qtbase/src/gui/painting/ + src/private/qdatabuffer_p.h # from qtbase/src/gui/painting/ + src/private/qmath_p.h # from qtbase/src/gui/painting/ + src/private/qnumeric_p.h # from qtbase/src/corelib/global/ +) + +add_custom_target(QBezier + SOURCES ${QBEZIER_SRCS} +) diff --git a/3rd-party/qbezier/LICENSE.GPL b/3rd-party/qbezier/LICENSE.GPL new file mode 100644 index 0000000..94a9ed0 --- /dev/null +++ b/3rd-party/qbezier/LICENSE.GPL @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/3rd-party/qbezier/README.txt b/3rd-party/qbezier/README.txt new file mode 100644 index 0000000..7418ead --- /dev/null +++ b/3rd-party/qbezier/README.txt @@ -0,0 +1,8 @@ +The files in src/private/ are available under the GPL v3 (cf. LICENSE.GPL) and +were taken unmodified from the follwing files in +qt-everywhere-opensource-src-5.2.0.tar.gz: + +qtbase/src/gui/painting/qbezier_p.h +qtbase/src/gui/painting/qdatabuffer_p.h +qtbase/src/gui/painting/qmath_p.h +qtbase/src/corelib/global/qnumeric_p.h diff --git a/3rd-party/qbezier/qbezier.pro b/3rd-party/qbezier/qbezier.pro new file mode 100644 index 0000000..a45d0b7 --- /dev/null +++ b/3rd-party/qbezier/qbezier.pro @@ -0,0 +1,38 @@ +# +# Copyright 2014-2015 Kai Pastor +# +# This file is part of OpenOrienteering. +# +# OpenOrienteering is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# OpenOrienteering is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with OpenOrienteering. If not, see . + +TEMPLATE = aux +TARGET = qbezier +CONFIG -= debug_and_release + +HEADERS = \ + src/private/qbezier_p.h \ + src/private/qdatabuffer_p.h \ + src/private/qmath_p.h \ + src/private/qnumeric_p.h \ + +OTHER_FILES = \ + LICENSE.GPL \ + README.txt + +QBEZIER_PRI = \ + "$$LITERAL_HASH Generated by $$_PRO_FILE_" \ + "DEPENDPATH += $$PWD/src" \ + "INCLUDEPATH += $$PWD/src" + +write_file($$OUT_PWD/qbezier.pri, QBEZIER_PRI) diff --git a/3rd-party/qbezier/src/mapper_qbezier.cpp b/3rd-party/qbezier/src/mapper_qbezier.cpp new file mode 100644 index 0000000..a2bdb90 --- /dev/null +++ b/3rd-party/qbezier/src/mapper_qbezier.cpp @@ -0,0 +1,5 @@ +// This file is part of OpenOrienteering. + +#include "private/qbezier_p.h" + +#define MAPPER_QBEZIER_VERSION 0x050200 diff --git a/3rd-party/qbezier/src/private/qbezier_p.h b/3rd-party/qbezier/src/private/qbezier_p.h new file mode 100644 index 0000000..3257fdc --- /dev/null +++ b/3rd-party/qbezier/src/private/qbezier_p.h @@ -0,0 +1,276 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QBEZIER_P_H +#define QBEZIER_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists for the convenience +// of other Qt classes. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include "QtCore/qpoint.h" +#include "QtCore/qline.h" +#include "QtCore/qrect.h" +#include "QtCore/qvector.h" +#include "QtCore/qlist.h" +#include "QtCore/qpair.h" +#include "QtGui/qtransform.h" +#include + +QT_BEGIN_NAMESPACE + +class QPolygonF; + +class Q_GUI_EXPORT QBezier +{ +public: + static QBezier fromPoints(const QPointF &p1, const QPointF &p2, + const QPointF &p3, const QPointF &p4); + + static void coefficients(qreal t, qreal &a, qreal &b, qreal &c, qreal &d); + + inline QPointF pointAt(qreal t) const; + inline QPointF normalVector(qreal t) const; + + inline QPointF derivedAt(qreal t) const; + inline QPointF secondDerivedAt(qreal t) const; + + QPolygonF toPolygon(qreal bezier_flattening_threshold = 0.5) const; + void addToPolygon(QPolygonF *p, qreal bezier_flattening_threshold = 0.5) const; + void addToPolygon(QDataBuffer &polygon, qreal bezier_flattening_threshold) const; + + QRectF bounds() const; + qreal length(qreal error = 0.01) const; + void addIfClose(qreal *length, qreal error) const; + + qreal tAtLength(qreal len) const; + + int stationaryYPoints(qreal &t0, qreal &t1) const; + qreal tForY(qreal t0, qreal t1, qreal y) const; + + QPointF pt1() const { return QPointF(x1, y1); } + QPointF pt2() const { return QPointF(x2, y2); } + QPointF pt3() const { return QPointF(x3, y3); } + QPointF pt4() const { return QPointF(x4, y4); } + + QBezier mapBy(const QTransform &transform) const; + + inline QPointF midPoint() const; + inline QLineF midTangent() const; + + inline QLineF startTangent() const; + inline QLineF endTangent() const; + + inline void parameterSplitLeft(qreal t, QBezier *left); + inline void split(QBezier *firstHalf, QBezier *secondHalf) const; + + int shifted(QBezier *curveSegments, int maxSegmets, + qreal offset, float threshold) const; + + QBezier bezierOnInterval(qreal t0, qreal t1) const; + QBezier getSubRange(qreal t0, qreal t1) const; + + qreal x1, y1, x2, y2, x3, y3, x4, y4; +}; + +inline QPointF QBezier::midPoint() const +{ + return QPointF((x1 + x4 + 3*(x2 + x3))/8., (y1 + y4 + 3*(y2 + y3))/8.); +} + +inline QLineF QBezier::midTangent() const +{ + QPointF mid = midPoint(); + QLineF dir(QLineF(x1, y1, x2, y2).pointAt(0.5), QLineF(x3, y3, x4, y4).pointAt(0.5)); + return QLineF(mid.x() - dir.dx(), mid.y() - dir.dy(), + mid.x() + dir.dx(), mid.y() + dir.dy()); +} + +inline QLineF QBezier::startTangent() const +{ + QLineF tangent(pt1(), pt2()); + if (tangent.isNull()) + tangent = QLineF(pt1(), pt3()); + if (tangent.isNull()) + tangent = QLineF(pt1(), pt4()); + return tangent; +} + +inline QLineF QBezier::endTangent() const +{ + QLineF tangent(pt4(), pt3()); + if (tangent.isNull()) + tangent = QLineF(pt4(), pt2()); + if (tangent.isNull()) + tangent = QLineF(pt4(), pt1()); + return tangent; +} + +inline void QBezier::coefficients(qreal t, qreal &a, qreal &b, qreal &c, qreal &d) +{ + qreal m_t = 1. - t; + b = m_t * m_t; + c = t * t; + d = c * t; + a = b * m_t; + b *= 3. * t; + c *= 3. * m_t; +} + +inline QPointF QBezier::pointAt(qreal t) const +{ + // numerically more stable: + qreal x, y; + + qreal m_t = 1. - t; + { + qreal a = x1*m_t + x2*t; + qreal b = x2*m_t + x3*t; + qreal c = x3*m_t + x4*t; + a = a*m_t + b*t; + b = b*m_t + c*t; + x = a*m_t + b*t; + } + { + qreal a = y1*m_t + y2*t; + qreal b = y2*m_t + y3*t; + qreal c = y3*m_t + y4*t; + a = a*m_t + b*t; + b = b*m_t + c*t; + y = a*m_t + b*t; + } + return QPointF(x, y); +} + +inline QPointF QBezier::normalVector(qreal t) const +{ + qreal m_t = 1. - t; + qreal a = m_t * m_t; + qreal b = t * m_t; + qreal c = t * t; + + return QPointF((y2-y1) * a + (y3-y2) * b + (y4-y3) * c, -(x2-x1) * a - (x3-x2) * b - (x4-x3) * c); +} + +inline QPointF QBezier::derivedAt(qreal t) const +{ + // p'(t) = 3 * (-(1-2t+t^2) * p0 + (1 - 4 * t + 3 * t^2) * p1 + (2 * t - 3 * t^2) * p2 + t^2 * p3) + + qreal m_t = 1. - t; + + qreal d = t * t; + qreal a = -m_t * m_t; + qreal b = 1 - 4 * t + 3 * d; + qreal c = 2 * t - 3 * d; + + return 3 * QPointF(a * x1 + b * x2 + c * x3 + d * x4, + a * y1 + b * y2 + c * y3 + d * y4); +} + +inline QPointF QBezier::secondDerivedAt(qreal t) const +{ + qreal a = 2. - 2. * t; + qreal b = -4 + 6 * t; + qreal c = 2 - 6 * t; + qreal d = 2 * t; + + return 3 * QPointF(a * x1 + b * x2 + c * x3 + d * x4, + a * y1 + b * y2 + c * y3 + d * y4); +} + +inline void QBezier::split(QBezier *firstHalf, QBezier *secondHalf) const +{ + Q_ASSERT(firstHalf); + Q_ASSERT(secondHalf); + + qreal c = (x2 + x3)*.5; + firstHalf->x2 = (x1 + x2)*.5; + secondHalf->x3 = (x3 + x4)*.5; + firstHalf->x1 = x1; + secondHalf->x4 = x4; + firstHalf->x3 = (firstHalf->x2 + c)*.5; + secondHalf->x2 = (secondHalf->x3 + c)*.5; + firstHalf->x4 = secondHalf->x1 = (firstHalf->x3 + secondHalf->x2)*.5; + + c = (y2 + y3)/2; + firstHalf->y2 = (y1 + y2)*.5; + secondHalf->y3 = (y3 + y4)*.5; + firstHalf->y1 = y1; + secondHalf->y4 = y4; + firstHalf->y3 = (firstHalf->y2 + c)*.5; + secondHalf->y2 = (secondHalf->y3 + c)*.5; + firstHalf->y4 = secondHalf->y1 = (firstHalf->y3 + secondHalf->y2)*.5; +} + +inline void QBezier::parameterSplitLeft(qreal t, QBezier *left) +{ + left->x1 = x1; + left->y1 = y1; + + left->x2 = x1 + t * ( x2 - x1 ); + left->y2 = y1 + t * ( y2 - y1 ); + + left->x3 = x2 + t * ( x3 - x2 ); // temporary holding spot + left->y3 = y2 + t * ( y3 - y2 ); // temporary holding spot + + x3 = x3 + t * ( x4 - x3 ); + y3 = y3 + t * ( y4 - y3 ); + + x2 = left->x3 + t * ( x3 - left->x3); + y2 = left->y3 + t * ( y3 - left->y3); + + left->x3 = left->x2 + t * ( left->x3 - left->x2 ); + left->y3 = left->y2 + t * ( left->y3 - left->y2 ); + + left->x4 = x1 = left->x3 + t * (x2 - left->x3); + left->y4 = y1 = left->y3 + t * (y2 - left->y3); +} + +QT_END_NAMESPACE + +#endif // QBEZIER_P_H diff --git a/3rd-party/qbezier/src/private/qdatabuffer_p.h b/3rd-party/qbezier/src/private/qdatabuffer_p.h new file mode 100644 index 0000000..45132fb --- /dev/null +++ b/3rd-party/qbezier/src/private/qdatabuffer_p.h @@ -0,0 +1,147 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QDATABUFFER_P_H +#define QDATABUFFER_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists for the convenience +// of other Qt classes. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include "QtCore/qbytearray.h" + +#include + +QT_BEGIN_NAMESPACE + +template class QDataBuffer +{ +public: + QDataBuffer(int res) + { + capacity = res; + if (res) + buffer = (Type*) malloc(capacity * sizeof(Type)); + else + buffer = 0; + siz = 0; + } + + ~QDataBuffer() + { + if (buffer) + free(buffer); + } + + inline void reset() { siz = 0; } + + inline bool isEmpty() const { return siz==0; } + + inline int size() const { return siz; } + inline Type *data() const { return buffer; } + + inline Type &at(int i) { Q_ASSERT(i >= 0 && i < siz); return buffer[i]; } + inline const Type &at(int i) const { Q_ASSERT(i >= 0 && i < siz); return buffer[i]; } + inline Type &last() { Q_ASSERT(!isEmpty()); return buffer[siz-1]; } + inline const Type &last() const { Q_ASSERT(!isEmpty()); return buffer[siz-1]; } + inline Type &first() { Q_ASSERT(!isEmpty()); return buffer[0]; } + inline const Type &first() const { Q_ASSERT(!isEmpty()); return buffer[0]; } + + inline void add(const Type &t) { + reserve(siz + 1); + buffer[siz] = t; + ++siz; + } + + inline void pop_back() { + Q_ASSERT(siz > 0); + --siz; + } + + inline void resize(int size) { + reserve(size); + siz = size; + } + + inline void reserve(int size) { + if (size > capacity) { + if (capacity == 0) + capacity = 1; + while (capacity < size) + capacity *= 2; + buffer = (Type*) realloc(buffer, capacity * sizeof(Type)); + } + } + + inline void shrink(int size) { + capacity = size; + if (size) + buffer = (Type*) realloc(buffer, capacity * sizeof(Type)); + else { + free(buffer); + buffer = 0; + } + } + + inline void swap(QDataBuffer &other) { + qSwap(capacity, other.capacity); + qSwap(siz, other.siz); + qSwap(buffer, other.buffer); + } + + inline QDataBuffer &operator<<(const Type &t) { add(t); return *this; } + +private: + int capacity; + int siz; + Type *buffer; +}; + +QT_END_NAMESPACE + +#endif // QDATABUFFER_P_H diff --git a/3rd-party/qbezier/src/private/qmath_p.h b/3rd-party/qbezier/src/private/qmath_p.h new file mode 100644 index 0000000..90920f4 --- /dev/null +++ b/3rd-party/qbezier/src/private/qmath_p.h @@ -0,0 +1,73 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QMATH_P_H +#define QMATH_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include +#include + +QT_BEGIN_NAMESPACE + +static const qreal Q_PI = qreal(3.14159265358979323846); // pi +static const qreal Q_2PI = qreal(6.28318530717958647693); // 2*pi +static const qreal Q_PI2 = qreal(1.57079632679489661923); // pi/2 +static const qreal Q_MM_PER_INCH = 25.4; + +inline int qIntSqrtInt(int v) +{ + return static_cast(qSqrt(static_cast(v))); +} + +QT_END_NAMESPACE + +#endif // QMATH_P_H diff --git a/3rd-party/qbezier/src/private/qnumeric_p.h b/3rd-party/qbezier/src/private/qnumeric_p.h new file mode 100644 index 0000000..dba5d4d --- /dev/null +++ b/3rd-party/qbezier/src/private/qnumeric_p.h @@ -0,0 +1,201 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QNUMERIC_P_H +#define QNUMERIC_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include "QtCore/qglobal.h" + +QT_BEGIN_NAMESPACE + +#if !defined(Q_CC_MIPS) + +static const union { unsigned char c[8]; double d; } qt_be_inf_bytes = { { 0x7f, 0xf0, 0, 0, 0, 0, 0, 0 } }; +static const union { unsigned char c[8]; double d; } qt_le_inf_bytes = { { 0, 0, 0, 0, 0, 0, 0xf0, 0x7f } }; +static inline double qt_inf() +{ + return (QSysInfo::ByteOrder == QSysInfo::BigEndian + ? qt_be_inf_bytes.d + : qt_le_inf_bytes.d); +} + +// Signaling NAN +static const union { unsigned char c[8]; double d; } qt_be_snan_bytes = { { 0x7f, 0xf8, 0, 0, 0, 0, 0, 0 } }; +static const union { unsigned char c[8]; double d; } qt_le_snan_bytes = { { 0, 0, 0, 0, 0, 0, 0xf8, 0x7f } }; +static inline double qt_snan() +{ + return (QSysInfo::ByteOrder == QSysInfo::BigEndian + ? qt_be_snan_bytes.d + : qt_le_snan_bytes.d); +} + +// Quiet NAN +static const union { unsigned char c[8]; double d; } qt_be_qnan_bytes = { { 0xff, 0xf8, 0, 0, 0, 0, 0, 0 } }; +static const union { unsigned char c[8]; double d; } qt_le_qnan_bytes = { { 0, 0, 0, 0, 0, 0, 0xf8, 0xff } }; +static inline double qt_qnan() +{ + return (QSysInfo::ByteOrder == QSysInfo::BigEndian + ? qt_be_qnan_bytes.d + : qt_le_qnan_bytes.d); +} + +#else // Q_CC_MIPS + +static const unsigned char qt_be_inf_bytes[] = { 0x7f, 0xf0, 0, 0, 0, 0, 0, 0 }; +static const unsigned char qt_le_inf_bytes[] = { 0, 0, 0, 0, 0, 0, 0xf0, 0x7f }; +static inline double qt_inf() +{ + const unsigned char *bytes; + bytes = (QSysInfo::ByteOrder == QSysInfo::BigEndian + ? qt_be_inf_bytes + : qt_le_inf_bytes); + + union { unsigned char c[8]; double d; } returnValue; + memcpy(returnValue.c, bytes, sizeof(returnValue.c)); + return returnValue.d; +} + +// Signaling NAN +static const unsigned char qt_be_snan_bytes[] = { 0x7f, 0xf8, 0, 0, 0, 0, 0, 0 }; +static const unsigned char qt_le_snan_bytes[] = { 0, 0, 0, 0, 0, 0, 0xf8, 0x7f }; +static inline double qt_snan() +{ + const unsigned char *bytes; + bytes = (QSysInfo::ByteOrder == QSysInfo::BigEndian + ? qt_be_snan_bytes + : qt_le_snan_bytes); + + union { unsigned char c[8]; double d; } returnValue; + memcpy(returnValue.c, bytes, sizeof(returnValue.c)); + return returnValue.d; +} + +// Quiet NAN +static const unsigned char qt_be_qnan_bytes[] = { 0xff, 0xf8, 0, 0, 0, 0, 0, 0 }; +static const unsigned char qt_le_qnan_bytes[] = { 0, 0, 0, 0, 0, 0, 0xf8, 0xff }; +static inline double qt_qnan() +{ + const unsigned char *bytes; + bytes = (QSysInfo::ByteOrder == QSysInfo::BigEndian + ? qt_be_qnan_bytes + : qt_le_qnan_bytes); + + union { unsigned char c[8]; double d; } returnValue; + memcpy(returnValue.c, bytes, sizeof(returnValue.c)); + return returnValue.d; +} + +#endif // Q_CC_MIPS + +static inline bool qt_is_inf(double d) +{ + uchar *ch = (uchar *)&d; + if (QSysInfo::ByteOrder == QSysInfo::BigEndian) { + return (ch[0] & 0x7f) == 0x7f && ch[1] == 0xf0; + } else { + return (ch[7] & 0x7f) == 0x7f && ch[6] == 0xf0; + } +} + +static inline bool qt_is_nan(double d) +{ + uchar *ch = (uchar *)&d; + if (QSysInfo::ByteOrder == QSysInfo::BigEndian) { + return (ch[0] & 0x7f) == 0x7f && ch[1] > 0xf0; + } else { + return (ch[7] & 0x7f) == 0x7f && ch[6] > 0xf0; + } +} + +static inline bool qt_is_finite(double d) +{ + uchar *ch = (uchar *)&d; + if (QSysInfo::ByteOrder == QSysInfo::BigEndian) { + return (ch[0] & 0x7f) != 0x7f || (ch[1] & 0xf0) != 0xf0; + } else { + return (ch[7] & 0x7f) != 0x7f || (ch[6] & 0xf0) != 0xf0; + } +} + +static inline bool qt_is_inf(float d) +{ + uchar *ch = (uchar *)&d; + if (QSysInfo::ByteOrder == QSysInfo::BigEndian) { + return (ch[0] & 0x7f) == 0x7f && ch[1] == 0x80; + } else { + return (ch[3] & 0x7f) == 0x7f && ch[2] == 0x80; + } +} + +static inline bool qt_is_nan(float d) +{ + uchar *ch = (uchar *)&d; + if (QSysInfo::ByteOrder == QSysInfo::BigEndian) { + return (ch[0] & 0x7f) == 0x7f && ch[1] > 0x80; + } else { + return (ch[3] & 0x7f) == 0x7f && ch[2] > 0x80; + } +} + +static inline bool qt_is_finite(float d) +{ + uchar *ch = (uchar *)&d; + if (QSysInfo::ByteOrder == QSysInfo::BigEndian) { + return (ch[0] & 0x7f) != 0x7f || (ch[1] & 0x80) != 0x80; + } else { + return (ch[3] & 0x7f) != 0x7f || (ch[2] & 0x80) != 0x80; + } +} + +QT_END_NAMESPACE + +#endif // QNUMERIC_P_H diff --git a/3rd-party/qt5/CMakeLists.txt b/3rd-party/qt5/CMakeLists.txt new file mode 100644 index 0000000..4ce1f5c --- /dev/null +++ b/3rd-party/qt5/CMakeLists.txt @@ -0,0 +1,354 @@ +# +# Copyright 2012, 2013, 2014 Kai Pastor +# +# This file is part of OpenOrienteering. +# +# OpenOrienteering is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# OpenOrienteering is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with OpenOrienteering. If not, see . + + +project(Qt5) + +cmake_minimum_required(VERSION 2.8.3) + +include(ExternalProject) + +# Configuration options + +set(QT5_VERSION_DEFAULT 5.5.1-openorienteering-2015-11-20) +set(QT5_VERSION ${QT5_VERSION_DEFAULT} CACHE STRING + "Version number of the Qt5 library, recommended value: ${QT5_VERSION_DEFAULT}") +mark_as_advanced(QT5_VERSION) + +string(REGEX MATCH "5.." QT5_MAJOR_MINOR ${QT5_VERSION}) +string(REGEX MATCH "5...." QT5_MAJOR_MINOR_REVISION ${QT5_VERSION}) +set(QT5_MAJOR_MINOR_REVISION ${QT5_MAJOR_MINOR_REVISION} CACHE STRING + "The Qt version number without additional release markers" FORCE) # Export +if (NOT "${QT5_VERSION}" MATCHES "^${QT5_MAJOR_MINOR_REVISION}") + message(WARNING + "The Qt5 library version is different from the current recommended version " + "(${QT5_VERSION} vs. ${QT5_VERSION_DEFAULT}).") +endif() + + +if(NOT MAPPER_LIBRARY_DESTINATION AND CMAKE_BUILD_TYPE MATCHES "Debug") + # stand-alone debug build of Qt5 + set(QT5_DEBUG_DEFAULT On) +else() + set(QT5_DEBUG_DEFAULT Off) +endif() +set(QT5_DEBUG ${QT5_DEBUG_DEFAULT} CACHE BOOL + "Enable debug build of Qt" +) +mark_as_advanced(QT5_DEBUG) + +message(STATUS "Configuring Qt ${QT5_VERSION}") + +set(QT5_MD5SUMS + # Schema: VERSION:MD5[:DOWNLOAD_URL] + 5.4.2:fa1c4d819b401b267eb246a543a63ea5 + 5.5.1:59f0216819152b77536cf660b015d784 + 5.5.1-openorienteering-2015-11-20:3799677d2835ad57e8fe4493c2e5c2de +) +foreach(line ${QT5_MD5SUMS}) + if(${line} MATCHES "^${QT5_VERSION}:") + string(REPLACE "${QT5_VERSION}:" "" QT5_MD5 ${line}) + break() + endif() +endforeach() +if(NOT QT5_MD5) + message(WARNING + "Unknown MD5 sum for Qt5 library ${QT5_VERSION}. " + "Edit ${PROJECT_SOURCE_DIR}/CMakeLists.txt, " + "or specify the correct QT5_MD5 value at the command line.") +endif() + +if(QT5_MD5 MATCHES ":") + message(WARNING "Not using an official release of Qt.") + string(REGEX REPLACE "^[0-9a-fA-F]*:" "" QT5_URL "${QT5_MD5}") + string(REGEX REPLACE ":.*" "" QT5_MD5 "${QT5_MD5}") +elseif(QT5_VERSION MATCHES "-openorienteering-") + set(QT5_URL "https://github.com/OpenOrienteering/sources/releases/download/3rd-party/qt-everywhere-opensource-src-${QT5_VERSION}.tar.gz") +else() + set(QT5_URL "http://download.qt-project.org/archive/qt/${QT5_MAJOR_MINOR}/${QT5_VERSION}/single/qt-everywhere-opensource-src-${QT5_VERSION}.tar.gz") +endif() + +find_program(SH_PROGRAM sh + PATHS + "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\MSYS-1.0_is1;Inno Setup: App Path]/bin" + "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\MinGW;InstallLocation]/bin" + C: + C:/MinGW + PATH_SUFFIXES msys/1.0/bin) +mark_as_advanced(SH_PROGRAM) + +if("${CMAKE_GENERATOR}" MATCHES "Makefiles" OR + "${CMAKE_EXTRA_GENERATOR}" MATCHES "Makefiles") + # use magic MAKE macro + set(QT5_MAKE_COMMAND "\$(MAKE)") +else() + # require make + set(QT5_MAKE_COMMAND "${SH_PROGRAM}" -l -e "${CMAKE_CURRENT_BINARY_DIR}/qt5-make") +endif() + +if(MINGW AND NOT CMAKE_CROSSCOMPILING) + set(QT5_CONFIG_SCRIPT qt5-config.cmd) + set(QT5_CONFIG_COMMAND "$ENV{ComSpec}" /C ${CMAKE_CURRENT_BINARY_DIR}/${QT5_CONFIG_SCRIPT}) + set(QT5_SOURCE_CONFIG + SOURCE_DIR "${CMAKE_CURRENT_BINARY_DIR}/src" + BUILD_IN_SOURCE 1 + ) +else() + set(QT5_CONFIG_SCRIPT qt5-config) + set(QT5_CONFIG_COMMAND "${SH_PROGRAM}" -l -e ${CMAKE_CURRENT_BINARY_DIR}/${QT5_CONFIG_SCRIPT}) + set(QT5_SOURCE_CONFIG ) + if(MINGW AND CMAKE_CROSSCOMPILING AND NOT QT5_PLATFORM) + string(REGEX REPLACE gcc\$ "" QT5_CROSS_COMPILE ${CMAKE_C_COMPILER}) + set(QT5_PLATFORM "-xplatform win32-g++ -device-option CROSS_COMPILE='${QT5_CROSS_COMPILE}'") + endif() +endif() + +# Build definition + +# Don't touch the configured qt5-patchqt unless the content really changes. +add_custom_command(OUTPUT qt5-patchqt + COMMAND ${CMAKE_COMMAND} -E copy_if_different qt5-patchqt.new qt5-patchqt + DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/qt5-patchqt.new +) + +# Don't touch the configured qt5-config unless the content really changes. +add_custom_command(OUTPUT ${QT5_CONFIG_SCRIPT} + COMMAND ${CMAKE_COMMAND} -E copy_if_different ${QT5_CONFIG_SCRIPT}.new ${QT5_CONFIG_SCRIPT} + DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${QT5_CONFIG_SCRIPT}.new +) + +if(UNIX AND NOT APPLE AND MAPPER_LIBRARY_DESTINATION) + set(QT5_INSTALL_ROOT "INSTALL_ROOT=") +endif() +ExternalProject_Add(Qt5 + DOWNLOAD_DIR ${PROJECT_SOURCE_DIR}/download + URL ${QT5_URL} + URL_MD5 ${QT5_MD5} + PATCH_COMMAND "${SH_PROGRAM}" -l -e ${CMAKE_CURRENT_BINARY_DIR}/qt5-patchqt + CONFIGURE_COMMAND ${QT5_CONFIG_COMMAND} + BUILD_COMMAND ${QT5_MAKE_COMMAND} + INSTALL_COMMAND ${QT5_MAKE_COMMAND} install ${QT5_INSTALL_ROOT} + ${QT5_SOURCE_CONFIG} +) +ExternalProject_Get_Property(Qt5 SOURCE_DIR) +ExternalProject_Get_Property(Qt5 BINARY_DIR) +ExternalProject_Get_Property(Qt5 INSTALL_DIR) +set_target_properties(Qt5 PROPERTIES INSTALL_DIR "${INSTALL_DIR}") + +# Trigger patch step when qt5-patchqt has changed. +ExternalProject_Add_Step(Qt5 patch-dependencies + COMMAND ${CMAKE_COMMAND} -E echo_append "" # Do nothing + DEPENDEES download update + DEPENDERS patch + DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/qt5-patchqt +) + +# Trigger confclean and configure steps when qt5-config has changed. +if(NOT "${SOURCE_DIR}" STREQUAL "${BINARY_DIR}") +ExternalProject_Add_Step(Qt5 confclean + COMMAND ${CMAKE_COMMAND} -E remove_directory "${BINARY_DIR}" + COMMAND ${CMAKE_COMMAND} -E make_directory "${BINARY_DIR}" + DEPENDEES patch + DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${QT5_CONFIG_SCRIPT} + WORKING_DIRECTORY "${SOURCE_DIR}" +) +ExternalProject_Add_Step(Qt5 configure-dependencies + COMMAND ${CMAKE_COMMAND} -E echo_append "" # Do nothing + DEPENDEES confclean + DEPENDERS configure + WORKING_DIRECTORY "${BINARY_DIR}" +) +else() +# In-source-build: re-trigger extract; download will be avoided by MD5 sum. +ExternalProject_Add_Step(Qt5 confclean + COMMAND ${CMAKE_COMMAND} -E echo_append "" # Do nothing + DEPENDERS download + DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${QT5_CONFIG_SCRIPT} + WORKING_DIRECTORY "${SOURCE_DIR}" +) +endif() + +# Build script configuration + +# Debug or release build +if (QT5_DEBUG) + set(QT5_CONFIG_EXTRA_OPTS "-debug -qml-debug ${QT5_CONFIG_EXTRA_OPTS}") +else() + set(QT5_CONFIG_EXTRA_OPTS "-release -no-qml-debug ${QT5_CONFIG_EXTRA_OPTS}") +endif() + +# Paths +if(NOT MAPPER_LIBRARY_DESTINATION) + # stand-alone build of Qt5 + set(QT5_BINARY_DESTINATION "") + set(QT5_PLUGINS_DESTINATION "/plugins") +elseif(MAPPER_LIBRARY_DESTINATION MATCHES "^/") + # absolute path + set(QT5_BINARY_DESTINATION "${MAPPER_LIBRARY_DESTINATION}") + set(QT5_PLUGINS_DESTINATION "${MAPPER_LIBRARY_DESTINATION}/plugins") +elseif(MAPPER_LIBRARY_DESTINATION STREQUAL ".") + # . + set(QT5_BINARY_DESTINATION "/binary") + set(QT5_PLUGINS_DESTINATION "/binary/plugins") +else() + # relative path other than . + set(QT5_BINARY_DESTINATION "/binary/${MAPPER_LIBRARY_DESTINATION}") + set(QT5_PLUGINS_DESTINATION "/binary/${MAPPER_LIBRARY_DESTINATION}/plugins") +endif() +if(NOT MAPPER_DATA_DESTINATION) + # stand-alone build of Qt5 + set(QT5_DATA_DESTINATION "") +elseif(MAPPER_DATA_DESTINATION MATCHES "^/") + # absolute path + set(QT5_DATA_DESTINATION "${MAPPER_DATA_DESTINATION}") +elseif(MAPPER_DATA_DESTINATION STREQUAL .) + # . + set(QT5_DATA_DESTINATION "/data") +else() + # relative path other than . + set(QT5_DATA_DESTINATION "/data/${MAPPER_DATA_DESTINATION}") +endif() + +# Cached only for export, not for reuse +set(QT5_DIR "${INSTALL_DIR}${QT5_BINARY_DESTINATION}" CACHE INTERNAL + "The Qt5 target platform directory." FORCE) +set(QT_TRANSLATIONS_DIR "${INSTALL_DIR}${QT5_DATA_DESTINATION}/translations" CACHE INTERNAL + "The Qt5 translation directory." FORCE) + +if(NOT QT5_INSTALL_ROOT) + set(QT5_BINARY_DESTINATION "${INSTALL_DIR}${QT5_BINARY_DESTINATION}") + set(QT5_PLUGINS_DESTINATION "${INSTALL_DIR}${QT5_PLUGINS_DESTINATION}") + set(QT5_DATA_DESTINATION "${INSTALL_DIR}${QT5_DATA_DESTINATION}") +endif() + +# Extra configuration options +if(QT5_INSTALL_ROOT AND NOT "${QT5_PLATFORM}" MATCHES "android") + set(QT5_CONFIG_EXTRA_OPTS "-R '${QT5_BINARY_DESTINATION}/lib' ${QT5_CONFIG_EXTRA_OPTS}") + if(Mapper_DEVELOPMENT_BUILD) + set(QT5_CONFIG_EXTRA_OPTS "-R '${INSTALL_DIR}${QT5_BINARY_DESTINATION}/lib' ${QT5_CONFIG_EXTRA_OPTS}") + endif() +endif() +# Cf. http://code.qt.io/cgit/qtsdk/qtsdk.git/tree/packaging-tools/releases/release-55?h=v5.5.1-packaging +if(APPLE) + set(QT5_CONFIG_EXTRA_OPTS "${QT5_CONFIG_EXTRA_OPTS} -no-framework -no-securetransport") +endif() +if(UNIX AND NOT APPLE AND NOT "${QT5_PLATFORM}" MATCHES "android") + set(QT5_CONFIG_ENVIRONMENT "LDFLAGS=-Wl,--enable-new-dtags") + set(QT5_CONFIG_EXTRA_OPTS "${QT5_CONFIG_EXTRA_OPTS} -qt-xcb") +endif() +if("${QT5_PLATFORM}" MATCHES "android") + set(QT5_CONFIG_EXTRA_OPTS + "${QT5_CONFIG_EXTRA_OPTS} -opengl es2 -sysconfdir /etc/xdg -no-icu -no-sql-sqlite -no-warnings-are-errors") +endif() +if(MINGW) + set(QT5_CONFIG_EXTRA_OPTS + "${QT5_CONFIG_EXTRA_OPTS} -qt-zlib -qt-libpng -qt-libjpeg -qt-sql-sqlite -qt-pcre") +endif() + +configure_file(qt5-patchqt.in qt5-patchqt.new @ONLY) +configure_file(${QT5_CONFIG_SCRIPT}.in ${QT5_CONFIG_SCRIPT}.new @ONLY) +configure_file(qt5-make.in qt5-make @ONLY) +configure_file(qt.conf.in qt.conf @ONLY) +configure_file(qt.conf.qrc.in qt.conf.qrc @ONLY) + +if(UNIX AND QT5_INSTALL_ROOT AND NOT "${QT5_PLATFORM}" MATCHES "android") + file(WRITE "${INSTALL_DIR}${QT5_BINARY_DESTINATION}/bin/qt.conf" + "[Paths]\n" + "Plugins=${INSTALL_DIR}${QT5_PLUGINS_DESTINATION}\n" + ) + set_target_properties(Qt5 PROPERTIES + PLUGINS_DIR "${INSTALL_DIR}${QT5_PLUGINS_DESTINATION}" + ) +endif() +function(WRITE_QT_CONF) + get_target_property(qt5_plugins_dir Qt5 PLUGINS_DIR) + if(NOT "${qt5_plugins_dir}" MATCHES NOTFOUND) + file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/qt.conf" + "[Paths]\n" + "Plugins=${qt5_plugins_dir}\n" + ) + endif() +endfunction() + +# Cross-compiling requires an extra host build in order to get +# qcollectiongenerator, qdoc and lrelease. +# In addition, Linux may have trouble with loading the correct platform plugin +# version when building a newer Qt version than installed. + +if((UNIX AND NOT APPLE) OR (CMAKE_CROSSCOMPILING AND NOT "${QT5_PLATFORM}" MATCHES "android")) + set(QT5_EXTRA_HOST_DIR "${BINARY_DIR}-host") + + configure_file(qt5-config-host.in qt5-config-host.new @ONLY) + + add_custom_command(OUTPUT qt5-config-host + COMMAND ${CMAKE_COMMAND} -E copy_if_different qt5-config-host.new qt5-config-host + DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/qt5-config-host.new + ) + ExternalProject_Add_Step(Qt5 confclean-host + COMMAND ${CMAKE_COMMAND} -E make_directory "${QT5_EXTRA_HOST_DIR}" + COMMAND ${CMAKE_COMMAND} -E remove_directory "${QT5_EXTRA_HOST_DIR}" + COMMAND ${CMAKE_COMMAND} -E make_directory "${QT5_EXTRA_HOST_DIR}" + DEPENDEES patch + DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/qt5-config-host + ) + ExternalProject_Add_Step(Qt5 configure-host + COMMAND "${SH_PROGRAM}" -l -e ${CMAKE_CURRENT_BINARY_DIR}/qt5-config-host + DEPENDEES confclean-host + WORKING_DIRECTORY "${QT5_EXTRA_HOST_DIR}" + ) + ExternalProject_Add_Step(Qt5 build-host + COMMAND ${QT5_MAKE_COMMAND} -C "${QT5_EXTRA_HOST_DIR}" module-qtbase + COMMAND ${QT5_MAKE_COMMAND} -C "${QT5_EXTRA_HOST_DIR}" module-qtdeclarative + COMMAND ${QT5_MAKE_COMMAND} -C "${QT5_EXTRA_HOST_DIR}" module-qttools-qmake_all + COMMAND ${QT5_MAKE_COMMAND} -C "${QT5_EXTRA_HOST_DIR}/qttools/src/assistant" sub-qcollectiongenerator + COMMAND ${QT5_MAKE_COMMAND} -C "${QT5_EXTRA_HOST_DIR}/qttools/src/linguist" sub-lrelease + DEPENDEES configure-host + ) + + if(NOT TARGET Qt5::qcollectiongenerator) + add_executable(Qt5::qcollectiongenerator IMPORTED GLOBAL) + set(imported_location ${QT5_EXTRA_HOST_DIR}/qttools/bin/qcollectiongenerator) + set_target_properties(Qt5::qcollectiongenerator PROPERTIES + IMPORTED_LOCATION ${imported_location} + ) + add_dependencies(Qt5::qcollectiongenerator Qt5) + endif() + if(NOT TARGET Qt5::qdoc) + add_executable(Qt5::qdoc IMPORTED GLOBAL) + set(imported_location ${QT5_EXTRA_HOST_DIR}/qtbase/bin/qdoc) + set_target_properties(Qt5::qdoc PROPERTIES + IMPORTED_LOCATION ${imported_location} + ) + add_dependencies(Qt5::qdoc Qt5) + endif() + if(NOT TARGET Qt5::lrelease) + add_executable(Qt5::lrelease IMPORTED GLOBAL) + set(imported_location ${QT5_EXTRA_HOST_DIR}/qttools/bin/lrelease) + set_target_properties(Qt5::lrelease PROPERTIES + IMPORTED_LOCATION ${imported_location} + ) + add_dependencies(Qt5::lrelease Qt5) + endif() +elseif(CMAKE_CROSSCOMPILING AND "${QT5_PLATFORM}" MATCHES "android") + execute_process( + COMMAND sed -i -e "/-plugindir /d;/-datadir /d" ${QT5_CONFIG_SCRIPT}.new + WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}" ) +endif() + +# Don't let Xcode re-root the install +set_target_properties(Qt5 PROPERTIES XCODE_ATTRIBUTE_INSTALL_ROOT "") diff --git a/3rd-party/qt5/download/README.txt b/3rd-party/qt5/download/README.txt new file mode 100644 index 0000000..25d5898 --- /dev/null +++ b/3rd-party/qt5/download/README.txt @@ -0,0 +1 @@ +This directory contains downloaded Qt5 source archives. diff --git a/3rd-party/qt5/patches/5.4.0/qtbase-qandroidstyle.patch b/3rd-party/qt5/patches/5.4.0/qtbase-qandroidstyle.patch new file mode 100644 index 0000000..6cf3a67 --- /dev/null +++ b/3rd-party/qt5/patches/5.4.0/qtbase-qandroidstyle.patch @@ -0,0 +1,27 @@ +diff -urw a/src/widgets/styles/qfusionstyle.cpp b/src/widgets/styles/qfusionstyle.cpp +--- a/src/widgets/styles/qfusionstyle.cpp 2014-12-05 22:17:05.988465490 +0100 ++++ b/src/widgets/styles/qfusionstyle.cpp 2014-12-09 03:02:17.117028249 +0100 +@@ -1746,9 +1746,9 @@ + painter->drawPixmap(visualPos(button->direction, button->rect, point), pixmap); + + if (button->direction == Qt::RightToLeft) +- ir.translate(-point.x() - 2, 0); ++ ir.setLeft(point.x() - pixmap.width()); + else +- ir.translate(point.x() + pixmap.width(), 0); ++ ir.setLeft(point.x() + pixmap.width() + 2); + + // left-align text if there is + if (!button->text.isEmpty()) +diff -urw a/src/widgets/styles/qstyle.cpp b/src/widgets/styles/qstyle.cpp +--- a/src/widgets/styles/qstyle.cpp 2014-12-05 22:17:05.992465431 +0100 ++++ b/src/widgets/styles/qstyle.cpp 2014-12-09 03:01:29.213766493 +0100 +@@ -2102,7 +2102,7 @@ + { + if (direction == Qt::LeftToRight) + return logicalPos; +- return QPoint(boundingRect.right() - logicalPos.x(), logicalPos.y()); ++ return QPoint(boundingRect.right() - logicalPos.x() + boundingRect.left(), logicalPos.y()); + } + + /*! diff --git a/3rd-party/qt5/patches/5.4.0/qtbase-qtbug-39874-qnetworkproxy_win.patch b/3rd-party/qt5/patches/5.4.0/qtbase-qtbug-39874-qnetworkproxy_win.patch new file mode 100644 index 0000000..aec79f8 --- /dev/null +++ b/3rd-party/qt5/patches/5.4.0/qtbase-qtbug-39874-qnetworkproxy_win.patch @@ -0,0 +1,45 @@ +2014-12-21 Kai Pastor +- Remove tests from patch + +From 938541e670249a4dfdcc8a3d787746b0af7114ec Mon Sep 17 00:00:00 2001 +From: Antonio Lotti +Date: Wed, 17 Dec 2014 15:55:09 +0100 +Subject: [PATCH] Windows : fix call to LookupAccountNameW + +The call to LookupAccountNameW from advapi32 was rewritten following +the example: +http://msdn.microsoft.com/en-us/library/aa392742%28v=vs.85%29.aspx +This prevents the generation of a garbage pointer when accessing +QWindowsSystemProxy::init() for Qt compiled as 64bit library +with MinGW-w64. + +Task-number: QTBUG-39874 +Task-number: QTBUG-38145 +Change-Id: I620b2fa64941f84838f9a386851480285336e8d1 + +diff --git a/src/network/kernel/qnetworkproxy_win.cpp b/src/network/kernel/qnetworkproxy_win.cpp +index da2c020..f2176d6 100644 +--- a/src/network/kernel/qnetworkproxy_win.cpp ++++ b/src/network/kernel/qnetworkproxy_win.cpp +@@ -130,10 +130,17 @@ static bool currentProcessIsService() + DWORD size = UNLEN; + if (ptrGetUserName(userName, &size)) { + SID_NAME_USE type = SidTypeUser; +- DWORD dummy = MAX_PATH; +- wchar_t dummyStr[MAX_PATH] = L""; +- PSID psid = 0; +- if (ptrLookupAccountName(NULL, userName, &psid, &dummy, dummyStr, &dummy, &type)) ++ DWORD sidSize = 0; ++ DWORD domainSize = 0; ++ // first call is to get the correct size ++ bool bRet = ptrLookupAccountName(NULL, userName, NULL, &sidSize, NULL, &domainSize, &type); ++ if (bRet == FALSE && ERROR_INSUFFICIENT_BUFFER != GetLastError()) ++ return false; ++ QVarLengthArray buff(sidSize); ++ QVarLengthArray domainName(domainSize); ++ // second call to LookupAccountNameW actually gets the SID ++ // both the pointer to the buffer and the pointer to the domain name should not be NULL ++ if (ptrLookupAccountName(NULL, userName, buff.data(), &sidSize, domainName.data(), &domainSize, &type)) + return type != SidTypeUser; //returns true if the current user is not a user + } + } diff --git a/3rd-party/qt5/patches/5.4.0/qtbase-qtbug-43124-qprintengine_win.patch b/3rd-party/qt5/patches/5.4.0/qtbase-qtbug-43124-qprintengine_win.patch new file mode 100644 index 0000000..d5a4809 --- /dev/null +++ b/3rd-party/qt5/patches/5.4.0/qtbase-qtbug-43124-qprintengine_win.patch @@ -0,0 +1,15 @@ +2014-12-07 Kai Pastor +- Fix QTBUG-43124: QPrinter::{width,height} return incorrect size + +diff -up a/src/printsupport/kernel/qprintengine_win.cpp.orig b/src/printsupport/kernel/qprintengine_win.cpp +--- a/src/printsupport/kernel/qprintengine_win.cpp.orig 2014-12-07 10:16:20.284863210 +0100 ++++ b/src/printsupport/kernel/qprintengine_win.cpp 2014-12-07 10:16:10.901005787 +0100 +@@ -931,6 +931,8 @@ void QWin32PrintEnginePrivate::initHDC() + default: + break; + } ++ ++ updateMetrics(); + } + + void QWin32PrintEnginePrivate::release() diff --git a/3rd-party/qt5/patches/5.4.2/qtbase-qandroidstyle.patch b/3rd-party/qt5/patches/5.4.2/qtbase-qandroidstyle.patch new file mode 100644 index 0000000..99d0d38 --- /dev/null +++ b/3rd-party/qt5/patches/5.4.2/qtbase-qandroidstyle.patch @@ -0,0 +1,27 @@ +diff -urw a/src/widgets/styles/qfusionstyle.cpp b/src/widgets/styles/qfusionstyle.cpp +--- a/src/widgets/styles/qfusionstyle.cpp 2014-12-05 22:17:05.988465490 +0100 ++++ b/src/widgets/styles/qfusionstyle.cpp 2014-12-09 03:02:17.117028249 +0100 +@@ -1746,9 +1746,9 @@ + painter->drawPixmap(visualPos(button->direction, button->rect, point), pixmap); + + if (button->direction == Qt::RightToLeft) +- ir.translate(-point.x() - 2, 0); ++ ir.setLeft(point.x() - w); + else +- ir.translate(point.x() + w, 0); ++ ir.setLeft(point.x() + w + 2); + + // left-align text if there is + if (!button->text.isEmpty()) +diff -urw a/src/widgets/styles/qstyle.cpp b/src/widgets/styles/qstyle.cpp +--- a/src/widgets/styles/qstyle.cpp 2014-12-05 22:17:05.992465431 +0100 ++++ b/src/widgets/styles/qstyle.cpp 2014-12-09 03:01:29.213766493 +0100 +@@ -2102,7 +2102,7 @@ + { + if (direction == Qt::LeftToRight) + return logicalPos; +- return QPoint(boundingRect.right() - logicalPos.x(), logicalPos.y()); ++ return QPoint(boundingRect.right() - logicalPos.x() + boundingRect.left(), logicalPos.y()); + } + + /*! diff --git a/3rd-party/qt5/patches/5.4.2/qttools-qtbug-45095-qdbus.patch b/3rd-party/qt5/patches/5.4.2/qttools-qtbug-45095-qdbus.patch new file mode 100644 index 0000000..c1c0343 --- /dev/null +++ b/3rd-party/qt5/patches/5.4.2/qttools-qtbug-45095-qdbus.patch @@ -0,0 +1,12 @@ +diff -urw a/src/src.pro b/src/src.pro +--- a/src/src.pro 2015-05-29 22:31:26.000000000 +0200 ++++ b/src/src.pro 2015-09-01 09:11:50.105424909 +0200 +@@ -25,7 +25,7 @@ + SUBDIRS += androiddeployqt + } + +-qtHaveModule(dbus): SUBDIRS += qdbus ++qtHaveModule(dbus):!android: SUBDIRS += qdbus + + win32|winrt:SUBDIRS += windeployqt + winrt:SUBDIRS += winrtrunner diff --git a/3rd-party/qt5/patches/5.4/qtbase-android-motionEvent.patch b/3rd-party/qt5/patches/5.4/qtbase-android-motionEvent.patch new file mode 100644 index 0000000..7e8c300 --- /dev/null +++ b/3rd-party/qt5/patches/5.4/qtbase-android-motionEvent.patch @@ -0,0 +1,33 @@ +Thomas Schoeps (OpenOrienteering) +- Correctly deal with the history provided by the event. +- Cf. QTBUG-38379 + +diff -up qt-everywhere-opensource-src-5.2.0/src/android/jar/src/org/qtproject/qt5/android/QtNative.java.orig qt-everywhere-opensource-src-5.2.0/src/android/jar/src/org/qtproject/qt5/android/QtNative.java +--- qt-everywhere-opensource-src-5.2.0/src/android/jar/src/org/qtproject/qt5/android/QtNative.java.orig 2014-01-25 14:20:16.140595706 +0100 ++++ qt-everywhere-opensource-src-5.2.0/src/android/jar/src/org/qtproject/qt5/android/QtNative.java 2014-01-25 14:22:47.274428101 +0100 +@@ -298,15 +298,15 @@ public class QtNative + { + int action = event.getActionMasked(); + if (action == MotionEvent.ACTION_MOVE) { +- int hsz = event.getHistorySize(); +- if (hsz > 0) { +- if (event.getX(index) != event.getHistoricalX(index, hsz-1) +- || event.getY(index) != event.getHistoricalY(index, hsz-1)) { +- return 1; +- } else { +- return 2; +- } +- } ++ //int hsz = event.getHistorySize(); ++ //if (hsz > 0) { ++ // if (event.getX(index) != event.getHistoricalX(index, hsz-1) ++ // || event.getY(index) != event.getHistoricalY(index, hsz-1)) { ++ // return 1; ++ // } else { ++ // return 2; ++ // } ++ //} + return 1; + } + if (action == MotionEvent.ACTION_DOWN || action == MotionEvent.ACTION_POINTER_DOWN && index == event.getActionIndex()) { + diff --git a/3rd-party/qt5/patches/5.4/qtbase-configure-android.patch b/3rd-party/qt5/patches/5.4/qtbase-configure-android.patch new file mode 100644 index 0000000..a90596e --- /dev/null +++ b/3rd-party/qt5/patches/5.4/qtbase-configure-android.patch @@ -0,0 +1,39 @@ +Kai Pastor (OpenOrienteering) +- Use the correct tools prefix and toolchain prefix (fixes Android x86 build) + +diff -up Qt5/configure-orig Qt5/configure +--- Qt5/configure-orig 2014-02-23 16:49:35.497321634 +0100 ++++ Qt5/configure 2014-02-23 16:50:01.952928372 +0100 +@@ -3368,18 +3368,22 @@ TEST_COMPILER=$QMAKE_CONF_COMPILER + + if [ "$XPLATFORM_ANDROID" = "yes" ] ; then + ANDROID_NDK_TOOLS_PREFIX= ++ ANDROID_NDK_TOOLCHAIN_PREFIX= + ANDROID_PLATFORM_ARCH= + case $CFG_DEFAULT_ANDROID_TARGET_ARCH in + armeabi*) + ANDROID_NDK_TOOLS_PREFIX=arm-linux-androideabi ++ ANDROID_NDK_TOOLCHAIN_PREFIX=$ANDROID_NDK_TOOLS_PREFIX + ANDROID_PLATFORM_ARCH=arch-arm + ;; + x86) +- ANDROID_NDK_TOOLS_PREFIX=x86 ++ ANDROID_NDK_TOOLS_PREFIX=i686-linux-android ++ ANDROID_NDK_TOOLCHAIN_PREFIX=x86 + ANDROID_PLATFORM_ARCH=arch-x86 + ;; + mips) + ANDROID_NDK_TOOLS_PREFIX=mipsel-linux-android ++ ANDROID_NDK_TOOLCHAIN_PREFIX=$ANDROID_NDK_TOOLS_PREFIX + ANDROID_PLATFORM_ARCH=arch-mips + ;; + *) +@@ -3387,7 +3391,7 @@ if [ "$XPLATFORM_ANDROID" = "yes" ] ; th + exit 1 + ;; + esac +- QMAKE_CONF_COMPILER=$CFG_DEFAULT_ANDROID_NDK_ROOT/toolchains/$ANDROID_NDK_TOOLS_PREFIX-$CFG_DEFAULT_ANDROID_NDK_TOOLCHAIN_VERSION/prebuilt/$CFG_DEFAULT_ANDROID_NDK_HOST/bin/$ANDROID_NDK_TOOLS_PREFIX-g++ ++ QMAKE_CONF_COMPILER=$CFG_DEFAULT_ANDROID_NDK_ROOT/toolchains/$ANDROID_NDK_TOOLCHAIN_PREFIX-$CFG_DEFAULT_ANDROID_NDK_TOOLCHAIN_VERSION/prebuilt/$CFG_DEFAULT_ANDROID_NDK_HOST/bin/$ANDROID_NDK_TOOLS_PREFIX-g++ + TEST_COMPILER="$QMAKE_CONF_COMPILER --sysroot=$CFG_DEFAULT_ANDROID_NDK_ROOT/platforms/$CFG_DEFAULT_ANDROID_PLATFORM/$ANDROID_PLATFORM_ARCH/" + fi + diff --git a/3rd-party/qt5/patches/5.4/qtbase-create-cmake.patch b/3rd-party/qt5/patches/5.4/qtbase-create-cmake.patch new file mode 100644 index 0000000..36251a0 --- /dev/null +++ b/3rd-party/qt5/patches/5.4/qtbase-create-cmake.patch @@ -0,0 +1,21 @@ +2014-10-21 Kai Pastor (OpenOrienteering) +- Updated for Qt-5.4.0-beta + +2014-09-19 Kai Pastor (OpenOrienteering) +- Never fail on missing CMake tests, as we remove all tests from source dir. + +diff -up Qt5/mkspecs/features/create_cmake.prf.orig Qt5/mkspecs/features/create_cmake.prf +--- Qt5/mkspecs/features/create_cmake.prf.orig ++++ Qt5/mkspecs/features/create_cmake.prf +@@ -305,7 +305,8 @@ + # with 'CONFIG -= create_cmake' + !equals(CMAKE_MODULE_TESTS, -) { + isEmpty(CMAKE_MODULE_TESTS): CMAKE_MODULE_TESTS = $$MODULE_BASE_INDIR/tests/auto/cmake +- !exists($$CMAKE_MODULE_TESTS): \ +- error("Missing CMake tests. Either create tests in tests/auto/cmake," \ +- "or disable cmake config file creation with CONFIG-=create_cmake.") ++ # Test dirs were removed in OpenOrienteering build. ++ #!exists($$CMAKE_MODULE_TESTS): \ ++ # error("Missing CMake tests. Either create tests in tests/auto/cmake," \ ++ # "or disable cmake config file creation with CONFIG-=create_cmake.") + } diff --git a/3rd-party/qt5/patches/5.4/qtbase-qdockwidget.patch b/3rd-party/qt5/patches/5.4/qtbase-qdockwidget.patch new file mode 100644 index 0000000..5016582 --- /dev/null +++ b/3rd-party/qt5/patches/5.4/qtbase-qdockwidget.patch @@ -0,0 +1,32 @@ +From 7e7acd1320f1d98c3c917b360b6e6c8db6202e9f Mon Sep 17 00:00:00 2001 +From: Kai Pastor +Date: Mon, 22 Dec 2014 08:54:10 +0100 +Subject: [PATCH] Android: Don't assume native window decoration in QDockWidget + +Android does not decorate a floating QDockWidget, leaving the user with +no option to close or move such a widget. This changes activates Qt's +own drawing of window decorations for this case (similar to Win CE). + +[ChangeLog][Android][QtWidgets] Enable QDockWidget window decorations. + +Change-Id: Id46a994a8be9b8f3e7b530af118315cd36b5fb0e +--- + src/widgets/widgets/qdockwidget.cpp | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/widgets/widgets/qdockwidget.cpp b/src/widgets/widgets/qdockwidget.cpp +index 121fb2d..01a1f50 100644 +--- a/src/widgets/widgets/qdockwidget.cpp ++++ b/src/widgets/widgets/qdockwidget.cpp +@@ -207,7 +207,7 @@ static bool isXcb() + + bool QDockWidgetLayout::nativeWindowDeco(bool floating) const + { +-#ifdef Q_OS_WINCE ++#if defined(Q_OS_WINCE) || defined(Q_OS_ANDROID) + return false; + #else + return !isXcb() && (floating && item_list[QDockWidgetLayout::TitleBar] == 0); +-- +1.9.1 + diff --git a/3rd-party/qt5/patches/5.5/qtbase-QTBUG-48203-print-crash.patch b/3rd-party/qt5/patches/5.5/qtbase-QTBUG-48203-print-crash.patch new file mode 100644 index 0000000..a920737 --- /dev/null +++ b/3rd-party/qt5/patches/5.5/qtbase-QTBUG-48203-print-crash.patch @@ -0,0 +1,36 @@ +From a5f470240f31d35e694a40fe837fc4f49bc32072 Mon Sep 17 00:00:00 2001 +From: Friedemann Kleint +Date: Mon, 28 Sep 2015 16:41:34 +0200 +Subject: [PATCH 1/1] qprintengine_win.cpp: Check access to members of DOCINFO + in warning. + +DOCINFO::lpszOutput can be 0. + +Task-number: QTBUG-48203 +Change-Id: Ia3940b5b3200143d8d50caa8f4f44c4b22bfff75 +Reviewed-by: Andy Shaw +--- + src/printsupport/kernel/qprintengine_win.cpp | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +diff --git a/src/printsupport/kernel/qprintengine_win.cpp b/src/printsupport/kernel/qprintengine_win.cpp +index b377401..a4209d8 100644 +--- a/src/printsupport/kernel/qprintengine_win.cpp ++++ b/src/printsupport/kernel/qprintengine_win.cpp +@@ -93,9 +93,10 @@ static QByteArray msgBeginFailed(const char *function, const DOCINFO &d) + { + QString result; + QTextStream str(&result); +- str << "QWin32PrintEngine::begin: " << function << " failed, document \"" +- << QString::fromWCharArray(d.lpszDocName) << '"'; +- if (d.lpszOutput[0]) ++ str << "QWin32PrintEngine::begin: " << function << " failed"; ++ if (d.lpszDocName && d.lpszDocName[0]) ++ str << ", document \"" << QString::fromWCharArray(d.lpszDocName) << '"'; ++ if (d.lpszOutput && d.lpszOutput[0]) + str << ", file \"" << QString::fromWCharArray(d.lpszOutput) << '"'; + return result.toLocal8Bit(); + } +-- +2.6.2.2.g1b5ffa3 + diff --git a/3rd-party/qt5/patches/5.5/qtbase-android-install.patch b/3rd-party/qt5/patches/5.5/qtbase-android-install.patch new file mode 100644 index 0000000..80734bb --- /dev/null +++ b/3rd-party/qt5/patches/5.5/qtbase-android-install.patch @@ -0,0 +1,36 @@ +From 6e4788f68f207fc1956587d4915bbdd7ed8a1fe1 Mon Sep 17 00:00:00 2001 +From: Kai Pastor +Date: Mon, 2 Nov 2015 00:35:43 +0100 +Subject: [PATCH] android_install: Install Qt apps to QT_INSTALL_LIBS + +Fixes failures on "make install" when building Qt for Android. +Makes it possible to build Qt tools for later deplyoment. + +Task-number: QTBUG-47453 +Task-number: QTBUG-45095 +Task-number: QTBUG-44347 +Task-number: QTBUG-38452 +Change-Id: I3d5f2e7fb780d5514a4359a46f3ae80faac6d897 +--- + mkspecs/features/android/android.prf | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/mkspecs/features/android/android.prf b/mkspecs/features/android/android.prf +index f428f7d..55a6ae7 100644 +--- a/mkspecs/features/android/android.prf ++++ b/mkspecs/features/android/android.prf +@@ -3,8 +3,9 @@ contains(TEMPLATE, ".*app") { + !contains(TARGET, ".so"): TARGET = lib$${TARGET}.so + QMAKE_LFLAGS += -Wl,-soname,$$shell_quote($$TARGET) + +- android_install: { +- target.path=/libs/$$ANDROID_TARGET_ARCH/ ++ android_install { ++ QTDIR_build: target.path=$$[QT_INSTALL_LIBS] ++ else: target.path=/libs/$$ANDROID_TARGET_ARCH/ + INSTALLS *= target + } + } +-- +1.9.1 + diff --git a/3rd-party/qt5/patches/5.5/qtbase-create-cmake.patch b/3rd-party/qt5/patches/5.5/qtbase-create-cmake.patch new file mode 100644 index 0000000..36251a0 --- /dev/null +++ b/3rd-party/qt5/patches/5.5/qtbase-create-cmake.patch @@ -0,0 +1,21 @@ +2014-10-21 Kai Pastor (OpenOrienteering) +- Updated for Qt-5.4.0-beta + +2014-09-19 Kai Pastor (OpenOrienteering) +- Never fail on missing CMake tests, as we remove all tests from source dir. + +diff -up Qt5/mkspecs/features/create_cmake.prf.orig Qt5/mkspecs/features/create_cmake.prf +--- Qt5/mkspecs/features/create_cmake.prf.orig ++++ Qt5/mkspecs/features/create_cmake.prf +@@ -305,7 +305,8 @@ + # with 'CONFIG -= create_cmake' + !equals(CMAKE_MODULE_TESTS, -) { + isEmpty(CMAKE_MODULE_TESTS): CMAKE_MODULE_TESTS = $$MODULE_BASE_INDIR/tests/auto/cmake +- !exists($$CMAKE_MODULE_TESTS): \ +- error("Missing CMake tests. Either create tests in tests/auto/cmake," \ +- "or disable cmake config file creation with CONFIG-=create_cmake.") ++ # Test dirs were removed in OpenOrienteering build. ++ #!exists($$CMAKE_MODULE_TESTS): \ ++ # error("Missing CMake tests. Either create tests in tests/auto/cmake," \ ++ # "or disable cmake config file creation with CONFIG-=create_cmake.") + } diff --git a/3rd-party/qt5/qt.conf.in b/3rd-party/qt5/qt.conf.in new file mode 100644 index 0000000..1ac6c57 --- /dev/null +++ b/3rd-party/qt5/qt.conf.in @@ -0,0 +1,3 @@ +[Paths] +Plugins=@MAPPER_LIBRARY_DESTINATION@/plugins +Translations=@MAPPER_DATA_DESTINATION@/translations diff --git a/3rd-party/qt5/qt.conf.qrc.in b/3rd-party/qt5/qt.conf.qrc.in new file mode 100644 index 0000000..c8d2a33 --- /dev/null +++ b/3rd-party/qt5/qt.conf.qrc.in @@ -0,0 +1,5 @@ + + + qt.conf + + diff --git a/3rd-party/qt5/qt5-config-host.in b/3rd-party/qt5/qt5-config-host.in new file mode 100644 index 0000000..3dbafb1 --- /dev/null +++ b/3rd-party/qt5/qt5-config-host.in @@ -0,0 +1,67 @@ +#!/bin/sh -e +# +# Copyright 2012, 2013, 2014 Kai Pastor +# +# This file is part of OpenOrienteering. +# +# OpenOrienteering is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# OpenOrienteering is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with OpenOrienteering. If not, see . + +# Configure for host system of cross compilation +QT5_CONFIG_HOST_OPTS= +if [ -n "@CMAKE_HOST_APPLE@" ] +then + QT5_CONFIG_HOST_OPTS="-no-framework" +fi + +"@SOURCE_DIR@/configure" \ + -opensource \ + -confirm-license \ + $QT5_CONFIG_HOST_OPTS \ + -prefix "@QT5_HOST_DIR@" \ + -release \ + -static \ + -gui \ + -widgets \ + -no-xcb \ + -qpa minimal \ + -no-qpa-platform-guard \ + -qt-sql-sqlite \ + -no-sql-db2 \ + -no-sql-ibase \ + -no-sql-mysql \ + -no-sql-oci \ + -no-sql-odbc \ + -no-sql-psql \ + -no-sql-sqlite2 \ + -no-sql-tds \ + -qt-zlib \ + -qt-libpng \ + -no-libjpeg \ + -no-gif \ + -no-openssl \ + -qt-pcre \ + -no-directfb \ + -no-linuxfb \ + -no-qml-debug \ + -no-cups \ + -no-opengl \ + -no-dbus \ + -no-accessibility \ + -no-fontconfig \ + -no-sm \ + -nomake examples \ + -nomake tests \ + -system-proxies \ + -no-glib \ + -no-audio-backend diff --git a/3rd-party/qt5/qt5-config.cmd.in b/3rd-party/qt5/qt5-config.cmd.in new file mode 100755 index 0000000..afec54c --- /dev/null +++ b/3rd-party/qt5/qt5-config.cmd.in @@ -0,0 +1,20 @@ +@REM Copyright 2013 Kai Pastor +@REM +@REM This file is part of OpenOrienteering. +@REM +@REM OpenOrienteering is free software: you can redistribute it and/or modify +@REM it under the terms of the GNU General Public License as published by +@REM the Free Software Foundation, either version 3 of the License, or +@REM (at your option) any later version. +@REM +@REM OpenOrienteering is distributed in the hope that it will be useful, +@REM but WITHOUT ANY WARRANTY; without even the implied warranty of +@REM MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +@REM GNU General Public License for more details. +@REM +@REM You should have received a copy of the GNU General Public License +@REM along with OpenOrienteering. If not, see . + +@echo off + +.\configure.bat -opensource -confirm-license @QT5_PLATFORM@ -prefix "@QT5_BINARY_DESTINATION@" -plugindir "@QT5_PLUGINS_DESTINATION@" -datadir "@QT5_DATA_DESTINATION@" @QT5_CONFIG_EXTRA_OPTS@ -release -shared -widgets -qt-sql-sqlite -no-sql-db2 -no-sql-ibase -no-sql-mysql -no-sql-oci -no-sql-odbc -no-sql-psql -no-sql-sqlite2 -no-sql-tds -qt-zlib -qt-libpng -qt-libjpeg -no-openssl -qt-pcre -make libs -make tools -nomake examples -nomake tests -no-audio-backend -opengl desktop diff --git a/3rd-party/qt5/qt5-config.in b/3rd-party/qt5/qt5-config.in new file mode 100644 index 0000000..c596e97 --- /dev/null +++ b/3rd-party/qt5/qt5-config.in @@ -0,0 +1,49 @@ +#!/bin/sh -e +# +# Copyright 2012, 2013, 2014 Kai Pastor +# +# This file is part of OpenOrienteering. +# +# OpenOrienteering is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# OpenOrienteering is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with OpenOrienteering. If not, see . + +# Configure +@QT5_CONFIG_ENVIRONMENT@ \ +"@SOURCE_DIR@/configure" \ + -opensource \ + -confirm-license \ + @QT5_PLATFORM@ \ + -prefix '@QT5_BINARY_DESTINATION@' \ + -plugindir '@QT5_PLUGINS_DESTINATION@' \ + -datadir '@QT5_DATA_DESTINATION@' \ + @QT5_CONFIG_EXTRA_OPTS@ \ + -shared \ + -gui \ + -widgets \ + -no-sql-db2 \ + -no-sql-ibase \ + -no-sql-mysql \ + -no-sql-oci \ + -no-sql-odbc \ + -no-sql-psql \ + -no-sql-sqlite2 \ + -no-sql-tds \ + -no-openssl \ + -no-directfb \ + -no-linuxfb \ + -make tools \ + -nomake examples \ + -nomake tests \ + -system-proxies \ + -no-glib \ + -no-audio-backend diff --git a/3rd-party/qt5/qt5-make.in b/3rd-party/qt5/qt5-make.in new file mode 100644 index 0000000..5beb38c --- /dev/null +++ b/3rd-party/qt5/qt5-make.in @@ -0,0 +1,28 @@ +#!/bin/sh -e +# +# Copyright 2012, 2013 Kai Pastor +# +# This file is part of OpenOrienteering. +# +# OpenOrienteering is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# OpenOrienteering is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with OpenOrienteering. If not, see . + +# sh wrapping: +# Especially MSYS needs -l so that it reads /etc/profile and sets up a proper +# environment. But /etc/profile will cd to the home directory. The wrapper needs +# to cd back to the BINARY_DIR. + +cd "@BINARY_DIR@" + +make "$@" + diff --git a/3rd-party/qt5/qt5-patchqt.in b/3rd-party/qt5/qt5-patchqt.in new file mode 100644 index 0000000..ee80496 --- /dev/null +++ b/3rd-party/qt5/qt5-patchqt.in @@ -0,0 +1,197 @@ +#!/bin/sh -e +# +# Copyright 2012-2015 Kai Pastor +# +# This file is part of OpenOrienteering. +# +# OpenOrienteering is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# OpenOrienteering is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with OpenOrienteering. If not, see . + +cd "@SOURCE_DIR@" + +PRETTY_DATE=$(date +%Y-%m-%d) +OO_LOG=OpenOrienteering/CHANGES.txt + +mkdir -p OpenOrienteering +cat > ${OO_LOG} << END_OPENORIENTEERING_README +This Qt source code distribution contains modifications by OpenOrienteering. + +$PRETTY_DATE: +- Removed a number of directories. +- Replaced a number of files by empty or no-op placeholders. +- Applied the following patches: +END_OPENORIENTEERING_README + +# [1] Customize build by removing and disabling subdirs. +for I in \ + gnuwin32 \ + qt*/doc \ + qt*/examples \ + qt*/src/doc/* \ + qt*/src/*/doc/* \ + qt*/tests \ + qt3d \ + qtactiveqt \ + qtbase/doc/src \ + qtbase/include/QtANGLE \ + qtbase/include/QtNetwork/[Qq][Ss]sl* \ + qtbase/include/QtNetwork/*/QtNetwork/private/[Qq][Ss]sl* \ + qtbase/lib/fonts \ + qtbase/src/3rdparty/angle \ + qtbase/src/3rdparty/des \ + qtbase/src/angle \ + qtbase/src/network/ssl/* \ + qtbase/src/sql/drivers/db2 \ + qtbase/src/sql/drivers/ibase \ + qtbase/src/sql/drivers/mysql \ + qtbase/src/sql/drivers/oci \ + qtbase/src/sql/drivers/odbc \ + qtbase/src/sql/drivers/psql \ + qtbase/src/sql/drivers/sqlite2 \ + qtbase/src/sql/drivers/tds \ + qtcanvas3d \ + qtconnectivity \ + qtdoc \ + qtenginio \ + qtgraphicaleffects \ + qtimageformats/src/3rdparty/libmng* \ + qtimageformats/src/3rdparty/patches/libmng* \ + qtimageformats/src/plugins/imageformats/mng/* \ + qtimageformats/src/plugins/imageformats/tga/* \ + qtimageformats/src/plugins/imageformats/wbmp/* \ + qtjsbackend \ + qtlocation/src/positioning/doc/snippets/* \ + qtmacextras \ + qtmultimedia \ + qtquick1 \ + qtquickcontrols \ + qtscript \ + qtserialport \ + qtsvg \ + qttools/src/designer/components/* \ + qttools/src/designer/designer/* \ + qttools/src/designer/plugins/* \ + qttools/src/designer/src/lib/extensions/* \ + qtwayland \ + qtwebchannel \ + qtwebengine \ + qtwebkit \ + qtwebkit-examples \ + qtwebkit-examples-and-demos \ + qtwebsockets \ + qtwinextras \ + qtx11extras \ + qtxmlpatterns +do + if [ -d "./$I" ] + then + case "$I" in + qtbase/doc) + ;; # Retain qtbase/doc/global + qtdoc/doc|qtdoc/doc/src/legal) + ;; # Retain qtdoc/doc/src/legal + qt*/src/*/doc/snippets) + ;; # Retain snippets, may have snippets.pro + *) + rm -R "./$I" ;; + esac + elif [ -f "./$I" ] + then + case "$I" in + */include/*) + echo "// $PRETTY_DATE: Replaced with empty placeholder file" > "./$I" ;; + *.pro) + echo "# $PRETTY_DATE: Replaced with no-op placeholder file" > "./$I" + echo "TEMPLATE = subdirs" >> "./$I" ;; + *.pri|*.pro|*.qdocconf) + echo "# $PRETTY_DATE: Replaced with empty placeholder file" > "./$I" ;; + *) + rm "./$I" ;; + esac + fi +done + +# [2] Normal patching +mkdir -p OpenOrienteering/patches +for I in \ + "@PROJECT_SOURCE_DIR@/patches/@QT5_MAJOR_MINOR@"/*.patch \ + "@PROJECT_SOURCE_DIR@/patches/@QT5_MAJOR_MINOR_REVISION@"/*.patch +do + PATCH=$(basename "$I") + if [ ! -e "$I" ] + then + true # no patch + elif [ ! -f "$I" ] + then + echo "Unknown element $I" >&2 + exit 1 + elif [ ! -f "OpenOrienteering/patches/$PATCH" ] + then + # Apply normally + MODULE=$(echo "$PATCH" | sed -e "s/-.*//") + if [ ! -d "$MODULE" ] + then + echo "No such Qt module: $MODULE" >&2 + exit 1 + fi + echo "-- $PATCH (New)" + ( cd "$MODULE" && patch -p1 < "$I" ) + cp "$I" "OpenOrienteering/patches/$PATCH" + echo " $PATCH " >> ${OO_LOG} + elif diff -q "$I" "OpenOrienteering/patches/$PATCH" + then + # Reapply for verification + MODULE=$(echo "$PATCH" | sed -e "s/-.*//") + if [ ! -d "$MODULE" ] + then + echo "No such Qt module: $MODULE" >&2 + exit 1 + fi + echo "-- $PATCH (Re-applied for verification)" + ( cd "$MODULE" && + patch --silent --reverse -p1 < "$I" && + patch -p1 < "$I" ) + echo " $PATCH " >> ${OO_LOG} + else + echo "A different patch named $PATCH was already applied." >&2 + exit 1 + fi +done + +for I in OpenOrienteering/patches/* +do + PATCH=$(basename "$I") + if [ ! -e "$I" ] + then + true # no patch + elif [ ! -f "$I" ] + then + echo "Unknown element $I" >&2 + exit 1 + elif grep -q " $PATCH " ${OO_LOG} + then + true + else + echo "Unknown patch $I" >&2 + exit 1 + fi +done + +# [3] MinGW on Windows issue +if [ ! -f qtbase/.gitignore ] +then + touch qtbase/.gitignore +fi + +# [4] Create an archive of the remaining source code +( cd .. && tar czf qt-everywhere-opensource-src-@QT5_MAJOR_MINOR_REVISION@-openorienteering-$PRETTY_DATE.tar.gz Qt5 ) diff --git a/3rd-party/qt5/qt5.pro b/3rd-party/qt5/qt5.pro new file mode 100644 index 0000000..58da3cf --- /dev/null +++ b/3rd-party/qt5/qt5.pro @@ -0,0 +1,60 @@ +# +# Copyright 2014 Kai Pastor +# +# This file is part of OpenOrienteering. +# +# OpenOrienteering is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# OpenOrienteering is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with OpenOrienteering. If not, see . + +TEMPLATE = aux +CONFIG -= debug_and_release +QT = + +OTHER_FILES = \ + CMakeLists.txt \ + qt.conf.in \ + qt.conf.qrc.in \ + qt5-config-host.in \ + qt5-config.cmd.in \ + qt5-config.in \ + qt5-make.in \ + qt5-patchqt.in + +qt5.dir = $$OUT_PWD/qt5 +qt5.target = $$qt5.dir/CMakeFiles/Qt5-complete + +android { + qt5.platform = -xplatform android-g++ \ + -android-ndk-platform android-9 \ + -android-arch "$$ANDROID_TARGET_ARCH" \ + -android-toolchain-version 4.9 +} + +qt5.debug = +CONFIG(debug, release|debug) { + qt5.debug = -DQT5_DEBUG:BOOL=ON +} + +qt5.cmake = \ + cmake "$$PWD" -UQT5_* -DQT5_PLATFORM=\"$$qt5.platform\" $$qt5.debug +qt5.commands = \ + cd "$$qt5.dir" && \ + $$qt5.cmake && \ + PATH="$$NDK_TOOLCHAIN_PATH/bin:${PATH}" $(MAKE) all + +mkpath($$qt5.dir) +system(cd "$$qt5.dir" && $$qt5.cmake) + +QMAKE_EXTRA_TARGETS += qt5 +PRE_TARGETDEPS += $$qt5.target +QMAKE_CLEAN += $$qt5.target $$qt5.dir/Qt5-prefix/src/Qt5-stamp/Qt5-download diff --git a/3rd-party/qtsingleapplication/CMakeLists.txt b/3rd-party/qtsingleapplication/CMakeLists.txt new file mode 100644 index 0000000..208bb47 --- /dev/null +++ b/3rd-party/qtsingleapplication/CMakeLists.txt @@ -0,0 +1,46 @@ +# +# Copyright 2012-2015 Kai Pastor +# +# This file is part of OpenOrienteering. +# +# OpenOrienteering is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# OpenOrienteering is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with OpenOrienteering. If not, see . + +find_package(Qt5Widgets REQUIRED) +find_package(Qt5Network REQUIRED) + +set(QSINGLEAPP_SRCS + src/qtlocalpeer.cpp + src/qtsingleapplication.cpp + src/qtsinglecoreapplication.cpp +) +set(QSINGLEAPP_MOC_INPUT + src/qtlocalpeer.h + src/qtsingleapplication.h + src/qtsinglecoreapplication.h +) +qt5_wrap_cpp(QSINGLEAPP_MOC ${QSINGLEAPP_MOC_INPUT}) + +add_library(QtSingleApplication STATIC + ${QSINGLEAPP_SRCS} + ${QSINGLEAPP_MOC} +) + +target_include_directories(QtSingleApplication + INTERFACE "${CMAKE_CURRENT_SOURCE_DIR}/src" +) + +target_link_libraries(QtSingleApplication + PUBLIC Qt5::Widgets + PUBLIC Qt5::Network +) diff --git a/3rd-party/qtsingleapplication/qtsingleapplication.pro b/3rd-party/qtsingleapplication/qtsingleapplication.pro new file mode 100644 index 0000000..598ffd0 --- /dev/null +++ b/3rd-party/qtsingleapplication/qtsingleapplication.pro @@ -0,0 +1,47 @@ +# +# Copyright 2014 Kai Pastor +# +# This file is part of OpenOrienteering. +# +# OpenOrienteering is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# OpenOrienteering is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with OpenOrienteering. If not, see . + +TEMPLATE = lib +TARGET = qtsingleapplication +CONFIG += staticlib +CONFIG += c++11 +CONFIG -= debug_and_release + +android { + # Avoid staticlib install by undocumented behaviour of qmake + INSTALLS = target + target.extra = @test -d . +} + +QT += core widgets network + +HEADERS = \ + src/qtsingleapplication.h \ + src/qtlocalpeer.h + +SOURCES = \ + src/qtsingleapplication.cpp \ + src/qtlocalpeer.cpp + +QTSINGLEAPPLICATION_PRI = \ + "$$LITERAL_HASH Generated by $$_PRO_FILE_" \ + "DEPENDPATH += $$PWD/src" \ + "INCLUDEPATH += $$PWD/src" \ + "LIBS += \"-L$$OUT_PWD\"" + +write_file($$OUT_PWD/qtsingleapplication.pri, QTSINGLEAPPLICATION_PRI) diff --git a/3rd-party/qtsingleapplication/src/QtLockedFile b/3rd-party/qtsingleapplication/src/QtLockedFile new file mode 100644 index 0000000..16b48ba --- /dev/null +++ b/3rd-party/qtsingleapplication/src/QtLockedFile @@ -0,0 +1 @@ +#include "qtlockedfile.h" diff --git a/3rd-party/qtsingleapplication/src/QtSingleApplication b/3rd-party/qtsingleapplication/src/QtSingleApplication new file mode 100644 index 0000000..d111bf7 --- /dev/null +++ b/3rd-party/qtsingleapplication/src/QtSingleApplication @@ -0,0 +1 @@ +#include "qtsingleapplication.h" diff --git a/3rd-party/qtsingleapplication/src/qtlocalpeer.cpp b/3rd-party/qtsingleapplication/src/qtlocalpeer.cpp new file mode 100644 index 0000000..c7ce527 --- /dev/null +++ b/3rd-party/qtsingleapplication/src/qtlocalpeer.cpp @@ -0,0 +1,204 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the Qt Solutions component. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + + +#include "qtlocalpeer.h" +#include +#include +#include + +#if defined(Q_OS_WIN) +#include +#include +typedef BOOL(WINAPI*PProcessIdToSessionId)(DWORD,DWORD*); +static PProcessIdToSessionId pProcessIdToSessionId = 0; +#endif +#if defined(Q_OS_UNIX) +#include +#include +#include +#endif + +namespace QtLP_Private { +#include "qtlockedfile.cpp" +#if defined(Q_OS_WIN) +#include "qtlockedfile_win.cpp" +#else +#include "qtlockedfile_unix.cpp" +#endif +} + +const char* QtLocalPeer::ack = "ack"; + +QtLocalPeer::QtLocalPeer(QObject* parent, const QString &appId) + : QObject(parent), id(appId) +{ + QString prefix = id; + if (id.isEmpty()) { + id = QCoreApplication::applicationFilePath(); +#if defined(Q_OS_WIN) + id = id.toLower(); +#endif + prefix = id.section(QLatin1Char('/'), -1); + } + prefix.remove(QRegExp("[^a-zA-Z]")); + prefix.truncate(6); + + QByteArray idc = id.toUtf8(); + quint16 idNum = qChecksum(idc.constData(), idc.size()); + socketName = QLatin1String("qtsingleapp-") + prefix + + QLatin1Char('-') + QString::number(idNum, 16); + +#if defined(Q_OS_WIN) + if (!pProcessIdToSessionId) { + QLibrary lib("kernel32"); + pProcessIdToSessionId = (PProcessIdToSessionId)lib.resolve("ProcessIdToSessionId"); + } + if (pProcessIdToSessionId) { + DWORD sessionId = 0; + pProcessIdToSessionId(GetCurrentProcessId(), &sessionId); + socketName += QLatin1Char('-') + QString::number(sessionId, 16); + } +#else + socketName += QLatin1Char('-') + QString::number(::getuid(), 16); +#endif + + server = new QLocalServer(this); + QString lockName = QDir(QDir::tempPath()).absolutePath() + + QLatin1Char('/') + socketName + + QLatin1String("-lockfile"); + lockFile.setFileName(lockName); + lockFile.open(QIODevice::ReadWrite); +} + + + +bool QtLocalPeer::isClient() +{ + if (lockFile.isLocked()) + return false; + + if (!lockFile.lock(QtLP_Private::QtLockedFile::WriteLock, false)) + return true; + + bool res = server->listen(socketName); +#if defined(Q_OS_UNIX) && (QT_VERSION >= QT_VERSION_CHECK(4,5,0)) + // ### Workaround + if (!res && server->serverError() == QAbstractSocket::AddressInUseError) { + QFile::remove(QDir::cleanPath(QDir::tempPath())+QLatin1Char('/')+socketName); + res = server->listen(socketName); + } +#endif + if (!res) + qWarning("QtSingleCoreApplication: listen on local socket failed, %s", qPrintable(server->errorString())); + QObject::connect(server, SIGNAL(newConnection()), SLOT(receiveConnection())); + return false; +} + + +bool QtLocalPeer::sendMessage(const QString &message, int timeout) +{ + if (!isClient()) + return false; + + QLocalSocket socket; + bool connOk = false; + for(int i = 0; i < 2; i++) { + // Try twice, in case the other instance is just starting up + socket.connectToServer(socketName); + connOk = socket.waitForConnected(timeout/2); + if (connOk || i) + break; + int ms = 250; +#if defined(Q_OS_WIN) + Sleep(DWORD(ms)); +#else + struct timespec ts = { ms / 1000, (ms % 1000) * 1000 * 1000 }; + nanosleep(&ts, NULL); +#endif + } + if (!connOk) + return false; + + QByteArray uMsg(message.toUtf8()); + QDataStream ds(&socket); + ds.writeBytes(uMsg.constData(), uMsg.size()); + bool res = socket.waitForBytesWritten(timeout); + if (res) { + res &= socket.waitForReadyRead(timeout); // wait for ack + if (res) + res &= (socket.read(qstrlen(ack)) == ack); + } + return res; +} + + +void QtLocalPeer::receiveConnection() +{ + QLocalSocket* socket = server->nextPendingConnection(); + if (!socket) + return; + + while (socket->bytesAvailable() < (int)sizeof(quint32)) + socket->waitForReadyRead(); + QDataStream ds(socket); + QByteArray uMsg; + quint32 remaining; + ds >> remaining; + uMsg.resize(remaining); + int got = 0; + char* uMsgBuf = uMsg.data(); + do { + got = ds.readRawData(uMsgBuf, remaining); + remaining -= got; + uMsgBuf += got; + } while (remaining && got >= 0 && socket->waitForReadyRead(2000)); + if (got < 0) { + qWarning("QtLocalPeer: Message reception failed %s", socket->errorString().toLatin1().constData()); + delete socket; + return; + } + QString message(QString::fromUtf8(uMsg)); + socket->write(ack, qstrlen(ack)); + socket->waitForBytesWritten(1000); + socket->waitForDisconnected(1000); // make sure client reads ack + delete socket; + emit messageReceived(message); //### (might take a long time to return) +} diff --git a/3rd-party/qtsingleapplication/src/qtlocalpeer.h b/3rd-party/qtsingleapplication/src/qtlocalpeer.h new file mode 100644 index 0000000..1b533b1 --- /dev/null +++ b/3rd-party/qtsingleapplication/src/qtlocalpeer.h @@ -0,0 +1,77 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the Qt Solutions component. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QTLOCALPEER_H +#define QTLOCALPEER_H + +#include +#include +#include + +#include "qtlockedfile.h" + +class QtLocalPeer : public QObject +{ + Q_OBJECT + +public: + QtLocalPeer(QObject *parent = 0, const QString &appId = QString()); + bool isClient(); + bool sendMessage(const QString &message, int timeout); + QString applicationId() const + { return id; } + +Q_SIGNALS: + void messageReceived(const QString &message); + +protected Q_SLOTS: + void receiveConnection(); + +protected: + QString id; + QString socketName; + QLocalServer* server; + QtLP_Private::QtLockedFile lockFile; + +private: + static const char* ack; +}; + +#endif // QTLOCALPEER_H diff --git a/3rd-party/qtsingleapplication/src/qtlockedfile.cpp b/3rd-party/qtsingleapplication/src/qtlockedfile.cpp new file mode 100644 index 0000000..c142a86 --- /dev/null +++ b/3rd-party/qtsingleapplication/src/qtlockedfile.cpp @@ -0,0 +1,193 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the Qt Solutions component. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qtlockedfile.h" + +/*! + \class QtLockedFile + + \brief The QtLockedFile class extends QFile with advisory locking + functions. + + A file may be locked in read or write mode. Multiple instances of + \e QtLockedFile, created in multiple processes running on the same + machine, may have a file locked in read mode. Exactly one instance + may have it locked in write mode. A read and a write lock cannot + exist simultaneously on the same file. + + The file locks are advisory. This means that nothing prevents + another process from manipulating a locked file using QFile or + file system functions offered by the OS. Serialization is only + guaranteed if all processes that access the file use + QLockedFile. Also, while holding a lock on a file, a process + must not open the same file again (through any API), or locks + can be unexpectedly lost. + + The lock provided by an instance of \e QtLockedFile is released + whenever the program terminates. This is true even when the + program crashes and no destructors are called. +*/ + +/*! \enum QtLockedFile::LockMode + + This enum describes the available lock modes. + + \value ReadLock A read lock. + \value WriteLock A write lock. + \value NoLock Neither a read lock nor a write lock. +*/ + +/*! + Constructs an unlocked \e QtLockedFile object. This constructor + behaves in the same way as \e QFile::QFile(). + + \sa QFile::QFile() +*/ +QtLockedFile::QtLockedFile() + : QFile() +{ +#ifdef Q_OS_WIN + wmutex = 0; + rmutex = 0; +#endif + m_lock_mode = NoLock; +} + +/*! + Constructs an unlocked QtLockedFile object with file \a name. This + constructor behaves in the same way as \e QFile::QFile(const + QString&). + + \sa QFile::QFile() +*/ +QtLockedFile::QtLockedFile(const QString &name) + : QFile(name) +{ +#ifdef Q_OS_WIN + wmutex = 0; + rmutex = 0; +#endif + m_lock_mode = NoLock; +} + +/*! + Opens the file in OpenMode \a mode. + + This is identical to QFile::open(), with the one exception that the + Truncate mode flag is disallowed. Truncation would conflict with the + advisory file locking, since the file would be modified before the + write lock is obtained. If truncation is required, use resize(0) + after obtaining the write lock. + + Returns true if successful; otherwise false. + + \sa QFile::open(), QFile::resize() +*/ +bool QtLockedFile::open(OpenMode mode) +{ + if (mode & QIODevice::Truncate) { + qWarning("QtLockedFile::open(): Truncate mode not allowed."); + return false; + } + return QFile::open(mode); +} + +/*! + Returns \e true if this object has a in read or write lock; + otherwise returns \e false. + + \sa lockMode() +*/ +bool QtLockedFile::isLocked() const +{ + return m_lock_mode != NoLock; +} + +/*! + Returns the type of lock currently held by this object, or \e + QtLockedFile::NoLock. + + \sa isLocked() +*/ +QtLockedFile::LockMode QtLockedFile::lockMode() const +{ + return m_lock_mode; +} + +/*! + \fn bool QtLockedFile::lock(LockMode mode, bool block = true) + + Obtains a lock of type \a mode. The file must be opened before it + can be locked. + + If \a block is true, this function will block until the lock is + aquired. If \a block is false, this function returns \e false + immediately if the lock cannot be aquired. + + If this object already has a lock of type \a mode, this function + returns \e true immediately. If this object has a lock of a + different type than \a mode, the lock is first released and then a + new lock is obtained. + + This function returns \e true if, after it executes, the file is + locked by this object, and \e false otherwise. + + \sa unlock(), isLocked(), lockMode() +*/ + +/*! + \fn bool QtLockedFile::unlock() + + Releases a lock. + + If the object has no lock, this function returns immediately. + + This function returns \e true if, after it executes, the file is + not locked by this object, and \e false otherwise. + + \sa lock(), isLocked(), lockMode() +*/ + +/*! + \fn QtLockedFile::~QtLockedFile() + + Destroys the \e QtLockedFile object. If any locks were held, they + are released. +*/ diff --git a/3rd-party/qtsingleapplication/src/qtlockedfile.h b/3rd-party/qtsingleapplication/src/qtlockedfile.h new file mode 100644 index 0000000..84c18e5 --- /dev/null +++ b/3rd-party/qtsingleapplication/src/qtlockedfile.h @@ -0,0 +1,97 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the Qt Solutions component. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QTLOCKEDFILE_H +#define QTLOCKEDFILE_H + +#include +#ifdef Q_OS_WIN +#include +#endif + +#if defined(Q_OS_WIN) +# if !defined(QT_QTLOCKEDFILE_EXPORT) && !defined(QT_QTLOCKEDFILE_IMPORT) +# define QT_QTLOCKEDFILE_EXPORT +# elif defined(QT_QTLOCKEDFILE_IMPORT) +# if defined(QT_QTLOCKEDFILE_EXPORT) +# undef QT_QTLOCKEDFILE_EXPORT +# endif +# define QT_QTLOCKEDFILE_EXPORT __declspec(dllimport) +# elif defined(QT_QTLOCKEDFILE_EXPORT) +# undef QT_QTLOCKEDFILE_EXPORT +# define QT_QTLOCKEDFILE_EXPORT __declspec(dllexport) +# endif +#else +# define QT_QTLOCKEDFILE_EXPORT +#endif + +namespace QtLP_Private { + +class QT_QTLOCKEDFILE_EXPORT QtLockedFile : public QFile +{ +public: + enum LockMode { NoLock = 0, ReadLock, WriteLock }; + + QtLockedFile(); + QtLockedFile(const QString &name); + ~QtLockedFile(); + + bool open(OpenMode mode); + + bool lock(LockMode mode, bool block = true); + bool unlock(); + bool isLocked() const; + LockMode lockMode() const; + +private: +#ifdef Q_OS_WIN + Qt::HANDLE wmutex; + Qt::HANDLE rmutex; + QVector rmutexes; + QString mutexname; + + Qt::HANDLE getMutexHandle(int idx, bool doCreate); + bool waitMutex(Qt::HANDLE mutex, bool doBlock); + +#endif + LockMode m_lock_mode; +}; +} +#endif diff --git a/3rd-party/qtsingleapplication/src/qtlockedfile_unix.cpp b/3rd-party/qtsingleapplication/src/qtlockedfile_unix.cpp new file mode 100644 index 0000000..976c1b9 --- /dev/null +++ b/3rd-party/qtsingleapplication/src/qtlockedfile_unix.cpp @@ -0,0 +1,115 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the Qt Solutions component. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include +#include +#include + +#include "qtlockedfile.h" + +bool QtLockedFile::lock(LockMode mode, bool block) +{ + if (!isOpen()) { + qWarning("QtLockedFile::lock(): file is not opened"); + return false; + } + + if (mode == NoLock) + return unlock(); + + if (mode == m_lock_mode) + return true; + + if (m_lock_mode != NoLock) + unlock(); + + struct flock fl; + fl.l_whence = SEEK_SET; + fl.l_start = 0; + fl.l_len = 0; + fl.l_type = (mode == ReadLock) ? F_RDLCK : F_WRLCK; + int cmd = block ? F_SETLKW : F_SETLK; + int ret = fcntl(handle(), cmd, &fl); + + if (ret == -1) { + if (errno != EINTR && errno != EAGAIN) + qWarning("QtLockedFile::lock(): fcntl: %s", strerror(errno)); + return false; + } + + + m_lock_mode = mode; + return true; +} + + +bool QtLockedFile::unlock() +{ + if (!isOpen()) { + qWarning("QtLockedFile::unlock(): file is not opened"); + return false; + } + + if (!isLocked()) + return true; + + struct flock fl; + fl.l_whence = SEEK_SET; + fl.l_start = 0; + fl.l_len = 0; + fl.l_type = F_UNLCK; + int ret = fcntl(handle(), F_SETLKW, &fl); + + if (ret == -1) { + qWarning("QtLockedFile::lock(): fcntl: %s", strerror(errno)); + return false; + } + + m_lock_mode = NoLock; + return true; +} + +QtLockedFile::~QtLockedFile() +{ + if (isOpen()) + unlock(); +} + diff --git a/3rd-party/qtsingleapplication/src/qtlockedfile_win.cpp b/3rd-party/qtsingleapplication/src/qtlockedfile_win.cpp new file mode 100644 index 0000000..5e21262 --- /dev/null +++ b/3rd-party/qtsingleapplication/src/qtlockedfile_win.cpp @@ -0,0 +1,211 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the Qt Solutions component. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qtlockedfile.h" +#include +#include + +#define MUTEX_PREFIX "QtLockedFile mutex " +// Maximum number of concurrent read locks. Must not be greater than MAXIMUM_WAIT_OBJECTS +#define MAX_READERS MAXIMUM_WAIT_OBJECTS + +#if QT_VERSION >= 0x050000 +#define QT_WA(unicode, ansi) unicode +#endif + +Qt::HANDLE QtLockedFile::getMutexHandle(int idx, bool doCreate) +{ + if (mutexname.isEmpty()) { + QFileInfo fi(*this); + mutexname = QString::fromLatin1(MUTEX_PREFIX) + + fi.absoluteFilePath().toLower(); + } + QString mname(mutexname); + if (idx >= 0) + mname += QString::number(idx); + + Qt::HANDLE mutex; + if (doCreate) { + QT_WA( { mutex = CreateMutexW(NULL, FALSE, (TCHAR*)mname.utf16()); }, + { mutex = CreateMutexA(NULL, FALSE, mname.toLocal8Bit().constData()); } ); + if (!mutex) { + qErrnoWarning("QtLockedFile::lock(): CreateMutex failed"); + return 0; + } + } + else { + QT_WA( { mutex = OpenMutexW(SYNCHRONIZE | MUTEX_MODIFY_STATE, FALSE, (TCHAR*)mname.utf16()); }, + { mutex = OpenMutexA(SYNCHRONIZE | MUTEX_MODIFY_STATE, FALSE, mname.toLocal8Bit().constData()); } ); + if (!mutex) { + if (GetLastError() != ERROR_FILE_NOT_FOUND) + qErrnoWarning("QtLockedFile::lock(): OpenMutex failed"); + return 0; + } + } + return mutex; +} + +bool QtLockedFile::waitMutex(Qt::HANDLE mutex, bool doBlock) +{ + Q_ASSERT(mutex); + DWORD res = WaitForSingleObject(mutex, doBlock ? INFINITE : 0); + switch (res) { + case WAIT_OBJECT_0: + case WAIT_ABANDONED: + return true; + break; + case WAIT_TIMEOUT: + break; + default: + qErrnoWarning("QtLockedFile::lock(): WaitForSingleObject failed"); + } + return false; +} + + + +bool QtLockedFile::lock(LockMode mode, bool block) +{ + if (!isOpen()) { + qWarning("QtLockedFile::lock(): file is not opened"); + return false; + } + + if (mode == NoLock) + return unlock(); + + if (mode == m_lock_mode) + return true; + + if (m_lock_mode != NoLock) + unlock(); + + if (!wmutex && !(wmutex = getMutexHandle(-1, true))) + return false; + + if (!waitMutex(wmutex, block)) + return false; + + if (mode == ReadLock) { + int idx = 0; + for (; idx < MAX_READERS; idx++) { + rmutex = getMutexHandle(idx, false); + if (!rmutex || waitMutex(rmutex, false)) + break; + CloseHandle(rmutex); + } + bool ok = true; + if (idx >= MAX_READERS) { + qWarning("QtLockedFile::lock(): too many readers"); + rmutex = 0; + ok = false; + } + else if (!rmutex) { + rmutex = getMutexHandle(idx, true); + if (!rmutex || !waitMutex(rmutex, false)) + ok = false; + } + if (!ok && rmutex) { + CloseHandle(rmutex); + rmutex = 0; + } + ReleaseMutex(wmutex); + if (!ok) + return false; + } + else { + Q_ASSERT(rmutexes.isEmpty()); + for (int i = 0; i < MAX_READERS; i++) { + Qt::HANDLE mutex = getMutexHandle(i, false); + if (mutex) + rmutexes.append(mutex); + } + if (rmutexes.size()) { + DWORD res = WaitForMultipleObjects(rmutexes.size(), rmutexes.constData(), + TRUE, block ? INFINITE : 0); + if (res != WAIT_OBJECT_0 && res != WAIT_ABANDONED) { + if (res != WAIT_TIMEOUT) + qErrnoWarning("QtLockedFile::lock(): WaitForMultipleObjects failed"); + m_lock_mode = WriteLock; // trick unlock() to clean up - semiyucky + unlock(); + return false; + } + } + } + + m_lock_mode = mode; + return true; +} + +bool QtLockedFile::unlock() +{ + if (!isOpen()) { + qWarning("QtLockedFile::unlock(): file is not opened"); + return false; + } + + if (!isLocked()) + return true; + + if (m_lock_mode == ReadLock) { + ReleaseMutex(rmutex); + CloseHandle(rmutex); + rmutex = 0; + } + else { + foreach(Qt::HANDLE mutex, rmutexes) { + ReleaseMutex(mutex); + CloseHandle(mutex); + } + rmutexes.clear(); + ReleaseMutex(wmutex); + } + + m_lock_mode = QtLockedFile::NoLock; + return true; +} + +QtLockedFile::~QtLockedFile() +{ + if (isOpen()) + unlock(); + if (wmutex) + CloseHandle(wmutex); +} diff --git a/3rd-party/qtsingleapplication/src/qtsingleapplication.cpp b/3rd-party/qtsingleapplication/src/qtsingleapplication.cpp new file mode 100644 index 0000000..d0fb15d --- /dev/null +++ b/3rd-party/qtsingleapplication/src/qtsingleapplication.cpp @@ -0,0 +1,347 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the Qt Solutions component. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + + +#include "qtsingleapplication.h" +#include "qtlocalpeer.h" +#include + + +/*! + \class QtSingleApplication qtsingleapplication.h + \brief The QtSingleApplication class provides an API to detect and + communicate with running instances of an application. + + This class allows you to create applications where only one + instance should be running at a time. I.e., if the user tries to + launch another instance, the already running instance will be + activated instead. Another usecase is a client-server system, + where the first started instance will assume the role of server, + and the later instances will act as clients of that server. + + By default, the full path of the executable file is used to + determine whether two processes are instances of the same + application. You can also provide an explicit identifier string + that will be compared instead. + + The application should create the QtSingleApplication object early + in the startup phase, and call isRunning() to find out if another + instance of this application is already running. If isRunning() + returns false, it means that no other instance is running, and + this instance has assumed the role as the running instance. In + this case, the application should continue with the initialization + of the application user interface before entering the event loop + with exec(), as normal. + + The messageReceived() signal will be emitted when the running + application receives messages from another instance of the same + application. When a message is received it might be helpful to the + user to raise the application so that it becomes visible. To + facilitate this, QtSingleApplication provides the + setActivationWindow() function and the activateWindow() slot. + + If isRunning() returns true, another instance is already + running. It may be alerted to the fact that another instance has + started by using the sendMessage() function. Also data such as + startup parameters (e.g. the name of the file the user wanted this + new instance to open) can be passed to the running instance with + this function. Then, the application should terminate (or enter + client mode). + + If isRunning() returns true, but sendMessage() fails, that is an + indication that the running instance is frozen. + + Here's an example that shows how to convert an existing + application to use QtSingleApplication. It is very simple and does + not make use of all QtSingleApplication's functionality (see the + examples for that). + + \code + // Original + int main(int argc, char **argv) + { + QApplication app(argc, argv); + + MyMainWidget mmw; + mmw.show(); + return app.exec(); + } + + // Single instance + int main(int argc, char **argv) + { + QtSingleApplication app(argc, argv); + + if (app.isRunning()) + return !app.sendMessage(someDataString); + + MyMainWidget mmw; + app.setActivationWindow(&mmw); + mmw.show(); + return app.exec(); + } + \endcode + + Once this QtSingleApplication instance is destroyed (normally when + the process exits or crashes), when the user next attempts to run the + application this instance will not, of course, be encountered. The + next instance to call isRunning() or sendMessage() will assume the + role as the new running instance. + + For console (non-GUI) applications, QtSingleCoreApplication may be + used instead of this class, to avoid the dependency on the QtGui + library. + + \sa QtSingleCoreApplication +*/ + + +void QtSingleApplication::sysInit(const QString &appId) +{ + actWin = 0; + peer = new QtLocalPeer(this, appId); + connect(peer, SIGNAL(messageReceived(const QString&)), SIGNAL(messageReceived(const QString&))); +} + + +/*! + Creates a QtSingleApplication object. The application identifier + will be QCoreApplication::applicationFilePath(). \a argc, \a + argv, and \a GUIenabled are passed on to the QAppliation constructor. + + If you are creating a console application (i.e. setting \a + GUIenabled to false), you may consider using + QtSingleCoreApplication instead. +*/ + +QtSingleApplication::QtSingleApplication(int &argc, char **argv, bool GUIenabled) + : QApplication(argc, argv, GUIenabled) +{ + sysInit(); +} + + +/*! + Creates a QtSingleApplication object with the application + identifier \a appId. \a argc and \a argv are passed on to the + QAppliation constructor. +*/ + +QtSingleApplication::QtSingleApplication(const QString &appId, int &argc, char **argv) + : QApplication(argc, argv) +{ + sysInit(appId); +} + +#if QT_VERSION < 0x050000 + +/*! + Creates a QtSingleApplication object. The application identifier + will be QCoreApplication::applicationFilePath(). \a argc, \a + argv, and \a type are passed on to the QAppliation constructor. +*/ +QtSingleApplication::QtSingleApplication(int &argc, char **argv, Type type) + : QApplication(argc, argv, type) +{ + sysInit(); +} + + +# if defined(Q_WS_X11) +/*! + Special constructor for X11, ref. the documentation of + QApplication's corresponding constructor. The application identifier + will be QCoreApplication::applicationFilePath(). \a dpy, \a visual, + and \a cmap are passed on to the QApplication constructor. +*/ +QtSingleApplication::QtSingleApplication(Display* dpy, Qt::HANDLE visual, Qt::HANDLE cmap) + : QApplication(dpy, visual, cmap) +{ + sysInit(); +} + +/*! + Special constructor for X11, ref. the documentation of + QApplication's corresponding constructor. The application identifier + will be QCoreApplication::applicationFilePath(). \a dpy, \a argc, \a + argv, \a visual, and \a cmap are passed on to the QApplication + constructor. +*/ +QtSingleApplication::QtSingleApplication(Display *dpy, int &argc, char **argv, Qt::HANDLE visual, Qt::HANDLE cmap) + : QApplication(dpy, argc, argv, visual, cmap) +{ + sysInit(); +} + +/*! + Special constructor for X11, ref. the documentation of + QApplication's corresponding constructor. The application identifier + will be \a appId. \a dpy, \a argc, \a + argv, \a visual, and \a cmap are passed on to the QApplication + constructor. +*/ +QtSingleApplication::QtSingleApplication(Display* dpy, const QString &appId, int argc, char **argv, Qt::HANDLE visual, Qt::HANDLE cmap) + : QApplication(dpy, argc, argv, visual, cmap) +{ + sysInit(appId); +} +# endif // Q_WS_X11 +#endif // QT_VERSION < 0x050000 + + +/*! + Returns true if another instance of this application is running; + otherwise false. + + This function does not find instances of this application that are + being run by a different user (on Windows: that are running in + another session). + + \sa sendMessage() +*/ + +bool QtSingleApplication::isRunning() +{ + return peer->isClient(); +} + + +/*! + Tries to send the text \a message to the currently running + instance. The QtSingleApplication object in the running instance + will emit the messageReceived() signal when it receives the + message. + + This function returns true if the message has been sent to, and + processed by, the current instance. If there is no instance + currently running, or if the running instance fails to process the + message within \a timeout milliseconds, this function return false. + + \sa isRunning(), messageReceived() +*/ +bool QtSingleApplication::sendMessage(const QString &message, int timeout) +{ + return peer->sendMessage(message, timeout); +} + + +/*! + Returns the application identifier. Two processes with the same + identifier will be regarded as instances of the same application. +*/ +QString QtSingleApplication::id() const +{ + return peer->applicationId(); +} + + +/*! + Sets the activation window of this application to \a aw. The + activation window is the widget that will be activated by + activateWindow(). This is typically the application's main window. + + If \a activateOnMessage is true (the default), the window will be + activated automatically every time a message is received, just prior + to the messageReceived() signal being emitted. + + \sa activateWindow(), messageReceived() +*/ + +void QtSingleApplication::setActivationWindow(QWidget* aw, bool activateOnMessage) +{ + actWin = aw; + if (activateOnMessage) + connect(peer, SIGNAL(messageReceived(const QString&)), this, SLOT(activateWindow())); + else + disconnect(peer, SIGNAL(messageReceived(const QString&)), this, SLOT(activateWindow())); +} + + +/*! + Returns the applications activation window if one has been set by + calling setActivationWindow(), otherwise returns 0. + + \sa setActivationWindow() +*/ +QWidget* QtSingleApplication::activationWindow() const +{ + return actWin; +} + + +/*! + De-minimizes, raises, and activates this application's activation window. + This function does nothing if no activation window has been set. + + This is a convenience function to show the user that this + application instance has been activated when he has tried to start + another instance. + + This function should typically be called in response to the + messageReceived() signal. By default, that will happen + automatically, if an activation window has been set. + + \sa setActivationWindow(), messageReceived(), initialize() +*/ +void QtSingleApplication::activateWindow() +{ + if (actWin) { + actWin->setWindowState(actWin->windowState() & ~Qt::WindowMinimized); + actWin->raise(); + actWin->activateWindow(); + } +} + + +/*! + \fn void QtSingleApplication::messageReceived(const QString& message) + + This signal is emitted when the current instance receives a \a + message from another instance of this application. + + \sa sendMessage(), setActivationWindow(), activateWindow() +*/ + + +/*! + \fn void QtSingleApplication::initialize(bool dummy = true) + + \obsolete +*/ diff --git a/3rd-party/qtsingleapplication/src/qtsingleapplication.h b/3rd-party/qtsingleapplication/src/qtsingleapplication.h new file mode 100644 index 0000000..049406f --- /dev/null +++ b/3rd-party/qtsingleapplication/src/qtsingleapplication.h @@ -0,0 +1,105 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the Qt Solutions component. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QTSINGLEAPPLICATION_H +#define QTSINGLEAPPLICATION_H + +#include + +class QtLocalPeer; + +#if defined(Q_OS_WIN) +# if !defined(QT_QTSINGLEAPPLICATION_EXPORT) && !defined(QT_QTSINGLEAPPLICATION_IMPORT) +# define QT_QTSINGLEAPPLICATION_EXPORT +# elif defined(QT_QTSINGLEAPPLICATION_IMPORT) +# if defined(QT_QTSINGLEAPPLICATION_EXPORT) +# undef QT_QTSINGLEAPPLICATION_EXPORT +# endif +# define QT_QTSINGLEAPPLICATION_EXPORT __declspec(dllimport) +# elif defined(QT_QTSINGLEAPPLICATION_EXPORT) +# undef QT_QTSINGLEAPPLICATION_EXPORT +# define QT_QTSINGLEAPPLICATION_EXPORT __declspec(dllexport) +# endif +#else +# define QT_QTSINGLEAPPLICATION_EXPORT +#endif + +class QT_QTSINGLEAPPLICATION_EXPORT QtSingleApplication : public QApplication +{ + Q_OBJECT + +public: + QtSingleApplication(int &argc, char **argv, bool GUIenabled = true); + QtSingleApplication(const QString &id, int &argc, char **argv); +#if QT_VERSION < 0x050000 + QtSingleApplication(int &argc, char **argv, Type type); +# if defined(Q_WS_X11) + QtSingleApplication(Display* dpy, Qt::HANDLE visual = 0, Qt::HANDLE colormap = 0); + QtSingleApplication(Display *dpy, int &argc, char **argv, Qt::HANDLE visual = 0, Qt::HANDLE cmap= 0); + QtSingleApplication(Display* dpy, const QString &appId, int argc, char **argv, Qt::HANDLE visual = 0, Qt::HANDLE colormap = 0); +# endif // Q_WS_X11 +#endif // QT_VERSION < 0x050000 + + bool isRunning(); + QString id() const; + + void setActivationWindow(QWidget* aw, bool activateOnMessage = true); + QWidget* activationWindow() const; + + // Obsolete: + void initialize(bool dummy = true) + { isRunning(); Q_UNUSED(dummy) } + +public Q_SLOTS: + bool sendMessage(const QString &message, int timeout = 5000); + void activateWindow(); + + +Q_SIGNALS: + void messageReceived(const QString &message); + + +private: + void sysInit(const QString &appId = QString()); + QtLocalPeer *peer; + QWidget *actWin; +}; + +#endif // QTSINGLEAPPLICATION_H diff --git a/3rd-party/qtsingleapplication/src/qtsingleapplication.pri b/3rd-party/qtsingleapplication/src/qtsingleapplication.pri new file mode 100644 index 0000000..6f2bced --- /dev/null +++ b/3rd-party/qtsingleapplication/src/qtsingleapplication.pri @@ -0,0 +1,17 @@ +include(../common.pri) +INCLUDEPATH += $$PWD +DEPENDPATH += $$PWD +QT *= network +greaterThan(QT_MAJOR_VERSION, 4): QT *= widgets + +qtsingleapplication-uselib:!qtsingleapplication-buildlib { + LIBS += -L$$QTSINGLEAPPLICATION_LIBDIR -l$$QTSINGLEAPPLICATION_LIBNAME +} else { + SOURCES += $$PWD/qtsingleapplication.cpp $$PWD/qtlocalpeer.cpp + HEADERS += $$PWD/qtsingleapplication.h $$PWD/qtlocalpeer.h +} + +win32 { + contains(TEMPLATE, lib):contains(CONFIG, shared):DEFINES += QT_QTSINGLEAPPLICATION_EXPORT + else:qtsingleapplication-uselib:DEFINES += QT_QTSINGLEAPPLICATION_IMPORT +} diff --git a/3rd-party/qtsingleapplication/src/qtsinglecoreapplication.cpp b/3rd-party/qtsingleapplication/src/qtsinglecoreapplication.cpp new file mode 100644 index 0000000..5634537 --- /dev/null +++ b/3rd-party/qtsingleapplication/src/qtsinglecoreapplication.cpp @@ -0,0 +1,149 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the Qt Solutions component. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + + +#include "qtsinglecoreapplication.h" +#include "qtlocalpeer.h" + +/*! + \class QtSingleCoreApplication qtsinglecoreapplication.h + \brief A variant of the QtSingleApplication class for non-GUI applications. + + This class is a variant of QtSingleApplication suited for use in + console (non-GUI) applications. It is an extension of + QCoreApplication (instead of QApplication). It does not require + the QtGui library. + + The API and usage is identical to QtSingleApplication, except that + functions relating to the "activation window" are not present, for + obvious reasons. Please refer to the QtSingleApplication + documentation for explanation of the usage. + + A QtSingleCoreApplication instance can communicate to a + QtSingleApplication instance if they share the same application + id. Hence, this class can be used to create a light-weight + command-line tool that sends commands to a GUI application. + + \sa QtSingleApplication +*/ + +/*! + Creates a QtSingleCoreApplication object. The application identifier + will be QCoreApplication::applicationFilePath(). \a argc and \a + argv are passed on to the QCoreAppliation constructor. +*/ + +QtSingleCoreApplication::QtSingleCoreApplication(int &argc, char **argv) + : QCoreApplication(argc, argv) +{ + peer = new QtLocalPeer(this); + connect(peer, SIGNAL(messageReceived(const QString&)), SIGNAL(messageReceived(const QString&))); +} + + +/*! + Creates a QtSingleCoreApplication object with the application + identifier \a appId. \a argc and \a argv are passed on to the + QCoreAppliation constructor. +*/ +QtSingleCoreApplication::QtSingleCoreApplication(const QString &appId, int &argc, char **argv) + : QCoreApplication(argc, argv) +{ + peer = new QtLocalPeer(this, appId); + connect(peer, SIGNAL(messageReceived(const QString&)), SIGNAL(messageReceived(const QString&))); +} + + +/*! + Returns true if another instance of this application is running; + otherwise false. + + This function does not find instances of this application that are + being run by a different user (on Windows: that are running in + another session). + + \sa sendMessage() +*/ + +bool QtSingleCoreApplication::isRunning() +{ + return peer->isClient(); +} + + +/*! + Tries to send the text \a message to the currently running + instance. The QtSingleCoreApplication object in the running instance + will emit the messageReceived() signal when it receives the + message. + + This function returns true if the message has been sent to, and + processed by, the current instance. If there is no instance + currently running, or if the running instance fails to process the + message within \a timeout milliseconds, this function return false. + + \sa isRunning(), messageReceived() +*/ + +bool QtSingleCoreApplication::sendMessage(const QString &message, int timeout) +{ + return peer->sendMessage(message, timeout); +} + + +/*! + Returns the application identifier. Two processes with the same + identifier will be regarded as instances of the same application. +*/ + +QString QtSingleCoreApplication::id() const +{ + return peer->applicationId(); +} + + +/*! + \fn void QtSingleCoreApplication::messageReceived(const QString& message) + + This signal is emitted when the current instance receives a \a + message from another instance of this application. + + \sa sendMessage() +*/ diff --git a/3rd-party/qtsingleapplication/src/qtsinglecoreapplication.h b/3rd-party/qtsingleapplication/src/qtsinglecoreapplication.h new file mode 100644 index 0000000..b87fffe --- /dev/null +++ b/3rd-party/qtsingleapplication/src/qtsinglecoreapplication.h @@ -0,0 +1,71 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the Qt Solutions component. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QTSINGLECOREAPPLICATION_H +#define QTSINGLECOREAPPLICATION_H + +#include + +class QtLocalPeer; + +class QtSingleCoreApplication : public QCoreApplication +{ + Q_OBJECT + +public: + QtSingleCoreApplication(int &argc, char **argv); + QtSingleCoreApplication(const QString &id, int &argc, char **argv); + + bool isRunning(); + QString id() const; + +public Q_SLOTS: + bool sendMessage(const QString &message, int timeout = 5000); + + +Q_SIGNALS: + void messageReceived(const QString &message); + + +private: + QtLocalPeer* peer; +}; + +#endif // QTSINGLECOREAPPLICATION_H diff --git a/3rd-party/qtsingleapplication/src/qtsinglecoreapplication.pri b/3rd-party/qtsingleapplication/src/qtsinglecoreapplication.pri new file mode 100644 index 0000000..d2d6cc3 --- /dev/null +++ b/3rd-party/qtsingleapplication/src/qtsinglecoreapplication.pri @@ -0,0 +1,10 @@ +INCLUDEPATH += $$PWD +DEPENDPATH += $$PWD +HEADERS += $$PWD/qtsinglecoreapplication.h $$PWD/qtlocalpeer.h +SOURCES += $$PWD/qtsinglecoreapplication.cpp $$PWD/qtlocalpeer.cpp + +QT *= network + +win32:contains(TEMPLATE, lib):contains(CONFIG, shared) { + DEFINES += QT_QTSINGLECOREAPPLICATION_EXPORT=__declspec(dllexport) +} diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..6295ce2 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,365 @@ +# +# Copyright 2012, 2013, 2014 Thomas Schöps +# Copyright 2012-2016 Kai Pastor +# +# This file is part of OpenOrienteering. +# +# OpenOrienteering is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# OpenOrienteering is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with OpenOrienteering. If not, see . + +cmake_minimum_required(VERSION 2.8.12 FATAL_ERROR) +cmake_policy(SET CMP0020 OLD) +if(CMAKE_VERSION VERSION_GREATER 2.9) +cmake_policy(SET CMP0026 OLD) +cmake_policy(SET CMP0048 OLD) +endif() +list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake") + +include(FeatureSummary) + +# Project declaration + +project(Mapper) + +set(Mapper_COPYRIGHT "(C) 2012-2016 OpenOrienteering developers") + +# All version components must be integers. +# We use Mapper_VERSION_PATCH >= 99 to mark development builds. +set(Mapper_VERSION_MAJOR 0) +set(Mapper_VERSION_MINOR 6) +if(NOT Mapper_VERSION_PATCH) + # This can be configured when running cmake + set(Mapper_VERSION_PATCH 7) +endif() + +set(MAPPER_VERSION_PRI "${PROJECT_SOURCE_DIR}/oo-mapper-version.pri") +file(READ "${MAPPER_VERSION_PRI}" current) +string(MD5 file_md5 "${current}") +set(output "# Generated in CMakeLists.txt, do not edit here. +Mapper_VERSION_MAJOR = ${Mapper_VERSION_MAJOR} +Mapper_VERSION_MINOR = ${Mapper_VERSION_MINOR} +Mapper_VERSION_PATCH = ${Mapper_VERSION_PATCH} +") +string(MD5 output_md5 "${output}") +if(NOT "${output_md5}" STREQUAL "${file_md5}") + file(WRITE "${MAPPER_VERSION_PRI}" "${output}") +endif() + +set(android_manifest "${PROJECT_SOURCE_DIR}/android/AndroidManifest.xml") +file(READ "${android_manifest}" current) +if(NOT current MATCHES " android:versionName=.${Mapper_VERSION_MAJOR}\\.${Mapper_VERSION_MINOR}\\.${Mapper_VERSION_PATCH}. ") + set(android_version_name "${Mapper_VERSION_MAJOR}.${Mapper_VERSION_MINOR}.${Mapper_VERSION_PATCH}") + math(EXPR android_version_int "${Mapper_VERSION_MAJOR} * 10000 + ${Mapper_VERSION_MINOR} * 100 + ${Mapper_VERSION_PATCH}") + string(REGEX REPLACE "( android:versionName=.)[0-9]*\\.[0-9]*\\.[0-9]*(. )" "\\1${android_version_name}\\2" output "${current}") + string(REGEX REPLACE "( android:versionCode=.)[0-9]*(. )" "\\1${android_version_int}\\2" output "${output}") + file(WRITE "${android_manifest}" "${output}") +endif() + +if(${CMAKE_CURRENT_BINARY_DIR} STREQUAL ${PROJECT_SOURCE_DIR}) + message(AUTHOR_WARNING "In-source builds are discouraged for development.") +endif() + +# Build configuration options + +if(NOT CMAKE_BUILD_TYPE) + SET(CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING + "Type of build, options are: None Debug Release RelWithDebInfo MinSizeRel." + FORCE) +endif(NOT CMAKE_BUILD_TYPE) + +if(APPLE) + SET(Mapper_MACOSX_VERSION "10.7" CACHE STRING + "Minimum Mac OS X version to build for, recommended: 10.7") +endif() + +option(Mapper_TRANSLATIONS_EMBEDDED "Embed all translations in the program executable") + +option(Mapper_DEBUG_TRANSLATIONS "Debug missing translations" OFF) + +set(Mapper_BUILD_CLIPPER_DEFAULT ON) +if(WIN32 OR APPLE) + set(Mapper_BUILD_PROJ_DEFAULT ON) + set(Mapper_BUILD_GDAL_DEFAULT ON) + set(Mapper_BUILD_QT_DEFAULT ON) + set(Mapper_BUILD_DOXYGEN_DEFAULT ON) + set(Mapper_BUILD_PACKAGE_DEFAULT ON) +else() + set(Mapper_BUILD_PROJ_DEFAULT OFF) + set(Mapper_BUILD_GDAL_DEFAULT OFF) + set(Mapper_BUILD_QT_DEFAULT ON) + set(Mapper_BUILD_DOXYGEN_DEFAULT OFF) + set(Mapper_BUILD_PACKAGE_DEFAULT OFF) +endif() + +option(Mapper_BUILD_CLIPPER "Build the Clipper package from source" ${Mapper_BUILD_CLIPPER_DEFAULT}) + +option(Mapper_BUILD_PROJ "Build the Proj library from source" ${Mapper_BUILD_PROJ_DEFAULT}) + +option(Mapper_BUILD_GDAL "Build the GDAL library" ${Mapper_BUILD_GDAL_DEFAULT}) + +option(Mapper_USE_GDAL "Use the GDAL library" ${Mapper_BUILD_GDAL}) + +option(Mapper_BUILD_QT "Build the Qt library from source" ${Mapper_BUILD_QT_DEFAULT}) + +option(Mapper_BUILD_DOXYGEN "Build the doxygen tool from source" ${Mapper_BUILD_DOXYGEN_DEFAULT}) + +if(CMAKE_BUILD_TYPE MATCHES Release|MinSizeRel|RelWithDebInfo) + set(Mapper_DEVELOPMENT_BUILD_DEFAULT OFF) +else() + set(Mapper_DEVELOPMENT_BUILD_DEFAULT ON) +endif() +option(Mapper_DEVELOPMENT_BUILD "Configure development build (loading resource from the build directory)" ${Mapper_DEVELOPMENT_BUILD_DEFAULT}) +mark_as_advanced(Mapper_DEVELOPMENT_BUILD) + +option(Mapper_AUTORUN_SYSTEM_TESTS "Run the system tests as part of the Mapper_Test target" ${Mapper_DEVELOPMENT_BUILD}) +option(Mapper_AUTORUN_MANUAL_TESTS "Run the system tests as part of the Mapper_Test target" OFF) +mark_as_advanced(Mapper_AUTORUN_SYSTEM_TESTS Mapper_AUTORUN_MANUAL_TESTS) + +option(Mapper_BUILD_PACKAGE "Create a target for building packages" ${Mapper_BUILD_PACKAGE_DEFAULT}) +option(Mapper_PACKAGE_PROJ "Include all required Proj components in the packages" ${Mapper_BUILD_PROJ}) +option(Mapper_PACKAGE_GDAL "Include all required GDAL components in the packages" ${Mapper_BUILD_GDAL}) +option(Mapper_PACKAGE_QT "Include all required Qt components in the packages" ${Mapper_BUILD_QT}) +option(Mapper_PACKAGE_ASSISTANT "Include Qt Assistant in the packages" ${Mapper_BUILD_QT}) +option(Mapper_PACKAGE_LINGUIST "Build a Qt Linguist package" ${Mapper_BUILD_PACKAGE_DEFAULT}) +mark_as_advanced(Mapper_BUILD_PACKAGE Mapper_PACKAGE_QT Mapper_PACKAGE_ASSISTANT Mapper_PACKAGE_PROJ Mapper_PACKAGE_LINGUIST) + +unset(Mapper_PACKAGE_LIBRARIES CACHE) # Legacy + + +# Installation configuration + +set(Mapper_PACKAGE_NAME "openorienteering-mapper" CACHE STRING + "The package name" +) + +# These value are used for the DESTINATION parameter of the install command +# and must not be empty. +if(WIN32 AND BIN_INSTALL_DIR) + set(MAPPER_RUNTIME_DESTINATION "${BIN_INSTALL_DIR}") + set(MAPPER_LIBRARY_DESTINATION "${LIB_INSTALL_DIR}") + set(MAPPER_DATA_DESTINATION "${SHARE_INSTALL_DIR}/${Mapper_PACKAGE_NAME}") + set(MAPPER_ABOUT_DESTINATION "${SHARE_INSTALL_DIR}/doc/${Mapper_PACKAGE_NAME}") +elseif(WIN32) + set(MAPPER_RUNTIME_DESTINATION .) + set(MAPPER_LIBRARY_DESTINATION .) + set(MAPPER_DATA_DESTINATION .) + set(MAPPER_ABOUT_DESTINATION "doc") +elseif(APPLE) + set(MAPPER_RUNTIME_DESTINATION .) + set(MAPPER_LIBRARY_DESTINATION .) + set(MAPPER_DATA_DESTINATION "Mapper.app/Contents/Resources") + set(MAPPER_ABOUT_DESTINATION "Mapper.app/Contents/Resources") +else() # LINUX and alike + set(MAPPER_RUNTIME_DESTINATION "/usr/bin") + set(MAPPER_LIBRARY_DESTINATION "/usr/lib/${Mapper_PACKAGE_NAME}") + set(MAPPER_DATA_DESTINATION "/usr/share/${Mapper_PACKAGE_NAME}") + set(MAPPER_ABOUT_DESTINATION "/usr/share/doc/${Mapper_PACKAGE_NAME}") +endif() + +if(CMAKE_CROSSCOMPILING) + message(STATUS "Crosscompiling, host: ${CMAKE_HOST_SYSTEM_NAME}, target: ${CMAKE_SYSTEM_NAME}") +endif() + + +# Build definitons + +if(CMAKE_VERSION VERSION_GREATER 3.0.2) + set(CMAKE_CXX_STANDARD 14) + set(CMAKE_CXX_STANDARD_REQUIRED FALSE) +else() + include(CheckCXXCompilerFlag) + check_cxx_compiler_flag("-std=c++11" std_cxx11) + if(NOT std_cxx11) + check_cxx_compiler_flag("-std=c++0x" std_cxx0x) + endif() + if(std_cxx11) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") + elseif(std_cxx0x) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x") + elseif(CMAKE_COMPILER_IS_GNUXX) + message(FATAL_ERROR "The compiler does not support C++11.") + else() + message(FATAL_ERROR "The compiler support for C++11 is not known.") + endif() +endif() + +if(APPLE AND Mapper_MACOSX_VERSION) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++ -mmacosx-version-min=${Mapper_MACOSX_VERSION}") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mmacosx-version-min=${Mapper_MACOSX_VERSION}") + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -mmacosx-version-min=${Mapper_MACOSX_VERSION}") +endif() + +if(CMAKE_COMPILER_IS_GNUCXX) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wpedantic -Wextra") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c99 -Wall -Wpedantic") +endif() + +add_custom_target(Mapper_prerequisites + SOURCES # Extra files to be shown in IDE + INSTALL.md + README.md + oo-mapper.pro + ${MAPPER_VERSION_PRI} +) +set(Mapper_prerequisites_FOUND TRUE) + +if(Mapper_BUILD_CLIPPER) + add_subdirectory(3rd-party/clipper) + add_feature_info(Mapper_BUILD_CLIPPER 1 "version: ${CLIPPER_VERSION}") + add_library(Polyclipping::Polyclipping ALIAS polyclipping) +else() + find_package(Polyclipping 6.1.3 MODULE REQUIRED) +endif() + +if(Mapper_BUILD_PROJ) + add_subdirectory(3rd-party/proj) + add_dependencies(Mapper_prerequisites Proj) + add_feature_info(Mapper_BUILD_PROJ 1 "version: ${PROJ_VERSION}") + find_package(PROJ4 MODULE QUIET) +else() + find_package(PROJ4 CONFIG QUIET) + if(NOT TARGET PROJ4::proj) + set(PROJ4_FOUND false) + find_package(PROJ4 MODULE REQUIRED) + endif() +endif() +if(NOT PROJ4_FOUND) + set(Mapper_prerequisites_FOUND FALSE) +endif() + +if(Mapper_BUILD_GDAL) + add_subdirectory(3rd-party/gdal) + add_dependencies(Mapper_prerequisites GDAL) + if(TARGET Proj) + add_dependencies(GDAL Proj) + endif() + if(NOT GDAL_FOUND) + set(Mapper_prerequisites_FOUND FALSE) + endif() + add_feature_info(Mapper_BUILD_GDAL 1 "version: ${GDAL_VERSION}") +elseif(Mapper_USE_GDAL) + find_package(GDAL REQUIRED) +endif() + +if(Mapper_BUILD_QT) + add_subdirectory(3rd-party/qt5) + add_dependencies(Mapper_prerequisites Qt5) + list(INSERT CMAKE_PREFIX_PATH 0 "${QT5_DIR}") + find_package(Qt5Core QUIET PATHS "${QT5_DIR}" NO_DEFAULT_PATH) + if(NOT Qt5Core_FOUND) + set(Mapper_prerequisites_FOUND FALSE) + endif() + add_feature_info(Mapper_BUILD_QT 1 "version: ${QT5_VERSION}") +endif() + +if(Mapper_BUILD_DOXYGEN) + add_subdirectory(3rd-party/doxygen) + add_feature_info(Mapper_BUILD_DOXYGEN 1 "version: ${DOXYGEN_VERSION}") +endif() + +if(Mapper_prerequisites_FOUND) + +if(UNIX AND NOT APPLE) +# set(CMAKE_INSTALL_RPATH "\$ORIGIN/../lib/${Mapper_PACKAGE_NAME}/lib") + set(CMAKE_INSTALL_RPATH "${MAPPER_LIBRARY_DESTINATION}/lib") +endif() + +add_definitions(-D_USE_MATH_DEFINES -DUNICODE) + +if(Mapper_DEVELOPMENT_BUILD) + add_definitions(-DMAPPER_DEVELOPMENT_BUILD) + include(EnableSanitize) + enable_sanitize(address undefined) + configure_file(suppress.txt.in suppress.txt COPYONLY) +else() + add_definitions(-DQT_NO_DEBUG -DQT_NO_DEBUG_OUTPUT -DQT_NO_WARNING_OUTPUT -DNDEBUG) +endif() + +if(NOT Mapper_VERSION_PATCH LESS 99) + set(Mapper_VERSION_DISPLAY "unstable ${Mapper_VERSION_MAJOR}.${Mapper_VERSION_MINOR}.${Mapper_VERSION_PATCH}") +else() + set(Mapper_VERSION_DISPLAY "${Mapper_VERSION_MAJOR}.${Mapper_VERSION_MINOR}.${Mapper_VERSION_PATCH}") +endif() + +# Subdirectories + +add_subdirectory("doc/licensing") +add_subdirectory("doc/manual") +add_subdirectory("examples") +add_subdirectory("symbol sets") +add_subdirectory("translations") +add_subdirectory("3rd-party/qbezier") +add_subdirectory("3rd-party/qtsingleapplication") +if (Mapper_USE_GDAL) + add_subdirectory("src/gdal") +endif() +add_subdirectory("src/libocad") +add_subdirectory("src/printsupport") +add_subdirectory("src") +add_subdirectory("packaging") +if(CMAKE_CROSSCOMPILING) + add_custom_target(TEST_WARNING ALL + COMMENT "Crosscompiling, skipping all tests") + add_dependencies(TEST_WARNING Mapper) +else() + enable_testing() + add_subdirectory("test") +endif() + +foreach(qt5_module Core Gui Network PrintSupport Test Widgets Xml) + if (TARGET Qt5::${qt5_module} AND TARGET Qt5) + add_dependencies(Qt5::${qt5_module} Qt5) + endif() +endforeach() + +install(FILES COPYING + DESTINATION "${MAPPER_ABOUT_DESTINATION}" +) +configure_file(COPYING COPYING COPYONLY) + +set(MAPPER_SUPERBUILD 0 CACHE INTERNAL "Flag to avoid superbuild loops." FORCE) + +elseif(MAPPER_SUPERBUILD) + + set(MAPPER_SUPERBUILD 0 CACHE INTERNAL "Flag to avoid superbuild loops." FORCE) + message(FATAL_ERROR "Mapper prerequisites marked as build but not found by cmake re-run.") + +else() # NOT Mapper_prerequisites_FOUND AND NOT MAPPER_SUPERBUILD + + if("${CMAKE_GENERATOR}" MATCHES "Makefiles" OR + "${CMAKE_EXTRA_GENERATOR}" MATCHES "Makefiles") + # use magic MAKE macro + set(_build_tool "\$(MAKE)") + else() + set(_build_tool ${CMAKE_BUILD_TOOL}) + endif() + add_custom_target(Mapper_superbuild ALL + COMMAND "${CMAKE_COMMAND}" . -DMAPPER_SUPERBUILD=1 + COMMAND ${_build_tool} + VERBATIM + ) + add_dependencies(Mapper_superbuild Mapper_prerequisites) + +endif() + +add_subdirectory("doc/api") +add_subdirectory("packaging/src") + +feature_summary(WHAT ALL) + +string(TOUPPER "${CMAKE_BUILD_TYPE}" type) +foreach(lang CXX C) + foreach(i "" _${type}) + message(STATUS "CMAKE_${lang}_FLAGS${i}: ${CMAKE_${lang}_FLAGS${i}}") + endforeach() +endforeach() diff --git a/COPYING b/COPYING new file mode 100644 index 0000000..94a9ed0 --- /dev/null +++ b/COPYING @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/INSTALL.md b/INSTALL.md new file mode 100644 index 0000000..2cbbb06 --- /dev/null +++ b/INSTALL.md @@ -0,0 +1,218 @@ +## General + +This document is about building OpenOrienteering Mapper from source code. + +The general build process prerequisites are: + - A supported platform: + - Mac OS X 10.10 (Yosemite). Mac OS X 10.7 or newer may work. + - Linux. Ubuntu 14.04 is known to work. + - The OpenOrienteering Mapper source code. + - CMake >= 2.8.12. + CMake is available from http://www.cmake.org/. + - A supported C++ compiler toolchain. C++11 is mandatory. + +See below for platform-specific details and build instructions. + + +## Qt Library + +This program uses the Qt library from http://www.qt.io which is released +under the terms of the GNU General Public License, Version 3. +The program needs at least Qt 5.2. Qt 5.5.1 is the recommended version. +By default CMake build settings for OS X and Windows, +a special OpenOrienteering source package of Qt 5.5.1 will be downloaded +and built as part of the build process. +You can change the cmake option `Mapper_BUILD_QT` to adjust this. + + +## Clipper Library + +The program uses the clipper code library from +http://www.angusj.com/delphi/clipper.php / +http://sourceforge.net/projects/polyclipping/ +which is released under the terms of the Boost Software License, Version 1.0. +The program is known to work with release 6.1.3a and not compile with releases +5.x.x or earlier. By default build settings, clipper 6.1.3a will be downloaded +and built as part of the build process. +You can change the cmake option `Mapper_BUILD_CLIPPER` to adjust this. + + +## PROJ.4 Cartographic Projections Library + +The program uses the PROJ.4 Cartographic Projections Library from +http://trac.osgeo.org/proj/ which is released under permissive license terms. +The program is known to work with the releases 4.8.0 (as contained in Ubuntu +14.04), 4.9.1 and 4.9.2. By default build settings, proj 4.9.2 will be +downloaded and built as part of the build process. On Linux, default settings +will use the installed proj library. +You can change the cmake option `Mapper_BUILD_PROJ` to adjust this. + + +## Getting the Source + +Download a zip or tar.gz Source code archive from + +https://github.com/OpenOrienteering/mapper/releases + +and unpack it, or checkout the source code with git: + + +``` +git clone https://github.com/OpenOrienteering/mapper.git +``` + +The directory created by unpacking or checkout will be referred to as the +source directory (`SOURCE_DIR`). + + +## Compiling on Linux + +The standard g++ compiler from a recent distribution should work. The Ubuntu +14.04 g++ is known to work. Make sure that the development packages of the +PROJ.4 library and of CUPS are installed. For a Ubuntu or Debian system, install +`libproj-dev` and `libcups2-dev`. + +For using the Qt libraries provided by the repositories, the following packages +need to be installed: +`qt5-default` (>= 5.2), `qttools5-dev`, `qttools5-dev-tools`, `libqt5sql5-sqlite` + +Open a terminal, and create a build directory, e.g. as subdirectory build in +the source directory, and change to that directory. From the build directory, +configure and build like this: + +``` +cmake PATH/TO/SOURCE_DIR +``` + +Now you may start the build process by running + +``` +make +``` + + +## Compiling on OS X + +The supported compiler is clang from the Command Line Tools for Xcode. +XCode 7.0.1 and the accompanying command line tools are known to work. + +Now create a build directory, e.g. as subdirectory build in the source +directory, and change to that directory. In the build directory, configure +and build like this: + +``` +cmake PATH/TO/SOURCE_DIR +``` + +Now you may start the build process by running + +``` +make +``` + +and generate a DragNDrop package by + +``` +make package +``` + + +## Cross-Compiling on Linux for Windows + +Some linux distributions may offer cross compiler packages based on MinGW or +MinGW-w64 (for Ubuntu: g++-mingw-w64 et al.), and even NSIS/makensis is +available. MXE.cc provides an alternative cross-compilation environment + +For MinGW-w64 i686 (32 bit) builds, configure the build with + +``` +cmake PATH/TO/SOURCE_DIR -DCMAKE_TOOLCHAIN_FILE=PATH/TO/SOURCE_DIR/cmake/toolchain/i686-w64-mingw32 +``` + +and proceed with + +``` +make +``` + + +## Cross-Compiling on Linux for Android + +In addition to the general build process prerequisites, you need: + - the Android SDK + - the Android NDK + - Qt 5.5.1 for Android which includes Qt Creator + +When downloading packages for specific Android API levels, +keep in mind that Qt5 requires at least API Level 9 to work, and apps +built for the armeabi-v7a ABI require at least an emulator image of API +level 14 to work with the emulator. + +The build of OpenOrienteering Mapper for Android is controlled by qmake and the +oo-mapper.pro file. The easist way to do the build is using Qt Creator where you +can define different "kits" representing different types of target devices. +Qt Creator takes care of switching between debug and release configurations. +For setting up the kits, see the Qt Creator documentation: + +http://doc.qt.io/qtcreator/creator-targets.html + +Mapper's dependencies, such as the PROJ.4 library, are build by cmake, based on +the exisiting CMakeList.txt files and Qt Creator's kit settings. + +For development, you may use the Android Qt kits which come with Qt Creator. +For official releases, you need to build the Qt libraries from the sources. +This can be done by loading 3rd-party/qt5/qt5.pro in Qt Creator, and building +it using a kit for Android. The resulting Qt kit can be added to Qt Creator +as another Qt version via Tools > Options... > Build & Run > Qt Versions. +Qt Creator will automatically create a kit for this, and then you can use this +kit to build official OpenOrienteering releases. +For general Qt5 for Android build instructions, see: + +http://qt-project.org/wiki/Qt5ForAndroidBuilding + + +## Binary Package Distribution + +Distributing binary code under open source licenses creates certain legal +obligations, such as the distribution of the corresponding source code and +build instructions for GPL licensed binaries. This is how to do this correctly +for Mapper. + +Official release packages need to be build from an official source code archive. +This is to make sure that every user can indeed get all required sources for the +binary release. + +Release packages will include the Qt libraries and the Qt assistant executable. +That is why release packages need to build the Qt components from the Qt source +code in the particular version which we distribute along with our source. The +Mapper default build configuration will normally take care of this. + +The same principle applies to the other third party components (PROJ.4, +Clipper). If the compiler requires distribution of additional libraries, such +as a libstdc++ DLL, these binaries' licenses must be respected as well, which +may add additional source code and build instruction distribution requirements. + +The build shall start from a fresh build directory. The build shall be in +release mode, i.e. with `-DCMAKE_BUILD_TYPE=Release`. Synopsis: + +``` +tar xvzf openorienteering-mapper_X.Y.Z-src.tgz +cd openorienteering-mapper_X.Y.Z +mkdir build +cd build +cmake .. -DCMAKE_BUILD_TYPE=Release +make +``` + +The actual package may be built by `make package`. However, this is used +(i.e. tested) only for OS X at the moment. +Android packages are built in Qt Creator using the provided `oo-mapper.pro` file. +Windows and Linux packages are regularly build on +https://build.opensuse.org/project/show/home:dg0yt, so proper package recipes for +common distributions and package managers can be found there. + +Packaging with cmake is not enabled by default for Linux. Add `-DMapper_BUILD_PACKAGE=1` +to change this. As already stated, this is untested, and you might need to look for +additional tweaks. + + diff --git a/README.md b/README.md new file mode 100644 index 0000000..48953ce --- /dev/null +++ b/README.md @@ -0,0 +1,46 @@ +# OpenOrienteering Mapper + +![Mapper Screenshot](http://openorienteering.github.io/mapper-manual/pages/images/main_window.png) + +OpenOrienteering Mapper is an orienteering mapmaking program and provides +a free and open source alternative to existing commercial software. +OpenOrienteering Mapper runs on Android, Windows, Mac OS X and Linux. + + - [Mapper Homepage](http://www.openorienteering.org/apps/mapper/) + - [Manual](http://www.openorienteering.org/mapper-manual/) + - [Downloads](https://github.com/OpenOrienteering/mapper/releases) + - [OpenOrienteering Blog](http://www.openorienteering.org/) + + +## Reporting Issues and Asking for Help + +Issues and possible improvements can be posted to our public [Ticket system](https://github.com/OpenOrienteering/mapper/issues). +Please make sure you provide all relevant information about your problem or idea. + + +## Contributing + +### Translating + +Translations can be edited online on [Weblate](https://hosted.weblate.org/projects/openorienteering/mapper/). You can register/login with your Github account. Find out more about translation in our [wiki](https://github.com/OpenOrienteering/mapper/wiki/Translation). + + +### Writing Documentation + +The Mapper manual lives in its [own repository](https://github.com/OpenOrienteering/mapper-manual) +which contains all information for you to get started. + + +### Writing Code + +For building Mapper from source see [`INSTALL.md`](https://github.com/OpenOrienteering/mapper/blob/master/INSTALL.md). +Pull requests are very welcome. + + - [Issue tracker](https://github.com/OpenOrienteering/mapper/issues) + - [API documentation](http://www.openorienteering.org/api-docs/mapper/) + - [Developer wiki](https://github.com/OpenOrienteering/mapper/wiki) + + +## License + +Mapper is licensed under the [GNU GENERAL PUBLIC LICENSE Version 3](https://www.gnu.org/licenses/gpl.html). diff --git a/android/AndroidManifest.xml b/android/AndroidManifest.xml new file mode 100644 index 0000000..626b5a2 --- /dev/null +++ b/android/AndroidManifest.xml @@ -0,0 +1,64 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/android/res/drawable-hdpi/icon.png b/android/res/drawable-hdpi/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..ed28510966760e2f541878604462bbc38ca72cdd GIT binary patch literal 11851 zcmV-RF0|2!P)x}E?4AOJ~3 zK~#9!?Yw7{T*aOL{i&Nf&h$j(oIs!zQ6Pdv1}9(*HpXj%SsU*k8=QzX2IIx{+JFsf zlWZ2lV%EY0111?0O-@39P);Lhq|t<)p6PT`RXs0m&mbXT@IL4N;yLHJXZqYe(|xO| zzxAtM{8qvLfBoG{0OGE@?mBk*^y%}J)>3P2jDDy!3P5WR0?-Hq8V$Pfc=GoTUAocU z$a8vRC|V)J-)~Lxzw1v3kv!XIKj~d-$8o~zufP7!zxmB?HXLxk0lfbD>w3p$EkNwC z#~!Eewbx!>(pv9|pa7*5aTpVaAxcYxFtKb4)3z~91A&45D6=6zX@ypbIEsm*2o+0& zAuw$l+qN-G6JdyCA~ZWqfYurnOO#S*trCz07^aD7m@opu4nS(HP_pri8fi~pSO$hL zF-${_A3uJb5MuoiM;x&W_7;F)7?D;nVHoO>d6H5Q_&!zNryhlbag0DCv_PZKfMFVV zmP5vI@lqa!VK5>9S~mo*F<7M}fge!y>(ruRu*9&Ta3YEQ;tI^yRv|ZUM^}A>=U|R+L(H3w zIDBsgZ4SdW6Gl%g^;Oi9IfrbT9H7wWZDsIDILa1~q!qqBf9ZyGF| zOR2-A);~aNTN|crVVMR&5D>dI>4)A#FI!8>vJ&KDiFee#49)DsaU3kmz%&h{RQT00 zHB->^_%bSQts(8XiGrvFWKKJZ%7g-FZH%auYPBkMSiyP+fb^&c$1-MMdmp}Qk$Ytg zeLwgu;r4-1aUXeJXy6Zj#mr~u`0nY{KYJ+Ky0_Ba*@5f2qia2kLWcT_RBS=}#v*+e z{2G75HZa6a%Tl1>-ls9s9<67eMD&&8>E67Vu@lCFZ4<|mz}EPWzskS^&thdfv{dLQ zBK!0k*o!Ztzh^t06UHU|h5-ZhDsAPMu5+%!$frRm0HT2s_I|Udw0X!lM#ixP7{2c} z@JLiI@SZ}}8saEopl^WCv&r241nW<^gkY$GPPyRO;M(9?;96+ULT5arfQ{d|7IFS> zahviKOC_QxO2Cd|%EM*qo=xk+Z?f*#^QiX@K-NPy+8J%nwb3aDX~5$olDhvTYMw=Hs6rgaRI62-Y?{*dZ-zn^?TkF* zfa@TICh&dYI3|iBLkOX2wVKZ5ayDStwygn10g_Ttu2cv-6Z^N1vi=7*V^123Rtl{& zN(jQCDq;T+;ZOyIKr4;(L!9yL^!)L!sDHl$X&Y3AhLKVd_&!6SPxi4TZ1~PEu_kn) zWkb;#22r_|v{x!4bz&oB7~@RnVEfarQ~%mExY-QDl`=|cwAP6}QlPX(X^mDIv!lS~ zD{rO47xYz!@auI3>s8#R-=XyCaHN+Y#KNktsT1ir5~ZQ5ilTej@VBab|C zuX4Fu|JJv@WkpeBi~=NtK+2fmpoY6-J=?Bbj5DDf6^2QpGDcVHw4bn$vEMkAj!%6I zUGtG~1g3!uBh1z&dTxD?{447i^lJq5I(_~96e^OQAKZ*6WRv!UMhS?EL$og1kFj4r zh0f0$g`pHt-A9`O>4(^b9L49~#JKY*Dq%Y5_YCriB<6pdq%-rdOl`2Xk z9qX1HJy-r0`IZ7(H+LfndHkCnq&8eeTV?`G5MkxgOnKru{9pYaieEd9;mbcy$MZMP zeAs;AY8_<>q>`wV!{F@?la_)~aj>Br5`bjmuFyy&5h<6_b8lilznp$Yk$e0t2HsqO zcI_R$-v9?qtRz7cYQwUc$BZ32t5_`RVzFqPe){Pb-+%x8>&A^6H*pjo(=;g$58)Q8 zlwNonWtm7Jh^54EY+C1~}rVu8i^R#Mh;y5N2f}xx5=YYZl)?aobMn_B1uOS-1K%^nmnn=dP zVT@rIxoV|ihG8gV9NQZ*~RaWcbxjog`^K*cdi2$WQ4*P;6C5{#A{>aDf-r83$yP=E{~ znonLtUrI2srHzh><7jFr&^o4*X%i?yF@|M|_V!NW>1Ur~`O4KOt#m%0 zHL#13Q}C*HDa zQ{T81+qQ_~7#dEcLZbzkg)Eu<<{+ae`NV**Rs-7tQxFW4Xg_%o%Fsxyh=n3X;Rg|W z?ztE1)~%&`>o#21<=4NyNj>%Cljb?+obx5EwJC&108&b07=odCg&rNyD}8#UPrrzW z91}wbOv7NuP()}jg^5Zz^ofXG70@dK`UvT-mT?S|;aZJe9nvQQ`c%kv=@WW3reW)FFN4AxvR{(hRAjuRayfFJk&d#FYOymwrO}Ek$qa(;L<4 zQvq8B`eDHwIxqMlo40RgyYlIYeYQk3vYiH*Y&$Q!_71aVOyQ-MU)Ha^^0Ilsg%^Gc zC<-BrNs}ful(cDrRH%H0stl>=m^zA5t%4k^5Gh3zMWfE7)`@o<$%v>_q3rwAR7{gDlikgb4gaN80i_!|q zGV!&fs$yy?qADY5zR%XIV8Xwh!oare_@+ociz1X~QMlxbtX}#yv1?J5F(u!pb>VdO zK4B8#m9v@LG{}(e^3wBv6Q$DNQrC6<%k#Vp5O3PFDFMjw9O8OFZuS&BVPRun8z!bO z7<}kC+_q+lefC+QioG zZZ>sw(On*-sixTaoBQw_2S*EBVc=oVe*D3R!7}OjGiez=1}ltlg+a=5>3jSo>=##1 zO_^-$>S9}WH=8$aW=pw5TPnwzA6!qS(1a@t91R)ArEtXl$VwI4bFnaz&xC<11h$4k zYYW>qZ(;9iFT@KKt}tjG+ey>E9E)ot*#XBgiHCjWp1cne7EL2wa~l{A^{T7gfxlXZ zP40TEdt1+ao@1D!vDXMdQcChoO$2F+@y8vCE5Q>6u7X^16Dz;^@3?nAN6PV#u8o~a z)3js*t53NYQ4dMk4xVWu2FpzQ!An~lbIs|f<@ck@>oEx?|5GvIG=)GW7D}|Htunm*8vrlB`q36+-l>~Q6BfJzFesCk+)xXCZ(?&QjM0I;V zUPlX-?IxB*DpGEm374KldHVnpCQo6YuOIz|V;KLZzftb)!EkL*3X#jR`ImR%+;|V^ z37tg4HL6>;W4APswjIzQYzJA37{mGQhOdGyBD?;KFfE2^F)KDp^RLUS%MY8)z)NeT-EggTmLT15 z7W1hL^)b!N{?7}r`-gBbNZB^7(loWT;ut3JmR`(A(mbXeS3=6N@GJ+XRA<&NzRhrx z#l-1zs1J10_2hr^(9i!B_v}N+2^&WXQm%(96-_M#JkKNU?!&10G?V45aP*(~0qPR9QHTy$}mT%mwQ6IKGI zE||rXf8HOt;(s9O$FfacSXRUCSiq$Dr>-l;t(Iv!5xWBj4Td2|rBmcEDD69iIrm*f zI*?e^0MB)C5qO40+DnnLY+NnyTnE#SaE7YP`R^;JEZUQ?W2Ug;fg5??JIAr)_dmt0 z4bj_XFyn!%$Ql;LULyleA|$SfRw;USf}%E+IU95nd3J&1P^clV!sZ zS{OK%gJ&m+GS{*&4S{KxxUNe&l|qLhxm+&ENf`#((9FO5Bg(GmPN5LjCs}BCa9)Ow;DHlDi6}{&qqDk!x)dD)RO+0tqH(2-7 z-Avr~aE|%@ZM2M=O06=4V`(O|cTy}@S$9k`LFZUzcblIYePvqlQ-i5%xuT?P2qzhLF#$|K7apPkw zfA&vI{>{r!=tM?glAAV6T-zpxNvgR8%XTmfF*-QIvaqG3K5HCuY8!DBBMgDIEYhZl zW7~`v93^97854vtGuo<{eh=~1M-Ya|;Bd?vD+if*{4dGpn{jMQ+qSI$<+|?fllHr> zKnQHd!Ln_#S~n^Qqd9#n+rmlbsPt^)-tU~q@YapYIrempzw8eDatYJ2VW$#~Mn?g| z8{THh?0L+Yw}AR!ABY@67#OCBVH(gV(TsT5rU2U%fQgTb?YiWZLJI@SbwTOTl1Wgn z5=)sB970LjD3MLY$W`~D!$Is+n&(~{B0J$wrq2H~wh`lcX$-@VLI^!}?AQ;Mpubm7 z5<)a876K(>oOBM$wpsDm?|Jd2ODOksv)}3GbJ*8^PE@aATF%b>XpLdnl)Bb1w0Rx- zeC}Lq0n+tIWpYVEA(?(mVGu?UDhjX+!C<7gX-$coZSb`j%~)E4<4_;$32f1CL|Yv0uQi*O4+LibBR^t1$37x<66OtGhLu`V7JVXZP+(Re@5wwc79&iTnlE^HSw9o@Ii2S5`_WNwx$U<9 zX4dREw6?aYME~vz$Ax1i|h9C~=I4Ril>JzMZCB;C@YSaSAdH6L1U@wBD(_`(Bdl9tJP@Ts5PkFYFSr|e0leH@16B$X4H_-GUNS%lUg<0PQ|_}C1K#^x~u zqzpk2OO%orrbQeEC@Jyl6{Z||B4ZEy1k^T@HfqG1?tyR!)6MX=cZMiTKbp2_hvV6T z&z*4=TeoiG%V(a+e*5hw9(?dY4ba!uCw8l(MI%dSIvys__3~r9^1C0=w|Xh*mUcR3 z@5B64&SmOhpF#xzVZDO3oqvoaAq=!uOj-B|(3&{(i31-IMWf0;oo(WcyMBq1Fm1tc zNEs36gf0OBKZ*#-C7fJyl0DSAk?YokL793jU{bDv9(WZ7UcydiS>C1CT7-j7JRi@s z`0Qz?^U}*NbNJzhaqI7Xhmva4!%<4@UV@a0F>QwpuRY3=#n-U$g(pchXW8q-udv4n zXE1K>g&+j=(m-O4EqiB1!as1uK|LW57zyct2EibmZDP&y53>B>-?8^$N0FO%IOSTE zX3xcs6{hV_+_;u|zkUSM7X33vUvdkzQjs`{kTRwoL9<=NRoju9?!vHB)O~{&mTqJ6 z{%138#=&&0TgEfbJj=p`3wiXBhZ*SarM0bNwA@^&RCezNr3;ckkJ@k# zvuDrdxxYQj#EBD7Iw4Cmtn3F$P*V1BJSx4L$&a1PDc3*4@t56Bx@8Pet&9wVQRhwT z4`S^6?=G!1mg_Opy`G0IJdxqPZVveJW&ANckE&l|D3bi=sv<&wR2nzmik-?b)V+?N zTE?%HS@!2!2qML}Oh3BXh3a_%)3WI=Nj4V+*F8|AJX9o|PE+@N_Sj<%xm=DY40qxr zi~`c|_jUp(tPU~t&`)vdO)oNL?m<+GeTjqkVaoS^vBY+C9=&vyu9yG9ec$*PrS7#H za`u(%{h4ntF&?DHm-PCQS$PMcLCc8d3DfDEdl21kJ?U+g!IxrHG-Q*h?A zCPJkUKorzD;`|#hQdzdGev4eboq4C7&%wv-4_lsq(i_;REKAqKEZE6PDCGDn?qvGHPg1K6BZP?|;G1&_prICP4AEEyT9L}-`Sj)gO)ZLe z<+ZmNm+r%(mw5BN76%{v=j;mAt+a>oc6iTv32V<4AWrZ`0=!+1nRA&eEKWj zVEV#O0+7z+N3EJdU1ZQc;=aB+1j;|jmz&PUiT2n@56Fa zyuQ3l$v~^2Y{rCkjv$8Y#S+Kq?Bl_>Dss< zNr3=={>j&P;+{JgoOm$Hwv^b~y@kgfdz1$rcwm?QZomCDzVyW}Qm@z8Z@+!{`0>Yc z_@W~?>6rOU9pfXH{ul@lMvCX&8Kh&66KR>aFNTOQEjJ;4Hgt>D3Y3A{+|Elk|A5V} zKZ$+be+Z>jgCixyC=0f6|HuHvag1eIWOGgQ_w{o9^*3;s zJN9@EIPd_{=?s3oGHN#cdKEX@%!)^DXX|tKaM=8roO0`v0BqZ~jb-n=!?Jgmv3~t} z%H=Yi=hEEV%-lWqpkA*L1U`k978c)iCzVQ-X1M~j`Em5nTiB^AOV%m|styZ3_8o*! zn5Ny3@??S%E|Z0mO7rrqKVsRv*OQ+(i){M@9sBhURJ_(l11F-n&_=yh;o^%g;zlpzg`_RZ!(TZWt&*{`~y69-8WHEa`>fp5-EiW z>a@4DaLh4Bam=yDypO`I@auJgAV5k@9ENP#QlZ7%f@yRSci)d;XDC$!OO|hE%E1?r zYoCdZhS6FeWkW~C5l%XXUm4=5pP$3lH=iZjK8E9ecqdM-Kv=7Ygch#FKMYV3jM`jx z?JxQ6`4=Fiq^YTiGtT%DS6uN!CQqJ6S_lqc6C*ZvBFppmPS)6P$pT7D} zv`n5uRIeZmGvW5c@p~q?q5Opq4I`k4WrQC}OgTtvwu)T$Fgh$@*eU` zQLPWtauUe_gfPK!So_?cdF7TL68RN6_t=kPF1ZEEc9VE;H{Sg&!Rn4z6h+v!om5=& zIcCn9!}|3bC=?2uamE>Z^SpDJGIbhJ=rdF*Vp-O1lT9N5=;~+x#1lXHSDZ`}$N%t7 z#?4!ZUmZ^J)jKjq8rjPoO|6uYSjNOrOyJj5Eyp*=OG``~($M zM+lcV*=B-Tna!_1&gv%?v-$PsNVm1I_bKNx@1(Ca2=Yl1P$@kkLAwWN#Me_wAq<0- z)^>(U#l(j(ZNB{FGg-cT1;6;kHFS1#5JeG{@(_k$VB5QQDrFRs&KFqu)ZIMwv$K&= z$R~b!FBA7Yg0NP>XylJ}*`hG&KIl;;FXI?Lh{#(-JfljyaWO)NDDCmLWfeN+oTl5C0VNKX)GajtRt}k8PS5meuG}f1tNB%9Az> zgQlh?Hgs*`U;p*1+;GFM$z(DN50$v+!V9q-kD*eLN~MBnntyjsg%Ad*e1W&_{|(Px z^L4!DHa_*U2NTJu3@3D(-R0*a+KwO z!@r4Pn$(7ddH2yfS^4Z#{%Yl;!HZ`>`z=P5&2at%Rw0?=0}Jnt&zb6 ze#q6=T+P*2UqiWEX3x2Ma>W%tVt8nfTCIkzR!5i7$d4KEoJV;>N@6-LwwvOGo4?N+ zcmAAA#{@op#s4sNuY(hCEbBugM=`?ok7Z0022^~>Sa$#`=pycZ0MpJ=EGgbuTcq=! z&Sl&3ci8yCpXh%31!~0#O_L@u>x46yu>aAtOx+U|h17~Y*pAnr6DRxxt@H;3;O_%y z!h{K2cKPL8bImoFmdQ;w-N@;mKaKKmX;d%lC^0(%v!lN8vd#Fz13Y~3$!uBjG)?1Y zaN;$OkRLNSSyra`q2MHKDdL9Y)B}mD1}LN}#H$}bhr?*wVad9XvY%)3y$?_uydE7Z zny2l>yw87zjy)GNykkjquph%PvF(KIYUmv%82!;C$g(V|)hb6UTEso~-c3uPz~JB@ zwr!(72;xSn)vzoK(?Y43)lc5V->yB6D5x=M!Eu~$#UDUx!g@6U`R^>Nk@r$cqBtUs zA|j~>!aCFQ!|2iqbl(fuwoO-`V)YiE{`C${)@H_$pJ&2?<7gT;gD9xuSBDAX2!n(h zL}Lq=RvK;U(P-YVoJOW|*KzC=i}m#MaN$K4GIh~bVC4V+4a`YIK~%~V>h&6fgM(P3 z3hX^Vl#&R;z)9t>ZHp+17~HgqEpI%<+NbYj^Q(U&H-0P!fAvcC`P{dN{2E%RotEM5 zByhyMOBpA58q3ABJ%%@|B^_QhkDDVUJoI8ig@DOS@^`ViP zSgN@d8HQ|o_a!#I_%J=J(HCU+}FD;K54%5u~_{9h-h40si%EL)WAr(@| z(O}dx&Cz`+!b{=iTQF42<|R+D>4gXAUG^fU{qiB~RCX7M-r0&Zh}gU6mPSR?@G=Z{ zujTdM{|9TIx|`vx8?YP?ueptuse3Z{;O{c~=+kKG7*D-2L{zKp*7g zSSlu#ZD3dqh9!`pPw$FV^e%gW-eoTk4EB&|YN0T0Dw#qjG79*htd{jbiBqjLb}EBE z*vG54U&+eHeowtvp<~W$=6&WHjGKQL9kceKX~GOFLlD$!RELVA$u>Qja}m1*N68pB z-$GC+vFa~(vh1N->3Z{3jFdy${9{>o&_eb;{9xj@u13c-a9mzpUV`R*NKHJB^59ma z9N8IaphU9OK?ZfAa*=v*8@26SRJzwv*|wgjG=%Fy+mu<%IOO9@J@6RD&s#{Qvy-S+ z)*s>r?RuHEOKH<89=Y_h3~${)Ve)K_z3g%(?6U|vl}(hMlti@((a845-BecJFSc4K zl#-;IT3GSKA9?k*A2YalEwNVYdE%K&JNgS4xi*Ca z%Ehfy38 z2UkgmV+_;MjV&2^w>oIoAEk)u6(0TmsZ{#A`KMF9&Y|D9hB)$xYZW5DiV((5A;Jf_ z0K0VPr3nUlc<`rRVa+ptBGod6sf+%Zy+8XMyw>sbc5k6z_F_d<;*EdAFa=R8cyUFI z?DUg}?KUa{TPSv|qIcDs3~XLUy*vm)OMyQW%CX455>`Qy-zSDr3@xHvW3$m+4!(ibKBs?;L#ArBny|N2NsUM)7_S zD5FbE#-y5CS^4-~Jb(Q~l)Af^zUV~eeeT<|&f1URVlRU|n^19`N#hOFriY-m9y68W z#kT{>VVb@!MembWFt}wcemOvRHeO37ZFA?)Ja!Vz9TRCDGm&g-J1H-XWg3`56IM!? zsWeVHjqP~YwvB08SeA)t8oDt?WtzLX_}2S<8_P{m+PsdHf4P$>3y)&IFI+%%aA2q9 zvpYxe{W@o-%wrsrF0}Ie4c}ww-M<0^M}6;RrXTe=0>931|2F)3jp16%oQ^t%zn*y8 zqnJ*Xt-TQ&`eN3sHrce{J}k#3Gj=*13+9sTn24Kg!b_#G9S7I8F>RZ;UMEyBhL^%j zrEpv?;W}9smTe}$SxLBL8YYHeDj@`IZEb&_AEW`>%h0!a2`Y}5ddMdellcL$)9&K2 z(LL&;-YTS;T6ps3=kU(`zoBLF9vuCH+sIFxMYY&VB$F)&Fa@^l;J6NsV`JMEj^kk4 z4z^`s*$$RzVp$fZX<``02>s>n^MjIo<`T=xfQEXhAJcIOYr`0}yW22fcOWUHMp+_u zCdZP+zvSHq|BKE!`*Zxi--VqkP%8}}F$e;m!1sy#GBc)w?0o}Od=W(#>urkbqeHM`$Gm&NY-^8|MFX81|lM3qxouaT?!d0?avb1Rpuio}!QcZ1~ zaOK@tnI`7iBuAA)X9|6m09AIFYNqK3<+EqH8)_)(MkpNB@9C^Ww zL_wVgzI7a{pID5SFJL-eA~Cy>r1x7ZC1cXfExh*MKcQAE^0D)Ojh)F6*2+nw9z}#< zNDzb|D@^XRQCl7azZ=u_cx6?@aGaq#-jibQR?3wMzVG7)0kM=xRa9s!)5P^WGMNn7 zOqNtCh39&BUW$~L++Ej6UXG3JxVWh_ZaRyT&h0eIyPIrdS8{<#98{UK;CPO`^md#~ zjz@p+FFbnbsq`#+5zEcsH6`^f6-PUPH3F2@8q0AR+Sq74iL%2KS`z1 zqip(2CPTitiF_`XNKZC{=cP!e)1)(LQjO(hSti-$HVi|s_Q}Pp{L38-tY1bjTtvy3 zL(lx)ZjI1KO4>*DDsH~Or~czlYy<o6S;aDUi?QNjLtN$z(?*CYAE=QW?B-1|9jVeDrpf-t`NH zyVsK`w9z_kE;9~0iK&NtlGcec2rCb0fR2ui59BC{4=TJ11l7TQCLVAMlMXzV{ z_0prPf9?U6-S=Otc=&hB_}Izp^ZD}`v)4iR!^H+MKoblVG2IkibL;4-FS3ygi{luy zrqGlp+`bZ9D2l@&_1w91g)8Y9sN&iQK|GyFkMo^G-RJ-j#3g#vMOl-LvHIzuX*!gXxYxdMjJEM0sRs~-D3)qyQIPMX8cxs<(6`Wl(mF`yK& zUnL$nBF1)v5aREXIE63_)3mT1=Ob}hw2U#dX2QIKnReadtoZ9)to+Lztbh8COq_oh z`7x8R1dN-zfO@e91BqkX=-5F@jcqrov`tOu;$}=0v!z(!{%2m}rvJH@Nz-Ow+cr&2 zd0Jar=#_FXq?c3IZ|)_K!CPw+p6;UJQ^LrM?X|b>mgJeQ<#4=iw^w^ zLTGBGq8=!g&;vy#A9p6xKXJD3t3#9qOCtw~5QZUs5Hq1OWr%Id#I{mZ-0Y2AU ziaGlqE-c$3o5|AF*2=hXV|9CbhtB8oW{+t#8HQkbTx4Z|Rl$;68nFD^};I<;P} z*Y!R3+_S3$9dgJa!_%fstJt=!4a30mywNY%w*BGfifKhGHOp5l7mjU@`bL{JZx)tm z(c8OStY5$0h@wdJ_xGEHLcy9eX;S+QcRn=sFONR7c1urRmu=hI<2YU`gxDgb>=#0m zqbRC{VOa5f-#1NDT9zd(%aXQjOUH4f=XuieJekYoR5qJcP890qd|st9Y1-P_bvl*O z>2!)2GiK;83<<)J{r1^MS8FxmI7SFT6h-v)^~o!)xI)jIIdk_C^ndvfxt)l5*-XZ$ zRI75q{`-BbG&J;`RcqEh>Dcy)Fp9PURUlyGpqBSudWZM&egETqo8a`0N0|M8?%2H< zQziqDO{G$Rm(OO*hDSg0G8>XTavym=^10aI^?&{Pe*gyCm2De1h5Y~k002ovPDHLk FV1i1aOl|-G literal 0 HcmV?d00001 diff --git a/android/res/drawable-ldpi/icon.png b/android/res/drawable-ldpi/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..83b482a6454dd82e2212a4d0b0ceae8a0155aecd GIT binary patch literal 3896 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 literal 0 HcmV?d00001 diff --git a/android/res/values/strings.xml b/android/res/values/strings.xml new file mode 100644 index 0000000..af51c8d --- /dev/null +++ b/android/res/values/strings.xml @@ -0,0 +1,5 @@ + + + + OpenOrienteering + diff --git a/android/src/org/openorienteering/mapper/MapperActivity.java b/android/src/org/openorienteering/mapper/MapperActivity.java new file mode 100644 index 0000000..7052191 --- /dev/null +++ b/android/src/org/openorienteering/mapper/MapperActivity.java @@ -0,0 +1,210 @@ +/* + * Copyright 2013 Thomas Schöps + * Copyright 2014 Thomas Schöps, Kai Pastor + * + * This file is part of OpenOrienteering. + * + * OpenOrienteering is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenOrienteering is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenOrienteering. If not, see . + */ + +package org.openorienteering.mapper; + +import android.os.Bundle; +import android.os.Looper; +import android.os.Build; +import android.os.SystemClock; +import android.app.AlertDialog; +import android.content.Intent; +import android.content.DialogInterface; +import android.content.pm.ActivityInfo; +import android.content.res.Configuration; +import android.location.Location; +import android.location.LocationManager; +import android.location.LocationProvider; +import android.location.LocationListener; +import android.location.GpsStatus; +import android.provider.Settings; +import android.view.Surface; +import android.widget.Toast; + + +/** + * Contains Android Java code for Mapper. + */ +public class MapperActivity extends org.qtproject.qt5.android.bindings.QtActivity +{ + private static MapperActivity instance; + + private String yes_string; + private String no_string; + private String gps_disabled_string; + + @Override + public void onCreate(Bundle savedInstanceState) + { + super.onCreate(savedInstanceState); + + instance = this; + } + + /** Call setIntent, as recommended for singleTask launch mode. */ + @Override + public void onNewIntent(Intent intent) + { + setIntent(intent); + } + + /** Returns the data string from the intent, and resets the intent. */ + public String takeIntentPath() + { + String result = ""; + Intent intent = getIntent(); + if (intent != null) + { + String action = intent.getAction(); + if (action == Intent.ACTION_EDIT || action == Intent.ACTION_VIEW) + { + result = intent.getDataString(); + } + setIntent(null); + } + return result; + } + + // Static methods to be called from C++ + + /** Checks if GPS is enabled in the Android settings and if not, prompts the user to enable it. + * The dialog box works asynchronously, so the method cannot return the result. */ + static void checkGPSEnabled() + { + LocationManager locationManager = (LocationManager) instance.getSystemService(LOCATION_SERVICE); + boolean enabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER); + if (!enabled) + { + instance.runOnUiThread(new Runnable() { + public void run() { + DialogInterface.OnClickListener dialogClickListener = new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + switch (which){ + case DialogInterface.BUTTON_POSITIVE: + Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS); + instance.startActivity(intent); + break; + + case DialogInterface.BUTTON_NEGATIVE: + //No button clicked + break; + } + } + }; + + AlertDialog.Builder builder = new AlertDialog.Builder(instance); + builder.setMessage(instance.gps_disabled_string) + .setPositiveButton(instance.yes_string, dialogClickListener) + .setNegativeButton(instance.no_string, dialogClickListener) + .show(); + } + }); + } + } + + public static void setTranslatableStrings(String yes_string, String no_string, String gps_disabled_string) + { + instance.yes_string = yes_string; + instance.no_string = no_string; + instance.gps_disabled_string = gps_disabled_string; + } + + public static void showShortMessage(final String message) + { + instance.runOnUiThread(new Runnable() { + public void run() { + Toast.makeText(instance, message, Toast.LENGTH_SHORT).show(); + } + }); + } + + /** Locks the current display orientation. + * While a native "locked" mode comes in API level 18, + * this method tries to determine and lock the current orientation + * even on devices with lower API level. On these devices, the screen + * may be temporary in reverse orientation. + */ + public static void lockOrientation() + { + // ActivityInfo.SCREEN_ORIENTATION_LOCKED == 14 comes with API level 18 + if (Build.VERSION.SDK_INT >= 18) + { + instance.setRequestedOrientation(14); + return; + } + + int orientation = instance.getResources().getConfiguration().orientation; + int rotation = instance.getWindowManager().getDefaultDisplay().getRotation(); + + if (orientation == Configuration.ORIENTATION_PORTRAIT) + { + if (rotation == Surface.ROTATION_180) + instance.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT); + else + instance.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); + } + else if (orientation == Configuration.ORIENTATION_LANDSCAPE) + { + if (rotation == Surface.ROTATION_180) + instance.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE); + else + instance.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); + } + + // If we read another value now, then we must reverse the rotation. + // Maybe this can occasionally return the old value (i.e. the value + // before the requested rotation takes effect). + int new_rotation = instance.getWindowManager().getDefaultDisplay().getRotation(); + if (new_rotation != rotation) + { + // first try didn't lock the original rotation, retry reverse. + if (orientation == Configuration.ORIENTATION_PORTRAIT) + { + if (new_rotation == Surface.ROTATION_180) + instance.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); + else + instance.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT); + } + else if (orientation == Configuration.ORIENTATION_LANDSCAPE) + { + if (new_rotation == Surface.ROTATION_180) + instance.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); + else + instance.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE); + } + } + } + + /** Unlocks the display orientation + * by setting the requested orientation to unspecified. + */ + public static void unlockOrientation() + { + instance.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED); + } + + /** Returns the display's current rotation. + */ + public static int getDisplayRotation() + { + return instance.getWindowManager().getDefaultDisplay().getRotation(); + } +} diff --git a/cmake/DeployQt5.cmake b/cmake/DeployQt5.cmake new file mode 100644 index 0000000..1acfa45 --- /dev/null +++ b/cmake/DeployQt5.cmake @@ -0,0 +1,336 @@ +# Source: http://cmake.org/gitweb?p=cmake.git;a=blob_plain;f=Modules/DeployQt4.cmake;hb=1e3248c9d0396e9c8b417eb35636ed951ca85988 +# (HEAD: http://cmake.org/gitweb?p=cmake.git;a=blob_plain;f=Modules/DeployQt4.cmake) +# +# Changes: +# 2013-01-26: Replaced qt4_/Qt4_/QT4_ with qt5_/Qt5_/QT5_, respectively. +# --- Kai Pastor +# +# 2012-09-28: Inserted this header +# Replaced BSD license terms reference with actual terms from the +# referenced Copyright.txt +# --- Kai Pastor + +# - Functions to help assemble a standalone Qt5 executable. +# A collection of CMake utility functions useful for deploying +# Qt5 executables. +# +# The following functions are provided by this module: +# write_qt5_conf +# resolve_qt5_paths +# fixup_qt5_executable +# install_qt5_plugin_path +# install_qt5_plugin +# install_qt5_executable +# Requires CMake 2.6 or greater because it uses function and +# PARENT_SCOPE. Also depends on BundleUtilities.cmake. +# +# WRITE_QT5_CONF( ) +# Writes a qt.conf file with the into . +# +# RESOLVE_QT5_PATHS( []) +# Loop through list and if any don't exist resolve them +# relative to the (if supplied) or the CMAKE_INSTALL_PREFIX. +# +# FIXUP_QT5_EXECUTABLE( [ ]) +# Copies Qt plugins, writes a Qt configuration file (if needed) and fixes up a +# Qt5 executable using BundleUtilities so it is standalone and can be +# drag-and-drop copied to another machine as long as all of the system +# libraries are compatible. +# +# should point to the executable to be fixed-up. +# +# should contain a list of the names or paths of any Qt plugins +# to be installed. +# +# will be passed to BundleUtilities and should be a list of any already +# installed plugins, libraries or executables to also be fixed-up. +# +# will be passed to BundleUtilities and should contain and directories +# to be searched to find library dependencies. +# +# allows an custom plugins directory to be used. +# +# will force a qt.conf file to be written even if not needed. +# +# INSTALL_QT5_PLUGIN_PATH(plugin executable copy installed_plugin_path_var ) +# Install (or copy) a resolved to the default plugins directory +# (or ) relative to and store the result in +# . +# +# If is set to TRUE then the plugins will be copied rather than +# installed. This is to allow this module to be used at CMake time rather than +# install time. +# +# If is set then anything installed will use this COMPONENT. +# +# INSTALL_QT5_PLUGIN(plugin executable copy installed_plugin_path_var ) +# Install (or copy) an unresolved to the default plugins directory +# (or ) relative to and store the result in +# . See documentation of INSTALL_QT5_PLUGIN_PATH. +# +# INSTALL_QT5_EXECUTABLE( [ ]) +# Installs Qt plugins, writes a Qt configuration file (if needed) and fixes up +# a Qt5 executable using BundleUtilities so it is standalone and can be +# drag-and-drop copied to another machine as long as all of the system +# libraries are compatible. The executable will be fixed-up at install time. +# is the COMPONENT used for bundle fixup and plugin installation. +# See documentation of FIXUP_QT5_BUNDLE. + +#============================================================================= +# Copyright 2011 Mike McQuaid +# +# Distributed under the OSI-approved BSD License (the "License"); +# Text as distributed with CMake in Copyright.txt: +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# * Neither the names of Kitware, Inc., the Insight Software Consortium, +# nor the names of their contributors may be used to endorse or promote +# products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +#============================================================================= + +# The functions defined in this file depend on the fixup_bundle function +# (and others) found in BundleUtilities.cmake + +include(BundleUtilities) +set(DeployQt5_cmake_dir "${CMAKE_CURRENT_LIST_DIR}") +set(DeployQt5_apple_plugins_dir "PlugIns") + +function(write_qt5_conf qt_conf_dir qt_conf_contents) + set(qt_conf_path "${qt_conf_dir}/qt.conf") + message(STATUS "Writing ${qt_conf_path}") + file(WRITE "${qt_conf_path}" "${qt_conf_contents}") +endfunction() + +function(resolve_qt5_paths paths_var) + set(executable_path ${ARGV1}) + + set(paths_resolved) + foreach(path ${${paths_var}}) + if(EXISTS "${path}") + list(APPEND paths_resolved "${path}") + else() + if(${executable_path}) + list(APPEND paths_resolved "${executable_path}/${path}") + else() + list(APPEND paths_resolved "\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/${path}") + endif() + endif() + endforeach() + set(${paths_var} ${paths_resolved} PARENT_SCOPE) +endfunction() + +function(fixup_qt5_executable executable) + set(qtplugins ${ARGV1}) + set(libs ${ARGV2}) + set(dirs ${ARGV3}) + set(plugins_dir ${ARGV4}) + set(request_qt_conf ${ARGV5}) + + message(STATUS "fixup_qt5_executable") + message(STATUS " executable='${executable}'") + message(STATUS " qtplugins='${qtplugins}'") + message(STATUS " libs='${libs}'") + message(STATUS " dirs='${dirs}'") + message(STATUS " plugins_dir='${plugins_dir}'") + message(STATUS " request_qt_conf='${request_qt_conf}'") + + if(QT_LIBRARY_DIR) + list(APPEND dirs "${QT_LIBRARY_DIR}") + endif() + if(QT_BINARY_DIR) + list(APPEND dirs "${QT_BINARY_DIR}") + endif() + + if(APPLE) + set(qt_conf_dir "${executable}/Contents/Resources") + set(executable_path "${executable}") + set(write_qt_conf TRUE) + if(NOT plugins_dir) + set(plugins_dir "${DeployQt5_apple_plugins_dir}") + endif() + else() + get_filename_component(executable_path "${executable}" PATH) + if(NOT executable_path) + set(executable_path ".") + endif() + set(qt_conf_dir "${executable_path}") + set(write_qt_conf ${request_qt_conf}) + endif() + + foreach(plugin ${qtplugins}) + set(installed_plugin_path "") + install_qt5_plugin("${plugin}" "${executable}" 1 installed_plugin_path) + list(APPEND libs ${installed_plugin_path}) + endforeach() + + foreach(lib ${libs}) + if(NOT EXISTS "${lib}") + message(FATAL_ERROR "Library does not exist: ${lib}") + endif() + endforeach() + + resolve_qt5_paths(libs "${executable_path}") + + if(write_qt_conf) + set(qt_conf_contents "[Paths]\nPlugins = ${plugins_dir}") + write_qt5_conf("${qt_conf_dir}" "${qt_conf_contents}") + endif() + + fixup_bundle("${executable}" "${libs}" "${dirs}") +endfunction() + +function(install_qt5_plugin_path plugin executable copy installed_plugin_path_var) + set(plugins_dir ${ARGV4}) + set(component ${ARGV5}) + set(configurations ${ARGV6}) + if(EXISTS "${plugin}") + if(APPLE) + if(NOT plugins_dir) + set(plugins_dir "${DeployQt5_apple_plugins_dir}") + endif() + set(plugins_path "${executable}/Contents/${plugins_dir}") + else() + get_filename_component(plugins_path "${executable}" PATH) + if(NOT plugins_path) + set(plugins_path ".") + endif() + if(plugins_dir) + set(plugins_path "${plugins_path}/${plugins_dir}") + endif() + endif() + + set(plugin_group "") + + get_filename_component(plugin_path "${plugin}" PATH) + get_filename_component(plugin_parent_path "${plugin_path}" PATH) + get_filename_component(plugin_parent_dir_name "${plugin_parent_path}" NAME) + get_filename_component(plugin_name "${plugin}" NAME) + string(TOLOWER "${plugin_parent_dir_name}" plugin_parent_dir_name) + + if("${plugin_parent_dir_name}" STREQUAL "plugins") + get_filename_component(plugin_group "${plugin_path}" NAME) + set(${plugin_group_var} "${plugin_group}") + endif() + set(plugins_path "${plugins_path}/${plugin_group}") + + if(${copy}) + file(MAKE_DIRECTORY "${plugins_path}") + file(COPY "${plugin}" DESTINATION "${plugins_path}") + else() + if(configurations AND (CMAKE_CONFIGURATION_TYPES OR CMAKE_BUILD_TYPE)) + set(configurations CONFIGURATIONS ${configurations}) + else() + unset(configurations) + endif() + install(FILES "${plugin}" DESTINATION "${plugins_path}" ${configurations} ${component}) + endif() + set(${installed_plugin_path_var} "${plugins_path}/${plugin_name}" PARENT_SCOPE) + endif() +endfunction() + +function(install_qt5_plugin plugin executable copy installed_plugin_path_var) + set(plugins_dir ${ARGV4}) + set(component ${ARGV5}) + if(EXISTS "${plugin}") + install_qt5_plugin_path("${plugin}" "${executable}" "${copy}" "${installed_plugin_path_var}" "${plugins_dir}" "${component}") + else() + string(TOUPPER "QT_${plugin}_PLUGIN" plugin_var) + set(plugin_release_var "${plugin_var}_RELEASE") + set(plugin_debug_var "${plugin_var}_DEBUG") + set(plugin_release "${${plugin_release_var}}") + set(plugin_debug "${${plugin_debug_var}}") + if(DEFINED "${plugin_release_var}" AND DEFINED "${plugin_debug_var}" AND NOT EXISTS "${plugin_release}" AND NOT EXISTS "${plugin_debug}") + message(WARNING "Qt plugin \"${plugin}\" not recognized or found.") + endif() + if(NOT EXISTS "${${plugin_debug_var}}") + set(plugin_debug "${plugin_release}") + endif() + + if(CMAKE_CONFIGURATION_TYPES OR CMAKE_BUILD_TYPE) + install_qt5_plugin_path("${plugin_release}" "${executable}" "${copy}" "${installed_plugin_path_var}_release" "${plugins_dir}" "${component}" "Release|RelWithDebInfo|MinSizeRel") + install_qt5_plugin_path("${plugin_debug}" "${executable}" "${copy}" "${installed_plugin_path_var}_debug" "${plugins_dir}" "${component}" "Debug") + + if(CMAKE_BUILD_TYPE MATCHES "^Debug$") + set(${installed_plugin_path_var} ${${installed_plugin_path_var}_debug}) + else() + set(${installed_plugin_path_var} ${${installed_plugin_path_var}_release}) + endif() + else() + install_qt5_plugin_path("${plugin_release}" "${executable}" "${copy}" "${installed_plugin_path_var}" "${plugins_dir}" "${component}") + endif() + endif() + set(${installed_plugin_path_var} ${${installed_plugin_path_var}} PARENT_SCOPE) +endfunction() + +function(install_qt5_executable executable) + set(qtplugins ${ARGV1}) + set(libs ${ARGV2}) + set(dirs ${ARGV3}) + set(plugins_dir ${ARGV4}) + set(request_qt_conf ${ARGV5}) + set(component ${ARGV6}) + if(QT_LIBRARY_DIR) + list(APPEND dirs "${QT_LIBRARY_DIR}") + endif() + if(QT_BINARY_DIR) + list(APPEND dirs "${QT_BINARY_DIR}") + endif() + if(component) + set(component COMPONENT ${component}) + else() + unset(component) + endif() + + get_filename_component(executable_absolute "${executable}" ABSOLUTE) + if(EXISTS "${QT_QTCORE_LIBRARY_RELEASE}") + gp_file_type("${executable_absolute}" "${QT_QTCORE_LIBRARY_RELEASE}" qtcore_type) + elseif(EXISTS "${QT_QTCORE_LIBRARY_DEBUG}") + gp_file_type("${executable_absolute}" "${QT_QTCORE_LIBRARY_DEBUG}" qtcore_type) + endif() + if(qtcore_type STREQUAL "system") + set(qt_plugins_dir "") + endif() + + if(QT_IS_STATIC) + message(WARNING "Qt built statically: not installing plugins.") + else() + foreach(plugin ${qtplugins}) + set(installed_plugin_paths "") + install_qt5_plugin("${plugin}" "${executable}" 0 installed_plugin_paths "${plugins_dir}" "${component}") + list(APPEND libs ${installed_plugin_paths}) + endforeach() + endif() + + resolve_qt5_paths(libs "") + + install(CODE + "include(\"${DeployQt5_cmake_dir}/DeployQt5.cmake\") + set(BU_CHMOD_BUNDLE_ITEMS TRUE) + FIXUP_QT5_EXECUTABLE(\"\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/${executable}\" \"\" \"${libs}\" \"${dirs}\" \"${plugins_dir}\" \"${request_qt_conf}\")" + ${component} + ) +endfunction() diff --git a/cmake/EnableSanitize.cmake b/cmake/EnableSanitize.cmake new file mode 100644 index 0000000..50a4b4b --- /dev/null +++ b/cmake/EnableSanitize.cmake @@ -0,0 +1,39 @@ +# +# Copyright 2016 Kai Pastor +# +# This file is part of OpenOrienteering. +# +# OpenOrienteering is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# OpenOrienteering is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with OpenOrienteering. If not, see . + + +if(NOT COMMAND check_cxx_compiler_flag) + include(CheckCXXCompilerFlag) +endif() + +macro(enable_sanitize) + foreach(option ${ARGV}) + if (option STREQUAL "NO_RECOVER") + set(full_option "-fno-sanitize-recover=all") + else() + set(full_option "-fsanitize=${option}") + endif() + if(NOT CMAKE_CXX_FLAGS MATCHES "${full_option}") + string(MAKE_C_IDENTIFIER ${option} option_id) + check_cxx_compiler_flag("${full_option}" SANITIZE_${option_id}) + if(SANITIZE_${option_id}) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${full_option}") + endif() + endif() + endforeach() +endmacro() diff --git a/cmake/FindPROJ4.cmake b/cmake/FindPROJ4.cmake new file mode 100644 index 0000000..093deaa --- /dev/null +++ b/cmake/FindPROJ4.cmake @@ -0,0 +1,152 @@ +#.rst: +# FindPROJ4 +# -------- +# +# Find the proj includes and library. +# +# IMPORTED Targets +# ^^^^^^^^^^^^^^^^ +# +# This module defines :prop_tgt:`IMPORTED` target ``PROJ4::proj``, +# if Proj.4 has been found. +# +# Result Variables +# ^^^^^^^^^^^^^^^^ +# +# This module defines the following variables: +# +# :: +# +# PROJ4_INCLUDE_DIRS - where to find proj_api.h, etc. +# PROJ4_LIBRARIES - List of libraries when using libproj. +# PROJ4_FOUND - True if libproj found. +# +# :: +# +# PROJ4_VERSION - The version of libproj found (x.y.z) +# PROJ4_VERSION_MAJOR - The major version of libproj +# PROJ4_VERSION_MINOR - The minor version of libproj +# PROJ4_VERSION_PATCH - The patch version of libproj +# PROJ4_VERSION_TWEAK - always 0 +# PROJ4_VERSION_COUNT - The number of version components, always 3 +# +# Hints +# ^^^^^ +# +# A user may set ``PROJ4_ROOT`` to a libproj installation root to tell this +# module where to look exclusively. + +#============================================================================= +# Copyright 2016 Kai Pastor +# +# +# This file was derived from CMake 3.5's module FindZLIB.cmake +# which has the following terms: +# +# Copyright 2001-2011 Kitware, Inc. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# * The names of Kitware, Inc., the Insight Consortium, or the names of +# any consortium members, or of any contributors, may not be used to +# endorse or promote products derived from this software without +# specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS ``AS IS'' +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR +# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +#============================================================================= + +# Search PROJ4_ROOT exclusively if it is set. +if(PROJ4_ROOT) + set(_PROJ4_SEARCH PATHS ${PROJ4_ROOT} NO_DEFAULT_PATH) +else() + set(_PROJ4_SEARCH) +endif() + +find_path(PROJ4_INCLUDE_DIR NAMES proj_api.h ${_PROJ4_SEARCH} PATH_SUFFIXES include) +mark_as_advanced(PROJ4_INCLUDE_DIR) + +if(PROJ4_INCLUDE_DIR AND EXISTS "${PROJ4_INCLUDE_DIR}/proj_api.h") + file(STRINGS "${PROJ4_INCLUDE_DIR}/proj_api.h" PROJ4_H REGEX "^#define PJ_VERSION [0-9]+$") + + string(REGEX REPLACE "^.*PJ_VERSION ([0-9]).*$" "\\1" PROJ4_VERSION_MAJOR "${PROJ4_H}") + string(REGEX REPLACE "^.*PJ_VERSION [0-9]([0-9]).*$" "\\1" PROJ4_VERSION_MINOR "${PROJ4_H}") + string(REGEX REPLACE "^.*PJ_VERSION [0-9][0-9]([0-9]).*$" "\\1" PROJ4_VERSION_PATCH "${PROJ4_H}") + set(PROJ4_VERSION "${PROJ4_VERSION_MAJOR}.${PROJ4_VERSION_MINOR}.${PROJ4_VERSION_PATCH}") + set(PROJ4_VERSION_COUNT 3) +endif() + +# Allow PROJ4_LIBRARY to be set manually, as the location of the proj library +if(NOT PROJ4_LIBRARY) + set(PROJ4_NAMES proj) + set(PROJ4_NAMES_DEBUG projd) + if(WIN32 AND DEFINED PROJ4_VERSION_MAJOR AND DEFINED PROJ4_VERSION_MINOR) + list(APPEND PROJ4_NAMES proj_${PROJ4_VERSION_MAJOR}_${PROJ4_VERSION_MINOR}) + list(APPEND PROJ4_NAMES projd_${PROJ4_VERSION_MAJOR}_${PROJ4_VERSION_MINOR}) + endif() + find_library(PROJ4_LIBRARY_RELEASE NAMES ${PROJ4_NAMES} ${_PROJ4_SEARCH} PATH_SUFFIXES lib) + find_library(PROJ4_LIBRARY_DEBUG NAMES ${PROJ4_NAMES_DEBUG} ${_PROJ4_SEARCH} PATH_SUFFIXES lib) + include(SelectLibraryConfigurations) + select_library_configurations(PROJ4) +endif() + +# handle the QUIETLY and REQUIRED arguments and set PROJ4_FOUND to TRUE if +# all listed variables are TRUE +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(PROJ4 + REQUIRED_VARS + PROJ4_LIBRARY + PROJ4_INCLUDE_DIR + VERSION_VAR + PROJ4_VERSION +) + +if(PROJ4_FOUND) + set(PROJ4_INCLUDE_DIRS ${PROJ4_INCLUDE_DIR}) + + if(NOT PROJ4_LIBRARIES) + set(PROJ4_LIBRARIES ${PROJ4_LIBRARY}) + endif() + + if(NOT TARGET PROJ4::proj) + add_library(PROJ4::proj UNKNOWN IMPORTED) + set_target_properties(PROJ4::proj PROPERTIES + INTERFACE_INCLUDE_DIRECTORIES "${PROJ4_INCLUDE_DIRS}") + + if(PROJ4_LIBRARY_RELEASE) + set_property(TARGET PROJ4::proj APPEND PROPERTY + IMPORTED_CONFIGURATIONS RELEASE) + set_target_properties(PROJ4::proj PROPERTIES + IMPORTED_LOCATION_RELEASE "${PROJ4_LIBRARY_RELEASE}") + endif() + + if(PROJ4_LIBRARY_DEBUG) + set_property(TARGET PROJ4::proj APPEND PROPERTY + IMPORTED_CONFIGURATIONS DEBUG) + set_target_properties(PROJ4::proj PROPERTIES + IMPORTED_LOCATION_DEBUG "${PROJ4_LIBRARY_DEBUG}") + endif() + + if(NOT PROJ4_LIBRARY_RELEASE AND NOT PROJ4_LIBRARY_DEBUG) + set_property(TARGET PROJ4::proj APPEND PROPERTY + IMPORTED_LOCATION "${PROJ4_LIBRARY}") + endif() + endif() +endif() diff --git a/cmake/FindPolyclipping.cmake b/cmake/FindPolyclipping.cmake new file mode 100644 index 0000000..ec64ff9 --- /dev/null +++ b/cmake/FindPolyclipping.cmake @@ -0,0 +1,156 @@ +#.rst: +# FindPolyclipping +# -------- +# +# Find the polyclipping includes and library. +# +# IMPORTED Targets +# ^^^^^^^^^^^^^^^^ +# +# This module defines :prop_tgt:`IMPORTED` target ``Polyclipping::Polyclipping``, +# if Polyclipping has been found. +# +# Result Variables +# ^^^^^^^^^^^^^^^^ +# +# This module defines the following variables: +# +# :: +# +# POLYCLIPPING_INCLUDE_DIRS - where to find clipper.hpp, etc. +# POLYCLIPPING_LIBRARIES - List of libraries when using libpolyclipping. +# POLYCLIPPING_FOUND - True if libpolyclipping found. +# +# :: +# +# POLYCLIPPING_VERSION - The version of libpolyclipping found (x.y.z) +# POLYCLIPPING_VERSION_MAJOR - The major version of libpolyclipping +# POLYCLIPPING_VERSION_MINOR - The minor version of libpolyclipping +# POLYCLIPPING_VERSION_PATCH - The patch version of libpolyclipping +# POLYCLIPPING_VERSION_TWEAK - The tweak version of libpolyclipping +# POLYCLIPPING_VERSION_COUNT - The number of version components +# +# Hints +# ^^^^^ +# +# A user may set ``POLYCLIPPING_ROOT`` to a libpolyclipping installation root +# to tell this module where to look exclusively. + +#============================================================================= +# Copyright 2016 Kai Pastor +# +# +# This file was derived from CMake 3.5's module FindZLIB.cmake +# which has the following terms: +# +# Copyright 2001-2011 Kitware, Inc. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# * The names of Kitware, Inc., the Insight Consortium, or the names of +# any consortium members, or of any contributors, may not be used to +# endorse or promote products derived from this software without +# specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS ``AS IS'' +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR +# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +#============================================================================= + +# Search POLYCLIPPING_ROOT exclusively if it is set. +if(POLYCLIPPING_ROOT) + set(_POLYCLIPPING_SEARCH PATHS ${POLYCLIPPING_ROOT} NO_DEFAULT_PATH) +else() + set(_POLYCLIPPING_SEARCH) +endif() + +find_path(POLYCLIPPING_INCLUDE_DIR NAMES clipper.hpp ${_POLYCLIPPING_SEARCH} PATH_SUFFIXES include include/polyclipping) +mark_as_advanced(POLYCLIPPING_INCLUDE_DIR) + +# Allow POLYCLIPPING_LIBRARY to be set manually, as the location of the polyclipping library +if(NOT POLYCLIPPING_LIBRARY) + set(POLYCLIPPING_NAMES polyclipping) + set(POLYCLIPPING_NAMES_DEBUG polyclippingd) + find_library(POLYCLIPPING_LIBRARY_RELEASE NAMES ${POLYCLIPPING_NAMES} ${_POLYCLIPPING_SEARCH} PATH_SUFFIXES lib) + find_library(POLYCLIPPING_LIBRARY_DEBUG NAMES ${POLYCLIPPING_NAMES_DEBUG} ${_POLYCLIPPING_SEARCH} PATH_SUFFIXES lib) + include(SelectLibraryConfigurations) + select_library_configurations(POLYCLIPPING) +endif() + +if(POLYCLIPPING_INCLUDE_DIR AND EXISTS "${POLYCLIPPING_INCLUDE_DIR}/clipper.hpp") + file(STRINGS "${POLYCLIPPING_INCLUDE_DIR}/clipper.hpp" POLYCLIPPING_H REGEX "^#define CLIPPER_VERSION \"[^\"]*\"$") + + string(REGEX REPLACE "^.*CLIPPER_VERSION \"([0-9]+).*$" "\\1" POLYCLIPPING_VERSION_MAJOR "${POLYCLIPPING_H}") + string(REGEX REPLACE "^.*CLIPPER_VERSION \"[0-9]+\\.([0-9]+).*$" "\\1" POLYCLIPPING_VERSION_MINOR "${POLYCLIPPING_H}") + string(REGEX REPLACE "^.*CLIPPER_VERSION \"[0-9]+\\.[0-9]+\\.([0-9]+).*$" "\\1" POLYCLIPPING_VERSION_PATCH "${POLYCLIPPING_H}") + set(POLYCLIPPING_VERSION "${POLYCLIPPING_VERSION_MAJOR}.${POLYCLIPPING_VERSION_MINOR}.${POLYCLIPPING_VERSION_PATCH}") + set(POLYCLIPPING_VERSION_COUNT 3) + + # only append a TWEAK version if it exists: + set(POLYCLIPPING_VERSION_TWEAK 0) + if( "${POLYCLIPPING_H}" MATCHES "CLIPPER_VERSION \"[0-9]+\\.[0-9]+\\.[0-9]+\\.([0-9]+)") + set(POLYCLIPPING_VERSION_TWEAK "${CMAKE_MATCH_1}") + set(POLYCLIPPING_VERSION "${POLYCLIPPING_VERSION}.${POLYCLIPPING_VERSION_TWEAK}") + set(POLYCLIPPING_VERSION_COUNT 4) + endif() +endif() + +# handle the QUIETLY and REQUIRED arguments and set POLYCLIPPING_FOUND to TRUE if +# all listed variables are TRUE +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(Polyclipping + REQUIRED_VARS + POLYCLIPPING_INCLUDE_DIR + POLYCLIPPING_LIBRARY + VERSION_VAR + POLYCLIPPING_VERSION +) + +if(POLYCLIPPING_FOUND) + set(POLYCLIPPING_INCLUDE_DIRS ${POLYCLIPPING_INCLUDE_DIR}) + + if(NOT POLYCLIPPING_LIBRARIES) + set(POLYCLIPPING_LIBRARIES ${POLYCLIPPING_LIBRARY}) + endif() + + if(NOT TARGET Polyclipping::Polyclipping) + add_library(Polyclipping::Polyclipping UNKNOWN IMPORTED) + set_target_properties(Polyclipping::Polyclipping PROPERTIES + INTERFACE_INCLUDE_DIRECTORIES "${POLYCLIPPING_INCLUDE_DIRS}") + + if(POLYCLIPPING_LIBRARY_RELEASE) + set_property(TARGET Polyclipping::Polyclipping APPEND PROPERTY + IMPORTED_CONFIGURATIONS RELEASE) + set_target_properties(Polyclipping::Polyclipping PROPERTIES + IMPORTED_LOCATION_RELEASE "${POLYCLIPPING_LIBRARY_RELEASE}") + endif() + + if(POLYCLIPPING_LIBRARY_DEBUG) + set_property(TARGET Polyclipping::Polyclipping APPEND PROPERTY + IMPORTED_CONFIGURATIONS DEBUG) + set_target_properties(Polyclipping::Polyclipping PROPERTIES + IMPORTED_LOCATION_DEBUG "${POLYCLIPPING_LIBRARY_DEBUG}") + endif() + + if(NOT POLYCLIPPING_LIBRARY_RELEASE AND NOT POLYCLIPPING_LIBRARY_DEBUG) + set_property(TARGET Polyclipping::Polyclipping APPEND PROPERTY + IMPORTED_LOCATION "${POLYCLIPPING_LIBRARY}") + endif() + endif() +endif() diff --git a/cmake/toolchain/arm-linux-android-abi-gcc.cmake b/cmake/toolchain/arm-linux-android-abi-gcc.cmake new file mode 100644 index 0000000..244850e --- /dev/null +++ b/cmake/toolchain/arm-linux-android-abi-gcc.cmake @@ -0,0 +1,37 @@ +#include(CMakeForceCompiler) +## Prefix detection only works with compiler id "GNU" +## CMake will look for prefixed g++, cpp, ld, etc. automatically +##CMAKE_FORCE_C_COMPILER(arm-linux-androideabi-gcc GNU) + +# This toolchain file is known to work with: +# TODO: VERIFY Ubuntu 12.04 (Precise) + +# Release build options +set(Mapper_BUILD_QT FALSE CACHE BOOL "Toolchain default") +set(Mapper_BUILD_PROJ TRUE CACHE BOOL "Toolchain default") +set(PROJ_VERSION 4.9.0b2 CACHE STRING "Toolchain default") + +# The name of the target operating system +SET(CMAKE_SYSTEM_NAME Linux) + +# The name of the target system name as known to GNU tools +set(GNU_SYSTEM_NAME arm-linux-androideabi) + +# The GCC version (Major.Minor) +set(GCC_VERSION 4.8) + +# Find the tools +find_program(CMAKE_C_COMPILER NAMES ${GNU_SYSTEM_NAME}-gcc) +find_program(CMAKE_CXX_COMPILER NAMES ${GNU_SYSTEM_NAME}-g++) + +# Set root path and behaviour of FIND_XXX() commands +#set(USER_TARGET_ROOT_PATH "${CMAKE_CURRENT_BINARY_DIR}/usr/${GNU_SYSTEM_NAME}") +#set(CMAKE_FIND_ROOT_PATH /usr/${GNU_SYSTEM_NAME} "${USER_TARGET_ROOT_PATH}") +set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) +set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) + +#set(BUILD_SHARED_LIBS ON) + +# Toolchain properties for gcc 4.6 +#set(TOOLCHAIN_SHARED_LIBS libgcc_s_sjlj-1 libstdc++-6) +set(TOOLCHAIN_PATH_SUFFIXES gcc/${GNU_SYSTEM_NAME}-${GCC_VERSION}) diff --git a/cmake/toolchain/bundle-test.cmake b/cmake/toolchain/bundle-test.cmake new file mode 100644 index 0000000..eb66740 --- /dev/null +++ b/cmake/toolchain/bundle-test.cmake @@ -0,0 +1,39 @@ +# +# Copyright 2012 Kai Pastor +# +# This file is part of OpenOrienteering. +# +# OpenOrienteering is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# OpenOrienteering is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with OpenOrienteering. If not, see . + +# This is a toolchain file for "cross-testing" Mac OS X packaging builds from +# Linux et al. It will not cross compile Mac OS X binaries, but places Linux +# binaries in a Mac OS X bundle file system layout and creates a TGZ archive +# instead of a DMG. +# +# Synopsis: +# cd PROJECT-DIR +# mkdir bundle-test +# cd bundle-test +# cmake .. -DCMAKE_TOOLCHAIN_FILE=../cmake/toolchain/bundle-test.cmake +# cmake . -DAPPLE=1 +# make +# make package +# + +set(CPACK_GENERATOR TGZ CACHE STRING "bundle-test.cmake default") +set(Mapper_BUILD_PROJ TRUE CACHE BOOL "bundle-test.cmake default") +set(Mapper_PACKAGE_ASSISTANT TRUE CACHE BOOL "bundle-test.cmake default") +set(Mapper_PACKAGE_LIBRARIES TRUE CACHE BOOL "bundle-test.cmake default") +set(Mapper_TRANSLATIONS_EMBEDDED TRUE CACHE BOOL "bundle-test.cmake default") + diff --git a/cmake/toolchain/i586-mingw32msvc.cmake b/cmake/toolchain/i586-mingw32msvc.cmake new file mode 100644 index 0000000..87bb7da --- /dev/null +++ b/cmake/toolchain/i586-mingw32msvc.cmake @@ -0,0 +1,35 @@ +# This toolchain file is known to work with: +# Ubuntu 10.04 (Lucid) + +# The name of the target operating system +set(CMAKE_SYSTEM_NAME Windows) + +# The name of the target system name as known to GNU tools +set(GNU_SYSTEM_NAME i586-mingw32msvc) + +# The GCC version (Major.Minor) +set(GCC_VERSION 4.4) + +# The name of the target system name as Qt platform +set(QT_PLATFORM "unsupported/win32-g++-${GCC_VERSION}-cross") + +# The name of a target system known to Qt from which to inherit settings +# when QT_PLATFORM is unknown to Qt +set(QT_PARENT_PLATFORM "unsupported/win32-g++-cross") + +# Find the tools +find_program(CMAKE_C_COMPILER NAMES ${GNU_SYSTEM_NAME}-gcc) +find_program(CMAKE_CXX_COMPILER NAMES ${GNU_SYSTEM_NAME}-g++) +find_program(CMAKE_RC_COMPILER NAMES ${GNU_SYSTEM_NAME}-windres) + +# Set root path and behaviour of FIND_XXX() commands +#set(USER_TARGET_ROOT_PATH "${CMAKE_CURRENT_BINARY_DIR}/usr/${GNU_SYSTEM_NAME}") +#set(CMAKE_FIND_ROOT_PATH /usr/${GNU_SYSTEM_NAME} "${USER_TARGET_ROOT_PATH}") +set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) +set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) + +set(BUILD_SHARED_LIBS ON) + +# Toolchain properties for gcc 4.4 +set(TOOLCHAIN_SHARED_LIBS) +set(TOOLCHAIN_PATH_SUFFIXES gcc/${GNU_SYSTEM_NAME}/${GCC_VERSION}) diff --git a/cmake/toolchain/i686-w64-mingw32.cmake b/cmake/toolchain/i686-w64-mingw32.cmake new file mode 100644 index 0000000..fca0401 --- /dev/null +++ b/cmake/toolchain/i686-w64-mingw32.cmake @@ -0,0 +1,42 @@ +# This toolchain file is known to work with: +# Ubuntu 12.04 (Precise) + +# Release build options +set(Mapper_BUILD_QT TRUE CACHE BOOL "Toolchain default") +set(Mapper_BUILD_PROJ TRUE CACHE BOOL "Toolchain default") + +# The name of the target operating system +set(CMAKE_SYSTEM_NAME Windows) + +# The name of the target system name as known to GNU tools +set(GNU_SYSTEM_NAME i686-w64-mingw32) + +# The GCC version (Major.Minor) +set(GCC_VERSION 4.6) + +# The name of the target system name as Qt platform +set(QT_PLATFORM "unsupported/win32-g++-${GCC_VERSION}-${GNU_SYSTEM_NAME}-cross") + +# The name of a target system known to Qt from which to inherit settings +# when QT_PLATFORM is unknown to Qt +set(QT_PARENT_PLATFORM "unsupported/win32-g++-${GCC_VERSION}-cross") + +# The name of the target system name as Qt5 platform +set(QT5_PLATFORM "-xplatform win32-g++ -device-option CROSS_COMPILE=${GNU_SYSTEM_NAME}-") + +# Find the tools +find_program(CMAKE_C_COMPILER NAMES ${GNU_SYSTEM_NAME}-gcc) +find_program(CMAKE_CXX_COMPILER NAMES ${GNU_SYSTEM_NAME}-g++) +find_program(CMAKE_RC_COMPILER NAMES ${GNU_SYSTEM_NAME}-windres) + +# Set root path and behaviour of FIND_XXX() commands +#set(USER_TARGET_ROOT_PATH "${CMAKE_CURRENT_BINARY_DIR}/usr/${GNU_SYSTEM_NAME}") +#set(CMAKE_FIND_ROOT_PATH /usr/${GNU_SYSTEM_NAME} "${USER_TARGET_ROOT_PATH}") +set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) +set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) + +set(BUILD_SHARED_LIBS ON) + +# Toolchain properties for gcc 4.6 +set(TOOLCHAIN_SHARED_LIBS libgcc_s_sjlj-1 libstdc++-6) +set(TOOLCHAIN_PATH_SUFFIXES gcc/${GNU_SYSTEM_NAME}/${GCC_VERSION}) diff --git a/doc/api/CMakeLists.txt b/doc/api/CMakeLists.txt new file mode 100644 index 0000000..db70896 --- /dev/null +++ b/doc/api/CMakeLists.txt @@ -0,0 +1,95 @@ +# +# Copyright 2012-2015 Kai Pastor +# +# This file is part of OpenOrienteering. +# +# OpenOrienteering is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# OpenOrienteering is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with OpenOrienteering. If not, see . + +message(STATUS "Configuring ${PROJECT_NAME} API documentation") + +set(API_SRCS + extra/code_overview.h + extra/mainpage.h +) + +set(TAG_FILES + qtcore.tags + qtgui.tags + qtwidgets.tags + qtxml.tags + qtnetwork.tags + qtprintsupport.tags +) + +find_program(DOXYGEN_EXECUTABLE NAMES doxygen + DOC "The path of the doxygen executable") +mark_as_advanced(DOXYGEN_EXECUTABLE) + +find_program(GIT_EXECUTABLE NAMES git + DOC "The path of the git executable") +mark_as_advanced(GIT_EXECUTABLE) + +set(API_DOCS_REPOSITORY "https://github.com/OpenOrienteering/api-docs.git" CACHE STRING + "The git repository where to push the api docs (only used on initial clone)") +set(API_DOCS_BRANCH "gh-pages" CACHE STRING + "The git branch where to push the api docs") +set(API_DOCS_PATH "mapper" CACHE STRING + "The path where to push the api docs") + +if(DOXYGEN_EXECUTABLE MATCHES NOTFOUND) + message(STATUS "doxygen executable not found.") +else() + set(url http://doc.qt.io/qt-5/) + foreach(file ${TAG_FILES}) + file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/${file}.cmake" + "file(DOWNLOAD \"${url}${file}\" \"${CMAKE_CURRENT_BINARY_DIR}/${file}\")\n") + add_custom_command(OUTPUT ${file} + COMMAND ${CMAKE_COMMAND} -P "${CMAKE_CURRENT_BINARY_DIR}/${file}.cmake" + COMMENT "Downloading ${file} from ${url}") + endforeach() + + configure_file(api-docs.sh.in api-docs.sh @ONLY) + configure_file(Doxyfile.in Doxyfile @ONLY) + configure_file(versionfilter.sh.in versionfilter.sh @ONLY) + add_custom_target(api-docs + COMMAND "${CMAKE_CURRENT_BINARY_DIR}/api-docs.sh" "${DOXYGEN_EXECUTABLE}" + COMMENT "Generating API documentation" + DEPENDS ${TAG_FILES} + SOURCES ${API_SRCS} + api-docs.sh + ) +endif() + +if(GIT_EXECUTABLE MATCHES NOTFOUND) + message(STATUS "git executable not found.") +elseif(TARGET api-docs) + add_custom_target(api-docs-repository + COMMAND "${CMAKE_CURRENT_SOURCE_DIR}/api-docs-repository.sh" "${API_DOCS_REPOSITORY}" "${API_DOCS_BRANCH}" "${API_DOCS_PATH}" + COMMENT "Preparing API docs repository" + SOURCES api-docs-repository.sh + ) + + add_custom_target(api-docs-commit + COMMAND "${CMAKE_CURRENT_SOURCE_DIR}/api-docs-commit.sh" "${API_DOCS_PATH}" + COMMENT "Committing changed API docs" + SOURCES api-docs-commit.sh + ) + add_dependencies(api-docs-commit api-docs api-docs-repository) + + add_custom_target(api-docs-push + COMMAND git push + COMMENT "Pushing changed API docs to ${API_DOCS_REPOSITORY}" + WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/repository" + ) +endif() diff --git a/doc/api/Doxyfile.in b/doc/api/Doxyfile.in new file mode 100644 index 0000000..ed36238 --- /dev/null +++ b/doc/api/Doxyfile.in @@ -0,0 +1,53 @@ +# +# Copyright 2014 Kai Pastor +# +# This file is part of OpenOrienteering. +# +# OpenOrienteering is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# OpenOrienteering is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with OpenOrienteering. If not, see . + +PROJECT_NAME = "@PROJECT_NAME@" +PROJECT_NUMBER = "@Mapper_VERSION_MAJOR@.@Mapper_VERSION_MINOR@.@Mapper_VERSION_PATCH@" +PROJECT_BRIEF = "API documentation" +PROJECT_LOGO = "@CMAKE_CURRENT_SOURCE_DIR@/../openorienteering.png" + +QUIET = YES + +INPUT = "@PROJECT_SOURCE_DIR@/src" +INPUT += "@PROJECT_SOURCE_DIR@/android/src" +INPUT += "@PROJECT_SOURCE_DIR@/test" +INPUT += "@PROJECT_SOURCE_DIR@/doc/api/extra" +RECURSIVE = YES +STRIP_FROM_PATH = "@PROJECT_SOURCE_DIR@" +FILE_VERSION_FILTER = "@CMAKE_CURRENT_BINARY_DIR@/versionfilter.sh" +SOURCE_BROWSER = NO +VERBATIM_HEADERS = NO + +INCLUDE_PATH += "@PROJECT_SOURCE_DIR@/src/printsupport/qt-5.5.1" +PREDEFINED = QT_PRINTSUPPORT_LIB QT_SENSORS_LIB QT_LOCATION_LIB +PREDEFINED += Qt5Core_VERSION=5.5 Qt5PrintSupport_VERSION=5.5 +JAVADOC_AUTOBRIEF = YES +QT_AUTOBRIEF = YES +BUILTIN_STL_SUPPORT = YES +EXTRACT_ALL = YES +HAVE_DOT = YES +GENERATE_TAGFILE = oomapper.tags +TAGFILES += qtcore.tags=http://doc.qt.io/qt-5/ +TAGFILES += qtgui.tags=http://doc.qt.io/qt-5/ +TAGFILES += qtwidgets.tags=http://doc.qt.io/qt-5/ +TAGFILES += qtxml.tags=http://doc.qt.io/qt-5/ +TAGFILES += qtnetwork.tags=http://doc.qt.io/qt-5/ +TAGFILES += qtprintsupport.tags=http://doc.qt.io/qt-5/ + +GENERATE_LATEX = NO +HTML_TIMESTAMP = NO diff --git a/doc/api/api-docs-commit.sh b/doc/api/api-docs-commit.sh new file mode 100755 index 0000000..531bccf --- /dev/null +++ b/doc/api/api-docs-commit.sh @@ -0,0 +1,38 @@ +#!/bin/sh -e +# +# Copyright 2015 Kai Pastor +# +# This file is part of OpenOrienteering. +# +# OpenOrienteering is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# OpenOrienteering is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with OpenOrienteering. If not, see . + +# Usage: api-docs-commit.sh PATH + +for I in "repository/${1:-.}"/*; do + if [ -e "$I" -a "${I##*/}" != "README.md" ]; then + rm -R "$I" + fi +done + +for I in html/*; do + if [ "${I##*.}" != "md5" -a "${I##*.}" != "map" ]; then + cp -R "$I" "repository/${1:-.}/" + fi +done + +cd repository +git add -A "${1:-.}" +git commit -m "Update${1:+ in $1}" + +echo "Now call \"make api-docs-push\" to publish the updated API docs." diff --git a/doc/api/api-docs-repository.sh b/doc/api/api-docs-repository.sh new file mode 100755 index 0000000..df0d613 --- /dev/null +++ b/doc/api/api-docs-repository.sh @@ -0,0 +1,36 @@ +#!/bin/sh -e +# +# Copyright 2015 Kai Pastor +# +# This file is part of OpenOrienteering. +# +# OpenOrienteering is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# OpenOrienteering is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with OpenOrienteering. If not, see . + +# Usage: api-docs-repository.sh REPOSITORY BRANCH PATH + +if [ ! -f repository.txt -o "$(cat repository.txt)" != "$1" ]; then + if [ -d repository ]; then + rm -Rf repository + fi + echo "$1" > repository.txt +fi + +if [ ! -d repository ]; then + git clone --depth 5 "$1" -b "$2" repository + cd repository +else + cd repository + git checkout "$2" "${3:-.}" + git pull --rebase +fi diff --git a/doc/api/api-docs.sh.in b/doc/api/api-docs.sh.in new file mode 100755 index 0000000..2600b2b --- /dev/null +++ b/doc/api/api-docs.sh.in @@ -0,0 +1,39 @@ +#!/bin/sh -e +# +# Copyright 2015 Kai Pastor +# +# This file is part of OpenOrienteering. +# +# OpenOrienteering is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# OpenOrienteering is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with OpenOrienteering. If not, see . + +# Usage: api-docs.sh DOXYGEN_EXECUTABLE + +SOURCE_DIR=$(echo "@PROJECT_SOURCE_DIR@/" | sed -e "s/\//\\\\\//g") +DOC_DIR=$(echo "@CMAKE_CURRENT_BINARY_DIR@/" | sed -e "s/\//\\\\\//g") + +test -d html || mkdir html + +for I in html/*; do + rm -Rf "$I" +done + +"$1" Doxyfile 2>&1 \ +| sed -e "s/${SOURCE_DIR}//g" > html/doxygen-warnings.txt + +sed -i -e " + s/\( ([^( ]* rev ......., [A-Za-z0-9 ]*)\)\(<\/a>\)/\2\1/ # Footer of class documentation + s/\([^( ]*\) rev \(.......\), /\2<\/tt><\/a> on / + s/\"${DOC_DIR}/\"/g + s/\"${SOURCE_DIR}/\"/g +" html/*.html diff --git a/doc/api/extra/code_overview.h b/doc/api/extra/code_overview.h new file mode 100644 index 0000000..80bd654 --- /dev/null +++ b/doc/api/extra/code_overview.h @@ -0,0 +1,111 @@ +/* + * Copyright 2012, 2013 Thomas Schöps, Kai Pastor + * + * This file is part of OpenOrienteering. + * + * OpenOrienteering is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenOrienteering is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenOrienteering. If not, see . + */ + +/** + +\page code_overview Code overview + +\date 2013-08-31 +\author Kai Pastor +\author Thomas Schöps + +\todo Review and update the code overview. + +\section core Core + +Map is a (too) huge class which represents a complete map. It contains dynamic arrays of: + +- Colors (MapColor) +- Symbols (Symbol) +- Templates (Template) +- Parts (MapPart) which in turn contain objects (Object). + +It also keeps track of the currently selected map objects and contains an UndoManager object. + +Furthermore, it has a MapRenderables renderables whose purpose will be explained soon, +and contains the settings for the georeferencing and for printing / exporting the map. + +Most features of a map are represented by Object. All map objects have got +coordinates, which are stored as a dynamic array of MapCoord. +A PointObject has got a single coordinate. +A TextObject has got either one coordinate (representing a single anchor point) +or two coordinate (representing a text box). For a text box, the first +coordinate gives the center of the box, and the second one its width and height. +For a PathObject, the coordinates are interpreted as a path, +i.e. a line consisting of polygonal and/or cubic bezier curve segments. + +To define paths with different kind of segments, the MapCoord objects store +extra flags: + +- curve start: if set, the coordinate is the first of 4 which define a bezier curve. +- dash point: used for line symbols, can be equivalent to an OC*D dash point or corner point +- hole point: if set, a break in the path starts at this coordinate and ends at the next one. + This is different from OC*D's hole points for areas: in OC*D, the first point of a hole in an area + is marked as a hole point, in OO Mapper the last point of the previous area is marked as hole point. + This is done for consistency with hole points for paths, so there are no hacks needed + for combined objects with lines, areas and holes in it. +- close point: if a path is closed and thus the last coordinate is at the same position + as its first one, the last coordinate is marked as close point. + +For path objects, the coordinates are also processed into another form +which approximates the path using only straight line segments: a vector of PathCoord. +These coordinates also contain information about the cumulative path length, +the parameter value if generated from a bezier curve, and from which segment +of the original coordinates they were generated. + + +\section rendering Rendering + +The process to display map objects works like this: + +- An Object is created, set up and added to a layer of a map. +- object->update(true) can be called to force an update of the object, + otherwise it is updated the next time the map is drawn. +- This update (re)generates the ObjectRenderables, a set of Renderable which + belong to the object. Instances of Renderable are the individual elements + that make up the visualization of the object, such as dots in a dotted line. + The power of a single renderable depends on the actual subclass, + ranging from a simple dot to a line of text. + The constraint is that every renderable uses just one map color. +- The ObjectRenderables are inserted into the MapRenderables of the map, + where they are sorted by their color priority. +- MapRenderables::draw() goes through all Renderables in order, + thus painting them with the correct color priority. + + +\section gui GUI + +The topmost application windows are provided by the MainWindow class. +It is just responsible for the window itself; every MainWindow also has a +subclass of MainWindowController which is responsible for the content. +Currently, this can be the HomeScreenController or MapEditorController, +but in the future there could also be a controller for course setting, for example. + +The MapEditorController has as most important members + +- a Map object which contains colors, symbols, objects etc., +- a MapView object which defines the view properties (zoom level, position offset, rotation), +- a MapWidget responsible for drawing, +- a MapEditorTool current_tool, for example the path drawing tool, +- a MapEditorActivity editor_activity. Activities are used to display stuff + that is common to multiple tools. Example: the TemplateAdjustActivity displays + the pass point positions when adjusting a template. + + +**/ diff --git a/doc/api/extra/mainpage.h b/doc/api/extra/mainpage.h new file mode 100644 index 0000000..c85984e --- /dev/null +++ b/doc/api/extra/mainpage.h @@ -0,0 +1,46 @@ +/* + * Copyright 2012 Thomas Schöps + * Copyright 2013-2015 Kai Pastor + * + * This file is part of OpenOrienteering. + * + * OpenOrienteering is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenOrienteering is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenOrienteering. If not, see . + */ + +/** + +\mainpage OpenOrienteering Mapper Developer Documentation + + +\section pages Contents + +- \subpage code_overview +- Class index +- Warnings issued by doxygen + + +\section links Web Links + +- OpenOrienteering Mapper repository on GitHub +- OpenOrienteering Mapper issues +- OpenOrienteering Mapper developer wiki +- Qt 5 documentation +- CMake documentation +- Doxygen documentation + +
+ +Qt is a trademark of The Qt Company Ltd. + + **/ diff --git a/doc/api/versionfilter.sh.in b/doc/api/versionfilter.sh.in new file mode 100755 index 0000000..9c82041 --- /dev/null +++ b/doc/api/versionfilter.sh.in @@ -0,0 +1,36 @@ +#!/bin/sh -e +# +# Copyright 2015 Kai Pastor +# +# This file is part of OpenOrienteering. +# +# OpenOrienteering is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# OpenOrienteering is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with OpenOrienteering. If not, see . + +FILE=$(echo "${1#@PROJECT_SOURCE_DIR@/}" | sed -e "s/\//\\\\\//g") + +if [ "$1" != "${1#@PROJECT_SOURCE_DIR@/}" ]; then +{ + cd $(dirname "$1") + { + git log -n 1 "${1##*/}" \ + || echo >&2 " at file $1" + } \ + | sed -e " + : start + N + /\\nDate: /! b start + s/commit \(.......\).*Date: *[a-zA-Z]* \([a-zA-Z]*\) \([0-9]*\) ..:..:.. \(20..\).*/$FILE rev \1, \3 \2 \4/ + q" +} +fi diff --git a/doc/coding-style.xml b/doc/coding-style.xml new file mode 100644 index 0000000..1171082 --- /dev/null +++ b/doc/coding-style.xml @@ -0,0 +1,39 @@ + + + + + + CodeStyleData + + true + false + false + true + false + true + false + false + true + false + true + false + true + true + false + true + false + true + false + 4 + true + false + 1 + false + 4 + + + + DisplayName + OpenOrienteering + + diff --git a/doc/licensing/CMakeLists.txt b/doc/licensing/CMakeLists.txt new file mode 100644 index 0000000..6eda8cd --- /dev/null +++ b/doc/licensing/CMakeLists.txt @@ -0,0 +1,102 @@ +# +# Copyright 2014, 2015 Kai Pastor +# +# This file is part of OpenOrienteering. +# +# OpenOrienteering is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# OpenOrienteering is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with OpenOrienteering. If not, see . + + +message(STATUS "Configuring ${PROJECT_NAME} licensing documentation") + + +find_package(Qt5Core REQUIRED) + +# Like Qt5::moc, Qt5::qdoc should come from Qt5CoreConfigExtra.cmake +if (NOT TARGET Qt5::qdoc AND TARGET Qt5::moc) + get_target_property(_qt5_moc_path Qt5::moc IMPORTED_LOCATION) + get_filename_component(_qt5_bin_prefix "${_qt5_moc_path}" PATH) + add_executable(Qt5::qdoc IMPORTED) + set(imported_location ${_qt5_bin_prefix}/qdoc) + if(NOT EXISTS "${imported_location}") + message(FATAL_ERROR "qdoc executable does not exist: " + "${imported_location}") + endif() + set_target_properties(Qt5::qdoc PROPERTIES + IMPORTED_LOCATION ${imported_location} + ) + if(TARGET Qt5) + add_dependencies(Qt5::qdoc Qt5) + endif() +endif() +set(Qt5Core_QDOC_EXECUTABLE Qt5::qdoc) + + +set(LICENSING_SRCS + licensing.qdocconf + licensing-html.qdocconf + licensing.css + src/licensing.qdoc + src/gdal-licensing.qdocinc + src/qt-licensing.qdocinc + src/trademarks.qdocinc + src/apache-2.0.qdoc + src/gpl-3.0.qdoc + src/lgpl-2.1.qdoc + src/lgpl-3.0.qdoc + src/gcc-runtime-library-exception.qdoc +) + +add_custom_target(licensing-sources + COMMENT "This target makes Qt Creator show all sources in the project tree." + SOURCES licensing.pro licensing.qrc ${LICENSING_SRCS} +) + +add_custom_command( + OUTPUT html/licensing.html + COMMENT "Running qdoc on licensing documentation" + COMMAND ${Qt5Core_QDOC_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/licensing.qdocconf" + -outputdir "${CMAKE_CURRENT_BINARY_DIR}/html" + DEPENDS ${LICENSING_SRCS} +) + +if(NOT CMAKE_CURRENT_SOURCE_DIR STREQUAL ${CMAKE_CURRENT_BINARY_DIR}) + add_custom_command( + OUTPUT licensing.qrc + COMMAND ${CMAKE_COMMAND} -E copy "${CMAKE_CURRENT_SOURCE_DIR}/licensing.qrc" licensing.qrc + DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/licensing.qrc" html/licensing.html + ) + qt5_add_resources(LICENSING_QRC_CPP + "${CMAKE_CURRENT_BINARY_DIR}/licensing.qrc" + OPTIONS -compress 9 -threshold 50 + ) +else() + add_custom_command( + OUTPUT licensing.tmp.qrc + COMMAND ${CMAKE_COMMAND} -E copy "${CMAKE_CURRENT_SOURCE_DIR}/licensing.qrc" licensing.tmp.qrc + DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/licensing.qrc" html/licensing.html + ) + qt5_add_resources(LICENSING_QRC_CPP + "${CMAKE_CURRENT_BINARY_DIR}/licensing.tmp.qrc" + OPTIONS -compress 9 -threshold 50 + ) +endif() + +add_library(doc-licensing + STATIC + ${LICENSING_QRC_CPP} +) + +target_link_libraries(doc-licensing + PUBLIC Qt5::Core +) diff --git a/doc/licensing/licensing-html.qdocconf b/doc/licensing/licensing-html.qdocconf new file mode 100644 index 0000000..234cb7e --- /dev/null +++ b/doc/licensing/licensing-html.qdocconf @@ -0,0 +1,28 @@ +# +# Copyright 2014 Kai Pastor +# +# This file is part of OpenOrienteering. +# +# OpenOrienteering is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# OpenOrienteering is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with OpenOrienteering. If not, see . + +HTML.stylesheets = licensing.css + +HTML.headerstyles = \ + " \n" + +# HTML.nonavigationbar = "true" + +macro.break.HTML = "
" +macro.copyright.HTML = "©" +macro.reg.HTML = "®" diff --git a/doc/licensing/licensing.css b/doc/licensing/licensing.css new file mode 100644 index 0000000..37bb290 --- /dev/null +++ b/doc/licensing/licensing.css @@ -0,0 +1,50 @@ +/* + * Copyright 2014 Kai Pastor + * + * This file is part of OpenOrienteering. + * + * OpenOrienteering is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenOrienteering is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenOrienteering. If not, see . + */ + + +body { + font-family: Arial, Helvetica; +} + +body:first-child { + font-size: 200%; +} + +blockquote { + margin-left: 20px; +} + +#buildversion { + display:none; +} + +.toc .level1 { +} + +.toc .level2 { + margin-left: 10px; +} + +.toc .level3 { + margin-left: 20px; +} + +.clearfix { + clear: both +} diff --git a/doc/licensing/licensing.pro b/doc/licensing/licensing.pro new file mode 100644 index 0000000..146685a --- /dev/null +++ b/doc/licensing/licensing.pro @@ -0,0 +1,85 @@ +# +# Copyright 2014, 2015 Kai Pastor +# +# This file is part of OpenOrienteering. +# +# OpenOrienteering is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# OpenOrienteering is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with OpenOrienteering. If not, see . + +TEMPLATE = lib +TARGET = doc-licensing +CONFIG += staticlib +CONFIG += c++11 +CONFIG -= debug_and_release +QT = core + +android { + # Avoid staticlib install by undocumented behaviour of qmake + INSTALLS = target + target.extra = @test -d . +} + +SOURCES = $$OUT_PWD/licensing_qrc.cpp + +LICENSING_SRCS = \ + $$PWD/licensing.qdocconf \ + $$PWD/licensing-html.qdocconf \ + $$PWD/licensing.css \ + $$PWD/src/licensing.qdoc \ + $$PWD/src/gdal-licensing.qdocinc \ + $$PWD/src/qt-licensing.qdocinc \ + $$PWD/src/trademarks.qdocinc \ + $$PWD/src/apache-2.0.qdoc \ + $$PWD/src/gpl-3.0.qdoc \ + $$PWD/src/lgpl-2.1.qdoc \ + $$PWD/src/lgpl-3.0.qdoc \ + $$PWD/src/gcc-runtime-library-exception.qdoc + +OTHER_FILES = \ + $$LICENSING_SRCS \ + CMakeLists.txt \ + licensing.css \ + licensing.qdocconf \ + licensing-html.qdocconf \ + licensing.qrc + +QMAKE_DIR = $$dirname(QMAKE_QMAKE) + +licensing_html.target = html/licensing.html +licensing_html.commands = \ + $$shell_quote($$QMAKE_DIR/qdoc) $$shell_quote($$PWD/licensing.qdocconf) -outputdir $$shell_quote($$OUT_PWD/html) +licensing_html.depends = $$LICENSING_SRCS Makefile + +licensing_qrc.target = licensing.qrc +licensing_qrc.commands = \ + $(COPY_FILE) $$shell_quote($$PWD/licensing.qrc) licensing.qrc +licensing_qrc.depends = $$PWD/licensing.qrc + +licensing_qrc_cpp.target = licensing_qrc.cpp +licensing_qrc_cpp.commands = \ + $$shell_quote($$QMAKE_DIR/rcc) -name licensing licensing.qrc -o licensing_qrc.cpp +licensing_qrc_cpp.depends = $$licensing_html.target $$licensing_qrc.target + +QMAKE_EXTRA_TARGETS += licensing_html licensing_qrc licensing_qrc_cpp +PRE_TARGETDEPS += $$licensing_qrc_cpp.target +QMAKE_CLEAN += $$licensing_qrc_cpp.target $$licensing_qrc.target + +win32: LICENSING_LIB = $$OUT_PWD/lib"$$TARGET".lib +else: LICENSING_LIB = $$OUT_PWD/lib"$$TARGET".a + +LICENSING_PRI = \ + "$$LITERAL_HASH Generated by $$_PRO_FILE_" \ + "DEPENDPATH += $$OUT_PWD" \ + "LIBS += \"-L$$OUT_PWD\" -ldoc-licensing" + +write_file($$OUT_PWD/licensing.pri, LICENSING_PRI) diff --git a/doc/licensing/licensing.qdocconf b/doc/licensing/licensing.qdocconf new file mode 100644 index 0000000..3d90d80 --- /dev/null +++ b/doc/licensing/licensing.qdocconf @@ -0,0 +1,35 @@ +# +# Copyright 2014 Kai Pastor +# +# This file is part of OpenOrienteering. +# +# OpenOrienteering is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# OpenOrienteering is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with OpenOrienteering. If not, see . + +project = OpenOrienteering Mapper +description = Information on Licensing + +naturallanguage = en_US +sourceencoding = UTF-8 +outputencoding = UTF-8 +outputformats = HTML + +sourcedirs = src +sources.fileextensions += *.qdoc + +# exampledirs = +# headerdirs = +# imagedirs = +# excludedirs = + +include(licensing-html.qdocconf) diff --git a/doc/licensing/licensing.qrc b/doc/licensing/licensing.qrc new file mode 100644 index 0000000..3fc58a7 --- /dev/null +++ b/doc/licensing/licensing.qrc @@ -0,0 +1,11 @@ + + + html/licensing.html + html/apache-2-0.html + html/gcc-runtime-library-exception-3-1.html + html/gpl-3-0.html + html/lgpl-2-1.html + html/lgpl-3-0.html + html/style/licensing.css + + diff --git a/doc/licensing/src/apache-2.0.qdoc b/doc/licensing/src/apache-2.0.qdoc new file mode 100644 index 0000000..bb79e6f --- /dev/null +++ b/doc/licensing/src/apache-2.0.qdoc @@ -0,0 +1,219 @@ +// This file is part of OpenOrienteering. + +/*! + +\page apache-2.0 + +\title Apache License + Version 2.0, January 2004 \break + \l http://www.apache.org/licenses/ + +\section1 TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +\list 1 + \li Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + \li Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + \li Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + \li Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + \list + \li (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + \li (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + \li (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + \li (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + \endlist + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + \li Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + \li Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + \li Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + \li Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + \li Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. +\endlist + + END OF TERMS AND CONDITIONS + +\section1 APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + +\code + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +\endcode + +\hr + +\e Reference: \l{http://www.apache.org/licenses/LICENSE-2.0} + +*/ diff --git a/doc/licensing/src/gcc-runtime-library-exception.qdoc b/doc/licensing/src/gcc-runtime-library-exception.qdoc new file mode 100644 index 0000000..f87454a --- /dev/null +++ b/doc/licensing/src/gcc-runtime-library-exception.qdoc @@ -0,0 +1,86 @@ +// This file is part of OpenOrienteering. + +/*! + +\page gcc-runtime-library-exception-3.1 + +\title GCC Runtime Library Exception + +\section1 GCC RUNTIME LIBRARY EXCEPTION + + Version 3.1, 31 March 2009 + + Copyright (C) 2009 Free Software Foundation, Inc. + + Everyone is permitted to copy and distribute verbatim copies of this + license document, but changing it is not allowed. + + This GCC Runtime Library Exception ("Exception") is an additional + permission under section 7 of the GNU General Public License, version + 3 ("GPLv3"). It applies to a given file (the "Runtime Library") that + bears a notice placed by the copyright holder of the file stating that + the file is governed by GPLv3 along with this Exception. + + When you use GCC to compile a program, GCC may combine portions of + certain GCC header files and runtime libraries with the compiled + program. The purpose of this Exception is to allow compilation of + non-GPL (including proprietary) programs to use, in this way, the + header files and runtime libraries covered by this Exception. + +\section2 0. Definitions. + + A file is an "Independent Module" if it either requires the Runtime + Library for execution after a Compilation Process, or makes use of an + interface provided by the Runtime Library, but is not otherwise based + on the Runtime Library. + + "GCC" means a version of the GNU Compiler Collection, with or without + modifications, governed by version 3 (or a specified later version) of + the GNU General Public License (GPL) with the option of using any + subsequent versions published by the FSF. + + "GPL-compatible Software" is software whose conditions of propagation, + modification and use would permit combination with GCC in accord with + the license of GCC. + + "Target Code" refers to output from any compiler for a real or virtual + target processor architecture, in executable form or suitable for + input to an assembler, loader, linker and/or execution + phase. Notwithstanding that, Target Code does not include data in any + format that is used as a compiler intermediate representation, or used + for producing a compiler intermediate representation. + + The "Compilation Process" transforms code entirely represented in + non-intermediate languages designed for human-written code, and/or in + Java Virtual Machine byte code, into Target Code. Thus, for example, + use of source code generators and preprocessors need not be considered + part of the Compilation Process, since the Compilation Process can be + understood as starting with the output of the generators or + preprocessors. + + A Compilation Process is "Eligible" if it is done using GCC, alone or + with other GPL-compatible software, or if it is done without using any + work based on GCC. For example, using non-GPL-compatible Software to + optimize any GCC intermediate representations would not qualify as an + Eligible Compilation Process. + +\section2 1. Grant of Additional Permission. + + You have permission to propagate a work of Target Code formed by + combining the Runtime Library with Independent Modules, even if such + propagation would otherwise violate the terms of GPLv3, provided that + all Target Code was generated by Eligible Compilation Processes. You + may then convey such a combination under terms of your choice, + consistent with the licensing of the Independent Modules. + +\section2 2. No Weakening of GCC Copyleft. + + The availability of this Exception does not imply any general + presumption that third-party software is unaffected by the copyleft + requirements of the license of GCC. + +\hr + +\e Reference: \l{http://gcc.gnu.org/onlinedocs/libstdc++/manual/license.html} + +*/ diff --git a/doc/licensing/src/gdal-licensing.qdocinc b/doc/licensing/src/gdal-licensing.qdocinc new file mode 100644 index 0000000..261f2c7 --- /dev/null +++ b/doc/licensing/src/gdal-licensing.qdocinc @@ -0,0 +1,268 @@ +\omit +// This file is part of OpenOrienteering. +\endomit + + \note Depending on the actual package, a particular copy of OpenOrienteering Mapper + may not contain code covered by one or more of the licenses listed here. + +In general GDAL/OGR is licensed under an MIT/X style license with the +following terms: + +\quotation +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, distribute, sublicense, +and/or sell copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +\endquotation + + +\section3 gdal/frmts/gtiff/tif_float.c + +\quotation +Copyright (c) 2002, Industrial Light & Magic, a division of Lucas +Digital Ltd. LLC + +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: +\list +\li Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. +\li Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. +\li Neither the name of Industrial Light & Magic nor the names of +its contributors may be used to endorse or promote products derived +from this software without specific prior written permission. +\endlist +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +\endquotation + + +\section3 gdal/frmts/hdf4/hdf-eos/* + +\quotation + Copyright (C) 1996 Hughes and Applied Research Corporation + + Permission to use, modify, and distribute this software and its documentation + for any purpose without fee is hereby granted, provided that the above + copyright notice appear in all copies and that both that copyright notice and + this permission notice appear in supporting documentation. +\endquotation + + +\section3 gdal/frmts/pcraster/libcsf + +\quotation +Copyright (c) 1997-2003, Utrecht University +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +\list +\li Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + +\li Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + +\li Neither the name of Utrecht University nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. +\endlist +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +\endquotation + + +\section3 gdal/frmts/grib/degrib/* + +The degrib and g2clib source code are modified versions of code produced +by NOAA NWS and are in the public domain subject to the following +restrictions: + +\quotation +http://www.weather.gov/im/softa.htm + +DISCLAIMER The United States Government makes no warranty, expressed or +implied, as to the usefulness of the software and documentation for any +purpose. The U.S. Government, its instrumentalities, officers, employees, +and agents assumes no responsibility (1) for the use of the software and +documentation listed below, or (2) to provide technical support to users. + +http://www.weather.gov/disclaimer.php + + The information on government servers are in the public domain, unless +specifically annotated otherwise, and may be used freely by the public so +long as you do not 1) claim it is your own (e.g. by claiming copyright for +NWS information -- see below), 2) use it in a manner that implies an +endorsement or affiliation with NOAA/NWS, or 3) modify it in content and +then present it as official government material. You also cannot present +information of your own in a way that makes it appear to be official +government information.. + + The user assumes the entire risk related to its use of this data. NWS is +providing this data "as is," and NWS disclaims any and all warranties, +whether express or implied, including (without limitation) any implied +warranties of merchantability or fitness for a particular purpose. In no +event will NWS be liable to you or to any third party for any direct, +indirect, incidental, consequential, special or exemplary damages or lost +profit resulting from any use or misuse of this data. + + As required by 17 U.S.C. 403, third parties producing copyrighted works +consisting predominantly of the material appearing in NWS Web pages must +provide notice with such work(s) identifying the NWS material incorporated +and stating that such material is not subject to copyright protection. +\endquotation + + +\section3 port/cpl_minizip* + +This is version 2005-Feb-10 of the Info-ZIP copyright and license. +The definitive version of this document should be available at +ftp://ftp.info-zip.org/pub/infozip/license.html indefinitely. + +\quotation +Copyright (c) 1990-2005 Info-ZIP. All rights reserved. + +For the purposes of this copyright and license, "Info-ZIP" is defined as +the following set of individuals: + + Mark Adler, John Bush, Karl Davis, Harald Denker, Jean-Michel Dubois, + Jean-loup Gailly, Hunter Goatley, Ed Gordon, Ian Gorman, Chris Herborth, + Dirk Haase, Greg Hartwig, Robert Heath, Jonathan Hudson, Paul Kienitz, + David Kirschbaum, Johnny Lee, Onno van der Linden, Igor Mandrichenko, + Steve P. Miller, Sergio Monesi, Keith Owens, George Petrov, Greg Roelofs, + Kai Uwe Rommel, Steve Salisbury, Dave Smith, Steven M. Schweda, + Christian Spieler, Cosmin Truta, Antoine Verheijen, Paul von Behren, + Rich Wales, Mike White + +This software is provided "as is," without warranty of any kind, express +or implied. In no event shall Info-ZIP or its contributors be held liable +for any direct, indirect, incidental, special or consequential damages +arising out of the use of or inability to use this software. + +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it +freely, subject to the following restrictions: +\list 1 +\li Redistributions of source code must retain the above copyright notice, + definition, disclaimer, and this list of conditions. + +\li Redistributions in binary form (compiled executables) must reproduce + the above copyright notice, definition, disclaimer, and this list of + conditions in documentation and/or other materials provided with the + distribution. The sole exception to this condition is redistribution + of a standard UnZipSFX binary (including SFXWiz) as part of a + self-extracting archive; that is permitted without inclusion of this + license, as long as the normal SFX banner has not been removed from + the binary or disabled. + +\li Altered versions--including, but not limited to, ports to new operating + systems, existing ports with new graphical interfaces, and dynamic, + shared, or static library versions--must be plainly marked as such + and must not be misrepresented as being the original source. Such + altered versions also must not be misrepresented as being Info-ZIP + releases--including, but not limited to, labeling of the altered + versions with the names "Info-ZIP" (or any variation thereof, including, + but not limited to, different capitalizations), "Pocket UnZip," "WiZ" + or "MacZip" without the explicit permission of Info-ZIP. Such altered + versions are further prohibited from misrepresentative use of the + Zip-Bugs or Info-ZIP e-mail addresses or of the Info-ZIP URL(s). + +\li Info-ZIP retains the right to use the names "Info-ZIP," "Zip," "UnZip," + "UnZipSFX," "WiZ," "Pocket UnZip," "Pocket Zip," and "MacZip" for its + own source and binary releases. +\endlist +\endquotation + + +\section3 gdal/ogr/ogrsf_frmts/dxf/intronurbs.cpp + +This code is derived from the code associated with the book "An Introduction +to NURBS" by David F. Rogers. More information on the book and the code is +available at: + + http://www.nar-associates.com/nurbs/ + +\quotation +Copyright (c) 2009, David F. Rogers +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: +\list +\li Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. +\li Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. +\li Neither the name of the David F. Rogers nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. +\endlist +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +\endquotation + + +\section3 gdal/alg/thinplatespline.cpp + +IEEE754 log() code derived from: +@(#)e_log.c 1.3 95/01/18 + +\quotation +Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + +Developed at SunSoft, a Sun Microsystems, Inc. business. +Permission to use, copy, modify, and distribute this +software is freely granted, provided that this notice +is preserved. +\endquotation diff --git a/doc/licensing/src/gpl-3.0.qdoc b/doc/licensing/src/gpl-3.0.qdoc new file mode 100644 index 0000000..c023adf --- /dev/null +++ b/doc/licensing/src/gpl-3.0.qdoc @@ -0,0 +1,702 @@ +// This file is part of OpenOrienteering. + +/*! + +\page gpl-3.0 + +\title GNU General Public License + +\chapter GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. <\l{http://fsf.org/}> \break + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +\section1 Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + +\section1 TERMS AND CONDITIONS + +\section2 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + +\section2 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + +\section2 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + +\section2 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + +\section2 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + +\section2 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + +\list +\li a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + +\li b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + +\li c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + +\li d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. +\endlist + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + +\section2 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + +\list +\li a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + +\li b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + +\li c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + +\li d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + +\li e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. +\endlist + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + +\section2 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + +\list +\li a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + +\li b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + +\li c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + +\li d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + +\li e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + +\li f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. +\endlist + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + +\section2 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + +\section2 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + +\section2 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + +\section2 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + +\section2 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + +\section2 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + +\section2 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + +\section2 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + +\section2 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + +\section2 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + +\section1 How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + +\quotation +\code + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +\endcode +\endquotation + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + +\quotation +\code + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. +\endcode +\endquotation + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +<\l{http://www.gnu.org/licenses/}>. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +<\l{http://www.gnu.org/philosophy/why-not-lgpl.html}>. + +\hr + +\e Reference: \l{http://www.gnu.org/licenses/gpl-3.0.en.html} + +*/ diff --git a/doc/licensing/src/lgpl-2.1.qdoc b/doc/licensing/src/lgpl-2.1.qdoc new file mode 100644 index 0000000..f8d9c6c --- /dev/null +++ b/doc/licensing/src/lgpl-2.1.qdoc @@ -0,0 +1,528 @@ +// This file is part of OpenOrienteering. + +/*! + +\page lgpl-2.1 + +\title GNU Lesser General Public License + + GNU LESSER GENERAL PUBLIC LICENSE \break + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. \break + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA \break + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + +\section1 Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + +\section1 GNU LESSER GENERAL PUBLIC LICENSE +\section1 TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + +\list +\li a) The modified work must itself be a software library. + +\li b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + +\li c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + +\li d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) +\endlist + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + +\list +\li a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + +\li b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + +\li c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + +\li d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + +\li e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. +\endlist + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + +\list +\li a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + +\li b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. +\endlist + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + +\section2 NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + +\section1 How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + +\quotation +\code + + Copyright (C) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +\endcode +\endquotation + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + +\quotation + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + , 1 April 1990 \break + Ty Coon, President of Vice +\endquotation + +That's all there is to it! + +\hr + +\e Reference: \l{http://www.gnu.org/licenses/lgpl-2.1.en.html} + +*/ diff --git a/doc/licensing/src/lgpl-3.0.qdoc b/doc/licensing/src/lgpl-3.0.qdoc new file mode 100644 index 0000000..053c067 --- /dev/null +++ b/doc/licensing/src/lgpl-3.0.qdoc @@ -0,0 +1,189 @@ +// This file is part of OpenOrienteering. + +/*! + +\page lgpl-3.0 + +\title GNU Lesser General Public License Version 3 + + GNU LESSER GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + + This version of the GNU Lesser General Public License incorporates +the terms and conditions of version 3 of the GNU General Public +License, supplemented by the additional permissions listed below. + +\section2 0. Additional Definitions. + + As used herein, "this License" refers to version 3 of the GNU Lesser +General Public License, and the "GNU GPL" refers to version 3 of the GNU +General Public License. + + "The Library" refers to a covered work governed by this License, +other than an Application or a Combined Work as defined below. + + An "Application" is any work that makes use of an interface provided +by the Library, but which is not otherwise based on the Library. +Defining a subclass of a class defined by the Library is deemed a mode +of using an interface provided by the Library. + + A "Combined Work" is a work produced by combining or linking an +Application with the Library. The particular version of the Library +with which the Combined Work was made is also called the "Linked +Version". + + The "Minimal Corresponding Source" for a Combined Work means the +Corresponding Source for the Combined Work, excluding any source code +for portions of the Combined Work that, considered in isolation, are +based on the Application, and not on the Linked Version. + + The "Corresponding Application Code" for a Combined Work means the +object code and/or source code for the Application, including any data +and utility programs needed for reproducing the Combined Work from the +Application, but excluding the System Libraries of the Combined Work. + +\section2 1. Exception to Section 3 of the GNU GPL. + + You may convey a covered work under sections 3 and 4 of this License +without being bound by section 3 of the GNU GPL. + +\section2 2. Conveying Modified Versions. + + If you modify a copy of the Library, and, in your modifications, a +facility refers to a function or data to be supplied by an Application +that uses the facility (other than as an argument passed when the +facility is invoked), then you may convey a copy of the modified +version: + +\list +\li a) under this License, provided that you make a good faith effort to + ensure that, in the event an Application does not supply the + function or data, the facility still operates, and performs + whatever part of its purpose remains meaningful, or + +\li b) under the GNU GPL, with none of the additional permissions of + this License applicable to that copy. +\endlist + +\section2 3. Object Code Incorporating Material from Library Header Files. + + The object code form of an Application may incorporate material from +a header file that is part of the Library. You may convey such object +code under terms of your choice, provided that, if the incorporated +material is not limited to numerical parameters, data structure +layouts and accessors, or small macros, inline functions and templates +(ten or fewer lines in length), you do both of the following: + +\list +\li a) Give prominent notice with each copy of the object code that the + Library is used in it and that the Library and its use are + covered by this License. + +\li b) Accompany the object code with a copy of the GNU GPL and this license + document. +\endlist + +\section2 4. Combined Works. + + You may convey a Combined Work under terms of your choice that, +taken together, effectively do not restrict modification of the +portions of the Library contained in the Combined Work and reverse +engineering for debugging such modifications, if you also do each of +the following: + +\list +\li a) Give prominent notice with each copy of the Combined Work that + the Library is used in it and that the Library and its use are + covered by this License. + +\li b) Accompany the Combined Work with a copy of the GNU GPL and this license + document. + +\li c) For a Combined Work that displays copyright notices during + execution, include the copyright notice for the Library among + these notices, as well as a reference directing the user to the + copies of the GNU GPL and this license document. + +\li d) Do one of the following: + + \list + \li 0) Convey the Minimal Corresponding Source under the terms of this + License, and the Corresponding Application Code in a form + suitable for, and under terms that permit, the user to + recombine or relink the Application with a modified version of + the Linked Version to produce a modified Combined Work, in the + manner specified by section 6 of the GNU GPL for conveying + Corresponding Source. + + \li 1) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (a) uses at run time + a copy of the Library already present on the user's computer + system, and (b) will operate properly with a modified version + of the Library that is interface-compatible with the Linked + Version. + \endlist + +\li e) Provide Installation Information, but only if you would otherwise + be required to provide such information under section 6 of the + GNU GPL, and only to the extent that such information is + necessary to install and execute a modified version of the + Combined Work produced by recombining or relinking the + Application with a modified version of the Linked Version. (If + you use option 4d0, the Installation Information must accompany + the Minimal Corresponding Source and Corresponding Application + Code. If you use option 4d1, you must provide the Installation + Information in the manner specified by section 6 of the GNU GPL + for conveying Corresponding Source.) +\endlist + +\section2 5. Combined Libraries. + + You may place library facilities that are a work based on the +Library side by side in a single library together with other library +facilities that are not Applications and are not covered by this +License, and convey such a combined library under terms of your +choice, if you do both of the following: + +\list +\li a) Accompany the combined library with a copy of the same work based + on the Library, uncombined with any other library facilities, + conveyed under the terms of this License. + +\li b) Give prominent notice with the combined library that part of it + is a work based on the Library, and explaining where to find the + accompanying uncombined form of the same work. +\endlist + +\section2 6. Revised Versions of the GNU Lesser General Public License. + + The Free Software Foundation may publish revised and/or new versions +of the GNU Lesser General Public License from time to time. Such new +versions will be similar in spirit to the present version, but may +differ in detail to address new problems or concerns. + + Each version is given a distinguishing version number. If the +Library as you received it specifies that a certain numbered version +of the GNU Lesser General Public License "or any later version" +applies to it, you have the option of following the terms and +conditions either of that published version or of any later version +published by the Free Software Foundation. If the Library as you +received it does not specify a version number of the GNU Lesser +General Public License, you may choose any version of the GNU Lesser +General Public License ever published by the Free Software Foundation. + + If the Library as you received it specifies that a proxy can decide +whether future versions of the GNU Lesser General Public License shall +apply, that proxy's public statement of acceptance of any version is +permanent authorization for you to choose that version for the +Library. + +\hr + +\e Reference: \l{http://www.gnu.org/licenses/lgpl-3.0.en.html} + +*/ diff --git a/doc/licensing/src/licensing.qdoc b/doc/licensing/src/licensing.qdoc new file mode 100644 index 0000000..869a610 --- /dev/null +++ b/doc/licensing/src/licensing.qdoc @@ -0,0 +1,265 @@ +/* + * Copyright 2014, 2015 Kai Pastor + * + * This file is part of OpenOrienteering. + * + * OpenOrienteering is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenOrienteering is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenOrienteering. If not, see . + */ + + +/*! + +\page licensing +\title OpenOrienteering Mapper Licensing + +\section1 OpenOrienteering Mapper + +\e {OpenOrienteering Mapper is a free software for drawing orienteering maps.} \break +\l http://openorienteering.org + +Copyright (C) 2012-2015 Kai Pastor, Thomas Schöps + +This program is free software: you can redistribute it and/or modify +it under the terms of the \l{GNU General Public License} as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +\l{GNU General Public License} (GPL) for more details. + + + +\section1 Third-party licenses, copyright notices, conditions and disclaimers + +OpenOrienteering Mapper includes, uses and/or is bundled with various +third-party material. +This document provides licensing information, copyright notices, conditions +and disclaimers for binary distributions of OpenOrienteering Mapper. +If you want to distribute or modify OpenOrienteering Mapper it is your +responsibility to ensure that you have met the licensing requirements of this +program and of any third-party material you are using or distributing. + +\note Depending on the actual package, a particular copy of OpenOrienteering +Mapper may not contain code covered by one or more of the licenses listed here. +The following information reflects the versions which are part of the releases +for Windows, OS X and Android. Linux packages will use the distribution's +packages for most 3rd-party-components. These 3rd-party packages come with +independent documentation on copyright and license terms. + + +\section2 Clipper library + +\e {The Clipper Library has been designed to perform boolean operations on + polygons, and polygon and polyline offsetting.} \break +\l http://www.angusj.com/delphi/clipper.php + +\quotation +Copyright (C) 2010-2014 Angus Johnson + +The Clipper Library (including Delphi, C++ & C# source code, other accompanying +code, examples and documentation), hereafter called "the Software", has been +released under the following license, terms and conditions: + +Boost Software License - Version 1.0 - August 17th, 2003 \break +\l http://www.boost.org/LICENSE_1_0.txt + +Permission is hereby granted, free of charge, to any person or organization +obtaining a copy of the Software covered by this license to use, reproduce, +display, distribute, execute, and transmit the Software, and to prepare +derivative works of the Software, and to permit third-parties to whom the +Software is furnished to do so, all subject to the following: + +The copyright notices in the Software and this entire statement, including the +above license grant, this restriction and the following disclaimer, must be +included in all copies of the Software, in whole or in part, and all derivative +works of the Software, unless such copies or derivative works are solely in the +form of machine-executable object code generated by a source language processor. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL +THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE FOR ANY +DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +\endquotation + + +\section2 GDAL - Geospatial Data Abstraction Library + +\e {GDAL is an open source X/MIT licensed translator library for raster and + vector geospatial data formats.} +\break +\l http://www.gdal.org/ + +\include gdal-licensing.qdocinc + + +\section2 GNU Standard C++ Library v3 + +\e {The GNU Standard C++ Library v3 is an ongoing project to implement the + ISO 14882 Standard C++ library as described in chapters 17 through 27 and + annex D.} \break +\l http://gcc.gnu.org/libstdc++/ + +\quotation + Copyright (C) 2014 Free Software Foundation, Inc. + + This library is free + software; you can redistribute it and/or modify it under the + terms of the \l{GNU General Public License} as published by the + Free Software Foundation; either version 3, or (at your option) + any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + Under Section 7 of GPL version 3, you are granted additional + permissions described in the \l{GCC Runtime Library Exception}, version + 3.1, as published by the Free Software Foundation. +\endquotation + + +\section2 PROJ.4 package + +\e {A cartographic projection software.} \break +\l http://trac.osgeo.org/proj/ + +\quotation +Copyright (c) 2000, Frank Warmerdam + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, distribute, sublicense, +and/or sell copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +\endquotation + + +\section2 Qt Solutions Component: Single Application + +\e {The QtSingleApplication component provides support for + applications that can be only started once per user.} \break +\l http://code.qt.io/cgit/qt-solutions/qt-solutions.git/ + +\quotation + Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +\endquotation + +\quotation + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + +\list + \li Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + \li Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + \li Neither the name of Digia Plc and its Subsidiary(-ies) nor the names + of its contributors may be used to endorse or promote products derived + from this software without specific prior written permission. +\endlist + + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +\endquotation + + +\section2 Qt Toolkit + +\e {Qt is a C++ toolkit for cross-platform application development. + Qt is The Qt Company Ltd product developed as an open source project.} +\break +\l http://qt.io + +For version, copyright and license terms of Qt see menu item Help > About Qt. +OpenOrienteering Mapper uses Qt under the terms of the +\l{GNU Lesser General Public License Version 3}. + +\include qt-licensing.qdocinc + + +\section2 Zlib Data Compression Library + +The 'zlib' compression library provides in-memory compression and +decompression functions + +\quotation + (C) 1995-2013 Jean-loup Gailly and Mark Adler + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + +\list 1 + \li The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + \li Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + \li This notice may not be removed or altered from any source distribution. +\endlist +\endquotation + + +\section1 Trademarks + +\include trademarks.qdocinc + + +\section1 Full Text of Selected Licenses + +\list + \li \l{Apache License}, version 2.0 + \li \l{GCC Runtime Library Exception}, version 3.1 + \li \l{GNU General Public License} (GPL), version 3.0 + \li \l{GNU Lesser General Public License} (LGPL), version 2.1 + \li \l{GNU Lesser General Public License Version 3} (LGPLv3) +\endlist + +*/ diff --git a/doc/licensing/src/qt-licensing.qdocinc b/doc/licensing/src/qt-licensing.qdocinc new file mode 100644 index 0000000..422c04c --- /dev/null +++ b/doc/licensing/src/qt-licensing.qdocinc @@ -0,0 +1,1587 @@ +\omit +/* + * Copyright 2014, 2015 Kai Pastor + * + * This file is part of OpenOrienteering. + * + * OpenOrienteering is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenOrienteering is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenOrienteering. If not, see . + */ +\endomit + + + +\section2 Licenses Used in Qt 5.5.1 + +This section lists other licenses used in Qt or in libraries that are supplied +alongside Qt modules, not provided under the +\l{GNU Lesser General Public License Version 3}. + +\note Depending on the actual package, a particular copy of OpenOrienteering Mapper + may not contain code covered by one or more of the licenses listed here. + + + +\section3 at-spi and at-spi2 + +This license applies to +\c{qtbase/src/3rd-party/atspi2/}. +In OpenOrienteering Mapper, this code is used under the terms of the +\l{GNU General Public License}, version 3. + +\quotation + Copyright 2010, 2011 Novell, Inc. \break + Copyright (c) 2012 SUSE LINUX Products GmbH, Nuernberg, Germany. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +\endquotation + + + +\section3 Big5 Text Codec + +This license applies to parts of some files in +\c{qtbase/src/corelib/codecs/}. + +\quotation + Copyright (C) 2000 Ming-Che Chuang \break + Copyright (C) 2002 James Su, Turbolinux Inc. \break + Copyright (C) 2002 Anthony Fok, ThizLinux Laboratory Ltd. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + +\list 1 + \li Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + \li Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +\endlist + + THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. +\endquotation + + + +\section3 Big5-HKSCS Text Codec + +This license applies to parts of some files in +\c{qtbase/src/corelib/codecs/}. + +\quotation + Copyright (C) 2000 Ming-Che Chuang \break + Copyright (C) 2001, 2002 James Su, Turbolinux Inc. \break + Copyright (C) 2002 WU Yi, HancomLinux Inc. \break + Copyright (C) 2001, 2002 Anthony Fok, ThizLinux Laboratory Ltd. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + +\list 1 + \li Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + \li Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +\endlist + + THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. +\endquotation + + + +\section3 brg_endian.h + +This license applies to +\c{qtbase/src/3rdparty/sha3/brg_endian.h}. + +\quotation + Copyright (c) 1998-2008, Brian Gladman, Worcester, UK. All rights reserved. + + LICENSE TERMS + + The redistribution and use of this software (with or without changes) + is allowed without the payment of fees or royalties provided that: + +\list 1 + \li source code distributions include the above copyright notice, this + list of conditions and the following disclaimer; + + \li binary distributions include the above copyright notice, this list + of conditions and the following disclaimer in their documentation; + + \li the name of the copyright holder is not used to endorse products + built using this software without specific written permission. +\endlist + + DISCLAIMER + + This software is provided 'as is' with no explicit or implied warranties + in respect of its properties, including, but not limited to, correctness + and/or fitness for purpose. +\endquotation + + + +\section3 Clucene Core Library + +This license applies to files in +\c{qttools/src/assistant/3rdparty/clucene}. + +\quotation + Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team + + The CLucene Core Library uses a dual license strategy for the source code. + These licenses are the GNU Lesser General Public License (LGPL) and the Apache + License (Version 2.0). Users can choose the license they wish to distribute + their software under. This means that you do not need to abide by *both* + licenses, but rather than you can choose the license which most suits your + needs. + + To rephrase this and to make it perfectly clear: \break + CLucene is distributed under the \l{GNU Lesser General Public License} (LGPL) \break + *or* \break + the \l{Apache License}, Version 2.0 + + However, we are an open source project, and we encourage users to use the LGPL + license and participate fully in the free software community. Dual licensing + of the CLucene source code provides open and free access to the technology both + for the GPL community and for other developers or companies that cannot use the + GPL. + + You can freely modify, extend, and improve the CLucene source code. The only + question is whether or not you must provide the source code and contribute + modifications to the community. The GNU and Apache licenses allow different + ranges of flexibility in this regard, but in the end, regardless of the license + used, we highly recommend that you submit any bugs, incompatibilities or + added features. + + Note that this same license does *not* apply to the CLucene Contributions + package. You should read the COPYING file in that directory or package for + more information. +\endquotation + + + +\section3 Cocoa Platform Plugin + +This license applies to parts of some files in +\c{qtbase/src/plugins/platforms/cocoa/}. + +\quotation + Copyright (C) 2007-2008, Apple, Inc. + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + +\list +\li Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. +\li Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. +\li Neither the name of Apple, Inc. nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. +\endlist + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +\endquotation + + + +\section3 Drag and Drop + + Copyright 1996 Daniel Dardailler. + + Permission to use, copy, modify, distribute, and sell this software for any + purpose is hereby granted without fee, provided that the above copyright + notice appear in all copies and that both that copyright notice and this + permission notice appear in supporting documentation, and that the name of + Daniel Dardailler not be used in advertising or publicity pertaining to + distribution of the software without specific, written prior permission. + Daniel Dardailler makes no representations about the suitability of this + software for any purpose. It is provided "as is" without express or implied + warranty. + + Modifications Copyright 1999 Matt Koss, under the same license as above. + + + +\section3 Easing Equations + +This license applies to +\c{qtbase/src/3rdparty/easing/easing.cpp}. + +\quotation + Copyright \copyright 2001 Robert Penner \break + All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, + are permitted provided that the following conditions are met: + +\list + \li Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + \li Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + \li Neither the name of the author nor the names of contributors may be used + to endorse or promote products derived from this software without specific + prior written permission. +\endlist + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +\endquotation + + + +\section3 EUC-JP Text Codec + +This license applies to parts of some files in +\c{qtbase/src/corelib/codecs/}. + +\quotation + Copyright (C) 1999 Serika Kurusugawa. All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + +\list 1 + \li Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + \li Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +\endlist + + THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS". + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. +\endquotation + + + +\section3 EUC-KR Text Codec + +This license applies to parts of some files in +\c{qtbase/src/corelib/codecs/}. + +\quotation + Copyright (C) 1999-2000 Mizi Research Inc. All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + +\list 1 + \li Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + \li Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +\endlist + + THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. +\endquotation + + + +\section3 forkfd + +This license applies to files in +\c{qtbase/src/3rdparty/forkfd/}. + +\quotation + Copyright (C) 2014 Intel Corporation \break + Copyright (C) 2015 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +\endquotation + + + +\section3 FreeBSD strtoll and strtoull + +This license applies to files in +\c{qtbase/src/3rdparty/freebsd/}. + +\quotation + Copyright (c) 1992, 1993 \break + The Regents of the University of California. All rights reserved. + + Copyright (c) 2011 The FreeBSD Foundation \break + All rights reserved. \break + Portions of this software were developed by David Chisnall + under sponsorship from the FreeBSD Foundation. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: +\list 1 + \li Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + \li Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + \li Neither the name of the University nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. +\endlist + + THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. +\endquotation + + + +\section3 GBK Text Codec + +This license applies to parts of some files in +\c{qtbase/src/corelib/codecs/}. + +\quotation + Copyright (C) 2000 TurboLinux, Inc. Written by Justin Yu and Sean Chen. \break + Copyright (C) 2001, 2002 Turbolinux, Inc. Written by James Su. \break + Copyright (C) 2001, 2002 ThizLinux Laboratory Ltd. Written by Anthony Fok. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + +\list 1 + \li Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + \li Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +\endlist + + THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. +\endquotation + + + +\section3 HarfBuzz + +This license applies to files in +\c{qtbase/src/3rdparty/harfbuzz} and +\c{qtbase/src/3rdparty/harfbuzz-ng}. + +\quotation + Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies) \break + Copyright \copyright 2010,2011,2012 Google, Inc. \break + Copyright \copyright 2012 Mozilla Foundation \break + Copyright \copyright 2011 Codethink Limited \break + Copyright \copyright 2008,2010 Nokia Corporation and/or its subsidiary(-ies) \break + Copyright \copyright 2009 Keith Stribley \break + Copyright \copyright 2009 Martin Hosken and SIL International \break + Copyright \copyright 2007 Chris Wilson \break + Copyright \copyright 2006 Behdad Esfahbod \break + Copyright \copyright 2005 David Turner \break + Copyright \copyright 2004,2007,2008,2009,2010 Red Hat, Inc. \break + Copyright \copyright 1998-2004 David Turner and Werner Lemberg + + Permission is hereby granted, without written agreement and without + license or royalty fees, to use, copy, modify, and distribute this + software and its documentation for any purpose, provided that the + above copyright notice and the following two paragraphs appear in + all copies of this software. + + IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + DAMAGE. + + THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. +\endquotation + + + +\section3 IAccessible2 IDL Specification + +This license applies to files in +\c{qtbase/src/3rdparty/iaccessible2/}. + +\quotation + Copyright (c) 2007, 2010 Linux Foundation \break + Copyright (c) 2006 IBM Corporation \break + Copyright (c) 2000, 2006 Sun Microsystems, Inc. \break + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + +\list 1 + \li Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + \li Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials + provided with the distribution. + + \li Neither the name of the Linux Foundation nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior written + permission. +\endlist + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +\endquotation + + + +\section3 ISO 2022-JP (JIS) Text Codec + +This license applies to parts of some files in +\c{qtbase/src/corelib/codecs/}. + +\quotation + Copyright (C) 1999 Serika Kurusugawa. All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + +\list 1 + \li Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + \li Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +\endlist + + THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS". + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. +\endquotation + + + +\section3 JasPer library + +This license applies to files in +\c{qtimageformats/src/3rdparty/jasper/}. + +\quotation + JasPer License Version 2.0 + + Copyright (c) 2001-2006 Michael David Adams \break + Copyright (c) 1999-2000 Image Power, Inc. \break + Copyright (c) 1999-2000 The University of British Columbia + + All rights reserved. + + Permission is hereby granted, free of charge, to any person (the + "User") obtaining a copy of this software and associated documentation + files (the "Software"), to deal in the Software without restriction, + including without limitation the rights to use, copy, modify, merge, + publish, distribute, and/or sell copies of the Software, and to permit + persons to whom the Software is furnished to do so, subject to the + following conditions: + +\list 1 + \li The above copyright notices and this permission notice (which + includes the disclaimer below) shall be included in all copies or + substantial portions of the Software. + + \li The name of a copyright holder shall not be used to endorse or + promote products derived from the Software without specific prior + written permission. +\endlist + + THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS + LICENSE. NO USE OF THE SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER + THIS DISCLAIMER. THE SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS + "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO + EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL + INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING + FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. NO ASSURANCES ARE + PROVIDED BY THE COPYRIGHT HOLDERS THAT THE SOFTWARE DOES NOT INFRINGE + THE PATENT OR OTHER INTELLECTUAL PROPERTY RIGHTS OF ANY OTHER ENTITY. + EACH COPYRIGHT HOLDER DISCLAIMS ANY LIABILITY TO THE USER FOR CLAIMS + BROUGHT BY ANY OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL + PROPERTY RIGHTS OR OTHERWISE. AS A CONDITION TO EXERCISING THE RIGHTS + GRANTED HEREUNDER, EACH USER HEREBY ASSUMES SOLE RESPONSIBILITY TO SECURE + ANY OTHER INTELLECTUAL PROPERTY RIGHTS NEEDED, IF ANY. THE SOFTWARE + IS NOT FAULT-TOLERANT AND IS NOT INTENDED FOR USE IN MISSION-CRITICAL + SYSTEMS, SUCH AS THOSE USED IN THE OPERATION OF NUCLEAR FACILITIES, + AIRCRAFT NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL + SYSTEMS, DIRECT LIFE SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH + THE FAILURE OF THE SOFTWARE OR SYSTEM COULD LEAD DIRECTLY TO DEATH, + PERSONAL INJURY, OR SEVERE PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH + RISK ACTIVITIES"). THE COPYRIGHT HOLDERS SPECIFICALLY DISCLAIM ANY + EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR HIGH RISK ACTIVITIES. +\endquotation + + + +\section3 LibTIFF library + +This license applies to most files in +\c{qtimageformats/src/3rdparty/libtiff/}. + +\quotation + Copyright (c) 1988-1997 Sam Leffler \break + Copyright (c) 1991-1997 Silicon Graphics, Inc. \break + Copyright (C) 2005, Andrey Kiselev \break + Copyright (c) 2009 Frank Warmerdam \break + Copyright (c) 2010, Andrey Kiselev + + Permission to use, copy, modify, distribute, and sell this software and + its documentation for any purpose is hereby granted without fee, provided + that (i) the above copyright notices and this permission notice appear in + all copies of the software and related documentation, and (ii) the names of + Sam Leffler and Silicon Graphics may not be used in any advertising or + publicity relating to the software without the specific, prior written + permission of Sam Leffler and Silicon Graphics. + + THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + + IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR + ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, + OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + OF THIS SOFTWARE. +\endquotation + + +This license applies to some files in +\c{qtimageformats/src/3rdparty/libtiff/}. + +\quotation + Copyright (c) 1996-1997 Sam Leffler \break + Copyright (c) 1996 Pixar + + Permission to use, copy, modify, distribute, and sell this software and + its documentation for any purpose is hereby granted without fee, provided + that (i) the above copyright notices and this permission notice appear in + all copies of the software and related documentation, and (ii) the names of + Pixar, Sam Leffler and Silicon Graphics may not be used in any advertising or + publicity relating to the software without the specific, prior written + permission of Pixar, Sam Leffler and Silicon Graphics. + + THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + + IN NO EVENT SHALL PIXAR, SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR + ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, + OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + OF THIS SOFTWARE. +\endquotation + + +This license applies to some files in +\c{qtimageformats/src/3rdparty/libtiff/}. + +\quotation + Copyright (c) 1997 Greg Ward Larson \break + Copyright (c) 1997 Silicon Graphics, Inc. + + Permission to use, copy, modify, distribute, and sell this software and + its documentation for any purpose is hereby granted without fee, provided + that (i) the above copyright notices and this permission notice appear in + all copies of the software and related documentation, and (ii) the names of + Sam Leffler, Greg Larson and Silicon Graphics may not be used in any + advertising or publicity relating to the software without the specific, + prior written permission of Sam Leffler, Greg Larson and Silicon Graphics. + + THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + + IN NO EVENT SHALL SAM LEFFLER, GREG LARSON OR SILICON GRAPHICS BE LIABLE + FOR ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, + OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + OF THIS SOFTWARE. +\endquotation + + +This license applies to some files in +\c{qtimageformats/src/3rdparty/libtiff/port}. + +\quotation + Copyright (c) 1987, 1993 + The Regents of the University of California. All rights reserved. \break + Copyright (c) 1987, 1993, 1994 + The Regents of the University of California. All rights reserved. \break + Copyright (c) 1989, 1993 + The Regents of the University of California. All rights reserved. \break + Copyright (c) 1990, 1993 + The Regents of the University of California. All rights reserved. \break + Copyright (c) 1992, 1993 + The Regents of the University of California. All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: +\list 1 + \li Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + \li Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + \li Neither the name of the University nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. +\endlist + + THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. +\endquotation + + + +\section3 Native Style for Android + +This license applies to +\c{qtbase/src/3rdparty/android/extract}. + +\quotation + Copyright (C) 2005 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +\endquotation + + + +\section3 PCRE library + +This licence applies to files in +\c{qtbase/src/3rdparty/pcre/} (the basic library functions) and +\c{qtbase/src/3rdparty/pcre/sljit/} (stack-less just-in-time compiler). + +\quotation +\code + THE BASIC LIBRARY FUNCTIONS + --------------------------- + + Written by: Philip Hazel + Email local part: ph10 + Email domain: cam.ac.uk + + University of Cambridge Computing Service, + Cambridge, England. + + Copyright (c) 1997-2015 University of Cambridge + All rights reserved. + + + PCRE JUST-IN-TIME COMPILATION SUPPORT + ------------------------------------- + + Written by: Zoltan Herczeg + Email local part: hzmester + Emain domain: freemail.hu + + Copyright(c) 2010-2015 Zoltan Herczeg + All rights reserved. + + + STACK-LESS JUST-IN-TIME COMPILER + -------------------------------- + + Written by: Zoltan Herczeg + Email local part: hzmester + Emain domain: freemail.hu + + Copyright(c) 2009-2015 Zoltan Herczeg + All rights reserved. + + + THE C++ WRAPPER FUNCTIONS + ------------------------- + + Contributed by: Google Inc. + + Copyright (c) 2007-2012, Google Inc. + All rights reserved. +\endcode + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + +\list + \li Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + \li Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + \li Neither the name of the University of Cambridge nor the name of Google + Inc. nor the names of their contributors may be used to endorse or + promote products derived from this software without specific prior + written permission. +\endlist + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +\endquotation + + + +\section3 pixman + +This license applies to the files in +\c{qtbase\src\3rdparty\pixman\}. + +\quotation + Copyright \copyright 2009 Nokia Corporation + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice (including the next + paragraph) shall be included in all copies or substantial portions of the + Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. +\endquotation + + + +\section3 Poly2Tri + +This license applies to files in +\c{qtlocation/src/3rdparty/poly2tri/}. + +\quotation + \span {} {Poly}2Tri Copyright (c) 2009-2010, \span {} {Poly}2Tri Contributors \break + \l http://code.google.com/p/poly2tri/ + + All rights reserved. \break + Redistribution and use in source and binary forms, with or without modification, + are permitted provided that the following conditions are met: + +\list + \li Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + \li Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + \li Neither the name of \span {} {Poly}2Tri nor the names of its contributors may be + used to endorse or promote products derived from this software without specific + prior written permission. +\endlist + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +\endquotation + + + +\section3 QCrashHandler class + +This license applies to parts of +\c{qtbase/src/corelib/kernel/qcrashhandler.cpp}. + +\quotation + Copyright (c) 1998 by Bjorn Reese + + Permission to use, copy, modify, and distribute this software for any + purpose with or without fee is hereby granted, provided that the above + copyright notice and this permission notice appear in all copies. + + THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND + CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER. +\endquotation + + + +\section3 QImage smooth scaling + +For smooth scaling, the \c{QImage::transformed()} functions use code based on +smooth scaling algorithm by Daniel M. Duley. + +\quotation + Copyright (C) 2004, 2005 Daniel M. Duley + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: +\list 1 + \li Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + \li Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +\endlist + + THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +\endquotation + + + +\section3 QKeyMapper class on X11 platforms + +This license applies to parts of +the internal QKeyMapper class on X11 platforms. + +\quotation + Copyright 1985, 1987, 1998 The Open Group + + Permission to use, copy, modify, distribute, and sell this software and its + documentation for any purpose is hereby granted without fee, provided that + the above copyright notice appear in all copies and that both that + copyright notice and this permission notice appear in supporting + documentation. + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + Except as contained in this notice, the name of The Open Group shall not be + used in advertising or otherwise to promote the sale, use or other dealings + in this Software without prior written authorization from The Open Group. +\endquotation + + + +\section3 QtCLucene Library + +This license applies to files in +\c{qttools/src/assistant/clucene/}. + +\quotation + Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team. \break + All rights reserved. + + Portion Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). \break + All rights reserved. + + This file may be used under the terms of the GNU Lesser General Public + License version 2.1 as published by the Free Software Foundation and + appearing in the file LICENSE.LGPL included in the packaging of this file. + Please review the following information to ensure the GNU Lesser General + Public License version 2.1 requirements will be met: \break + \l{http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html}. +\endquotation + + + +\section3 qtmain Library + +This license applies to files in +\c{qtbase/src/winmain/}. + +\quotation +Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). \break +Contact: \l http://www.qt-project.org/legal + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: +\list +\li Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +\li Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. +\li Neither the name of Digia Plc and its Subsidiary(-ies) nor the names + of its contributors may be used to endorse or promote products derived + from this software without specific prior written permission. +\endlist + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +\endquotation + + + +\section3 QUrl::fromUserInput + +This license applies to parts of \c{qtbase/src/corelib/io/qurl.cpp}. + +\quotation + Copyright (C) Research In Motion Limited 2009. All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + +\list + \li Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + \li Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + \li Neither the name of Research In Motion Limited nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. +\endlist + + THIS SOFTWARE IS PROVIDED BY Research In Motion Limited ''AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL Research In Motion Limited BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +\endquotation + + + +\section3 Secure Hash Algorithms (SHA) + +This license applies to files in +\c{qtbase/src/3rdparty/rfc6234/}. + +\quotation + Copyright (c) 2011 IETF Trust and the persons identified as + authors of the code. All rights reserved. + + Redistribution and use in source and binary forms, with or + without modification, are permitted provided that the following + conditions are met: + +\list + \li Redistributions of source code must retain the above + copyright notice, this list of conditions and + the following disclaimer. + + \li Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + + \li Neither the name of Internet Society, IETF or IETF Trust, nor + the names of specific contributors, may be used to endorse or + promote products derived from this software without specific + prior written permission. +\endlist + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +\endquotation + + + +\section3 Shift-JIS Text Codec + +This license applies to parts of some files in +\c{qtbase/src/corelib/codecs/}. + +\quotation + Copyright (C) 1999 Serika Kurusugawa. All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + +\list 1 + \li Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + \li Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. +\endlist + + THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS". ANY EXPRESS + OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +\endquotation + + + +\section3 TSCII Text Codec + +This license applies to parts of some files in +\c{qtbase/src/corelib/codecs/}. + +\quotation + Copyright (c) 2000 Hans Petter Bieker. All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + +\list 1 + \li Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + \li Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +\endlist + + THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. +\endquotation + + + +\section3 Unicode Character Database Data Files + +This license applies to files in +\c{qtbase/util/unicode/data/}. + +\quotation + Copyright \copyright 1991-2014 Unicode, Inc. All rights reserved. + Distributed under the Terms of Use in + http://www.unicode.org/copyright.html. + + Permission is hereby granted, free of charge, to any person + obtaining a copy of the Unicode data files and any associated + documentation (the "Data Files") or Unicode software and any + associated documentation (the "Software") to deal in the Data + Files or Software without restriction, including without + limitation the rights to use, copy, modify, merge, publish, + distribute, and/or sell copies of the Data Files or Software, + and to permit persons to whom the Data Files or Software are + furnished to do so, provided that (a) the above copyright + notice(s) and this permission notice appear with all copies + of the Data Files or Software, (b) both the above copyright + notice(s) and this permission notice appear in associated + documentation, and (c) there is clear notice in each modified + Data File or in the Software as well as in the documentation + associated with the Data File(s) or Software that the data or + software has been modified. + + THE DATA FILES AND SOFTWARE ARE PROVIDED "AS IS", WITHOUT + WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. + IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED + IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT + OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING + FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF + CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THE DATA FILES + OR SOFTWARE. + + Except as contained in this notice, the name of a copyright + holder shall not be used in advertising or otherwise to promote + the sale, use or other dealings in these Data Files or Software + without prior written authorization of the copyright holder. +\endquotation + + +\section3 WebP codec + +This license applies to files in +\c{qtimageformats/src/3rdparty/libwebp/}. + +\quotation + Copyright (c) 2010, Google Inc. All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + +\list + \li Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + \li Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + + \li Neither the name of Google nor the names of its contributors may + be used to endorse or promote products derived from this software + without specific prior written permission. +\endlist + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +\endquotation + + + +\section3 xcb + +This license applies to most files in +\c{qtbase/src/3rdparty/xcb/}. + +\quotation + Copyright \copyright 2008-2009 Julien Danjou \break + Copyright \copyright 2008 Bart Massey + Copyright \copyright 2008 Ian Osgood + Copyright \copyright 2008 Jamey Sharp + Copyright \copyright 2008 Josh Triplett + Copyright \copyright 2008 Ulrich Eckhardt + Copyright \copyright 2008 Arnaud Fontaine + Copyright \copyright 2007-2008 Vincent Torri + Copyright \copyright 2007 Bart Massey + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation + files (the "Software"), to deal in the Software without + restriction, including without limitation the rights to use, copy, + modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY + CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + Except as contained in this notice, the names of the authors or + their institutions shall not be used in advertising or otherwise to + promote the sale, use or other dealings in this Software without + prior written authorization from the authors. + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation + files (the "Software"), to deal in the Software without + restriction, including without limitation the rights to use, copy, + modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: +\endquotation + + +This license applies to +\c{qtbase/src/3rdparty/xcb/xcb-util-renderutil/util.c}. + +\quotation + Copyright \copyright 2000 Keith Packard + + Permission to use, copy, modify, distribute, and sell this software and its + documentation for any purpose is hereby granted without fee, provided that + the above copyright notice appear in all copies and that both that + copyright notice and this permission notice appear in supporting + documentation, and that the name of Keith Packard not be used in + advertising or publicity pertaining to distribution of the software without + specific, written prior permission. Keith Packard makes no + representations about the suitability of this software for any purpose. It + is provided "as is" without express or implied warranty. + + KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR + CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + PERFORMANCE OF THIS SOFTWARE. +\endquotation + + + +\section3 xkb + +The following is a list of copyright notices and license statements in +\c{qtbase/src/3rdparty/xkbcommon}. + +\quotation + Copyright \copyright 2009-2012 Daniel Stone \break + Copyright \copyright 2012 Ran Benita \break + Copyright \copyright 2010, 2012 Intel Corporation \break + Copyright \copyright 2008, 2009 Dan Nicholson \break + Copyright \copyright 2010 Francisco Jerez + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice (including the next + paragraph) shall be included in all copies or substantial portions of the + Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. + + + \hr + + + Copyright 1985, 1987, 1988, 1990, 1998 The Open Group + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + Except as contained in this notice, the names of the authors or their + institutions shall not be used in advertising or otherwise to promote the + sale, use or other dealings in this Software without prior written + authorization from the authors. + + \hr + + Copyright (c) 1993, 1994, 1995, 1996 by Silicon Graphics Computer Systems, Inc. + + Permission to use, copy, modify, and distribute this + software and its documentation for any purpose and without + fee is hereby granted, provided that the above copyright + notice appear in all copies and that both that copyright + notice and this permission notice appear in supporting + documentation, and that the name of Silicon Graphics not be + used in advertising or publicity pertaining to distribution + of the software without specific prior written permission. + Silicon Graphics makes no representation about the suitability + of this software for any purpose. It is provided "as is" + without any express or implied warranty. + + SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS + SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON + GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL + DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE + OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH + THE USE OR PERFORMANCE OF THIS SOFTWARE. + + \hr + + Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts. + + All Rights Reserved + + Permission to use, copy, modify, and distribute this software and its + documentation for any purpose and without fee is hereby granted, + provided that the above copyright notice appear in all copies and that + both that copyright notice and this permission notice appear in + supporting documentation, and that the name of Digital not be + used in advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING + ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL + DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR + ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, + ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + SOFTWARE. + + \hr + + Copyright (C) 2011 Joseph Adams + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +\endquotation + + + +\section3 Additional Credits and Acknowledgements + +This software is based in part on the work of the Independent JPEG Group. + +Portions of this software are copyright \copyright 2012 The FreeType Project +(\l{http://www.freetype.org}). All rights reserved. + +We are very grateful to the following projects which are used in or distributed +alongside this software, and to the people behind these projects: + +\list +\li The \l{http://zlib.net/ zlib} Data Compression Library + (Jean-loup Gailly, Mark Adler) +\li The \l{http://www.libpng.org/pub/png/ libpng} PNG reference library + (Glenn Randers-Pehrson et al.) +\li The \l{http://www.sqlite.org/ sqlite} database engine +\endlist + diff --git a/doc/licensing/src/trademarks.qdocinc b/doc/licensing/src/trademarks.qdocinc new file mode 100644 index 0000000..19a6915 --- /dev/null +++ b/doc/licensing/src/trademarks.qdocinc @@ -0,0 +1,29 @@ +\omit +/* + * Copyright 2014, 2015 Kai Pastor + * + * This file is part of OpenOrienteering. + * + * OpenOrienteering is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenOrienteering is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenOrienteering. If not, see . + */ +\endomit + + +Qt and the Qt logo are trademarks of The Qt Company Ltd. + +Digia and the Digia logo are trademarks of Digia Plc and/or +its subsidiaries in Finland and other countries. + +All other company, product, or service names may be trademarks or service marks +of others and are the property of their respective owners. diff --git a/doc/man/Mapper.1 b/doc/man/Mapper.1 new file mode 100644 index 0000000..8e6bf32 --- /dev/null +++ b/doc/man/Mapper.1 @@ -0,0 +1,40 @@ +.TH MAPPER 1 2015-12-13 OpenOrienteering + +.SH NAME +Mapper \- orienteering map drawing software + +.SH SYNOPSIS +.B Mapper +.RI [ FILES ] + +.SH DESCRIPTION +OpenOrienteering Mapper is an orienteering map drawing software. +It comes with predefined symbol sets implementing the IOF standards +ISOM (1:15000, 1:10000) and ISSOM (1:5000, 1:4000). +But it is easy to implement other symbol sets. + +.SH OPTIONS +This program takes map file names as options. + +.SH AUTHOR +This manual page was written by Kai Pastor . + +.SH "REPORTING BUGS" +Report bugs in the OpenOrienteering ticket system: +.br + + +.SH COPYRIGHT +Copyright \(co 2015 The OpenOrienteering developers +.br +License GPLv3: GNU GPL version 3 . +.br +This is free software: you are free to change and redistribute it. +There is NO WARRANTY, to the extent permitted by law. + +.SH "SEE ALSO" +Extended documentation for +.B Mapper +is available from the program's help menu and also online at: +.br + diff --git a/doc/manual/CMakeLists.txt b/doc/manual/CMakeLists.txt new file mode 100644 index 0000000..ce6021e --- /dev/null +++ b/doc/manual/CMakeLists.txt @@ -0,0 +1,185 @@ +# +# Copyright 2012, 2013, 2014 Thomas Schöps +# Copyright 2012-2015 Kai Pastor +# +# This file is part of OpenOrienteering. +# +# OpenOrienteering is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# OpenOrienteering is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with OpenOrienteering. If not, see . + +if(NOT PROJECT_NAME) + project(Mapper_Manual NONE) + cmake_minimum_required(VERSION 2.8.8) +else() + message(STATUS "Configuring ${PROJECT_NAME} user manual") +endif() + +if(NOT ANDROID) # --------------------------------------------------- + +if (CMAKE_CROSSCOMPILING AND NOT TARGET Qt5::qcollectiongenerator) + find_program(Qt5Help_QCOLLECTIONGENERATOR_EXECUTABLE + NAMES qcollectiongenerator-qt5 qcollectiongenerator + DOC "The path of the Qt Assistant executable" + ) + add_executable(Qt5::qcollectiongenerator IMPORTED) + set_target_properties(Qt5::qcollectiongenerator PROPERTIES + IMPORTED_LOCATION ${Qt5Help_QCOLLECTIONGENERATOR_EXECUTABLE} + ) +endif() + +enable_language(CXX) +find_package(Qt5Help REQUIRED) + +# Not exported from Qt5 +if (NOT TARGET Qt5::qcollectiongenerator AND TARGET Qt5::moc) + add_executable(Qt5::qcollectiongenerator IMPORTED) + get_target_property(imported_location Qt5::moc IMPORTED_LOCATION) + get_filename_component(imported_location ${imported_location} PATH) + set(imported_location ${imported_location}/qcollectiongenerator) + if(NOT EXISTS "${imported_location}") + message(FATAL_ERROR "qcollectiongenerator executable does not exist: " + "${imported_location}") + endif() + set_target_properties(Qt5::qcollectiongenerator PROPERTIES + IMPORTED_LOCATION ${imported_location} + ) +endif() +set(Qt5Help_QCOLLECTIONGENERATOR_EXECUTABLE Qt5::qcollectiongenerator) + +find_program(Qt5Help_ASSISTANT_EXECUTABLE NAMES assistant${CMAKE_EXECUTABLE_SUFFIX} Assistant${CMAKE_EXECUTABLE_SUFFIX} + DOC "The path of the Qt Assistant executable" + HINTS ${QT5_DIR} + PATH_SUFFIXES bin + NO_DEFAULT_PATH) +mark_as_advanced(Qt5Help_ASSISTANT_EXECUTABLE) + +endif(NOT ANDROID) # --------------------------------------------------- + +set(Mapper_HELP_NAMESPACE "openorienteering.mapper-${Mapper_VERSION_MAJOR}.${Mapper_VERSION_MINOR}.${Mapper_VERSION_PATCH}.help" + CACHE INTERNAL "The namespace where the current version's help will be located.") + +set(Mapper_HELP_COLLECTION "Mapper ${Mapper_VERSION_DISPLAY} Manual.qhc") +set(Mapper_COMPRESSED_HELP "Mapper ${Mapper_VERSION_DISPLAY} Manual.qch") +configure_file(Manual.qhcp.in Manual.qhcp @ONLY) + +find_program(DOXYGEN_EXECUTABLE NAMES doxygen + DOC "The path of the doxygen executable") +mark_as_advanced(DOXYGEN_EXECUTABLE) + +if(DOXYGEN_EXECUTABLE MATCHES NOTFOUND) + message(WARNING "doxygen executable not found.") +else() + configure_file(preprocess-markdown.cmake.in preprocess-markdown.cmake @ONLY) + add_custom_target( + Mapper-manual-pages + COMMAND ${CMAKE_COMMAND} -P preprocess-markdown.cmake + ) + + if(NOT MANUAL_SECTIONS) + if(APPLE) + set(MANUAL_SECTIONS_DEFAULT OSX) + elseif(UNIX) + set(MANUAL_SECTIONS_DEFAULT LINUX) + elseif(WIN32) + set(MANUAL_SECTIONS_DEFAULT WINDOWS) + else() + set(MANUAL_SECTIONS_DEFAULT OTHER) + endif() + set(MANUAL_SECTIONS "${MANUAL_SECTIONS_DEFAULT}" + CACHE STRING "Conditional manual sections to be enabled") + endif() + message(STATUS "Conditional manual sections: ${MANUAL_SECTIONS}") + + configure_file(Doxyfile.in Doxyfile @ONLY) + + configure_file(postprocess-qhp.cmake.in postprocess-qhp.cmake @ONLY) + add_custom_command( + OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/html/index.qhp + COMMAND ${CMAKE_COMMAND} + ARGS -E remove_directory html + COMMAND ${DOXYGEN_EXECUTABLE} + ARGS Doxyfile + COMMAND ${CMAKE_COMMAND} + ARGS -P postprocess-qhp.cmake + MAIN_DEPENDENCY preprocess-markdown.stamp + DEPENDS Mapper-manual-pages + ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile + ${CMAKE_CURRENT_BINARY_DIR}/postprocess-qhp.cmake + ${DOXYGEN_EXECUTABLE} + header.html + footer.html + style.css + COMMENT "Running doxygen on the manual" + ) + set_source_files_properties(preprocess-markdown.stamp PROPERTIES GENERATED 1) + + if(NOT ANDROID) # --------------------------------------------------- + + set(MAPPER_MANUAL_TARGET "${Mapper_HELP_COLLECTION}") + + add_custom_command( + OUTPUT ${Mapper_HELP_COLLECTION} ${Mapper_COMPRESSED_HELP} + COMMAND ${Qt5Help_QCOLLECTIONGENERATOR_EXECUTABLE} + ARGS Manual.qhcp + -o "${Mapper_HELP_COLLECTION}" + MAIN_DEPENDENCY ${CMAKE_CURRENT_BINARY_DIR}/html/index.qhp + DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/Manual.qhcp + ${CMAKE_CURRENT_BINARY_DIR}/html/index.qhp + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + COMMENT "Running qcollectiongenerator on the manual" + ) + + if(NOT CMAKE_CROSSCOMPILING) + add_custom_target(view-Mapper-manual + COMMAND "${Qt5Help_ASSISTANT_EXECUTABLE}" + -collectionFile "${Mapper_HELP_COLLECTION}" + DEPENDS Mapper-manual + COMMENT "Opening Mapper manual" + ) + endif() + + install( + FILES "${CMAKE_CURRENT_BINARY_DIR}/${Mapper_HELP_COLLECTION}" + "${CMAKE_CURRENT_BINARY_DIR}/${Mapper_COMPRESSED_HELP}" + DESTINATION "${MAPPER_DATA_DESTINATION}/doc/manual") + + elseif(ANDROID) # --------------------------------------------------- + + set(MAPPER_MANUAL_TARGET "${CMAKE_CURRENT_BINARY_DIR}/html/index.qhp") + + file(APPEND "${CMAKE_CURRENT_BINARY_DIR}/Doxyfile" \n + "FILE_PATTERNS = android* toolbar*" \n + "USE_MDFILE_AS_MAINPAGE = android-index.md" \n + ) + + install(CODE " + file(READ \"${CMAKE_CURRENT_BINARY_DIR}/html/index.qhp\" index_qhp) + string(REGEX MATCHALL \"[^<]*\" matches \${index_qhp}) + foreach(match \${matches}) + string(REGEX REPLACE \".*\" \"\" match \"\${match}\") + string(REGEX REPLACE \".*\" \"\" match \"\${match}\") + file(INSTALL DESTINATION /assets/doc/manual FILES \"${CMAKE_CURRENT_BINARY_DIR}/html/\${match}\") + endforeach() + ") + + endif() # --------------------------------------------------- + + add_custom_target(Mapper-manual ALL + DEPENDS "${MAPPER_MANUAL_TARGET}" + # Sources to be listed in Qt Creator + SOURCES header.html + footer.html + style.css + ) + +endif() diff --git a/doc/manual/Doxyfile.in b/doc/manual/Doxyfile.in new file mode 100644 index 0000000..e82cf9a --- /dev/null +++ b/doc/manual/Doxyfile.in @@ -0,0 +1,51 @@ +# +# Copyright 2014, 2015 Kai Pastor +# +# This file is part of OpenOrienteering. +# +# OpenOrienteering is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# OpenOrienteering is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with OpenOrienteering. If not, see . + +PROJECT_NAME = "Mapper" +PROJECT_NUMBER = "@Mapper_VERSION_DISPLAY@" +PROJECT_BRIEF = "User Manual" +PROJECT_LOGO = "@CMAKE_CURRENT_SOURCE_DIR@/../openorienteering.png" + +QUIET = YES + +INPUT = "@CMAKE_CURRENT_BINARY_DIR@/pages-tmp" +STRIP_FROM_PATH = "@CMAKE_CURRENT_BINARY_DIR@/pages-tmp" +IMAGE_PATH = "@CMAKE_CURRENT_SOURCE_DIR@/pages/images" +IMAGE_PATH += "@CMAKE_CURRENT_SOURCE_DIR@/../../images" +ENABLE_PREPROCESSING = NO +USE_MATHJAX = NO + +GENERATE_HTML = YES +DISABLE_INDEX = YES +GENERATE_TREEVIEW = NO +HTML_TIMESTAMP = NO +SEARCHENGINE = NO +HTML_HEADER = "@CMAKE_CURRENT_SOURCE_DIR@/header.html" +HTML_FOOTER = "@CMAKE_CURRENT_SOURCE_DIR@/footer.html" +HTML_STYLESHEET = "@CMAKE_CURRENT_SOURCE_DIR@/style.css" +HTML_EXTRA_FILES = "@CMAKE_CURRENT_SOURCE_DIR@/pages/attachment/scribble_1024.png" +HTML_EXTRA_FILES += "@CMAKE_CURRENT_SOURCE_DIR@/pages/attachment/scribble_2048.png" + +GENERATE_QHP = YES +QCH_FILE = "../Mapper ${Mapper_VERSION_DISPLAY}.qch" +QHP_NAMESPACE = "@Mapper_HELP_NAMESPACE@" +QHP_VIRTUAL_FOLDER = manual + +GENERATE_LATEX = NO + +ENABLED_SECTIONS = @MANUAL_SECTIONS@ diff --git a/doc/manual/Manual.qhcp.in b/doc/manual/Manual.qhcp.in new file mode 100644 index 0000000..2ccacef --- /dev/null +++ b/doc/manual/Manual.qhcp.in @@ -0,0 +1,19 @@ + + + + @CMAKE_CURRENT_SOURCE_DIR@/../../images/mapper-help.png + OpenOrienteering Mapper Help + qthelp://@Mapper_HELP_NAMESPACE@/manual/index.html + + + + + html/index.qhp + @Mapper_COMPRESSED_HELP@ + + + + @Mapper_COMPRESSED_HELP@ + + + diff --git a/doc/manual/footer.html b/doc/manual/footer.html new file mode 100644 index 0000000..7325a1c --- /dev/null +++ b/doc/manual/footer.html @@ -0,0 +1,6 @@ +
+ + + diff --git a/doc/manual/header.html b/doc/manual/header.html new file mode 100644 index 0000000..0f51ad9 --- /dev/null +++ b/doc/manual/header.html @@ -0,0 +1,16 @@ + + + + + + OpenOrienteering $projectname: $title + + + +
+ +
+ OpenOrienteering $projectname $projectnumber +
+ diff --git a/doc/manual/manual.pro b/doc/manual/manual.pro new file mode 100644 index 0000000..95f4fc7 --- /dev/null +++ b/doc/manual/manual.pro @@ -0,0 +1,60 @@ +# +# Copyright 2015 Kai Pastor +# +# This file is part of OpenOrienteering. +# +# OpenOrienteering is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# OpenOrienteering is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with OpenOrienteering. If not, see . + +TEMPLATE = aux +CONFIG -= debug_and_release + +CMAKE_TOOLCHAIN_FILE = $$clean_path($$OUT_PWD/../../toolchain.cmake) +if (exists($$CMAKE_TOOLCHAIN_FILE)) { + CMAKE_ARGS += "-DCMAKE_TOOLCHAIN_FILE=\"$$CMAKE_TOOLCHAIN_FILE\"" + manual.depends += $$CMAKE_TOOLCHAIN_FILE +} + +manual.dir = $$OUT_PWD/manual +manual.target = $$manual.dir/html/index.qhp +manual.commands = @\ + mkdir -p "$$manual.dir" && \ + cd "$$manual.dir" && \ + if [ ! -f "html/index.qhp" ] ; then \ + if [ -d CMakeFiles -o -f CMakeCache.txt ] ; then rm -R CMake*; fi ; \ + cmake "$$PWD" $$CMAKE_ARGS ; \ + fi && \ + $(MAKE) VERBOSE=$(VERBOSE) && \ + $(MAKE) -C "$$manual.dir" install DESTDIR=\"$$clean_path($$OUT_PWD/../..)\" + +QMAKE_EXTRA_TARGETS += manual +PRE_TARGETDEPS += $$manual.target +QMAKE_CLEAN += $$manual.target \ + $$manual.dir/html/* \ + $$manual.dir/*.{qch,qhc} \ + *.{qch,qhc} +android { + INSTALLS += manual_data + manual_data.path = /assets/doc/manual + manual_data.extra = $(MAKE) -C "$$manual.dir" install DESTDIR=$(INSTALL_ROOT) +} + +OTHER_FILES += \ + CMakeLists.txt \ + Doxyfile.in \ + footer.html \ + header.html \ + Manual.qhcp.in \ + postprocess-qhp.cmake.in \ + preprocess-markdown.cmake.in \ + style.css diff --git a/doc/manual/pages/android-app.md b/doc/manual/pages/android-app.md new file mode 100644 index 0000000..d801a6c --- /dev/null +++ b/doc/manual/pages/android-app.md @@ -0,0 +1,96 @@ +--- +title: Using the Mapper App +keywords: Android +--- + +[Toolbars]: toolbars.md + +On startup, the app shows a list of map files available from the [supported storage locations](android-storage.md). To start editing a map, touch its filename. + +This will show a map editor screen which is similar to the desktop version. In the following, only the functionality which differs from the desktop version will be explained. To find out about the other symbols, see [Toolbars] in the desktop application's manual. + + + +The mobile map editor +--------------------- + +![ ](images/Android_UI_explanation.png) + +(1) Hides the top bar. + +(2) Compass display toggle + +When this item is activated, a compass is shown in the top-left corner of the screen. The red line indicates the north direction, while the black-white lines show the up direction of your device. If both are aligned, the device is aligned with magnetic north. When the needle is close to the north direction, a green circle appears which quickly shows how well the device is aligned: the larger it is, the better the alignment is. The compass works three-dimensionally, so you do not need to hold the device in a flat pose for it to work. + +Note: the usefulness of the compass depends on the presence of a gyroscope, as mentioned in the device recommendations section. + +Attention: the compass is very sensitive to magnetic materials. Android tries the eliminate the influence of local magnetic fields, but this requires calibration. To do this, move the device around in the shape of an 8 while rotating it and while the compass is active. If the local influence changes, re-calibration is required. + +(3) GPS position display toggle + +This will show a dot at your current position. In addition, in case an accuracy estimate is available, this shows a circle around the dot which indicates the positioning accuracy. The chance of your real position being in the circle is approximately 70%. + +While this is active, your GPS track is automatically recorded into a GPX file in the directory of your map, named " - GPS-.gpx". This file is included as a template in the map. You can simply show it using button (7) to view your track. + +Note that track recording is interrupted while the screen is off or the app is in the background to save battery. If you want to record a track, you need to keep the app active. + +(4) GPS distance rings toggle + +This button is active if GPS position display is active. When activated, this will display rings in 10 meter and 20 meter distance from the GPS position which can be used to do rough distance estimates. + +(5) Automatic north alignment of map toggle + +When this toggle is active, the map is automatically rotated to north using the device's internal compass. The update frequency is 1 update per second. This is quite low on purpose to save battery, but you probably still need some replacement batteries when using this mode. While interacting with the map and for another 1.5 seconds after that, the map is not rotated to allow editing without unwanted rotations. If GPS position display is activated at the same time, a line starting from the GPS position and going in the direction of the up direction of your device is displayed which shows your viewing direction (assuming you are holding the device upright). + +(6) Touch cursor toggle + +This symbol activates a helper cursor which allows slow, but precise editing with fingers only. The cursor consists of a circular area and a pointer above the circle. + +![ ](images/touch_cursor.png) + +Touching the map anywhere outside the circle moves the pointer to this position. Touching the circle simulates a real touch at the pointer position above the circle. + +(7) Template visibility toggle + +This shows a list of all opened templates. Touching a template toggles its visibility. + +(8) Close button + +This closes the active map and returns to the map selection screen. + +(9) Overflow button + +Depending on the screen size of your device, some of the symbols available not fit onto the screen. They are instead placed in a list which is shown on touching the overflow button. If all symbols fit on the screen, this button is unused. + +(10) Record temporary GPS trace + +This symbol is enabled when the GPS position display is active. It records a temporary trace of the GPS position, which is intended to act as a guideline for drawings. Using the GPS trace directly is rarely useful because of the GPS uncertainty. + +(11) Record temporary GPS position + +This records a single point at your current GPS position to act as drawing help. + +(12) Clear temporary GPS markers + +This removes the markers created with (10) and (11) again. Note that markers are not saved in map files, so they will also disappear when closing the map file. + +(13) Paint-on-template settings + +This button allows to select the active image for scribbling (using the symbol above it). + +(14) Free-hand draw tool + +Allows to draw paths free-handedly. + +(15) GPS point draw tool + +Sets a point object at the GPS position. Selecting this button first enters an averaging mode. While it is active, the GPS position is averaged to get a more accurate estimate. Touch the map display anywhere to finish the averaging. + +(16) Symbol selector + +Displays the active symbol, and opens the symbol selection screen when touched. + +(17) Map parts selector + +This button opens a popup for changing the active map part. + diff --git a/doc/manual/pages/android-index.md b/doc/manual/pages/android-index.md new file mode 100644 index 0000000..bee935a --- /dev/null +++ b/doc/manual/pages/android-index.md @@ -0,0 +1,27 @@ +--- +title: The Mapper App for Android +keywords: Android +redirect_from: + - /android/ + - '/Android Manual/' +--- + +The Android version of OpenOrienteering Mapper is not as self-descriptive as +the desktop version, so please read this first for important instructions. + +{% if doxygen %} +**Note:** The [online version](http://openorienteering.github.io/mapper-manual/android/) of this documentation may contain additions and corrections. +{% endif %} + + +Contents +-------- + +[Device requirements and recommendations](android-requirements.md){: .subpage} + +[Preparing a map on the PC](android-pc.md){: .subpage} + +[Storing Maps and Templates on Android Devices](android-storage.md){: .subpage} + +[Using the Mapper app](android-app.md){: .subpage} + diff --git a/doc/manual/pages/android-pc.md b/doc/manual/pages/android-pc.md new file mode 100644 index 0000000..b40b108 --- /dev/null +++ b/doc/manual/pages/android-pc.md @@ -0,0 +1,96 @@ +--- +title: Preparing a Map on the PC +--- + +The Android app cannot be used to create new maps because it would be cumbersome +to setup the base maps there. Instead, maps should be prepared with templates +and possibly georeferencing using the PC version of Mapper first and then +transferred to the mobile device for surveying. + +If you want to use live GPS display, the map must be georeferenced. There are +several options how to do this: + + +Georeferencing when you create a new map +---------------------------------------- + +The first thing to do after creating a new map should be to load a georeferenced +template. If you do not have one, you may use for example an OpenStreetMap +export in case there is sufficient data at the map's location. To do so, go to +http://www.openstreetmap.org, locate the map region, and click 'Export'. Then +select an area which covers all of your templates and save the export as .osm +file. This file can then be loaded into Mapper as a georeferenced template. + +On loading the first georeferenced template, Mapper will show the georeferencing +dialog. This may look a bit intimidating at first, but when loading a template, +usually little needs to be changed there. First, the projection type should be +checked. If you do not know which projection to use, just select UTM. Second, +the magnetic declination should be entered to align the map with magnetic north. +You may simply use the lookup button to look it up on the internet for the place +of the template you loaded. However, be aware that the lookup only uses a model +which may deviate from the real declination. It may be advantageous to check +this in the terrain. All remaining values in the georeferencing dialog are +already initialized using the newly loaded template, so you can then finish the +dialog. + +Then load all remaining templates and finish preparing the map. +Non-georeferenced templates will need to be moved to match the location of the +georeferenced templates. + + +Georeferencing when you use an existing map +------------------------------------------- + +In this case, the easiest way is to first create a new map with the same symbol +set as the existing map. The old map can be selected as the symbol set source in +the new map dialog to do this. Then load a georeferenced template as detailed in +the paragraph above (use e.g. OpenStreetMap if you do not have a georeferenced +template). + +After that, load the existing map as template in the new map. Then use the +alignment tools for templates to move the existing map to match with the new +georeferenced template. When you are finished, import the existing map template +into the new map file using the corresponding action in the template dock widget, +and you should be done. + +Attention: especially for old maps, the whole existing map may be locally +distorted. In this case it will not be possible to match the old map and the +georeferenced template and the only way to georeference the map is to do a +tedious undistortion. Mapper does not provide a tool for this. + + +Preparing for free-hand scribbling +---------------------------------- + +![](../mapper-images/pencil.png) + +OO Mapper supports free-hand drawing onto image templates using the tool with +the pencil icon shown above. This is especially convenient to use in case you +want to do only (or mostly) drafting while you are in the field, and draw the +final version of the map at home on a PC. It has the advantage of being quick +and it only alters the template you draw on, i.e. it does not create new map +objects, so Mapper's map display does not become slower. This may be relevant on +mobile devices because of little processing power or because of battery runtime. + +If you want to use this functionality, you should best load a separate, +initially transparent image template in png format for it. Suited images can be +downloaded here: + + - size 1024x1024 + - size 2048x2048 + +The images contain a red border, but are transparent everywhere else. After +downloading a file, load it in your map file and move it so it covers the area +you want to draw scribbles on. Make sure that the image resolution of the +template is good enough by drawing a test scribble. If not, you need to scale it +down using the template settings. You may also create multiple copies of the +file and load them as separate templates. + +Direct drawing onto base map images is NOT recommended because you will not be +able to use the eraser without also erasing the base map and because these +images usually are in the lossy JPEG format which will introduce visible +artifacts when saving the file and loading it again. + +Note that to view the scribbles on a PC after creating them on a mobile device, +you need to transfer not only the map file, but also the affected image template +file(s) back to the PC, as the scribbles are saved directly in the image files. diff --git a/doc/manual/pages/android-requirements.md b/doc/manual/pages/android-requirements.md new file mode 100644 index 0000000..d3d3003 --- /dev/null +++ b/doc/manual/pages/android-requirements.md @@ -0,0 +1,55 @@ +--- +title: Device Requirements and Recommendations +keywords: Android +--- + +Android version +--------------- + +The minimum version for running the app is 2.3. Write access to SD cards may require Android 4.4 (cf. [Storage locations](android-storage.md)) + + +Water-proofing +-------------- + +For obvious reasons, water-proof devices may be advantageous. + +Stylus +------ + +For doing any serious work, a stylus is a must-have (because of precision & +speed, and because of temperature during winter). You should preferably look +for devices which come with an adapted stylus such as the Samsung Galaxy Note +series, as general styluses for capacitive touch screens have rather wide tips. + + +Screen size +----------- + +There is a compromise between ease of handling (better on smaller devices) and +overview (better on larger devices). + + +Battery +------- + +It is very desirable to use a device with replaceable battery. It may be +possible to use an external battery pack for devices with integrated battery. + + +Sensors +------- + +OpenOrienteering Mapper can use integrated GPS receivers. However, their +accuracy may be low, so it may be advantageous to connect to an external GPS +receiver. There is no direct support for external devices in Mapper, but +some third party apps bridge the gap. For example the [Bluetooth GPS app](https://play.google.com/store/apps/details?id=googoo.android.btgps&rdid=googoo.android.btgps) +provides a "mock" location provider which can be used when Android is put in +developer mode. + +The app can use a magnetometer and accelerometer as a compass. Almost all modern +devices should contain these sensors. If a gyroscope is also available, it will +be used to improve the compass stability. However, these sensors are typically +not accurate enough to be used for measurements. They can be used for +convenience when not relying on a compass, but for accurate measurements, an +external compass is recommended. diff --git a/doc/manual/pages/android-storage.md b/doc/manual/pages/android-storage.md new file mode 100644 index 0000000..fb1c2aa --- /dev/null +++ b/doc/manual/pages/android-storage.md @@ -0,0 +1,39 @@ +--- +title: Storing Maps and Templates on Android Devices +keywords: Android +--- + +Storage locations +----------------- + +Android organizes storage and permissions different than PCs. +Especially on SD cards, write access for apps is restricted. + +You can choose the following locations for storing data which you want to edit and to display in OpenOrienteering Mapper: + +- Folder "OOMapper" at the top level of the primary storage volume. On most devices, the primary storage volume is a part of the built-in storage. + Files in this area are stored permanently, until you decide to remove them. + Unfortunately, there is usually only limited capacity available - this memory is expensive when buying the device. + +- Path "Android/data/org.openorienteering.mapper/files" on arbitrary storage volumes such as SD cards (since Mapper 0.6.5). + This is the only convenient way to store map data on cheap extra memory cards. + However, you need to be aware of the fact that these folders are removed by Android when you uninstall the Mapper app. + So please carefully save your changes to a PC. + +OpenOrienteering Mapper for Android will create these folders when they are missing, and scan them for map files. +It will display warnings when you open maps from the non-permanent app-specific folders or from read-only locations. (Top-level "OOMapper" folders on secondary storage volumes are scanned, but cannot be written to.) + + +File transfer +------------- + +You can transfer files from and to a PC via a USB cable. Android supports multiple file transfer protocols. + +- MTP is the preferred method now. There is hardly any interference for apps while the device is connected to the PC. + Via MTP, Android will only show files which are known to its Media Scanner. If you cannot find a file such a recorded GPX track, a reboot of the device could trigger a rescan. + +- Mass Storage makes the storage unavailable for apps for the duration of the connection with the PC. + (Android also needs to terminate apps which are stored on the volume which is provided as mass storage.) + Unlike MTP, mass storage does not depend on the media scanner, so all files are always visible. + +In some cases, users suffered from files being damaged during transfer. This can be worked around by choosing another method for file transfer. Remember to keep backups and to verify transferred files. diff --git a/doc/manual/pages/attachment/scribble_1024.png b/doc/manual/pages/attachment/scribble_1024.png new file mode 100644 index 0000000000000000000000000000000000000000..2de8cacee616aa60b0305b4ec91f47c6302974a1 GIT binary patch literal 5733 zcmeAS@N?(olHy`uVBq!ia0y~yU;#2&7&zE~RK2WrGmv6S@^*J&_z!{$_AZ~yz#t~& z>EaktaqI1^je-pZJS+#ro#nsWpSseePlKt_Jm}BE-YivFpvHtPr$MF}-2W@m_URAh``6> z0LeFi2nK>o;!IQknbiOy2%CsxC5;SM06Sz57>?vs;+UkkoH!F3NDT`}!l9Aj5Z4R> z!$}Efuv$`FPKx2AgaueFtqdn2yNo6g^uXd^P-6fB;tKacQ*(f88G>~Yk^-;>2arz* z*Lfs_1ti>PWH^z|MY5d)my=>RQaBRFq?O@FUL}r6oO5X!i!?Qylz@h)9Zez(K!6l( zgCL1GFc^TMg_H^vy%<*j>c`P?ZU9RWXSf1b?I19mIOigHjTD!YVmJw5G1|Dm8dyk? zM370VSOmv7tqjNNYe-_iZY7PH>W~!BDi*;FR9YF1)z^^3fZa;sn#+)2A;EB@a3qpRBg3)# z8jmQE&ZTKAQeybOWnq`n7=S~UH*0_-!vRLKJMR4Zmo3^_2jY6V`njxgN@xNAr~a)2=YKS~=Tves9y) z)(6KPzo-mVpB&cLtv!5JZe5qeeczQz62)GUVD{qh+|XPmy|Gq)y7=YQPX9P;^iu4+ zB$=!i8zV0{3A~uK5hv~MZhQyAPYSvej7S9Z2yR0JfB8>5B2W+^iIB>lpjkvnAwnt= zh>%1`HG=?Z05yObKn+v_P=oDH4c-h?8wPEzbHDmtzdd-}#QxZ>)?BcWam;1cZ;2E( z@|C=ZdQz*vC_FsC44xvj1^gra5&xKI04M;3EeC}|D?z*3_Hy{RI|(!*}NDc~RR zkNC$#13&>N00p3+8mP(T4Ku^c=(ZdFEKh*I(jF%T6o5jaftrLuRQ`M?l*0Hx@9gCA zt&#S3H>2fGyKTI&OGa%M>WQ}Nrs3m{mb7Aj-#0rKKqs0a0n8q}o6DoZUZ}9Aeo&DR z#fFEZQAS6EgcuqWV8ld7&A@VW6&3bGNOOo#1E>Mi0BT?w*gR@*yW`%uq(_a#GnZ58 r|FC@K%7r+i&!YEhAFhts`Iy@3g7F>uXR4=fEZMixk)GmISO4fA&zPkU literal 0 HcmV?d00001 diff --git a/doc/manual/pages/color_dock_widget.md b/doc/manual/pages/color_dock_widget.md new file mode 100644 index 0000000..f7b293b --- /dev/null +++ b/doc/manual/pages/color_dock_widget.md @@ -0,0 +1,57 @@ +--- +title: Color Window +authors: + - Peter Hoban + - Thomas Schoeps +keywords: Colors +edited: 26 February 2013 +--- + +

This window can be shown by clicking the menu item Symbols -> Color window.

+ +



+ +

Introduction

+ +

Colors on orienteering maps are defined in the orienteering map standards, ISOM and ISSOM, as colors from the Pantone Matching System (PMS). The recommended way to print maps is to use these spot colors to print each color layer separately onto the map sheet. This way colors printed later will overlap colors which are printed earlier. The color system in OpenOrienteering Mapper follows this analogy: each map file contains a prioritized list of available colors, where colors higher in the list overlap lower colors.

+ +

Colors can be managed with the buttons at the bottom of the list. To edit a color, double click its entry in the color list.

+ +

Color editor

+ +

Today there are different methods for printing maps and the color editor in OpenOrienteering Mapper is adjusted to that, so there are different settings for "desktop" and "professional" printing.

+ +

Desktop printing

+ +



+ +

The first page addresses "desktop" printing, i.e. printing maps with cheap home laser printers. These devices use the RGB color space to define colors, where each color consists of a given amount of red, green and blue (this is not to be confused with how the colors are actually printed; it is just how the PC tells the printer which color to print). So on the desktop page, you can define how the RGB value for a color should be calculated by OpenOrienteering Mapper:

+ +
    +
  • Evaluate spot colors: the spot colors referenced by this color will define its RGB color. This is only possible if this color references at least one spot color (see later)
  • +
  • Evaluate CMYK color: the CMYK value of this color will be converted to a RGB value (see later)
  • +
  • Custom RGB color: you can enter the RGB value directly
  • +
+ +

Note that while defining RGB colors is enough for normal desktop printing, using the overprinting simulation effect requires to define spot color printing options also. + +

Professional printing

+ +



+ +

This page is divided into two parts. On the left are the settings for spot color printing:

+
    +
  • If the first option is activated, this color entry represents a spot color and will thus define a color layer. Enter the spot color name in the text field below the option.
  • +
  • If the second option is activated, this color entry represents a color which is printed as a percentage of a spot color (screen) or a mixture of multiple spot colors (overprint). Choose the referenced spot colors and their amounts below.
  • +
+ +

When multiple colors overlap each other on the map and overprinting simulation is activated, the program simulates the effect of overprinting real spot colors where the colors are darkened when printed on top of each other. This can be very useful to increase map legibility, however it is not desired in all situations. Sometimes a color on top of another should erase the lower color completely. This can be set by activating the "Knockout" option.

+ +

On the right side of the professional page, there are the options for CMYK color printing. These are similar to the RGB color options:

+ +
    +
  • Evaluate spot colors: the spot colors referenced by this color will define its CMYK color. This is only possible if this color references at least one spot color
  • +
  • Evaluate RGB color: the RGB value of this color will be converted to a CMYK value
  • +
  • Custom process color: you can enter the CMYK value directly
  • +
+ diff --git a/doc/manual/pages/colors_symbols.md b/doc/manual/pages/colors_symbols.md new file mode 100644 index 0000000..e74b27f --- /dev/null +++ b/doc/manual/pages/colors_symbols.md @@ -0,0 +1,15 @@ +--- +title: Colors and Symbols +edited: 26 November 2015 +--- + +Modifying map colors and symbols + +[Color Window](color_dock_widget.md){: .subpage}
+Color system explanation and working with colors + +[Symbol Pane](symbol_dock_widget.md){: .subpage}
+Types of symbols and how to create a new symbol + +[Symbol Replacement Dialog](symbol_replace_dialog.md){: .subpage}
+Replacing the current symbol set by another, useful for updating the symbol set version diff --git a/doc/manual/pages/course_design.md b/doc/manual/pages/course_design.md new file mode 100644 index 0000000..e132c40 --- /dev/null +++ b/doc/manual/pages/course_design.md @@ -0,0 +1,81 @@ +--- +title: Using the Course Design Symbol Set +keywords: Courses, Symbol sets +--- + +[Templates]: templates.md +[IOF Homepage]: http://orienteering.org + +OpenOrienteering Mapper doesn't have a sophisticated course planning feature. +The Course Design symbol set provides basic support for designing maps with +courses and control desriptions. It contains the overprinting symbols from the +ISOM 2000 and the control descriptions from IOF's "International Specification +for Control Descriptions - 2004". See the [IOF Homepage] for details. + +![ ](images/course_design.png) + + +Loading a base map +------------------ + +Open the base map as a template in the background. See [Templates] for details. + + +Drawing the course +------------------ + +For simple courses which consist only of start, controls, finish and free +navigation you may use symbol 799 Simple Orienteering Course. For more complex +courses use the individual overprinting symbols. The labels for the controls +have to be created explicitly. + + +Creating the control description sheet +-------------------------------------- + +The Course Design symbol set contains the individual pictograms as well as +symbols for the different sections which together form the control description +sheet. The pictograms' names indicate the column of the control description sheet where +they are to be used. + +The control description symbols are meant to be used with a grid of horizontal +and vertical lines spaced 3.0 millimeters. By pressing the Shift key while +creating a new element, you may easily align all the parts of the description. + + +About the control description sheet +----------------------------------- + +The control description sheet starts with a heading which consists of blocks for +the event title, classes (optional), and (in a single row) course code, course +length and and height climb. The course length is given in kilometres rounded to +the nearest 0.1 km. The height climb is given in metres rounded to the nearest +5 m. + +The heading is followed by lines describing the start location, the individual +controls, and special routes. The description of start and individual controls +uses eight colums which are refered to as A...H. + +| Column | Description | +| ------ | ----------- | +| A | Control number. Numbering of controls is in the sequence they are to be visited, unless the description is for a Score competition. | +| B | Control code. The control code should be a number greater than 30. | +| C | Which of any similar feature. This column is used when there is more than one similar feature within the control circle; e.g. south eastern. | +| D | Control feature. The feature, as shown on the map, at the centre of the circle deÞ ning the control site; e.g. clearing; boulder. The description of each control is based on the International Specification for Orienteering Maps (ISOM 2000). | +| E | Appearance. Further information on the nature of the feature if it is required; e.g. overgrown; ruined. In certain circumstances also used for a second control feature where the description requires this. | + | F | Dimensions / Combinations. Dimensions of the feature should be given where the size of the control feature on the map is symbolic rather than to scale. Also used for the two combination symbols (crossing; junction). | +| G | Location of the control flag. Position of the control flag with respect to the feature; e.g. west corner (outside); south foot. | +| H | Other information. Other information that may be of importance to the competitor; e.g. radio control; refreshments. | + + +Specifications for Trail Orienteering +------------------------------------- + +There are two variations in the use of the columns when using IOF Control Descriptions for Trail Orienteering. + +| Column | Description | +| ------ | ----------- | +| B | Number of control flags. This column is used to denote the number of control flags visible at this control; e.g. A-C equals three control flags to choose from; A-D equals four control flags to choose from. | +| H | Direction of observation. This column is used to denote the direction in which to view a feature. For example an arrow pointing north indicates that the competitor should be on a path/track to the south of the control circle. | + + diff --git a/doc/manual/pages/edit_menu.md b/doc/manual/pages/edit_menu.md new file mode 100644 index 0000000..b15004d --- /dev/null +++ b/doc/manual/pages/edit_menu.md @@ -0,0 +1,80 @@ +--- +title: Edit Menu +authors: + - Peter Hoban + - Thomas Schoeps + - Kai Pastor +keywords: Menus +edited: 10 Januar 2016 +--- + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
UndoCtrl+ZThis most important function reverses the last change made to the map. Repeating 'Undo' will undo earlier changes, one step at a time.
+Attention: While changes to map objects can be undone this way, not all map changes are covered by the undo system. This includes changes to colors, symbols or templates.
RedoCtrl+Y, Ctrl+Shift+ZWhen you have taken Undo too far this will reverse the process — again one step at a time.
CutCtrl+XThis removes the selected object(s) and moves them to the clipboard.
CopyCtrl+CThis copies the selected object(s) to the clipboard.
PasteCtrl+VThis inserts the map object(s) on the clipboard into the map. They will be centered at the view midpoint.
+Note: When copying objects between different maps, their symbols and colors may be copied too in order to be able to display the objects in the new map in the same way as in the source map.
DeleteDelThis action deletes the selected object(s).
Select allCtrl+AThis selects all objects in the current map part.
Select nothingCtrl+Shift+AAfter this action, no object is selected.
Invert selectionCtrl+IThis action inverts the selection in the current map part.
Select all objects with selected symbolsAfter this action, the selection consists of all objects in the current map part which have the selected symbol(s).
Clear undo / redo historyClears the history of undo and redo steps, i.e. all undo and redo steps will be deleted. This reduces the file size for map file formats where the last undo and redo steps are stored, e.g. the omap format.
diff --git a/doc/manual/pages/faq.md b/doc/manual/pages/faq.md new file mode 100644 index 0000000..b3ad1e1 --- /dev/null +++ b/doc/manual/pages/faq.md @@ -0,0 +1,59 @@ +--- +title: Frequently Asked Questions (FAQ) +authors: + - Peter Hoban + - Kai Pastor + - Thomas Schoeps +keywords: FAQ +edited: 29 November 2015 +--- + +* TOC +{:toc} + +## Navigation + +### How do I move the map? +The easiest way is to hold the middle mouse button while moving the mouse. But you can also press F6 and move the mouse, or use the corresponding toolbar button, or use the cursor keys. + +### How to zoom in and out? +You can use the mouse wheel, press F7/F8 or +/- keys, or click the zoom buttons in the toolbar. + + +## Drawing + +### I want to start drawing a map, but have no idea how to. +Start by reading the [short introduction to o-mapping](mapping-introduction.md). + +### How do I add points to an existing path or delete points from it? +With the path object selected using the edit tool, hold Ctrl and click a free spot on the path to create a new point there. You can even move the mouse in the same action to set the position of the new point. To delete a point, hold Ctrl and click an existing point. + +### How do I change line segments from curved to straight and vice versa? +With the [line edit tool](toolbars.md#tool_edit_line), select the object you want to edit and hold Ctrl while clicking the line segment. This switches the segment between curved and straight. + + +## Advanced editing + +### How can I cut out a part of a map to take it for a new map? +First you save the map to the new file. Then draw some closed line or area (symbol doesn't matter) arround the border of the part which you want to keep. Now when this border object is finished and selected, click on the "Cutout" icon or menu item, then press the enter key. + + +## File formats + +### What are the advantages of the .omap format? +The .omap format is OpenOrienteering Mapper's native format. It is XML-based, which means for example that it is relatively easy for other developers to access the information in map files. Additionally, it is platform independent, error-resistant and makes it possible to keep a high compatibility between different versions of the format. + +### What is the difference between .xmap and .omap format? +The .xmap format is nearly identical but more verbose, even suitable for direct manual editing. The .omap format is tuned towards minimum size and fast processing. + +### Can Mapper read and write .ocd files? +Yes, Mapper reads .ocd files from different version (8 .. 11). But currently only version 8 .ocd files can be written. Beware that some details are neither loaded from nor saved to .ocd files, and some additional inaccuracies might occur. + + +## Mobile devices + +### Will Mapper be available for Android? +An Android version is available. It already has a special user interface, but it needs a lot of work. See the [instructions for the Android app](android-index.md). + +### Will Mapper be available for iPhone / iPad? +Probably not, due to distribution issues. Technically, a build should be feasible. diff --git a/doc/manual/pages/file_menu.md b/doc/manual/pages/file_menu.md new file mode 100644 index 0000000..5eba87d --- /dev/null +++ b/doc/manual/pages/file_menu.md @@ -0,0 +1,81 @@ +--- +title: File Menu +authors: + - Peter Hoban + - Kai Pastor + - Thomas Schoeps +keywords: Menus +edited: 29 November 2015 +--- + +These controls provide standard file management tools. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NewCtrl+NThis shows the dialog to create a new map.
Open...Ctrl+OShows the dialog to open an existing map file. Currently supported formats are .omap, .xmap or .ocd (versions 6 to 11).
Open recent This shows a list of recently opened files, recognizing that a file to be opened will often have been previously opened in the recent past.
SaveCtrl+SSaves the currently opened file. OCD files will be saved in version 8 format.
Save as...Ctrl+Shift+SShows the file dialog for choosing a file name and file format to save the currently opened map.
Import... Permits the import of maps or data in other formats. Currently the following formats are supported: .omap, .xmap, .ocd (version 6 to 11), .gpx, .osm, .dxf.
Export as.. Permits the export of the currently opened map to another format. Currently pdf and raster image export are supported.
PrintCtrl+P

Shows the print dialog to print the currently opened map.

Settings Opens the settings dialog. (On OS X, the settings are in the usual place instead.) +
CloseCtrl+W, Ctrl+F4Closes the current program window.
ExitCtrl+QExits the program, which will close all open map windows.
diff --git a/doc/manual/pages/georeferencing.md b/doc/manual/pages/georeferencing.md new file mode 100644 index 0000000..7463375 --- /dev/null +++ b/doc/manual/pages/georeferencing.md @@ -0,0 +1,78 @@ +--- +title: Georeferencing +authors: + - Peter Hoban + - Thomas Schoeps +keywords: Georeferencing +edited: 25 February 2013 +--- + + + +

Introduction

+

Georeferencing of a map is the best way for aligning templates (such as base maps or aerial imagery) and GPS tracks. In short, to georeference a map means to establish a known relationship between the paper coordinates of the map and the coordinates of a geographic coordinate reference system. This way, data which is known in a geographic coordinate reference system (such as GPS coordinates) can be transformed to map coordinates and thus displayed on the map, and vice versa the map can be transformed to geographic coordinates and e.g. be displayed on a world map. More information is available on Wikipedia.

+ +

Georeferencing properties are set in a dialog which is available from the menu Map > Georeferencing.... The dialog is divided in three sections: Map coordinate reference system, Reference point and Map north.

+ +Georeferencing dialog + +

Map coordinate reference system

+ +

This section defines in which kind of projected coordinates (real-world metric cartesian coordinates) the reference point relating map and geographic coordinates is defined. Projected coordinates are transformed to map coordinates by scaling and rotation. You should thus choose the coordinate reference system in which you know the real-world coordinates of a point on the map. In case you just want to load some GPS tracks, you can also just safely use UTM, which is widely used world-wide. Other choices are:

+ +
    +
  • Gauss-Krüger: this is similar to UTM and widely used in Germany, but is being superseded by UTM.
  • +
  • From Proj.4 specification: projections are internally handled by the PROJ.4 Cartographic Projections library, so coordinate reference systems can also be given in its internal specification format. Examples may be found at http://www.remotesensing.org/geotiff/proj_list/ and http://spatialreference.org/. When selecting this option, the specification field will be pre-filled with the specification of the previously selected coordinate reference system.
  • +
  • Local: this enables you to use local projected coordinates without a mapping to global geographic coordinates.
  • +
+ +

Depending on the selected coordinate reference system more settings may show up. For example, for UTM the zone number must be given in addition.

+ + +

Reference point

+ +

Settings in this section define the reference point, which is the point for which coordinates in all of the involved coordinate systems are known. Thus it acts as the anchor between the different coordinate reference systems.

+ +

In case the georeferencing dialog is triggered by loading a georeferenced template in a map which is not georeferenced yet, these settings are probably already pre-filled with sensible values (assuming that no other map objects exist yet), so they do not need to be changed in this case.

+ +

The Map coordinates field shows the map paper coordinates of this point. To change them, use the Select... button. The georeferencing dialog will then be hidden until you select a point on the map (left mouse click) or cancel the selection process (another mouse button). Changing the reference point on the map will not affect the other sections.

+ +

The next set of coordinates gives the reference point east-west and north-south position in projected coordinates, for example in UTM or Gauss-Krüger coordinates. Unless working with local coordinates, changing easting or northing will update the geographic coordinates. Easting and northing are given in meters.

+ +

The third set of coordinates gives the reference point position in geographic coordinates. Note that after the selection of a coordinate reference system other than local, projected and geographic coordinates are linked together, so changing one will also change the other. Geographic coordinates specify a location on the planet's surface by +latitude and longitude. Latitude and longitude are measured in decimal degrees. Also note that according to convention, the first coordinate here is the latitude (northing) and the second the longitude (easting).

+
    +
  • The latitude specifies the north-south position of the reference point as an angle relative to the equatorial plane. Negative values indicate the southern hemisphere.
  • +
  • The longitude specifies the east-west position as angle relative to a prime meridian. Negative values indicate a position west of the prime meridian.
  • +
+

The Datum field shows the datum the geographic coordinates refer to. This is especially relevant for the longitude.

+ +

The second last line in the Reference point section contains hyperlinks for opening the reference point in OpenStreetMap or in the World of O Maps directory.

+ +

The last option in this section determines which coordinates will be recalculated and which stay equal when changing the coordinate reference system.

+ + +

Map north

+ +

In the Declination field the angle between true north and magnetic north at the position of the map has to be entered to make magnetic north be at the top. This can be looked up from an online accessible model as soon as the reference point geographic coordinates are entered, however it should be checked with a precise compass if accuracy is required.

+ +

Grivation determines the rotation which moves the magnetic north to the top of the map. Grivation is composed of magnetic declination (the angle between true north and magnetic north) and grid convergence (the angle between true north and grid north).

+ + + +

The (mouse) cursor position of the map editor can be displayed in map coordinates, projected coordinates or geographic coordinates (decimal or as degrees/minutes/seconds, DMS). The coordinates of the cursor on the map sheet are discussed here.

+ +

Further reading

+ + diff --git a/doc/manual/pages/grid.md b/doc/manual/pages/grid.md new file mode 100644 index 0000000..60cf5d3 --- /dev/null +++ b/doc/manual/pages/grid.md @@ -0,0 +1,33 @@ +--- +title: Map Grid +authors: + - Peter Hoban + - Thomas Schoeps +keywords: Map +edited: 25 February 2013 +--- + +

The map grid can be activated by clicking the corresponding button in the view toolbar. Settings for the grid can be changed by clicking the arrow to the right of this button.

+ +

Grid settings

+ + +

Show grid

+

Toggles the grid's visibility.

+ +

Snap to grid

+

If activated, holding the Shift key while drawing or editing objects will snap not only to existing objects, but also to intersections of grid lines if the grid is visible.

+ +

Line color

+

The line color can be adjusted here.

+ +

Display

+

Here the display can be constrained to horizontal or vertical lines only.

+ +

Alignment

+

Here you can choose whether the vertical grid lines should align with magnetic north (which is assumed to be identical with the up direction of the paper), the grid north or true north directions. The latter work only if the map is georeferenced. If grid north is selected, in addition the origin of the grid will be shifted to the grid coordinates origin. Furthermore, it is possible to define an offset angle which is added to the north angle to calculate the grid orientation.

+ +

Positioning

+

The spacing of the grid lines can be specified here.
+Normally, at the coordinate system origin there will always be a grid line intersection. Using the offset values, it can be shifted away from the coordinate system origin.

+ diff --git a/doc/manual/pages/images/Android_UI_explanation.png b/doc/manual/pages/images/Android_UI_explanation.png new file mode 100644 index 0000000000000000000000000000000000000000..15fd6a813afcd339342231ec14fd874db15611e6 GIT binary patch literal 211085 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�gI`ID|)PI@q1yDd*(Wk<;*3IQ)svw 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�Q^{0YZ^vtyl&AAt= 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¬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 literal 0 HcmV?d00001 diff --git a/doc/manual/pages/images/color_dock_widget.png b/doc/manual/pages/images/color_dock_widget.png new file mode 100644 index 0000000000000000000000000000000000000000..d1831b1585e04afb6f6db428281e2b0941a2b95f GIT binary patch literal 97165 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 z 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

Z>`DU_RVMN#=dsuxRMXal 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 z zBZ0+jTW2Dj$V57EZoY9R(`Gd*r>uA1oxXnY?N}9pwqmlMzd6x%=FY8`rT-meP&sQ( z?0_`3Md-EXv6I}OS{@e5)!F9{d9#i=DU&!CmSoLc*W2KMX$vN*9&C}_^&r)Fs z1$7Kf1-D&y^&Z04?vsV{K8y&M<0SX}#?{_IgMZ%cJZF*jzGyz!D3_Pw3zSu+W*^ zq^0{2$t9gQM*%6U@Qx6qLAv20Q~^=@i<}(6fUH?lB%K^g$l&xS-Eh(VjkQYfFNyf* zl|#NKK1*^|MT8NvudrV`aam2o`+6?ml!Tt3K|P&X0wqaMRuUi`GPd5+j~Cq(t`~w# zPNkL*DJ1TU$Nc~5Zi}<-sWWGKGObh9CwQx|vsf!?PoR$s_)W|$5?oZ-7e?gIBg z){hWn(LJ)M6sKI&4ih(|@uMLS8^6182Sdv`YoVCr5KN*^gt^Dg(Z{7mbp5a=v+1KV46a11G>A;LBy*jk#gkQ!P99{Uq>uCBSdO#hE=o+q=`x{)7= zKl#g5E&Ixb+!6mmD@Hs2tTtuX!#6c}@?>vd72o(uePr2}MUDghZ*hUjyZZ-rUXBL} zKySSN#$D%@-AGJAnm~31uH}k|$%{%kwAP6(LX=G}Iz?{jAc4&Z9k! z!fYbSeL@TVgVZS7l`U%I2D38grG^nh$43#DS0II-O!NtX**&e4lD6D>#Xl*ObIcaW zU zIQ$xc>JlhIL<$%&>}%-U#ZgN()@Y}vx}_}BR>SB`@S zt6Y*Ys?4hsiPJn9hH0JAy@WXA&K>gZ7m)G9FF=IXY}k-{ei1R*ELFM%k*wCMS1%MA z!1O0BUi>tDS%Gj4ym@1gB~<$4_DjyXm<=7g7u*!X3p1)a3O_(71%*YoL!sG#2w5D# z(UxO#!(|bm@ZtJNOKECo;L7q#Zpd{5e#0cfE=!YcQM>T0MT;v4PEt?-CTGFVgnXcH z>M87W%o*a&U`Cl!K0Ya(#>LM9HKUUdyeUmNcAArr7!qIw!o&u4cRstcui_dBLW-~L z4Je@RJ`4TJ^|ABDdVOH;vjY)lN}fkE1t#Z%)>3B0F>iALy>k=qEREo6e=)F9C~$b{ijs85Ern?Klm z6scMw)jofzfCM2z(O$BEf^L)6N7z6cUZLcZIt^oZ#gHb3a1?Ij3UdQaP+mr))tSpz zuAFJuhgw(d%(OYLGupLmou(kyVA>hIUC~Zs%lJg+DQx+ITe^LFN?3FnDu4PRaU%j%Yg5;yB&&(baz1|i zNL4vVl0c0J{b28g>Dl~mNmj|1?gtT*3zl>pp;2H3MWNM|X2o6GFT!FWwlJFI2kGf2 zup1au_orDlGV;4YYJhugyS8nKlxZj8@Z1O7-aTs?U0LZX)*QmDtXY!~w$Qh(U%R%I zptlz?qfSio2S;ASMJs#7rmrq^*S;bg*@lDM|` z^)13G89+b>Wpi4IbZ^5%Cvg`5?$@Lytq55O=op-g-TU<$6_+Q$muWsRSl2aFH=HY9 zFM{#Kmc1vaaXvt%xLqjRvcz;ephk=tlUDSDCn)Zwf$#&= z&%C%~P$KE0pmTfSE5TV}w|x~0Ie(j=!-d)cdSKWigg(jl8g@-*vHXkk^9XH(=L^Ye z)1>n%Msx-&&#-K%jva-#I`&=Ton@2TwqA~;YYk;nH=JZlp0F5v5Mss;%eb?>V+*6- zI&xV;$MkV+JG12D$JTv+&&g zU^*iB_it<9KU(kDor-5**0vx)7-q z(lJSK)wQ}!L5^KeOyjA?9m^aK^yP9fs*lb$)=af$UyXPuCRhE zSK)5aR_EbdDbwq@pn-2F5j=S2a&e+^V2LlJu{@n@B9euubaz*D-g}Sal5UvwtP+BS)2~+ygS1(rlPz=1mkuSGN?U?x2#D!+w>k!(72A(%qp!jHyatJvXwH<&o1B6s z#F)W_N}nmRs4wRtS76-{SU}8QYM*z!~ zTY1}aN6v!>bG0?JRy?JIV#5nl%N7^a;d=2~{DhT_sm=t`8E1M8x2Rvk5L~Jcf>M5> zag2fj?z>Ij;&;#UJA2mLWI*Pxc0Tus|3P7_anzlwoOr0>?sHDg_g3z62P+hx+m`9QVqd=O)*}&bg*Ak#;*Fexqt6I0U}c z17F_N$tAOj(Nws?P${ja8o|GN2+$yXYUSaSzs-dpisM@B>D^DrbYbC&t?csSA}f_8 zsWo~#=exPGkJ+f1TDxw}*b~!y9ABJAW=Hv4{g+zFCj8|aS!W7-3iTtZt#cASqb76f zv>7(TI_Iq-v$^*oHEz`C+1_B)Dq-BGi_A4DO?@#~qov+bFKgLwcQQ*KLX8Lo0*#$g zoQyX zAeY`0+YjI)?cm-!f~p5XD&ylE)rBU`^-4(Vq%=|5HX>6hOI@Cgo{chnC24tlw-)N3sh}r7-3B=s7zJ zxwH?(mFUlqB8tdrns9MVFxKP+qWT6�yOu_jZY_0Q@EF6|V2>47$v804_C|UWH~- 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�xCBE%U^CEFY=QH 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 literal 0 HcmV?d00001 diff --git a/doc/manual/pages/images/color_editor_desktop.png b/doc/manual/pages/images/color_editor_desktop.png new file mode 100644 index 0000000000000000000000000000000000000000..edd21f1ea99ec6ad3e909754c2bf96d32b4adc8f GIT binary patch literal 35336 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 literal 0 HcmV?d00001 diff --git a/doc/manual/pages/images/color_editor_professional.png b/doc/manual/pages/images/color_editor_professional.png new file mode 100644 index 0000000000000000000000000000000000000000..46da52e088a509e4e54c3fa5cca1acbb446ac909 GIT binary patch literal 51197 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 literal 0 HcmV?d00001 diff --git a/doc/manual/pages/images/course_design.png b/doc/manual/pages/images/course_design.png new file mode 100644 index 0000000000000000000000000000000000000000..7e763e72576fd7f852e651d8438dc3b2aefb45e6 GIT binary patch literal 138556 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 z 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 literal 0 HcmV?d00001 diff --git a/doc/manual/pages/images/georeferencing.png b/doc/manual/pages/images/georeferencing.png new file mode 100644 index 0000000000000000000000000000000000000000..6216ffc48dadc41532fbbcefff70291363f4616f GIT binary patch literal 73351 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

JK!Mw+IskSU8I?&6zX}< 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˖V&jyd>B;ksq?EdhDKxBG%=>8qP;oW|wKoAQJ!J$|wX6sa|SN zUHm&Wi!ZT5hHvZZs0T{D1{antD*F3Fmt)i1O)s_;R3O1q;D){ZK@Se$IM+CE#bJqw zK~T}fq@R>O9qgN86;f=C8i|9iSrzNDi%G&TKkbUHev{noDLvVO4Ha|u(=4^;H_n>t zagF5pCd3f|dPA!b)EV;G@2G2?$^O7Kb|L#zG6ri;?r~_jHfC$4jk-5-Nhv95JnbL$RTFUXrEZ&tHm!sd z8=E$+6ru;$8B?WRZ$b=(kNcVzYI@$J0+PWay(K`|PxLP*fqEDU~Z| zZjOat7E6Gz;5PTXmQqs|!^jH(Yy&@BMLg)W0{MSvmA0BBY3~f?#&zyuSMQ%p``o&B zaC__M4i2Ax98vvS3vjw1_(QRM4rCc#WMZ5chdpvvz%5Y8H{Alb@ZT26>uVzlAE_W$ z^>Fgm_49Q%n~z8(fQn-HD9zQgd<}9Yqr@kf(q?k`Ii_r^)+KztzD(m~-Q05ZZUP=F z#;oFzk{to1iu5{tO=BlhQoimg@L|Hcd8a-Tl5DR0CH$O zoIS9BV&}Wq;yvUP*kbaQ+xWzE3eyXw`r)sm{@gU|>Pr>c6Ex7OuEwxR#Xg(Q*B~IH z?7-vVkmj789A-;c?%A`<188WO!5A9V`YFqGq;!O~_j6de;B$UA=ZUv?HoPxo*u|w) zpxKvJcU5!R5h1lW>e9o>k3%7%MU42dc%_IJvoUpXO~@}TwUEL3PcqS!bNemznfkry zv2v4yw(W`X7+w{|GO`-28f+O0{0o7tVEcgXNo}=>3X#g2OLV>Sv!wQhSLa)uQXOLtIXAB9YbV{BJ zJ_z)0B8|#?)2z{K^OUiuY_BCGFiEVe`kDLHs+?IBC@zn!(Z8oOd~%y%wBBU_vL5x+5&im~(T@ns@Q3(pA08bLus~j6cbRG5b+E-w3k!j`><{IT`|*mLa-L>j zYU&NZ&YyuC9fu(r?G+FiNHLz<4b&aBQ#$3yNJyUy2fP6ledVg1QK3##&0*tq^F%JH zb9FV4@L7xNdzEu9;l#>G9pxdHLd=dCVcPonKEeo$Vx&)rYV!FbvLjb045R zK&+0iCyHY$wH94*s3mz_6KiVDW;BSMTgAN=BQ~AW29mIROxxTxTm=#=6ah-pLEHrHPkl23l z_vdSyI!sod=>y{k2P##FaB#8#8t@9!qc#wy)HROw@^Gcz!(Dl&pY@bW_!jOmmZp}1 zPmppK3xQPBFAmt=l$Ov}^LH5;b6#Nm*-HFU%_Vsz7wlj$*M~ssc~d%#LaUMD5v%ST z6>C6a=M$iqq9Hr!vZ-gg$MW-MXbh*uLxw_q19y{8pB#3|wv8oim<9_DxbTP=X>qRB zGVHcYMg0x$O#aAjIlkj;w}mCr@P+fJwWvsRzD-VwUPrFAi}h>B?{|1SohVXLSs;NX z?rBtHbnn>t`)u7U%soQzI(IWBk6f@n?vTmoOV{I0*RyifiZ|YO7sFPD>CWORRi>1* zH#IQBSiZEjJi<=@k}6=D;d+)MRQp5ZuKQ;1yS?F$qZ8?d6I1Ium`W5fL%%0zV%FIQ z@%di|E7NJqKXrH3>Wse~pPjSir_ZYv9le5yq%yl-XJzNkYqWbqmTsNOB~)SO zsg`>YvRl2=we0@M$!s!QR%~+#DocD$Ln4S}CuO6504>}V=XHz&0wvp~ZOPXlvFscD z>wk)pE#kKMIb?CIGE-CEPDJ9;swV&TnkiE&Q$@2!f3X$PxrQAwm>*V-%}y&B0SC2j zph8NC&hvpx;naf5H4f=_7uB~jBnMJ$RRo}hahm=swVRmJ-9gYnHB9mZe)YF^Iu^x7 zM=vUsGU)d-Ui=-2zE-~==!1$$kskbfaWUq6_!aL(e1L!grgA~Q?y3#({eA2oHJQD1 zFCJh=>_`6H)X;fpn#bqiMer^9_OP#-NfluohQKlwA78nK3|VRkToERxoF|0t5+r>6gS3Ip_DnkWh6b?$ z?hP-m4(waeR9LyDe0;m(%90iJD_eo!W?2_ev~ppjPmCJCY}Amgei10{JJ+6f#rb8Y z!MW^w`Zgx!Ev=d+#$)fv*1@Y3cUs;v0w$|E`n@H=$D>qm?`Fy9>eV|DC$_Wehh_hJ zg8R%nnqPnFip}61i$Mojv0coADHnp!(EC9_*#SgP1V-qs#~fU)`S?naIBH)6UJ>6I zH$q=KIKV;-9|5KzD(dNW<32oxLOT5DDkE3{_Xn8Df01zJwEw(SZEX5t1@BSM-;~t} zY~0Moq>1u=@9&b=2;&qpq=H%|Xw>Kx-+Y``EOE+zb1INQjsN*4SMnWWAx~Z>GNr?V zT=i780wF&rN(+|9zb^DLF>);yOG07w6P?Rk;|}G*6Aascbn5b zme}1gSRYFHblyF(@LQL6Rg#{o>Q74}7|!-%WoYM*Dda<1^V)ay@wz6MT24 z0~J(L?0>qF=I)XGyHZK#>FVh}#ZAweM4taUfbtk2_U~Tef5%JyAN4!_JDjp9N?0rB z)op9QyBd?~pFU^8KmoHfgblq1`w9YCF3N{#B6sD3?6D%`2?=}lOlR>>3u2H?17mj~ z>c-(vWp1(KCWwN9gA)0+gm|-b>K{W*abtNF+KJu4Sg9317@OtgI92O)NppwK_nV{k zcIGJqhY2E>Tl@dTwKQME3#SN&@H!`{}w8HFfY@8JC5-<0AO8reWejB{ru-VQqqP!)2?8q z+)oX+=#p9I`0%$Ex4zzLrs{XR(>OI;L5%76^2z+sCU$Y|-`UiY21&nquZaEY(i{8>`>O!094)!+Xm zGo@#=#)<^I%&S*akjCKQ!ONT>^^BbSYh0xzvsJ^J9L3!B*$bEA5^B+&>5I{tD-;MO zYfdj>?rChieTOp;S@H2~F4qp0*Q6g#7o(^O>bkHnkn_uj3EU7pUC)c+Hm@lGdB>1A z4PxSG#E@x;`_T;O3TqvmXp~>{6cD>3g3f%L?e2XSseGCZrHIF0T>Ehj+6OW)ZPu^| zM+)^eRzd~~lsqz|2#P_BRPAs_e|$d%f;kC9x34r)9eCq4CmBnNTDsf6CU5ZqFx<|z z?c*a_eY7S(WyRpIc^vlX&>~x|mSA(jt!E9p(4}`M zwGEnb7>wI(#A_B6RUmtWVwNClCZT^usR=P0@`dd|nI+-3RhnZty_Q+63?Af4dtodv zb~obK)@8|x1d`J5`E@ab{33sKHWG;7vO^;R%=eWMCJtNUQt1e#h((QxkLfmvZ&KcZ zU*`wzQQE85gnllOhCOu`+dtidiFm!LBGAo7F7i4Z4<}DxMFvLXlU@#)Swq@_WXI$W z>#z(ubv?DVC$Ng|KjHcU34hm-x~u`5d|0G}9d8biOJ6DOaI)4>rs^C7cE$E~vq}C@ z3mX?Gv+!URT76sINA*JW@|| zw_Mr8QJ=oc6|Rv8V))KzPQsCQFv_+;91*%t2ny-An-ksDGt>=?6A{ahN{Y#*>G-BgYHhuj4DU7% zj|5fE1^Z$pt*5n{1U%e(Wrcjh2cl4qC!AC!(I! z%x&eTc)}oWAuhCCI;%QNb0PH`PAO*10=l=n}-$2i( zI|xEii1?$p6->%XhkkEwU$0stc$$dI#uJ+D-)TSP2W4KWrALb=1ldZ)&Z2b2G6u?PYokC==OR^4yMnuZOCIO`_5>kJkg&sc2B?+JR9{?a{uDe=w}*X& znkJGC23?7JpVB*&U+N!=o*r(A#q_5iyNpD^>~WU4vzz9aBIsGGhSpnuJh}4>a;djpFfsXo zjZ^OX50Q#J2tRsnW7pX)Ggxn9a2KbnDf8VeaK&^)T1=Fn4?>tp5F7-}u#MZsAla{} znxkkwvj;gjIfGf+bhQx<4Vv(BvuM<{o0QyMLuS!UJq|2o5%EnU_C&G z%{&=aA&(P*A0%-?Z|5(lfawV(pEjA9u6B)+)~fC+ak6#8>t(peprrBz_K*4F%G>MX z>w}E4Jvd%UNW}7hBRP$qpBK8u9h{IndXO?g`V1n_FK+1LZqy}4?Um4fO;D?Ne*f#65b`7yomN;93+li& z3BVu}L-k0z(vTc5z^mms*e@=5xjFGM8W{-L`q`2($tAFirec-w2n@HL{54$>;@3&y zv8b2OH9|?`LvL=FPINiiW`@AtAYy)LO-*E4GeQopM9_fWL*#qFq7*v=k&&RJr z;&6XV%-oz7vLM=615Y*Tq<-2hQg2xnAf8^hVpD0VI&H$bv|*)D&R>GOkd@U{NEJ$& zKcHbaIQ{o$#0yc6aF@T7ypWv10`kAV7j!RuJU*Du8yY%pZxOG;c_)Vl8n0vq5Wy{;$Tl*56#1Cv@SAT3_c6P)% zdRu+vv)Ws9cfP)PJ+PGDJ2GN4`;#*|CZ+@~_68E#(oT@NKy}0Nsf6oKF$o$HDT1?s zdYSD`gAsA7E^66i6z`*LgO1_+PK_cTA&E#P_ikE)d#;wTtQL*^1~k#IWL?kp5voSc zwKs!_6SB*(e)YD=s?k%5pt-5nGD##t;1*e?KL18)Y-|pb`;ImIWDHE=h~@phKDp?a z#mo2ha*mEmov}e+`GOiNaICq9?k+pfF4`sLB=2fF@qIX!b)sL6$jDGmEW{>Jc+=S7 zNNuEDz>7To>py!SEwvFB)H_U<@7f)(xSzA+`OFR9*l9ox*N~lw7 zv0Y~P^XF}FX=#{^b7_P)peYoAgvE{{4?fZ;z3cvY%ZXkfDUmmt%jCMA2PN{uKry#4 zhxn#N#87U`@ao2f;OFy`h{bA`Z9aIm)cPTd+@Pia_L4W!2@PFcO5MZ3ZSWM*L@_+Z z#*Q%?huE|NotiHm30egvAa{EqH+jRzD3b?mmE0c}?d{d)5xo#fG71}*MJpXV+BQ`Y zt30ePMXw?^n(I#|mm@R53kW`sDhHDG@Jx-zAkU39Ft-*F5!pXDV76fX_1VK4l7a+f zWEf;jrqwec84$`BA+_%bUoeuGke4D$B(~r&G*2%P*hQYDDDL82{0-!1<9yts6nJT zB45LC+N9>&*_7f-&dX~RI5S|c3JPz}p*6D-e&vQ?j zU&uFog`R5+9_zdC=^mdbKj-9(0n2oMEm*^0QRzY34~yk=XkD%IJ6&C*3&z^UE=_WE zq_v?0I~OXLg+xTW4QP}f5z?B*Dg*CYa}gO<)xQba|w5# zuSi$lSkO+Ag}%GHYAHKCyS+_U0FTG~CSZVy`LWX%8)~Ymk;{VG_&o1XSl0$KVf!vK z9=>luZ1J4*x$$JyGjQtaH)Rz=q>UV6!at$ru;`+Y_`J;d77Co!RT)lka3HHzInxEk zvSqr@@PRvf@q=v=E<{eL78&0GTWyBs7!&j{VPIm+MC;rK{dG%F+^f=zK)ANkcg3-F zmuuTr|7%)G`UZZ!iHh^?FSqfbqY)|Au&VVDVid2vWcbEEQW8MG7y$IcK)DEm!&PlUU9C$>b~f1P z%v7sC-a{-Ma_=m9)1dT)(CWrJbG{mBzyJ4LdQLLH>%aN(>; zD;TFMsiTc?9*@rwcVp{G7n`_T9VAGW=52IvZ>*u5svdM3&VL$9?0kJn#M+lDay`d7IVV{v*vv z?+-bFFI;G$kr{7yLJcJ2_%PAXT!3{E$&Y0X?^q_6azKLG7e@}r+^BD}q(0ymYihzu z^209SaST(Dic5QVjT^La@Ynt@Z9;ktR!IeFzxykb@o+JuJS;HIt+k;cQJfFEsIs)9 z_+P84sZyFeZiG6`(O0hh_QKFLsaG`5H`+Qq}!=+LfNzcO#Z+G|qz z57}qPd@ZNrmB;YVHQ4uB^# zH5JY87^&z3{X|w!oQ?z@Js-`Ho-Q5k+CEX<@A>DcA_P(Fz{IBbr z_x*OR>+od*d+)W^Uh5ZgjydKS>5_M@lf&1MKH4RC@j~Q^_M5lwqcSjV-n=Qt1t;~x zfPw)$e3~?CrL+O@`u%%lUUSg3Xm1 zyD%&23J8KMI*2@j)X)(`%|l4D?-9NF(HsZ+&8)V?XCYt!1X4BOGn`$q68; z-ROfQUv8-b(sRFme)G1f_56kcFx0}=R>Y_2JP3||eJ44=wJLs%sXz#%}n@Jx!r*p5^bJBbG* zVca&WLKt~0%6AJ}0Zs&397484pJbiF^K9-vT!6R$ZF4>E1b15@AsL$8YL`XKr^X{m zVtsgD)y8Hai=F*O2^^B{;*GR#-@<9tNUiDaP4Y^xn4L)BWBTm)HUs>1&+S|~>H?ac zZGI2>2p#k&k8#T-+11cb>~=7%xp#*jw#=}j+yWDsMDiw@b=4bKCOpJ!<}Jrqmv2?s z%h))8Bn`M(`CYoGTGx$c$R^NcH{+_P<)_i%l@jhsA$9f}9pUyv#3d_3X>~j2&~U%S zC{GGcV&WHnGxd=;t8f)v(z8l85!*z!h@HWkKZ^h<47uau9*wFDg$mlcuS>%jl|1!2 zm1viRMMU~CBsuP5R=oiv&oQB6W-u`E)~|`b^TeBig7V2z>CI?dQqmsKai9U|8mn56 zLj;{Vq)#L`hDiMdXF_!2p^+si)BR4S!a?VgDX8#8)mc7C61|z`FRAl7TU8nmNiNr4 z)UdXySKEAe)UEak`syHg4_@OiXVK}$M)Xy?a&K=hW>9{?he!liU0m;2 z-h9@M%V<6RP$ z^ox+3V8pQl&RJIFi z!JscxZ_w=L*U!3s&;{8m9}RMcMVIx0sW0QC<{Eq6`}pY^8UoDbXLRh!14&ZX=qt+W zSU3hSz_~VBAzRn|e*^OHsbwFGRHDHe9S%);h{Uus^kjkTiA-r{r-R=u3m+Qp3%Gef z1pWrPHRHyg67leV{rp)TXmnv``ugg1j<-P)ge$}6@6z(Zj)F4jI@o@grg_{Spn630 z#CgL7WTm8@Rk0(GyY&2~hUs+Wm&6{=PedG^08i0tR3q-(xs$25FDfkT1O6rh5Ifwx zd-oGo{QI~#2AH;!+b?-Qq}kryT?WOZ@`_4Y zfjrd|7E~%{xrJM=nBC85361Unf)Eg?%83P6^W;;K4 zQyf#AN-`nn$Z!#G?%}Pj=KUhbTHoXs47s;$(CNT*&rN|DiIvm72`mB*94NjBPi(3! zXXFC24;hEh0Lj}xzD8A11e*-=*%(U-m&+buo$2T^xX6w>Z1`AMSjej)Esbqq!Ni5) zb4!Z>3VuI0+J3b8Z!NFj1V%@Jm4=Js#&k_qtow2giHoZ%s9vJYIy!vav9;5*Jq5kU z9u|vJEgs8vyAJ>x1W7xj#S~0yfNI`)I5Dq=^awcW_DM4?mXcS8dr|qgu{6KYg3Y}8M zmPQ2*cPbPZpFDl?YPjii@M%3jH%HFPjEmcV;CDjU^QBevFju1-#H#cZ&8uy0QUt?&EXHrEkaT3Ua_@yJL>e4@sHL;$b{gtA>J zosmV@K?y!SfNuE0+JR`$6`fb3v3_Q3`1b4aPFiv@ZPmBx0GLZfe|qb_vfJYM#Kpl! zbCX>4w$gysR7I78^@V{RQP9*b-DP`P!ZKx39hj=`bm1s|T0r#>TrG}gnq&4qt7&9? zKDRSAT1*nxbw4?5=fzJ>eeGl)1)$r!Y1=!ulVgIV9bSz>nL`PjNVL@w~#4bc6Kh zH|81u$I;&%HiM*{rb_;70$MoJ)vE3m6ubk~0&IiFqQFAm*4&>gcL6_A`JH0i;6y_DA*U?*R)$$g7aA z1l0A7!jh0l7(A=1MTFBX#+gKy5%F1ZDrOEPJ7%$8D>ezJttACpzVpO+y0XdxdKEA5 zwnnzwOirnT777MKG>6`^%i6)r2@fdc0)mLjUC9kqJ#P{0Re4DA*w0SxfqV(zVPF-` z2O=HJryVWXP!-02OWy)R4JQwe6oiw#DHt~h35m6hBc?OYd3itmP8ZA7s*|WF)N7A? zUKXqb0^Dp(gqMLv#8^zx2?x)MO=U9tSYfr;Ge^bJJHpQL2?M632_;RS)r$NL}GPOy(W zq3#OskfkkySBTD%IfstU+};L{$7nex?Wy9Mlfm}Qp&_(>wV=a|vw(&s-+@cN1^^p> zfg&kf>F^nf>V6PB0bPeER(pO>es8FMmO!fEy_KQt3F#AyRTn3C6^fdw-=EfuH$8UM zP4yGn4SmEz+WfK5q&49a;Zt9z6ToUI1VCAa`q*JjaNgu~##C#$+0VgJT3p z2Bn5G$Vcz54KqWv7e*bD%zI#0s<6GA^vv_heIB=1z+G`~-wpt6j2u<=G!t0^u5Yl? zQ++Yj%=$b{B|=5{SqYsDCC5Miad2|S`=gV|N^8I6UM*@rZ8lIi?&`XR&U1R%#Xgv> zf#dAVbGIw*eA;n+tST4+p?521QR?1mkT6m3{O`G4|98gs^?lQ%qNkTKvTjhuRX

+Drücken Sie beim Bearbeiten einer Karte die Tab-Taste, um schnell zwischen dem Bearbeitungstool und den Zeichentools zu wechseln. +Dies ist der dritte Tipp des Tages, der jedoch nur ein Platzhalter ist. Wenn Sie einen Tipp wissen, fügen Sie ihn doch hinzu ... diff --git a/help/tip-of-the-day/tips_en.txt b/help/tip-of-the-day/tips_en.txt new file mode 100644 index 0000000..66cc951 --- /dev/null +++ b/help/tip-of-the-day/tips_en.txt @@ -0,0 +1,16 @@ +

Welcome to OpenOrienteering Mapper!

If this is the first time you use the program, please read this first.

You might want to check out the settings and adjust the program to you. For detailed advice on using Mapper, read the help files.

Quick start advice:
  • Create or load a map using the buttons on the left
  • Hold the middle mouse button to drag the map
  • Zoom using the mouse wheel, if available
  • Read the hints in the status bar at the bottom to learn how the tools work
+

Examples

+While editing a map, press Tab to switch between the edit tool and the drawing tools quickly. +A map with few well chosen features will give a much better map than a map cluttered with many insignificant features.

Eduard Imhof +Features that are not important for a competitor taking part in a sprint orienteering event should not be mapped. Examples of this are waste baskets, fire hydrants, parking meters and individual street lights as they clutter the map with unhelpful detail. +In the end, it is the mapmaker's task to produce precise and legible orienteering maps by applying the specifications and generalisation rules, such as selection, simplification and exaggeration. +Mapping multilevel structures (bridges, underpasses or underground buildings) is confusing. Generally only the main "running" level should be shown. However, underground passages (e.g. underpasses, lighted tunnels) or overpasses (e.g. bridges), which are important for competitors should be mapped. +All line widths and symbol dimensions must be kept strictly to their specified value. Certain minimum dimensions must also be observed. These are based on both printing technology and the need for legibility. +Minimum gap between two line symbols of the same colour, in brown or black: 0.15 mm, in blue: 0.25 mm. +Minimum gap between line symbols and area symbols of the same colour, in black: 0.15 mm. +Shortest dotted line: at least two dots. +Shortest dashed line: at least two dashes. +Smallest area enclosed by a dotted line: 1.5 mm (diameter) with 5 dots. +Smallest area of colour:
  • Blue, green, grey or yellow full colour: 0.5 mm2
  • Black dot screen: 0.5 mm2
  • Blue, brown, green or yellow dot screen: 1.0 mm2
+All features plotting smaller than the minimum dimensions must be either exaggerated or omitted, depending on whether or not they are of significance to the competitor. +The sprint map format should not exceed DIN A4. diff --git a/help/tip-of-the-day/tips_fr.txt b/help/tip-of-the-day/tips_fr.txt new file mode 100644 index 0000000..4fb60f1 --- /dev/null +++ b/help/tip-of-the-day/tips_fr.txt @@ -0,0 +1,16 @@ +

Bienvenue dans OpenOrienteering Mapper !

Si c'est la première fois que vous utilisez ce logiciel, prenez le temps de lire ceci.

Il est possible d'accéder aux préférences et de personnaliser la configuration du logiciel. Pour des conseils détaillés sur l'utilisation de Mapper, consultez le manuel.

Conseils pour commencer tout de suite:
- Créer ou charger une carte avec les boutons à gauche
- Maintenir appuyer la molette de la souris pour déplacer la carte
- Pour zoomer, utiliser la molette de la souris, si disponible
- Lire les conseils dans la barre d'état (en bas de l'écran) afin d'apprendre à utiliser les outils. +

Exemples

+Lors de l'édition d'une carte, appuyer sur Tab pour basculer rapidement entre l'outil d'édition et les outils de dessin. +Une carte avec peu de symboles bien choisis sera bien meilleure qu'une carte encombrée de symboles inutiles.

Eduard Imhof +Les objets inutiles pour les compétiteurs dans une course d'orientation de sprint ne devraient pas être cartographiés. Par exemple les corbeilles de rue, les bouches d'incendie, les parcmètres, les révèrbères sont des détails inutiles qui encombrent la carte. +L'objectif du cartographe est de produire une carte précise et lisible en appliquant les principes spécifiques et généraux suivant : sélection, simplification et exagération. +Cartographier des structures multi-niveaux (pont, passages souterrains ou batîments souterrains) est source de confusion. En général, seul le "niveau principal de course" doit apparaître. Cependant les passages souterrains, tunnel éclairés ou les passages aériens comme les ponts qui sont utiles pour les orienteurs doivent être cartographiés. +Toutes les largeurs de lignes et les tailles des symboles doivent conserver leur valeur spécifiée. Certaines dimensions minimales doivent être respectées pour apparaître correctement à l'impression et permettre une bonne lisibilité de la carte. +Écart minimum entre deux symboles de ligne de la même couleur :
en brun ou noir : 0,15 mm
en bleu : 0,25 mm +Écart minimum entre deux symboles de surface de la même couleur : en noir : 0,15 mm +Pour les lignes en pointillés : au moins deux pointillés doivent apparaître +Pour les lignes en tirets : au moins deux tirets doivent apparaître +Les surfaces délimitées par des lignes tirets doivent avoir un diamètre au moins égal à 1,5 mm et être composées d'au moins 5 tirets +Les surfaces de couleurs doivent avoir un diamètre minimum :
Bleu, vert, gris ou jaune en plein : 0,5 mm²;
Pointillés noirs : 0,5 mm²;
Bleu, marron, vert ou jaune en pointillés : 1,0 mm² +Tous les objets plus petits que les dimensions minimums doivent être exagérées (agrandies sur la carte) ou ne pas apparaître, en fonction de leur utilité ou non pour les orienteurs. +La taille d'une carte de sprint ne doit pas dépasser le format A4. diff --git a/help/tip-of-the-day/tips_ru.txt b/help/tip-of-the-day/tips_ru.txt new file mode 100644 index 0000000..1d8ed4d --- /dev/null +++ b/help/tip-of-the-day/tips_ru.txt @@ -0,0 +1,14 @@ +

Добро пожаловать в OpenOrienteering Mapper!

Если вы вперые открыли эту программу, прочитайте это сначала.

Возможно вы захотите ознакомиться с Параметрами и настроить программу под себя. Более подробно об использовании Mapper читайте в Справке.

Советы по быстрому старту:
  • Создайте или загрузите карту с помощью кнопок слева
  • Удерживайте среднюю кнопку мыши для перемещения карты
  • Изменяйте масштаб с помощью колесика мыши, если возможно
  • Читайте подсказки в нижней части окна, чтобы понять как работает инструмент
+

Примеры

+Во время редактирования карты, используйте Tab для быстрого переключения между инструментами редактирования и рисования. +A map with few well chosen features will give a much better map than a map cluttered with many insignificant features.

Eduard Imhof +Объекты, которые не важны для спортсмена в спринт ориентировании, не отображаются. Примерами могут служить мусорные корзины, пожарные помпы, парковочные столбы и т.п. +Отображение многоуровневых конструкций (мосты, подземные переходы или прочее) сбивает с толку. Как правило только главный "беговой" уровень должен быть отображен. Однако, если такие объекты важны для участников, то они должны быть отображены. +Все толщины линий и размеры символов должны строго соответствовать указанным значениям. Минимальные размеры также должны соблюдаться. Они основаны, и на технологии печати и на потребности в удобочитаемости. +Промежуток между двумя линиями одного и того же цвета должен быть не менее 0,15 мм (для чёрного, коричневого) и 0,25 мм (для голубого). +Минимальные размеры точечных линий: минимум две точки. +Минимальные размеры пунктирных линий: минимум два штриха. +Минимальный размер площади, отображаемой точками: 1,5 мм диаметром (5 точек). +Минимальный размер площадей, отображаемых цветом:
  • голубой, зелёной, серой или жёлтой заливками: 0,5 мм2
  • чёрной точечной сеткой: 0,5 мм2
  • голубой, коричневой, зелёной или жёлтой точечной сеткой: 1,0 мм2
+Все объекты меньших размеров должны быть или утрированны (обобщены) или пропущены (не нанесены на карту), в зависимости от того насколько они важны для ориентирования. +Размер карты для спринта не должен превышать формата DIN A4. diff --git a/help/tip-of-the-day/tips_uk.txt b/help/tip-of-the-day/tips_uk.txt new file mode 100644 index 0000000..063d56a --- /dev/null +++ b/help/tip-of-the-day/tips_uk.txt @@ -0,0 +1,16 @@ +

Вітаємо в OpenOrienteering Mapper!

Якщо ви запустили цю програму вперше, вам можуть бути цікавими наші поради.

Можливо ви захочете переглянути налаштування щоб налаштувати програму на свій смак. Детальні поради щодо використання Mapper можна знайти у вбудованій довідці.

Швидкий старт:
  • Створіть або відкрийте карту за допомогою кнопок ліворуч
  • Утримуйте середню кнопку миші щоб переміщувати карту
  • Віддаляйте або наближайте карту за допомогою коліщатка на миші
  • Читайте підказки у рядку статусу в нижній частині вікна щоб дізнатися як можуть працювати інструменти
+

Зразки

+Під час креслення карти, використовуйте Tab щоб швидко переключатися між інструментами креслення і редагування. +A map with few well chosen features will give a much better map than a map cluttered with many insignificant features.

Eduard Imhof +Не варто зображати на спринтерській карті об'єкти, що є неважливими для учасника змагань. Прикладами таких об'єктів є сміттєві урни, пожежні гідранти, парковочні автомати та ліхтарні стовпи - це лише навантажує карту непотрібними деталями. +Кінцевою задачею картографа є випуск точної чіткої карти, застосовуючи при цьому специфікацію і прийоми генералізації, такі як вибіркове відображення, спрощення або перебільшення. +Зображення багаторівневих конструкцій (мостів, підземних переходів або інших споруд) спантеличує. У загальному випадку лише головний "біговий" рівень має бути зображений. Однак, проходи (підземні переходи, освічені тунелі, мости), що важливі для учасників змагань, мають бути показані. +Товщина ліній та розміри знаків повинні точно відповідати визначеним величинам. Також мають бути витримані певні мінімальні розміри. Ці вимоги забезпечують чіткість карти незалежно від технології друку. +Мінімальна відстань між двома лінійними знаками однакового кольору - коричневий або чорний: 0.15 мм, синій: 0.25 мм. +Мінімальна відстань між лінією та точковим об'єктом чорного кольору - 0.15 мм. +Найкоротша лінія з точок: мінімум дві точки. +Найкоротша лінія зі штрихами: мінімум два штрихи. +Мінімальна площа обнесена контуром: діаметр 1.5 мм і 5 точок. +Мінімальні площі для об'єктів певних кольорів:
  • Синій, зелений, сірий або повний жовтий: 0.5 мм2
  • Заповнення чорними точками: 0.5 мм2
  • Заповнення синіми, коричневими, зеленими чи жовтими точками: 1.0 мм2
+Всі елементи креслення що менші за мінімальні дозволені, мають бути збільшені, або упущені, в залежності від того наскільки вони важливі для учасника змагань. +Формат карти для спринту не повинен перевищувати DIN A4. diff --git a/images/about.png b/images/about.png new file mode 100644 index 0000000000000000000000000000000000000000..749c825e0743a3d6341572de182ba101d64e2ae0 GIT binary patch literal 1901 zcmV-z2a@=SP);LPjufD2=|8-OE7BK$+UZa)$s?zGqO6geu5xXE(epV?3 zPt2bp`mX_eaj1ipqrK3K`0! zB5BXV4+4y}^uiv!PM7hq;bL0(k3Rq1k;G+KTz{?LTZh`@R5-mDyrG z3(~`JG^tdIY&Js}MQE*1N+Tv_rjjr>S~{?2-=Y2a@?PbnT#~R;>DE{8t!-Ss>-6{3 zuh(Czf9b(fm>UAo?OUixx&=kr_qQK6Cp_tjiFE( zSGn?@{Kn_|Vo<2DmBhjWhWJ$U*%kaD7 zCarddf*UYCeF#j9PGxa&W4OgBQiUo`b_DH}L8Y)^gOTxlW#u^EzafAH-Fs@Qo5hIPb5h>5@^h#0Ji z@KPSuQhZMUCr@S$YF9t~k)wx8LYqr*gdaiU@+vB_AYfe0Y}vzvZM2QCVH2ZMND?5{ zV8bRh?jUi1LNG~)QncO+fD+IA?$+B56^yOX@i!=xg)lZ`4pdk?zlBMJVkN^Sn(6vF zg;E6*Y$G;CIcX4!jeTsdfeoAJbcvu-6R~>NdTwnf|pG=msqOnm$)1xUH- zTT@fxrCR+w)`HRkR-rX$oiH@40EGy=xc*6WE+U;?VCKLq64o*P4q{@IcF>s$Dl^2z z#W#6!>45i(jeBO`(U-3UxN0w$J)C`fYHE*HZ>|wX;Jnq^7qtS`D$cInkFQSP?!O1? zuaIs26*pbLEso>n$FXh!zw5KSw7{A6&78Im=vE;2mOpUka%167XRn&`ci!B6Uokm) z?2xnY_p@ZO3fBdtL8-o@;8No__2fPd&CRj09TJ9JJ~p<@EzuvC&0Ij40IM@B^(Ogq zaGWdpFxDwi@HDTSTWlv*PA>ia+b`}m1*s$sw?w>&ByoWRV?f!r#Uoo}xp^l?jvQin zE1;JMI+f>&dxV#+jPl6+`*Bqaz|VjAH;SVZbmBCfMi*7dFniNv@%8h|r+DC32RZei zfvXEqDhSMPE-bD@d#n3U%E1^&3?vDd1eSL0pgK88vl|hFF$jnVE88I|Q)SzZapcGm z#%Jc}rl;BRUHoqUz_d~CkjrE!7IVV~dP@)eQ}mqx$+~XoyC;hls@{Az~9uoM24EQ)f3(O7YUd4k$3jAY%KmR@iR&>>aBV zu=2ItrXXpx*j!!VA+0X_bZvdTIxXpSBn+?BTki^0OLOTv#RHNR=qZCX3 z3IITW_Q2I3E+xJ8!Wfb4oI{=fYL2^FR5qxf$z00000NkvXXu0mjf)s2>+ literal 0 HcmV?d00001 diff --git a/images/arrow-down.png b/images/arrow-down.png new file mode 100644 index 0000000000000000000000000000000000000000..dce3f15ef5739854e5fcf3d8f03f8da077d2617e GIT binary patch literal 1187 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 literal 0 HcmV?d00001 diff --git a/images/arrow-thin-upleft.png b/images/arrow-thin-upleft.png new file mode 100644 index 0000000000000000000000000000000000000000..63c81ae4182acaa3da1d9b39fbf1226d6dbe1033 GIT binary patch literal 441 zcmV;q0Y?6bP)!BkcUmV*8S!T;kQxi*l_-Zq7p#@5=x_6qR~#70z7 zBu<(UmgDZc+nw3Gu&^_`!#>~4?rg$WOfkV{`{f}%V3BiP8IZtZ9GCV>{Qb|E8@$6g zei@i3$G_a-8h>_-`G#fA`J)O6{J=@6>SmqatFxV{Alh>Kqdh+b)cSh|Vr}FNp38Ebjvm z_>TA60Id;$H)U^M?z*uRA`bbfv_Qn618O6pkGduz`mS9qL=1U@Yan9icRUmkHFmQh zh$?^~h-!eoh^l}-i0Xht5lsMxAesU8MKlHMKul6fGrVmM*noI|S9pf!qX5_ j%tixr5T}^q5q{qRb?f~)r9}Q-00000NkvXXu0mjfx+b|w literal 0 HcmV?d00001 diff --git a/images/arrow-up.png b/images/arrow-up.png new file mode 100644 index 0000000000000000000000000000000000000000..afb307b18c130d44b130c57f64075744d703b791 GIT binary patch literal 1193 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 literal 0 HcmV?d00001 diff --git a/images/colors.png b/images/colors.png new file mode 100644 index 0000000000000000000000000000000000000000..862df465c16a660184cf3501b0c28bea32161019 GIT binary patch literal 267 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdzwj^(N7l!{JxM1({$v_d#0*}aI z1_o|n5N2eUHAey{$X?><>&kwQkx@X1e`;VjNJus_B%;JQKQ}iuuLQ_tU~n!iAf%++mGr9^TnhK3Vw^eYdsJ!4g zy1c@CBDcHx(TTpE1#Zj?lje&|`mufAUC)g(-koDO}i-8z_U+@fH{M_% zo#s}5KhslFc$HGsfq;sJ!>YS|g(Q#jk(Ep<~BL?%Y9YWCRgW z&onlAHztz`=v-2PmQd);)@1TWYgeprD__5R_X6Nj;1GmNcQ<-yh-%BiTU`zH^#tN^ zL~B6MB5d0F0)xZDqddO zX4NW+Lqll8;9h!|Wn0_rH5GSjdpm=}!}Rs`QWpy0H%;!O)7u>@JeAT1{eEWid9sDV z5|!)ntu-P-I2L2-$`v9jSE6;X^qru!t$^0HT0i^cuNcecna$@3`u$W|;btHak82T8 z_a-LT_2P>QB-dIa#ZvVpfPoJ_AU`~eH9n5d>*el8AC-U|l9hxs?HwJAOiUmmDiM!s zHv^9M4Rv+KY(CGxg9rTK@Zpk=fJmuw(Aa-xu3yKO%i)`tWN!2x-f)HQ#~+I! zqS4w8tE1L)?d_a-?>(Y{070M6>tw+LbS7dkC4f`C*da%>Mr&=$St0%4r=PN_rG@Fi z0r305FbD?x44yx4uh%TFN=kOLb?mZL01~m70y;g|Gqqq9i;^uAcS6F!agCrJxpF^6sZ-_U+%#=sH2Z-YnTAWgANGwD+uqdywa01)L<~O6cAq zj2iWP82vE?@srEtm^6drayhJ`kAK#8a?hwoYi#10a(+akwLGMNu>cvAt_Y4Jo7)Xq zv%V?9#j6+idFL)Z`R~WTJX#ED5*^IU%(Jekwwxav(6W6MbM0XTDnZNgIo;s+sxgfs zD_1vjSHDau|3hxizRZqo8@YWu<;rbahT8$<=jGuHh)9*sFjTCnioYH?vfzPo7K*Mt z-`mm17nkqw+}b*=+G!0Di+zB2wiL=o-#uivqGd z8s)3cK6B^2OT;$QPO%m`+LkjnH^+Pt<}6s92y&x$h@G1o+$tRfbcLG#yLgdAG>U)> zXR}41%hQv~9qdk}?#x+MA?WuLt*YX0fBsX&5Yg@ni$$Bv`ldQAT>h41V>NRYtX&o4 zi%Z|q+*AVzWV%gyAoZN z-67<(M)tyRNGx3BX&q}JyW zky591ojAehwQH~6u4N9rme4cbR%gFS!yY_;9h3)Dz0Lw!mR>Wcid_EA7 zsp)Al_wN_GQ>m-Ke-?v3$GgU9BsV*2jZREd zJ*w)bJ)9l_UMd|ksV5TzMSpM!z~S}bA&du?Pkw;xQ@|uN3?_PJE03r zv)Q*iTE=L*Bho=XPspH&pS|aiGox5Vd4uRZ(S%NO_K3&6jB*vF4dQX44?6SNDju(9 z4NDFJ=L;OXk;vd$@? F2>_|eakKyc literal 0 HcmV?d00001 diff --git a/images/copy-coords.png b/images/copy-coords.png new file mode 100644 index 0000000000000000000000000000000000000000..05e3deadfe93381fb212c15ca92ecafde4b7fc6a GIT binary patch literal 1306 zcmV+#1?BpQP)Uka zNTpIOKA(S8Et{OwR6BA)WoKbwp+>+k3@#Rn$(p7)lgXq&DJ6=cR+UxZiPN$RB zEGh`L6&04YVp1L+9#*p1EC&Fpst&~C@sO_TqOR*oBocA=^z_X6{r(Kcakqq2T?L}i zs2mD~)-E+UpU-pQaM(i#VSzxvV2s@w2{kSHme1!eyTC9EZfIyo&FAw)vpD*=rbX4& z#IuA_dk4hQ(YHmn&!0nuj{&n8y4{8vD1h| zB{VASARtKIxQvdr44yx*4YDkmAtwZiqAbmUWHM=s#^0YhhfriaWXDFVsbI^RwL#3J zfVV%MMt5Ke2cFtmcMa}VA^h&-S&V7zkR6`7G7YjD+@iY+Ec*kbp8^L$3rtSGa;+c`uyu((I6}4gq6|J zK*Nw}7+GV^G$uRO;-jOdVHKs8zHV)8&5n(Y)wL)Rl}tW2(zAGCH$i{zE&#yDg-LvM zViIn}cM~-}Sa!pb2r$Ora=8lY)~(CcQ^2isnETQM`g=E&`TY_0tzw*6-8;?qx|>IoQ^2%y)~Nyz_a_>!6>b917`()Nr>Y(baZs2su$Z3Xu;gtS2g@7NkN9Y&Teu&V?i1cVR(1p6Kiz{u!zWebHI9=g{9NfH47JkLWEMQak;MWC|X z+!KI{AFnI#A|u#-PbWBzgD8sST6ujlA;58*WvwJ;Wd(r42L~`Wd!ZKk*$7@bxCMeB zKomttk_1VTAc`WUrl-KbZsq}(%XRh2mA{vK7nF!oje^J1i07Vc!#6)%hr_kL4E-~E znxU*|#Ajc83P~znN+eN2E}w%#c9gTJP|SMj(WN$j?}K;Vq?FcdUTTBwx1lR=4ioXB z0$tt-^l#o;zMk*exf`YVhGF3Mk@MJn--E|q!yEQ5B(x%lRJx$l?%%rwt?m(UxeyNQ z-(H5B=Xp>{kw_$vNF*?NVFaAO-RSG>JGAV(z>W(_?B;nMM_wE(fAc&KK@dPGMLM0v z{QNw$SQMfpBo4pu@(w~sdPNEp3I#YE4wLnzkgO&x&+}l6A(bi~sDDjd#`MfI8|b_H z=fRzWdkG=B>0Pi~IeF^%SmffL-7CE}vPG`9G`C*ezwhZojg5^z;{R6u1(ozYNh!Vo Q@c;k-07*qoM6N<$f&gZ7Bme*a literal 0 HcmV?d00001 diff --git a/images/copy.png b/images/copy.png new file mode 100644 index 0000000000000000000000000000000000000000..3348ee08fd8fcefa1b65a454e1ca6126267216f4 GIT binary patch literal 723 zcmV;^0xbQBP)LE$lq)T3AJjC7XEIa$68}xyYnVs4B|K|TZ zv)KUuI0yi?wwf26;b<|-g-z4=S+6zj#?8|Kz!{DfuQaY^sgI53`a+Um|ym8$`fH^ZGT_xM3LY>$S$|P=HpeCG`(` zy@kuG*%s;Mjr9tkaA0X^N$S7cc>y4sA|)ae3I(tKe->dd1zCjR6?5$Q2Yqpj0YB*JVj%3Zl+*(4i>dAVjPKoO6`RW$D_^?slwToN(B9C_oShT3-T4BA!GrZhjL7sz&RY)eR6 u7G6`dK2#+;?SSGVfrkuyA9@%VPTkaqQ{XxMqp1vNGJ~h9pUXO@geCx)2rPx#24YJ`L;(K){{a7>y{D4^000SaNLh0L01FcU01FcV0GgZ_00007bV*G`2iyW2 z3jr^8xGqWn00XW`L_t(o!^M?PNF!$$#-AB==EG#2gw1G)`A0^wB_%o_nC8$zPf}VM z3WY)`fzmBS=wZQ&hg|lOlY*6^^rqBT-!nULJXj*cXCGLy#X zC0UHb)kKqhPBS0x$Nc7fzUTdb=49ZWMFW6g7_ixFcx^Ha1Bpc9Hg!hZ01U&x*x1IYbmrb`F1J(tl) z+W@ZnU?&C<)vQ}r_sq@Bp{J(@6B844g|S!+R;v}~=jWK5oNWCN-jo(W5D*H5Fh4(E zw{A9@-v#iK#bUV%W?5KR*qxb~dC)XKBgwK1j^hvr1Q3Zt006VIvk(N~aVQk}Skttx zFV{Pr&ZY73@wY4%%QsB}T$*q%H9b9zOeTZD!9j$>VThuL(a}-Jvivv4ag{(I5Q{`2 z?kZSB6vdAUg~Gq8s{YwhVjC?+qfw;OY3%OqVtIKP`}_MC9v&v^>+63>l4Pu|uKp;B zA|H>(U*z+7V`*t=rM9=LNr0z~7B@FH5ekLia=E}T3;>|7ukXK1CL{TLzRzqn+Z$f5 z_kBSS#B4TOT3lRw=iuN#2Y~MTic_&z#P;?!dV71Zx3`CAGztK}_s%R83M?x%{P z{7@>D;ujYe102VFq3ilHnx^9>lPT763QkW?K?s4OD5z8_kR%BJpsMNxA*AGVI=|I* z-KQwZZ>d!3IeGK77{>Ge0W8SI&0sjj9{>OV07*qoM6N<$f-$4&z5oCK literal 0 HcmV?d00001 diff --git a/images/cursor-delete.png b/images/cursor-delete.png new file mode 100644 index 0000000000000000000000000000000000000000..9f6f44a39eb22b60135a84eb52cfdc72cc30c5e1 GIT binary patch literal 814 zcmV+}1JV46P)Px%=t)FDR9M69mCH+1VHk&h?|05zoQpHr#F&Wpyfi43WeJI(=!gVC(4y-m+C(l| z20`SX5K)U(27!=-EediGZ4{28gqf?AW&zw1zuSJbyUJ@H;HvM*o55D)| zectnaz|U}GDGUJToWtkyWetLJ&bcH>JX@XMsWdb+WDfuUqR}YNhKdz{Y^hiQNPT2l z#VUYos8|D#X%%Y#GOc1=fJ~~`5Fk@3HU!9&icJ9kU?;o4wn8^EGn2U)kR)m4ZIC1> z)&8AT(A(R)UcroR#BCLvZ*47pT3hP@K!2WvDl2!rvRd=DIs*iNhKGk~D}@(3I_O(R zN2>@7mbqN_I-SnyRr{m8z0j7Q-_N|>`xk+N&F&Jm)2^$frFkMzKM6vK({2w0a&rUY zq0rbDAhHk)`UIjLmQ1$f7)IqjRjsgU+OrWLkv4!sUa#p8gd(RXHVQ<@v)hXs{r;N6 z4o7^y$J5P#AeNShR237+zy>s<+K6x&CMB+WOB03?GAV>mNJ2e@~qa9Dv#%+ z$XGS$I@6YyF&dAL-HOF7Jkhk-v?>6Ace4ClHjFp*9?ub%AnavCBoGM%kglqHBpMyP z^6AsLVO^j2r$w|`9)vI00~9G-EjEfd()g~ve_u@Lzqe=81&^^t=Ac2 zMFfBm!AvB;;&Cd~_1zP){C3DNKJN&?*S0p76}ZiaI*Eu3&iRroa~6*SvP?cz%|B|I zfrPG)jRTR5w&}J2=9`->7E!!LL|w!=>6*re!r`$S)6+c_hT-$6>K-Txc@?FwnDc|P z!1IqlY`we0?EoyRs@oxoXDysVS5*uyER0;5nz|e|%~7T(k8j#+cM24xUNcQ7K#l`2 z(z>@#`2E78s;bi;>grdnh?DiS}IOcE=0CY1J7y(`n05ivdrX6`aTtv?EZgPx#24YJ`L;(K){{a7>y{D4^000SaNLh0L01FcU01FcV0GgZ_00007bV*G`2iyb& z4jUgu*2`l600JdRL_t(o!|j%_i{d~O#^2l?!4MD^TljL3DgUg#JPU zul5i^bk6x_P18OV3WW~|a{0Das})62g!Ot2 z005FCK^(_m+xC1qoqh>|;IZ9qKLY@~Ppg4FkH0`w)eDUAeYILWTPzlv*=)wP+wE5X zK!PCXilX3pyy*t6h%xFMbI?uGBYa;27`_3x_mesKK-e7I2=B?uFD65!RFsf!X&~lbRRZqF{{iRZ<cztX8YrTCG;BR4V7|_4<52ibtc-k0^e#FH_pb=-_+<>TW3N1a8bg00000 LNkvXXu0mjfDjFzW literal 0 HcmV?d00001 diff --git a/images/cursor-draw-path.png b/images/cursor-draw-path.png new file mode 100644 index 0000000000000000000000000000000000000000..efb5382a91590475f8dc2790836829b80424f685 GIT binary patch literal 622 zcmV-!0+IcRP)Px%C`m*?R9M69RXvLuQ53yzTt~-27!^~PbOB>wKmvh*R7tT|m^ATEC^m~#>JUgF zuAm!F_Pup1Ee z3h{P!NXb&yM0FAYWrft%jHYp;!B$3J%i#~|7}ffFmbDi(_m zP1AfI3Vm6!2o*y(^N~My#Ua!r5zmJQ>0$Z&X7K_D;gC(J^>yIjx z%6FdUK~WU&`Fs$KMqlRh`RqXmB$LS>Hk<8!xm<1n08mQ7@ApF}6grb6>E1!dkeYkKF8zn$C{=A%d+5hyJ0q)fvT#+ZntkOA3-1x;5m*1(==hT*}!JA0guOnwOUQ( zdHz}^*sLHRisA!G=`+JHKv5LvbUL)rXjBcuc%DckeqOEp1&PE4j*01PS^xk507*qo IM6N<$f>?Hq)$ literal 0 HcmV?d00001 diff --git a/images/cursor-draw-rectangle.png b/images/cursor-draw-rectangle.png new file mode 100644 index 0000000000000000000000000000000000000000..bcda7bc92b1d99284744c4f27d740c2dd5a00035 GIT binary patch literal 398 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz#^NA%Cx&(BWL^R}Y)RhkE)4%c zaKYZ?lYt_f1s;*b3=G`DAk4@xYmNj^kiEpy*OmPa3oD0oGXKBFtk0enx%r@g;JdZ^v)9jCRB+zzLemP? zz*5eTwaw2e)slIHE*4+nW;|yZwp8wi;p1?FV+r@aKiO;Vt$Dba=fRXo?{>Z8WpFWN z?cmt+{dwjryQx9yE?1;|TO=MAO0@ASS&0bVcxC78B{?N%d7;dHxvP=cj$S|ii3c}C z&%H15@{h|>mV$E23mk9y7>tW67HK?*2sh35*L*4Q_+k|Ie%3%Q&v4n*sgXNOx~`Y5 m6+e2;l8wR9rG3)*7fdsx+iJ@V1^xpAi^0>?&t;ucLK6U{Jd^zZ literal 0 HcmV?d00001 diff --git a/images/cursor-draw-text.png b/images/cursor-draw-text.png new file mode 100644 index 0000000000000000000000000000000000000000..49d770dac692f5d60cd88faec423b5ccfcd7217b GIT binary patch literal 676 zcmV;V0$crwP)Px%UP(kjR9M69mOo1zK^VrLnZ5V+Zr#PCP((q9AXrFJosA-AktV^Ae1qgW*gIb# z1T11>AR#G}CLE->R4M!vDGu>gJa_N*c5im(-4xMqftX-CH5eb5VqpF}?=wGM1~{7v zj93y^tTP!XiUQXz0o*Wf!@z&fz?Dm!#Cigl5CXrNAFuuCDbBd(dg!JRUB5;o{(^x& z?ompK_4W0N5JE6Bj4?%{(HJPD_)-#>oSdu+AzAe*u3ImP!teL{2*dDI7>2L2ECT@F^Sm{sRP{UtejCBk z($c)Oc13HAFbtW9-a3x+=HTD}%nSf4K@iMeSOVp8`5rSbq-lycj^7I*ZV}OVuh;vS z=Q)^p!FAoc=jj8dYI}S8_RP%8j^}xgy4@~;qdVA+2-bE z2LMW=GB7bQF-t@bq9{V1=ZNDN#uzX&nE6McQp$(E@6Q700Dv=!%eS_+9LI5CX*Qe1ND`=4s}&;J==FL? zk_1r{eTbsy-B5wn_x+TJ)`$p1wBh^y3joPT476G;8XFtiDT;#fJm)OS+5lDn1jkFd zNs@%dnCDVT$;`RdnnnttQmPEV9UA2!#tZ-rU~n>&Qu?3xVtoT;WFPYqD9e=q0000< KMNUMnLSTZl(LK!o literal 0 HcmV?d00001 diff --git a/images/cursor-fill.png b/images/cursor-fill.png new file mode 100644 index 0000000000000000000000000000000000000000..730101a2cafb964d3149863c82dbfc149ceb0c9f GIT binary patch literal 832 zcmV-G1Hb%`Ci(+m z6ry1obP<>#gHK!Koo*BgyjguIn9tpT_l4&??~j)k z2u~a;OTY>%ECZZ#thxlS#=sf_|2+dMF0vTwB4C6NEcITf{cRLs_N)%AEuz)8h{zu> z5LQp=ep|LcP{jcY;p7#evls95J@hSG0sT~FE5N^gmBZcFi>7`;OeNCJO-cR^H+h5x`r4)=Y2!!D6I|tIz z(m^SOD2hl+O-FLd#``+GPE;L2O=Nt3XJ?09qtQT76f`z8q2^ExN=wQh2m&NY!ua?& z8csCESa)Wps%C%#Tu~GVBG-DSmAsMB=PVcuLQxc$OlC-u1g%yJy*1ceJ^R_T(R2__Vqgi`8lsbUK|$tEVO* z2s0?6q==}pmQyYDQ{TU_uI_7(=9#Ze6saEp{)15>%U@;p(9xn literal 0 HcmV?d00001 diff --git a/images/cursor-georeferencing-add.png b/images/cursor-georeferencing-add.png new file mode 100644 index 0000000000000000000000000000000000000000..3dae5bda894aaa7201993c7aa569abc3a49f237f GIT binary patch literal 211 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz#^NA%Cx&(BWL^R}y`Cl6K7jMd?OH7t1Dp_fCzFcCY#i+8>lKqHL zg5-}{wpGn{uh}LrsC>JZ)*P(ye@mn2MA3<<4{pvW&bized{}jDQZC2Bt+Mx~uYGbo z#X(u+_9KTQHq!)Migs`*-4qut@OELy(y^T(7E=Bo+IL2?XsDi(@vR*VkwAwrc)I$z JtaD0e0szhGP>cWo literal 0 HcmV?d00001 diff --git a/images/cursor-georeferencing-move.png b/images/cursor-georeferencing-move.png new file mode 100644 index 0000000000000000000000000000000000000000..e35917a90746fc16039bcf45b8e389a6d1939399 GIT binary patch literal 268 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz#^NA%Cx&(BWL^R}$2?seLn02p zoo2{&*nr1%KX2>0rEx`q^KXV<)U-)6Sm^#kw#)bO5!ER!T3hNrFG;sml&)wo=wf%6 z#GyFDae|6#OW525-=2$n3=CeHTLLaJtO+q`sJakl$h;w7Bg2I-Fy>mYauN4}r6BxB zmw`d%ChPuIz2|GpnUyZxV-sBY);`S9D|79FS8jiHD6}7ZBfpWmp}p|Vz3pX>U(^LR z-ZZcipXcZ!E~_x7CGbW3zi>}Z9eTr{}zEW{R{kvQ1@0EUEdtMIcBL+`b KKbLh*2~7YL{b;}d literal 0 HcmV?d00001 diff --git a/images/cursor-hollow.png b/images/cursor-hollow.png new file mode 100644 index 0000000000000000000000000000000000000000..4fa2d9124c25bbfb974ab9a66eda2bbd9f0e6038 GIT binary patch literal 210 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz#^NA%Cx&(BWL^R}J)SO(ArXh) zPTk3SKtX^dd|hMIikV^CxVRQ{lqNK${G2HKUe#RkVsD-R1G|%eG=ry;rmBzAB$uGT z*%y{vlTv43Nak@}62TOxIqiVWj^H^gN_Ac+1eI4H#JtwJnPVy;pnZHXx;hvu>&|M6ku6{1-oD!M< DMOR1! literal 0 HcmV?d00001 diff --git a/images/cursor-invisible.png b/images/cursor-invisible.png new file mode 100644 index 0000000000000000000000000000000000000000..9aef78259e068f6e64b2507753091b6c466b7072 GIT binary patch literal 81 zcmeAS@N?(olHy`uVBq!ia0vp^Od!m`1|*BN@u~nR#^NA%Cx&(BWL^R}+@3CuAsp9} c6CBtX7=#!Y-*<*A0SYsCy85}Sb4q9e05_`;qyPW_ literal 0 HcmV?d00001 diff --git a/images/cursor-paint-on-template.png b/images/cursor-paint-on-template.png new file mode 100644 index 0000000000000000000000000000000000000000..7cf21ccf068cdd12320f3de2564e95bf61a21302 GIT binary patch literal 723 zcmV;^0xbQBP)Px%jY&j7R9M5!m%&RLQ4q$zr%fzE4}qWuy}AfR38ZdF4!a3LO_jzFD0s`ESEYv{ zJ+~nA4@fUkdhk#}FCu6cR1}ia2HG@-5?BZcApuLmMyXAfj0~M6~Q760U#oR)9JJff{2J@SthG0L6_or-Z}sPs8lLsg%vFTtE^}NTz;5s z#XkU6SaAiwY%8t+m~F+i0A^az5x^`fIs%ww#f<;}V6+M|Gc%4rATV{?V{|KBKA-RT zR>5HK-rCw)Zed~JYd9SK&^3T8%dNLTmSysIJXl#-0RYwufXn6jY`5DTnM}r}Y1$J} z6vsPWG9Hh&4!rQ202uaub#?V+B9Wk2EcV;y^O4{0|K4dYYad8>o<}N`V*NCf*Xx~% zMx)uu$;lxA*xA`(rBdmEBuSsH+kdAWB$Z0_)y+<))9!Y=6Vubv!`W;Wj4_;_pTFyL zcssyAw6wJJVsUYCyi_VtqtRf=Wb)hg_V&}8Vg?4_cDqHM=U?f%4pmi=PN(aqr>DYg zaRUJmMbRz@!W)j`pePCzi$$iY>f7VvW2Kv+v~M{aj!m!Ed%s*R)7jY>Qxrwo+uM8A z?Nr>C1VIRdLZN8AUPrA~W0_1w*LD4QFJpPX<&RHHOrTn=QZAQ+s;WUrlCq`%L?V$* zpU*dz&*$mnYDL zY1;e4!^4k^u`wbV0Wbo<)@ExHz|V`N0cZfw0sO-Mq(9)geT^BOi7fyC002ovPDHLk FV1jCLQU?G4 literal 0 HcmV?d00001 diff --git a/images/cursor-rotate.png b/images/cursor-rotate.png new file mode 100644 index 0000000000000000000000000000000000000000..4b7d1aea0dc96213eb9fb0caffa6bc3eab21daa4 GIT binary patch literal 756 zcmV#U} zgG^BX0LB=D(P)$n0%MFZMNwF;PT+RN$H(OZ001bL%UBK-9RRshbO72PQmgn4Kn@jG z0HjuN1wd*Q*8)hXqAP$@D!KwlrQ${a001$&p!gR$hGC?e0g9qJZv#b9?e>eSV0Cr% zx(g-Uh>~B}4!Vm&=H})UQ&UrVr_Jv)$r!#=BGd)U~ktlnarC?rGl%~YAqZN zdqhz%IXS6!I2^MK!$3Nno=zr{p8)_iHa0XGjplu!P&jBb8a&5wA4Qqoot>R~G)?1d zHoMi!IX%rltJMUITV3m^RO;RShy4ko!Dx@gV(hI}akm^F9}7Hx&T6%~>4k*_`=9ld zl@&Y3aTCL~VRm$M^!(OuLAT`d`6|n@YlDM>Ff%i=9a>!MKrBC7wvUXAY=7f<7#J8> zE0s!BQ5I1s6tehyzN}WK8#}91K&aQZn$0E>1Yw%vzJkp*bZ~fBcpQtxPP?6<>;)i~ z%kc(-;jOm6U!@|+p^J-4_r+!X0ih&Vl}h!Rrs*f~c>GlKRlKycq;R=hdH~edX#N0F mMG8kpN7ZOF+JgW2OMU{0Gk|9@7WRk$0000T~HaGlfB)9?TQ0CZi)FjQ;+!cwsTSTAU+_zfTo6)ym2t9SuGTg6rY znkrreprztf09q>k2mk=E&nmFH(2d7qdOe^h%I0rS6lGoh{VEs?2HOs#IuQdou-$II zX|-DH-|S(6x`8aq$Apj$01OcEYqeU%K$>vZM5EE8cszc=aa_goJT|abuxk$a!zW(g zf#bMG+qRJ^K(pCo2}{n?sWc=KiL*>5!$^|E?6n7ESw7}C?uh64rwAeE?=LSq{eHhH zisG&7x=BLFyTxLmI*#+q5a#as7*hjgKV~NY@DLb)@B0oQ4(792#C6@r)oOVr2;yx%pFb#<%dBadH>PQR zHVi}cJa6p#z8biKZnw*Lp2ym@jp*7_ z4oH&3luD&f#bU9eY1((wGT&Z(xLQ$r1&u}n=kvKbnM`0hovMaz0QEWGIL@e|F4Iev)g|lM*|c00000NkvXXu0mjf+m9ae literal 0 HcmV?d00001 diff --git a/images/cut.png b/images/cut.png new file mode 100644 index 0000000000000000000000000000000000000000..217663b19c426af17532b2a6c49c5e8bd119911a GIT binary patch literal 2087 zcmV+?2-x?DP)Zdu$ZP9ml^jJGXbYcjr6fw@v(r4VYq#0HI(2_~?g@7cB8Fk&x9!=}gY_lG8mz1Mcv z*Vdb+^<$MewN0BgMaGMx<2BUQ)@E|SH>IVf#XMf;t5Zo{Q}fzffL5fWq{alS7bl7x z7r>^{cNdl{R9CHBZ3oB?ckbF*IGN;9N}}4GdlxVIs(tm!uh|t!w@%defdDl%I~Lni z+kzPdGnteGixw`jJ8bIPlL4sPU9;Zf@#N=Z=TIReN=r*MCsS*u1OQ6sWo1rRIOmX3 zA~*M8>To#b)b9G(GZQ7>xpQX@|AAGFd?NxdU__6QkF~!Kmg}IZ@;2QNC1Fo zT3A)K(xnjkhX0rTgz?0jn)=3^uN0|_*&w9^r4(n*Hbpq+C#M8Zy`}m%Ka{z#@2hrKtrR$;Sx+wtwfF6vz*45n= z3I=b15CYBxN**nBQi^qTbw4d08{5#(U{e+QpUal5&`i?;0H~@BjYk@FZd&UnD&cVf z{CL!?!-sTL9UW4`F!9*pr4GfWzAdFB@z_vkxH2^@HQDEz1|b9pA-H_G&59Y( zQ(L!I?;kJ6ga80gx%uUf48v$@yWDCKLLeoOk`Zcjm7UClZGsH@wa2a3w2k1cl@ zh5;!h6osJaY?EO`_zx!1|3Ux&h()dEPM>Kq7-Nu9A{L8bMcFDhW#kw2^?o0-IsaH% zvPd<}(XZZax8sw4AJwTuO;uIZ)h`WDRaMn4rPy=)#IbOEDhQ#NJ-bNdQu{!4*h_MA z@>qQ6hi?rb5C{yq-M$BYtWyR6fY3;Edv{M~Fcb;`04&SGyt(rnib9u{EGTtFA`wU_ zp=lZpA8FJr!~9-FMTPl)1MvI(QPZ-XYdmsD*E9`MN<<=2EL&Pe&Yk}ZLI^O%aH08} z!3F=e+$FfpWonDs<5}x@wY2CK=iAp<)?KHgyUOrgpqx_r>Vm>T zS7(2J_+oo|*Uez?`-%`r5pGsrYHvqcQWB&o63PJ%02>Do3Nf*)V<-U2MsT&OcO({z zt>LCwcztlN@;}YZH?Q^eMHd$ryBMY0{-P*PKM-Ia;3bs)u6V`_t)sU$JTx+L$}7Z- z?*jYFfru*b_ed-jxxFdfRXsl%!iX&*xy$8(VVaBpXVw6{&jN2MLge)Z0&Q2ix?&}B z=C~N}+kL>a`v5FTE0Plv835e4c{AkY{E2S>v3R=xmiXLmGpOrejCI^QbxdI$F2xRy zrda}57Jpt2+){*C+8YQ&34pBBRGUTVhWh{%O4m(KNzu9o2Ets39b=O>0GgsGug}cM zN$BkBiwe&7-U}c&-`myK7tPJcNKh!<-2iA~Aq4RHwZ6V+ZdR7l#@L-B+8qGSd7j(l zf*uYV0M3q0?q%%bjFc3ws;cM?1WZGS-`oqJ2=VKlK)_U06-ho{Qi7r!919_YXbS3j z)a&uUw5;6w06>TZ0B)yKAwcm9K*H~VwH`%j&qz*wWKKbW^W?d6`Vg>b9UuWD0Z5K} zIY4d@^5SQ0ZTigYY)7)s_lTR)js{@uGe82Nbb(vbY?M+E;LdV=rwrd??8BKkIp3V- z^^#M~&AP?8lHhimg}J#NhpOV_`SaoHoHx8+S#RA2r?|U}B>=I9u?<<2R?MF@ON*K& z+IxC}L0wlFV`9a^h0fuT5qY|$<-pU1@gx8q7htu(jBG{uv@kc<{ZM*3wK0Z~PzW8p zz0vMKfVW8L-!8<*0BjiDL*lMrv?Q&#S5vyO2-udHnyTbwW;&95J^(;Zf4}%|YiqF0 zvL1g0Xa!)7eFIt#6sIw^8>4?Rlu+6?#QFaBh1h!p2;NQ>cQVH180P@^62MbV>9fg< zJq6A)2p|NdXS+=ErLDlZ+pu!Hy&x`3?@3A@;K1md$}v}d`#wH0Vocjz_CHHMd&M+J RSE&F1002ovPDHLkV1jK^+$sP7 literal 0 HcmV?d00001 diff --git a/images/delete.png b/images/delete.png new file mode 100644 index 0000000000000000000000000000000000000000..429c7716e55213ba0e4372072829f6273b2dbed3 GIT binary patch literal 1889 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 U1>%)jhX4Qo07*qoM6N<$f<^KxZ~y=R literal 0 HcmV?d00001 diff --git a/images/draw-freehand.png b/images/draw-freehand.png new file mode 100644 index 0000000000000000000000000000000000000000..4d17746191c50f3a1d7bc448838aac6f416491a5 GIT binary patch literal 1997 zcmV;;2Qv7HP)Y2UQxRA&{&fA?;7H`!%(lVx|a$+87PF@Yi^Am1SrN05eKkz@u8O6vGg%2Ww; z>Nw6QjHu)2w2sbLBXrtvf)xd^RuLpj14;x2%SQqs3E3osC7W!%*zda^_g??#CIp7I zK+Bmq|LvaVdEfUr&pB7%W5l;1Y+|y**>@)uN z^0T#H+K^E=duH%kW*Mn3mg37E5#`m*xc{2`5=gh{|xQGxl&6>bi;$hUHZHx3+$ z_B}Qcezn~6?Be1%FU_8k$eeWhGRb~{h`~%qO>r)Av7n!bU24g3=GcB+ zwrsuy6e7cC(M4WIj>Wh+cqKfn5!RhNN$O#5^nstiY8C4@t}AnE#0;WCt)!&ejD%!* zF8(&zIn=!CtrLN+M-lV`5qP28T)k+)yt2twn~;nS5gY0tky5$niK#dIm(JE53%>fO z?JRz@>L)p}t+t;pTU2aPl_X)`dw@!FkHigs;#NGORDK*c{YV04y>5SH#man9&=47D zMoC7wHJqfgPr9wB>Pv6_Cp`Gr2z+y`sb<;Yk|ow`s}K))i3fU#B~)6vB{>>b-rajF zaFCA~;s<-Z(V3g;{K?`4b4^MrN~Hf1stT98V)Tt9dc(=gt$YIUfdot@{lSgpEAvG` zAndz{Dktd~NYK$I4aXI6YyI(o$YUe0ZSADzS1emtVzF2RY1Bh9;wKnYXz7V1WLf#s z8^=aZ-{)_cKq>G#&<02oG76jlo(Bvc+J>9UvfOzt*AEwzJY`J914R9;C<+P}Nj{CIo0^paxQh?>lms3_s;bh})kR}t;}XB$zXbRi@O7Yh%!-AHxpJ<# zVN2!OBArf4=;nV>QW9<6I4#{#e;}rm|KnuBf6uA61BU?jrcIlutgOW8bP|n5@%#OR zLLsbHE2X8SxZQ4AT3TGd65s?dde)SOnbtujSXHU5%w_>lDW_si-aZl zSHC|I`pbl$>w)hBKXtp^LTzm=27`g#-d_BEKawON%QDGil29l_C=|lwa#2uFKy!0* z9*_kbxl03fhhxY5Wy`Ztq==1nlaf`MyWlh>o#oIfZy+DaBwg^GptyxRseiHA7--|lgWhF>m7fV)vH%? z=FAy@&Eo|0g06h(v?-Qk$d8(eB4lI|lr15Vz^(%gcg^@h;H`{|jLholY65}4ICy@3 zK9eU;rlFx>3_u1nRaI5Ym@$Knjt)jfMzGmz6c!fJ-rl}OytCtJH(9bRLMk#qY{bjk z2M+ePc6fhOcQmwb0=Nx01(8`#vk14Tr25>D92#lX37K>pp7{*ORFlK5uzjL5YnVzey3z*mbZ1!h9KIBT3RY0c|)Y z&#^tZ`jn?nTBw9Ve;61TFl^hlEw`zu$)?lkGN(?RDmtA`g2CW8xWQl`Cntx?moL-M z&;amP;0I~Id-p=Y>2!|k#bUA0-`@`q(E!t~^-43BmOWD{iegbX9G)Hs1YEK#TdY>A z)@(KlsZ@%AfdPhxhe;-r==FN+c01kO-5fo7l(f&k45R?v1cy}tE$|(;+pTxGTqufy z!{Olg@#Bn)jI?TiOhsjn*Xwn!Sg}GYiXw?b0!2|!)%TxK5Cn8O9a&jf6ciLtP*8x! z;~4{Q0-gg}fd~)-66qFH(`43Ny?S+u+wI0~w{!mdc`jVI0PvcSzM`GLt0g5RtY5#L zKp=q6=OdX+0-)7u?=qPB`g(5Oyb18nwCK7&Wa0|xc6?q zb#*lkhXYZ(37#=Zd9)BZmeqd@T9vAPB5N{dLnPkMk| f>0;t1v5@>9h4(JijaBcf00000NkvXXu0mjfoP*95 literal 0 HcmV?d00001 diff --git a/images/draw-path.png b/images/draw-path.png new file mode 100644 index 0000000000000000000000000000000000000000..b4adfba7c7a8cb096c5913657a8c0627d88fc172 GIT binary patch literal 1209 zcmV;q1V;ObP)Px(b4f%&R9M5cmqBPFWfaGM&CH}Q8|ab_p+j0BmF<*W>vpr1k}cE*TLi_UcxV-o zbx}OZ>OsYm;IXHQ;=x{o!s4Yz52mc`5>Z$dyVfjC+ilWq+L%dZ(&QW4Bpyt{c4fQC zI(_gRK6u~v{@;7=`@i>~J@Ehr@Hwyy`~@67wDQ1jz^6c-94EpTaOW`@4LKGNwlxm@m;k`SV~hKGlV#bPZz zt`z`p0xwKYPowKPo12>mApr1ty(o&(RIJr%Xqv|M_BKGR)ueioyd4Mx2!%qVQYnNG zsH)1qzyO9}Aj>ib2L}M?y3Y3YHVX?20Bbp4{e?gAeI`)&a6^!N93|NeadBuT=y?S}Cs;JtdHJ?za2;ItA3xuw6_(ZSKt zQFCuuR>R0gbyq*Nw2}j4G8t4=ZSHkl2atfPZF0$fL~222Mpad9U|;~#G^tc7`2Bur zwHm2Z>N2nk{Cb)m_<4DG8C6xAUdZKgOifJ@2m}DW0zNoR59EM%dU|>Y27{QUNx57` zmSrX;CP*X_*tY!&a0dACGyv=YFRiYw_DxPsB1sa(ViDW6@pwFpkB^hf<;Y|*W55L< z29(?ca0L7gTummEL?RIYN~IFTVv$Ov!szHIilUHACNBV&fm?OYxdH$n1DKX&y}ZA_ z-w_UnQ51z@u}G;@LI}a&;2@f&v9`7r0>Z#g_44crfGThssAjX-$kx`DG%_-R&*#Ik zEQAo0%Vk2L5W!%O)z#H!fOEhi@V6TP8lkua6fDbnF&>Z0V`F1znnpgK$8nq{h_h$U zl1L=Z0a+k^5+h1&CT#`y1-MZPvHRI{2_%ZS)@Eou;H#bMA zRBBK(4<0-9F-G8&Bn^q(dGfDPb!KA$I@P9LM| zo}M0es$mPV1l(O;U&rJ5_sYY=!K!(eD=2+OjX0CZhv zZ*T93-Lc%p>&F9u0N1WvqfjUui*dDDC7Db%yJJn$=<4cXc6JtE)2$H5=g*(VG);DP zb{?yw>pFhFpT)(+M(_BUTL3DlREjHCt{{XsHW^8hgx~L{ySp2J`T6tvb40sojZ2`1n>#)4N!FHs}rbS*y#5kT~#0rd|98QTateO XxJ}H%eiRJA00000NkvXXu0mjf2HYym literal 0 HcmV?d00001 diff --git a/images/draw-point-gps.png b/images/draw-point-gps.png new file mode 100644 index 0000000000000000000000000000000000000000..b66373044330ca0cd8391a6185ed8a043eab5e57 GIT binary patch literal 1530 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 literal 0 HcmV?d00001 diff --git a/images/gps-distance-rings.png b/images/gps-distance-rings.png new file mode 100644 index 0000000000000000000000000000000000000000..8b1a1a1ae41486a0544e5b3072edbafdee748195 GIT binary patch literal 970 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 UFoW|y!2kdN07*qoM6N<$f^7Xfy#N3J literal 0 HcmV?d00001 diff --git a/images/grid.png b/images/grid.png new file mode 100644 index 0000000000000000000000000000000000000000..733c2313f8f9e3e0243172bbeecad8b33b03de86 GIT binary patch literal 224 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdzwj^(N7l!{JxM1({$v_d#0*}aI z1_o|n5N2eUHAey{$X?><>&kwILxzV#Zb$TNS)hTpLwh90mvdxS3j3^ HP6>URb{B^_F*d3 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 literal 0 HcmV?d00001 diff --git a/images/mapper-icon/Mapper-16.png b/images/mapper-icon/Mapper-16.png new file mode 100644 index 0000000000000000000000000000000000000000..1897cb7df96042e67de105716ccf39f145f9b9c3 GIT binary patch literal 1917 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 literal 0 HcmV?d00001 diff --git a/images/mapper-icon/Mapper-256.png b/images/mapper-icon/Mapper-256.png new file mode 100644 index 0000000000000000000000000000000000000000..0f50efee0614cbaeb921a979e99dc3847b917d19 GIT binary patch literal 61581 zcmbSyWmF} zc)hw;r<1B*C6!9LldAryC@=99{u?|P7}!@SNl|4mF!0YLI2bJS=S|14)b#U)3lh@+ zso0r5v{q=%!4iif78W69E@2)X4zbTnF1AmF{s-fK z78T~;;p7q$VqphMWap@AXJ`E%3s5w-1KBy5+u0L~sBjWft6SIt?OdH`{^_27w^r1|(Za<9DDG%y zL;NrO@>={4@`c5?S%uiy*xA`Qx&CQ44-YfD2nRD83o{S1Ff*$->3{J8|9^DG^jR6E ze~jb*F_!;ieOll@$^SO}&xijWJSMiEBgXM_XzcfWy#@n2?UWJ~QgvH7?S%2uac%^> zx4J%CZ(7SO168;P&|t;1PzvEV6HBPE212Jx*lU-ljQT?Z!r{XpIK4=v(V^ndEQQhL z6697V@4Mz#JG-5_Ha#!a(z2FW>%reX((KdLm)Fxgr}_Un@m>z?Mh)Y|d`t^udtFN% zwq-xq%U^pZa!Ee@Q($#H^VNM`KLXiFUg*!JB7_~^hFgaVGDWBn_c6TS=*?>gtK06? z(C(r3yY=#1y<%?z9fTQD-l9I;<7e(az*79bh1b92OmlHyZ(WZw0Ula*qqP%cDe0ar zY`P0N{2@L8uei&6d;_An38Z-Y9k;lH{xwP`NqweQ*)g zEj!`$hbPdy8gMPv-z0ff1V-^D*Io-I{`EqS;zRRQqO3hGV z+YA-NyfrSR3p}0gigqWcDA!dPcjSCzWHlQlu=%JULy7Win8@OCTUOL=S|58pM za z{`b)c%>x_wF4GnWMiHd5Lv4T-e9t?$^kQDTVi{CBXPf)t&}3s6b&j0)qVhNPD>k|J zOuZ#~h!R}DcSu7j;Ikr>6Prl+El1?ikE?MMfI2-TtL=!@&eEYfp08A&-`h8&xQAfwTQx07G%9`3q3=@Xt+qh@NiI~%5N z_^p3OTnO)9s4uFG)=n}H1jJ12Xp|iEw9>n<&NxoKInL=3m4{B;a9Yq$X%bi!4rJML ztNzeprGUB4cA?n9AErW`1{EZV@@X-H#+vr_qf+{+M=zqxgty%s0x0xY@CIeCGxT_Ue=~^pW-=OfEb29>}i>lL(df26YE*Z=U)gKmW zhWD!CTTrBpKFVU}4MOqbTja4E5-0h=e}bh5NdRYuJhI6x>MDz!rP#b9;YX+uj=j4rB+*5BM*vgDkVFb#V{2q>36U)_5QIVokMn?Waa- z9k2RwCVRYUa;>zaQ8)*uX(rv|O<1E0Nm!Q^d~8BLicL-Wt{>uit~q>|5|mC66Gj!U zjWNV%zRB(1ezj55pzW7^E>!;2K-zGaSeLCrBSQ1X+`LOc;L)P_ekVPRF@Up75tcFv z6q+8=0qyO`QZE3P$GToo`;b#DG~LE%6KOQ=Z&LVI^$cDwyIcC;jCo^|@%8?KssM80 zCH|}`vXhGDghNJCd&H&!A#dezd{0U@t|O04gVcOPw+nAp zGOJ?!A)A_%e6+y*3saTQn*JoWulv_)XXVEb#~B-2ebX7`$(nnws(l_Sq?@)|mIG5{ zM1_4r30f~(ujn>gABJh|4diw-JkKe?mAMEfmsBsR=~Z6W=kK9W$P|5oAr9kcE;jha zmEE@RJ&do$+u1^b2|v?fLuRPZ;jX;-2%B-%#ReQ&`7hl%FOwdRmSIwczlM&Rpo$gX zB}fjS#tfl+4Moi(Ba9%yfFGrV2^?X3#*+f27`XVz65b6k@W zbJeyPdfO!b%XWrN9@)<;$`C0I)0_0A_4W?`hmR?R1}+W@QutP z9ll3Zk1~K`7ixst>}Sj4TGkNH_oEJ-fOApbX6;M>J~PB`X(Tb$MFyf_s8q+u9(VSN zt~b*aj^bZJ38O)Su(GO@SZt0q&KzaOmfLraqQ^oVOf0sJ?65Y(u>AOe@)u-`^Jl^q zzmTKnSh>I9EiYr1vE);re8U|SbVUyESBi{=rZ%#hX&?IC&*Z&jWD=v2eM% zr~G=_1Z=`*ZLj23$kE~juH4eM`3R9|e{ynsy`!!y^_$*~&ogY2B@-$PATjqA&2dxK zLc-F?fwBBW6dgiKEl@3cH8-6<8B@*g`-~`;0 zdEQ5XN_ju+L7Wtm=F#EGd3QqdQe7=JqA*M_m!CU}4#jF(KvSQMHdjA78ggcH(`>*3 z!^79zyDhudIQ;EI3jQ_G2y&``lGK79J%KrhkT%#W7b#MTz&ZzFhL~jxYh)-t$t53`#lU}mTI&C zPR!3uc*C&^2|xoT3_Ep=#yuvpt;+{fWTmB8XM~!bG8M>Ljcds8vnyKu*2UGB9fdgJ znDp5#7D%yWRGyA@*i!{78w8xA!lU`?=uEC48NA8t#5sn69iU)?89p|~Z$_<2%+xw* zztoUL}!uQY9k@ zBfw5j087yH`uf^&B6Bt9_*$Cewm`vFcqveUzc~6aMG+EXvsZr-n0aSnBv#w+qDK|nPHt_Qt&KA0{9*4P&hb^5llVw&bE zw4^{!7axB6mXVIKQiu0_`VHe&QT5Vy5ojGgJ!x3%e#aL! zuSZ=-<~yefC}R{9*q%o5GPS+e4IYevJ3M-LsWp&7C>x`TJv<$Z%lSYHMCJ=Vtm+qx zXD^6=6-w4+xRc8i!yXfK^E8ex8ubUGNm6INeiR3JJrE{lxgZ`hdD87y>xV8+-pu;s zV)E;*3m-maK4z}l&UFp!k>(bb<3Ew-qMZ5w+EoTOkijn)L*F#a4UBJ9u`4KPb+*7aa*%Uvz zZj_uRz9B{;Zf|vYL!i3x>*c{t+@vHgkkGRq(Fmb;5weBEk3X+g(&}^3SvI}G>q@Y| zgWWdw9yH}0Y``de^fu=ebVli<+l%)o&tqIIqqjn|p2uwI=OvPvlQ!&;7=yMlT;q47 z1Su%g!Y&a;Df((XDIb47;;U8R6DdJyN&S^(NT(*Io6BG$PNmaLR;S@E5qXsBbC{tu z5!PJH6<3TVk-zB^GcPTdh&QlWMfMHxsk8h!rr=pg3g?`Z+P_NK8QQXSiVut)YihYk@Re~Gd!$4e}l}1$#c@6b)8t27!-wV^f zXwNM?QwM#ct+hoq{{6N2VCHG}1;xuHqh^g($kD~AxVGaf{L@RgM4f14;zeAgYwkfb zpkRN_iTP&Cb+=`AF|WKG0p{TXn*{^Vil&!=X3tAO#Huywk}}i=?oytP5oXXfCjA2~ zvns*Ns7OkA`5LsjRJlHL2rkzTtC zLYIG?TQo9T7FraT#l&KBh8W5oF-s*3fh%i*?nCoveOCYrS6*%4Fs{tb$xdANfO5ZP z4%?@O7&5@T1$;VE@O5{}6Kb*B^zcTCQh(JzIV) zNYOb!gqAe5hGED#K2}af@^`hg;%p~Y!r8a1!^dqq=8KFR3;_>2g_yV%kZjnNW6`h4 zux>;}iCTLL1myxD{MI8vRJY$rJHh$`UnZ=h2(G(kJzZ(i)o7nn?&5@-)hR|BiBp+MAs7j}&G1(gc}%0U&g%;b?+_qLuF&vT zu13}cbRrXMwquXJD{&v<>&NIp1*`aj$iF{39HtW)9L9Y$f1fI;G5Sk;N|kaXslA#S z-igR>MGc<7X-p@eLVEW-iGB=t&I1$ha_$4!n35UTI*yfJ-7G;&mo_Df&FjEN++IVY z4X)v@(WZVX|NHl1ev>8iO7|Ors4G4>xtem~<(DIaTnlqixDHLMubPU9m6Be9QJxut!0p_+2RjH~k#d`Z-%a|EQ z^v4|{zUSK2C3L|b@8uNxM<+lCR#@0g-^p6(01FOGUVU75XAl9lPVhT`-yiA*JKtp4 z5qw*d*{E>f(PP3R7-XVz4$UZq?7{DhVLFM@Cxd#nG6FEew&cXa&v#m@+4K5Sj^t!k z(SW#_lf>T6hydFvuDv>Qa|1vny^;Tdydu*Z!S`OQ z&V{bl^MUd9;m%Y8!3E~@?$9NNYn7o+J=R3ahvxO`-B*o{La01~mzoQJohZ<%yn!A* z_oF;gW9!i}Ee2&2R;xPKiSM^R&yo)1TuHl&HTDr5^}Qa#U|r4qv)@E!*KE5%QvFfp zU3RkP6wP#8cX!x3Om_p<1 zX_J57hs}_*Epz?C!Ojl9P2}!_;L>^E6lM#cUeEI#JO}FLgCi9aK0Rk~Uj`F}pH5z5 z(m~bzj74KUO3+=hyHK8>M_9@|8KgPy@RtjCI@|2T^B@k|7mFYdh$vC=Qyodi3>~3= zlo~eU#vF(5cAqsukQ-B7~rG|=K zpG;C}q@-Om>La~;Ktvz!@Hu_^-8}0#9LPFpe4DOtCkXDVa`@sT$m&yy-43`kf#kfv zkoF5qp>JRzGqQ_WG^O*e<+wOfC1NvTrhXe8grt$+>WV#en)))c(Tz-!qICt2^TV%=t`_PLe*gkG7<(%!eqf7XR3bnb4jI-9H3pDZ2 z(m}^wDAp+k1V|x1WvOzAZ~~=qzka_;CCBNn+=oI?(o+jrWO@aAbN%=sSiCfz!vM)| z|C@iACy1Zuowu(tv=;c}Xb8t`V8*J%i8f+BIazkVrQ#hK>E#2^N@f%>II%r_I^>G| z1}k{gc4c?7MTxJxzYg#Q3$=a3EtBM#va!WVLsYY`rKd0;A-j=J6=8~I1=QqhIIrfQ z@XtgCGcb_mGfq$Pbr(7mma|Ou5Pf7;mvrRgM>*deJ`U!fcv++*)iYr|m+0o)UKD1m zHRu%GhP(d>N;`nMZmB7i^I6~%j=A#skfH&zQWH~4%Ar0+`Nl@6?5#tlD^b(>maJb8 zni^y^6TH~)gRvtS2LAPXuq|f^^@GnTbSaq-y>6{=51X3fgy_AWl1t+1#&2U`-=6EKFABY zYu6~t`z!*U2z1Ec zpg5W$tAt1l98Ito3#K4@2oxmMn>_Zt?wziv3qHBbG0(C2ekmz<3VLW42v1ypgK`IV zt(GQuA`AwHz_E>ELR3O1+BZ)MT$uLD!w0&ELKpS1!Wv_W;+6{qang@IwZx=ct5}xw z>v-h`?+?O(6_3iu1<)GZ`u@jBdNvtnz6oMz?G-kH%3f9bdE5T9@B58$ik`=jf^GX* z6M*mKwBFa_;QOXK?Hj!T9ZI?*y@4>Kfn9tote@4(e3m6*;|_5BUjIX6cK&M#{M+Ue z(Nc5D)9gcgcS4b;AjXlZ`cf}^X+d~5oYPzGnFJNk8|EnN%$y|)v`>(>3M zYmvJ_>b<`k$9v0B5J7C#<7{$9Jg^WlIm`+hzUMe)Ix{JlK);9SoF4+){sU_N{Fu;w&P=DO+qfP8d9OKS1CufhF` zJ(t)220*EwE=gIb3McZREDQ$Ib+0mT?;I9hXW`2%WCYagQz{fjJ=wZwG|zOHR~kX0 z&NujVHq?&74}!c&p^twDPFzwz{pMH)pZxaC5L)8tp{3hL08YZ-h7t67VYhYp6dgV| zk4`g7VNnv5i`-dE6)!QmbWeOcMu`8s!6c?w)6}Jx>sMGroSEUKN24s!RfR=aed+Q(5`O?GfWt0^aULedVLSeYp2@x?SySf-}f!lTR?v-44K+J zz)z+8%Lw5Qll?dM8c5`#)bG`}Z!rRa?*KlQ&b#ANbW1ZFpI^bZw8OUS*|d4Enj3V9={#K61up$gxza6HD&Jv z@r?GO`IHBNSbB}~U$Uz=pc!y5F@5I636Ts2fy0HKE(Cn_$6*40?H7N*rcOhffzq;mF4;kq1jHeH*i627e7-!ieVQ7m&uBoj(@K0oN;1QgiEkaUyUZwKC zr6@2L^S=wh^U050Tz+f>ify)I-H~sdg(COrE0aDuVUt*;x`la8h51ny_2tfo2>H8@KpDte%cWIzf$RkbPwwD0n_jYEP}dqHGy-=ha#FwJ zgxI;W?dv@F{O*36+_U3l!GO;%xPcW9l@Q(cCqZkLyWUGj3vglkcFcTZjBSiX@Fm7Z za8=HgOz<)WS63+l2$}+-Bs8qQT2=5mGki0hYDm@j!A1p}Cd3?)8j;M1k`Nia_UzfK zI8XYr2i=>OdrpRJbpGQau-Ux{=Wup)Db(La8CXK*QT9GO&>dBj7uMbi5~BNVZ#AG&b|gg!AF?DF%oc({DK}f#t$CeWyR+2;Bf` z!}FrR{4vI<#@;!i#dX^t%uOO1$yjecynE#sm-`U_5CbaUW&SOKLg>yOel~;eew7}l zuI4(iW>r4Za(2FhP%~MsXTPC=(2Pu><+2jNsqUyZ)oaLXd{~6+dZ{@v?@PTA> z_PPH|hIU%bw(E`_{f@j| zU#2h~P4Y8+S59h+zWfYbIA;Bwp!^L91`4^|9Y2FwTTR85P!^m*{JkR-Ly-R}Dc)7m zIvc!hAoNwKkt)aQ+H>Df2c4gvf0m{M{47g{wU43EQ%;xvnaG#0S6w?|+T!MA z7~TANCv?{F1RI4|_xf~R!Fcn0y>CZdHL)Q6^upijFxR30lKG!)C($9j902K0I?_T?M164xbQ zQW0EQNB(&vHt5ai&MqXZLziB=6T_8v|2kh|wIt8?@q7O8;sX22cgU}h{BsSza;u*j zY4cH$Z*eH|yq;PQYMjSS6DzfY7kt}rG0g~=#D8LDcpj|$+%{__ZgEC7oy@Xo5gENT zKv7c=7e32;3r3Wdz3xlj)xVi>Ng=NsnNYU zu;obx8tq>|b~G~Ra?)-gp`~h~IF1;xofeFz2`7OU@QIh(&{;98lfMT!*h1{4Kth5c zbWiD53ecliw~y3Mul*$%8JQz$77XDcgUU%fE~C#~Nb$MH2;0^T$x4hAnysy!O8^(i z;$rY~F;74*`VcphRbQo{(zk<&p^=Ey5snpx_bMECi#Tq+2vegcey*Nob3#rVFF2Ud zfU7YxEVr(Ec7AfXSFEhP=~VI8c6_*t}_f#QtuLfOKh@2v$QUx(qC zkd`-uIx+Tbb7J5R1Ot69vYdopg?f5wddF98Ym{$}n$M%u5I)_rvr6n799fM9y#YL} zVb#$@kn9_4nQAiBxwiN8qR8k6!@7ehcZUOW&kr7J;PxV9;`c3MxplzjT>$|tT z{;_^0Xr&s3@miSdnZ9X(t4?*;Kvif8VM7$hzApauTGtCb_Kp|)iKo8MIC5Vdy1G94 z4YshZZvN1+YiYMNThyy2h3mf;no3VuwxG=q$X52B`DG-HdLsjyB0}uj7RVretE_lo?XP z)%N50F{{D7!}=jZ{I_54APCZ&(c)1XGqZB57kaDY-3|=#pJ(lu&GzZ(by{%7)vH5< zhYot0eJ!AB?;xr-^{z@x5ZdoLZN22CPZx#8sUca7ZEo$OpaUr)S5D!Hb2b4RR>elK z+c?ga&S1E9g`;2>i@ly-4xQDY^>UV;y_*D0ZV4-2?(-5*#BLTYBnH!lsEB}iO^^_lN^<57*uswsvA=NTSI6brvkHCs zlo**@2?9fj#!jcLe0)0`YRT6RogvDX@D!u|W0OqXkP5~GSZj}PJo_uAmBsMg!G4WR z#=v>T31X<8F4s0c720+tI5ZL0j2@8ov8!8XfkiNFT4r`Pu&KsYma8 z-*34vgFe?u>Di4ZEV^W|zd^_%AE}j=EK6#YQncV%PyUhH=#`a~q09@W#7-waHNiE6 z)smrdKkS%rbbX!^k=dTpNK^lSCW|iFe;eRE6~Cg4GyYk@OV(v>N?kcYo8E`icWx6z@@$_${4 z7bwnWKiVaM(u|&sQ(}3^z0Xupys2V~MHF-VU8=B6jKO|6owDWHGI%h;X(;k&gKk%6 zEL*+Y>kaV*9RG2VfHZ3STxT`LhiRV->!wR9Ti1X2H9PKts~*hy%BJWZsbpU0VXXI| zOf`3f)t}z;`T4Ih4ksc{g_i(@!2~8w$IE$p_h>zJF~*k>MkkY;s(cUV_yO+i&d@yG ztl%~vY0(d1M1hm|o0-{l8gU1fin|qhT#0$Pq2vg@IjhQ3ZQr?271%FJ#ccgAGG64F zG!5q~QFT8UO5KM&{2}07D3-q-o=R*jcvDxGp)HXZfs3DYheAetkq%_C;lKi6sH~?9 zWPWtuzzaRT?My2&UNxB=@JR)2S5pLBk34KUQJ8o>UXlbEv-rp3 zf6h}r%E9xY=i?(ctAle0zET$HaFaV&9ru|2%NC~hH!y^2ejDBV5hBg+A?F7@i4g_2 zqiV0qxxUc6GjX2s5Cs?|tGy3D~b~Y_|YFFCfDbiLic@ooW^JhNz2CA>)!8DI-rOToogC@z;+FD7U*kn zmT>%@U4t_7u~SP=3)PjXnPXmuRHI$b(uGCc%eu*n*puzS_aFaN^LIoIO)`{EVHVE- zDDmf*CHQljR40MD9U8&?=jXs- z=Y@k(F2_2i?{n(cnI=TPY&F=STO#9+B5_-5I9l5B0dEu6s7c@jjT;W zLXPK{iJRa{LBEkKmK9$+N=5|FDFU%m zh5h8w(%{uO+x9ksSzZ}o8z(x0SQzsj4bMqxOYxr|V@QqNM zN%PgGwvU1Sf@EDqoHU&iM@DZtbQXD!AAZDOXb=C{tyQeFqlHMzSPNpQ@?;F5@;LVIm0mKya; zyCKrw6;FPHF0U4&z-@x4wc4`$8e4!E7lzmVH2dy`1&`iRoiB2lO?MHHk2`RnbV4Lt zuVF!W z0+qif6CCfLTCGh%wh^p_%v&u=97aA&FZ~8$sH2OW_Q!;HNxa%HJd|&=2dS$6ocoKw z%*sxkm~_-%Ue;RaN{{v}Mj+hAtwb@ttT3vTCJj^A&WuWjW8soxnjA8oy3C$tZCNHn z7&DB;q;iT7503Vc&COrjhNp~?PYNTpGdV3tl{!3pK3eQ3eNa+t*L}XYwW8Zp=1Z|P zdg0g@osymsO`?N^)Gxs=Z{BZ*+>W9xzJHUFU~z6}%qB|Fp#7a*GSN0R+lYMKFH!mK zZrOGY9KAE9#01}5*BpjFLeoDv zh7kx&>~7@PJibBPkV(EL`u1ASvXqp-Bf7+0Qiw}|M+R+OJq?yx)z1ACi1bdqSp#d{T`km^#4x{8aVH9v(TR;S0Ppnry?(M7AgHso4ZMndelWWV?JjtmyC64;e z@#Wbm#o~u^(nw8hEquKH(Fu_t*VAk02-F_hqx;SNPux%>j}a5fRYmG*XU^ z%zumGV}FBO>waUJg^>BV==Sw;9ZzP!f6S=aCfi(`W%=79+-}dr_e4Ax{c^pqK%AWz z%wCpns`2XzW9~6B&y2;BS7YRYfV8i*jBaG^$4}A>VN@_KdWUZQ7mGSSk!B3JOk2I) zTGTHDtz*&ysztDHMV5M@dHD4VAA37`7Gj39n)N9{_?d*e*3fU!zVDg&m4&6q{yc;_ zc>OZ-N-(*oL>?zrwU^`Sf^3#J(a8&3P^t5UY=CDZReJ5PLM0WWr{}h8B`{zTc*brw z!=v4M*X?R+S@MB-UBJOJ=Hk@pOTuR$nXk~ax$Ld;@1>=PYuAw1m-`FsHv$nLxtpm8 zDb^A)5nt}dtpq^n{CSYcW!-6-zuSN%L$(4mm*>?a-d5W#P;>}2U1KI}fBWNcXRVVn z`XXIsgv#jMItK^3o=tRz-&3bEb&dx~Q4mYy?@(qcccvN^IYFqTc)?7#hDVZ-zk^Il z)R#!y#SKoCdK57Ogdj6oNf)czpxmG3`4y!%2iE=!}c z5>KMweRx$v?w{0z=7IP|gmPYS6;ZEBW-f8rPEnff6;1aCWJK zANl5LRb2B{*+V=LnqNFB<1TE?91awGPhy6L_a;w=gfZ&v!^?Z74GXqsfZE*MCp**n z{!P9eeg@OAI3BELzr<@h$f8a3Tktn~9b_rPt^!kzPE<4qC&@KM4EUfpx|=nE44W#ar-71$7M;ghEsSEd z$+SVXDeYU|x}KjU#S|=BE%r`Y8;jU|C=jCtD@n$%J)Aj&EjwU0+BOpi`ugEbR&2Eu z7fg7_w$ouA^nlcLMvpJxr2)bSxdlGI-kll|@uS22ar%HC=t)f~r=9tYBCJsz&|L_D z^qeW=sMP8iLn44o{XUlPmXXv~VOcFVzU z??11H-z_PM5My}xLhTcyAvXBr0bZ1+#g#U!h&c}$I7kW`u@qx`L`4OS$Rb+HT9ixz zbxL%kXGL*#(z!=Uxls@xBY1t^watE{k(7QDZ4gqrX+aQMy#Jngcyu%ro%Oxuwf{o= z?RgiKYdo!__u_yISD|N~`3sfTT>=gcVINijkbiYr;qR-~VrEg~(j!ltWUv0o;4k&8 zpSWEpriD!+$b>zT%;8=BhPQDh2W1*+?>;$1wvO%IdYadh?lM)dd~-gc)Ufw&p^}=A zk`9T_G8lt-@44mWR@i&gHB!~^D#LW3I<}uXBY(r%V zb0C^AweZM;~QmQ1A%Fyv#)(I}_IHQXMW=?5{a^6oK5ZmWf3SE)jcdwJUs2G_HBxP04rmrPI>Z7DEzHACs-6#bbpa!Zqo+l7x^O zo*p2pOPwhf}tLSL=A`k*U#4pr=oh2USh|xQ%Ad2)+9R#Rt0EdiTyp z3exU?f+r@Vr=yF23CObx5zbT69<3J8JXjls-rQ95^Ey!|EVare@j~LFV#gwhHZL@7K7ZW?J6W?4h>@3BI;~T!4$Nh z=>w^VUdF&!qh*oyqIgAd*iV;kNlyPc$wsu%NJE^R+^9qUtAl1qJ#wWMFGnes{tN%^ z)&<{qTt$vx9ftR#Cyxvgpc}lY%Nuo_78Q2l=pOk8o}t3Gct(;u^~0O_=QOK(;!@R_ z)jC!B*rJXnPnjAMs?v**TVic{|3NPtmrfKl%|;YcC$;14kzq;rQOr-@Hp7#%GW}XH z0C(%I;}Q36TXT=59%DvT{9YBglxYHR6sEZ!eItb9S>bXjq`kI*q%cKoT9_KYpZe+T z^JAZz{Q4sh_$JcpmkK=yuc&@0_!4(NjCfN07uCyqtP>0u6Icl8w)6Fc^#=n&ID8Fv zSZskOlA*zi-h_2JS#IUp3MsDg__4Kg8Wc8<76U_sskTn~n1&%GjI*lh54eRtSARlw z_B);6>{SA5jI7<~Fhh|bLqfOhO8vXL#3R|5xWUBW|6YV zI@wT9g+?k<%Gnf5JSqX4D4#zUBnBs_rG#dN{^GMX2SQIBnqlIk`2gWXgFkC=QpF5Z zFHhE~1E*iEo3zM_t{^BTFR?T zu^CEBxO4~7Yey##SGx_&Kf%H0rzuA{%^X zXDreEO%F@L;Ry~C6ALfquoV-Nmsr8dWSrRku&2ZCAJhq@UKTGdHedFeB#oz*?B`18$m|RxOKD9uQIOvCrUu}y?eOlEJzNZXpcOT0mLn(kXiD8mD?T3saFVA_^&J|M1QegkbgRAHZOs&0C zgw86^+M31el%*iU=`Uq^h^3Y%D#o@h_@e1X%^#q)rdCL2_j`l}K23$P|G}9(uVQl< zRGg@+7m_w%JyhBo3rlzsMi4FORL(d2vbFWlsZdyFw>797E^n~04AWjYloU+AewL;RJX}UWhfuI} z2ykw(Uc?x{YPVfZDx>q7x&VzE#?|OeDK`~Q3Z7LLh{B6w;ZL1K0=Hc~RE91)5VG-Z z0<6V0hH8WxSHXq%uS!V)NGRctu@F=2R!q2=w;K#efD0jiRxmmK%x`74U6_T&m6(M) zX9cQcE_b8euwoeTK-R6(8yjBx!>x7kLH(++-OgBBDGZL8wPR{^&a}wv8fg3CI3d>E8YZtuT;FM!X<;+)t;vo& zvUTpu@^08c75kZ=K}DbqS(a~JrOgU6;`b}xgQ};-l}Ud=nr6FI_+1S`=IiYFHf^{A z`gA)rx*UrHIrjtRQo+G@hZL3P`D=(Mv&eNLO^V=J$JPt&V!hr&hQudIO9!S_eF7yt zV_KM?a$Kb)`f-O5koGW=FmOEKoJ>vBX5&1tIK>)6vPPbudzu)uVSi2xjGX{TSL&%g zvcmF=t>RY#N7}k0{$5RGWEK{>gveCqs=k-WZkBxbM1~5s|WZ zlX|=ZhGkIZBHKVDzB2yW0T~~luA`oB?D045(;O6)@Z?9`Eu1mu_>T%>2L&Ss{ml@A3r0)&IAz8|Ik6RU&|q)sz_5tq4i5d zHO^l}GE^P)KW;qYeq^~{ZbG;C1roE{d9J@!=EVOXAcl6u_L`C`WZq3JvR6-z5RBxB zj%?rfgSj=VXa_K@(2bsJWgC4igny@}$}(%{#Lnn;#~Xv|oY1ckgr(P4A7~kBsjXYf z7lMwG#UO{uIl|$zA%_jguvRR5hI|C3CAcFp#{%&WM}90i=L9FZ{I=toz;}QHi-kw+J9WiLlM4S zRNZc=_C+(?0T8P8R|VtC_djU1v9}o>4MWm8dxEK~7&WU8(&Px>A^Fl^f1pdl%N*w9 zANZ#PBM2^%x>iKm4jBjzzcUIu2VH*g_bXt%&%Y2ULHb39mHgUPUw%T=)T7@O2N(S5 zvFl?BwP_jTdqp8|n(|2)X)W{E?#c{oo`?>)x?b1}3B++eYjY+wMTet!A{>N;0J;27m_qZnB`Mqn0D#1OTNB`lT)-h-@?cz?He5SWXb=NBv?> zSg*eiYEEn*?_B*uswOvoKf&?j1+N6FB#YVTu3F~Je73^B}RTB(R@6%6l)2gYad)GHB*1Yl2^pxM_CK9n5MDt_xeo_ULiFq z=;xQHwCJhGJPPT>x#J@tFcfN$4H)AQI2te{P}BKF)Jh{=?V&L?I(%5s=r4Ms( zLIfV;OTUbyTx>aH*m!^Ah54(DH}#DY*1_r54SIF4E$^RlS7D^*5w56?OL{?} z$g>tBk8Y@5&O^2nR0R!Z>Mjj~&~WufIQILCuj2XLw%p0|KqM|lfTnvOLN)0w89j!u zBr|A45q5uC<1#cvB4|Oo4)hD--HdBz5ZN1bMG;oMxjoFOFoQ74coC|kS6BCE)xFDV zjk2*|$#!Vn#ro<3h1Yht$)u6HB};>0iWpJUjI$S|oF53j? z;yw%s?nI%S*;!N}1wuNX9gC9OKK+1{sxH(sR{&xR)EmNg9Nw4XGUksRCuTJG_#L=q z3_sA9pbP792w4Rb#jXTP4C5YJ~)_kSYWem=RHIUyG7mF zZ;c9qH!ZVmW-+DJuDIZOE=;QZQ7ja+Y=5}!XJF&9-0nOc_a`t8!?uEx?&l@+D1zr% zC@)i{qGx^$flhhjF_woCNnT&OB%T|;#&n{!Ph&mSBM87de4z{jr^c=S`{_@3J;ys8 zUTe+?p4-rjrGM7 zVa7l)N#Ea6PO;%-nJ)=_Rgj07YTxTX3@XIHp>se}DSrOq_WA3X;l)|^aOSd;{aBir z(c|hOA5bgcVm={)#a+5S+*pSA;CDB z&zOfr7r)7>_(Plne_c2Y7O7!4gfbP&yNdow!T^*FljdjgI!f4ZTE6m;pLIau-8kCJN@Ko7xx zhW>7s%NFtHbzN!U*C5-?WuudP*39UCiV>|7Cw%&Bx@UgjT8O}3k^_Gs3H{j($m9ES zmwf+-hW%YBqn|=re+Rw!rUS{lUpbI?$q4)M2e}uNX9zerI>oM#6)6lfE8LoNFxoTVyZtFtNlaJ!a zAODVlr(Y4vG+n%rSDA*!SrTkdRXJL&z6{Z190TP3@D?IYak&h?)1(zY%(3Qe2M*wv zW7c5)74O2XFa3ld<}~!FJLT-e{=Ytt=bqV&8K)jgis@|fU00!@r6p&DV}gV}`09Ra zfAnc|{rR5=?Q4?_T`c^?PRmeaz5MLUFGA(YB|JOY5>yr#9{O0v-4ES zxYc_0f+EF2sseEs)1w`>ITKw+I?y<4HdcJ)zcBdpW~6weoy%C-Licy+=P!q^p%yzg zzAWNgJe$v)Le0ucRW$>PrQ6och`%fYPM=XS6vMIqxfV4it$-e2=pQ$7{t+Osk6znH z_sN+Daf=Fa>}*RBsMf_~ITn7lEu{O~{`_L>maLq=o+JN{Njy(Z0VuZ0JrVJBm;o;d z@eb|ZkF|sX7G3>*?6~SC!C2GMr|yzng7L$>IQ0E{aroBXiCKQ$nrgUfE8v<@E_T@^ zdWR7o8b!Fh3-NBF@{BBH_N@18hMLS?dCU5TqL}ybi&4IG0e0`%WfYzegS%a#o!RW! z*EEM!cFPu!V;B8HgII9I#pt;2Z;0$ZET$0^OB%u4bbYLt2OoP81CKrjcYQVdO^qTx z;i{_;G)VT3BHlkD3a!EiI;1PY8#_l*^rBp?oZKmn;RlqleDOY84JpB%zvLnPP}g9{5kL! zBncjp6@Ri}I&a!-?FE-2lGGlPW0UW1csj83P-80=%JDp8epr*2fbZve+Qy_+cKAWn6Q!* z5_c$0>w~pF!MC!N3$Wyx4`PUX>cRegF}Kb14V^}2ME<(Gu}+r;H)jak9<(1kfSNVO zVdQ^(v+tV172oMh1sTA%E;W=q4mI{OneE z$dD}m`hOv&rO?sdE|ziF(TiDDEmm?Vw!xpeKBmoGuq7eH^H6WcshTI)IF7K!?2^z-3fk zd2yh%6>(zz<=?pmuBsAQ9;_(SdvH$K;})qZ7YVv`l#sRYc?!y3PgwI$zO70Q*|Hly zMb}k9XlGx>)*@-;G8b>iAe2+gYbz-$N1Wc{5c!{tZ#@IEKX?JOV7Q>#^oi;P`1+X+ z?vgC}ur=n=UUmBK2dCB8dd|P%-D0aV3z#gLk?4)%B)Nx_DCU3DQU{Pu$EEvL?Cz?` zr<@h&CRZRuuPy!B$LV)<%)9d4s93fLoo$E3HF?ay-`96bJq~Ndauh3;hj!jy*?G2t;%d`DfvelPtM?m3p-LtWD8`p2!pB z*T-oBDsCc>-N!P=QJV`U#Fii;7ze*vcke;@ip5y`)hmUw;?QBiyYUXS$e$m*gKJqM zXukGR)V=v693)H5MKlr~n&~aoNO5J-ghz!l(?tim(6jj;_{SYLqNi;?mfvs{D%P~H zntz?HsrbXZA4((v|GWmQxarfPRrcWiR%?-~%MgCk8rw&akAb{Jo{tcGYZA1P5>!>2 z5-^K{fz4$`Dh0J=!0EfJ_UzY!!ms!p#BfruSWlB;Aw2z8<+=-MF`E)>bOhZ80|+n~P3ioCBu; zQ=vGPUA7vPYg?d`azrX_HTxj2hunev;|BiN+H>HK{e2nugDCl~p0zwS@A%8Rv_wQj z?ulgu75+>q24E=yq%#3>)v|e*6XO_~2JW@r*KE6D(h&hfe3r6Ok6*d<|x-KLPv6@-y`3MHFt2+*WJ~ zzv)A3nw}L@HhkwCP<~2jK;++q1gn5eLidaj=wzL_l9M-5akU`7Ca3%;*7*s5ujxk6 zHEYI#nbtJaSSpr6^|C4~z4A;#jVYtmHy|ti;semQ-hZ61CI|lZb*9ieVhj8wG$Gk7 zXI$0i@>eH~86Wy2eg7%P0Vc(T0uqUoU|I>ti~z$cIcQ?X_H9_bhTzp5U&FRbKaY_o zUxDM_MG0^UW;BelwM($_SKokE?#HfIWGg5SXEe9!n$};eE+@ZowDTZ#J^CxOZ~iAz zq%gR#BWZNv@z7A-qu^3?y!^nO@RgL|oGU($mRmoIz5n%X5ij|7Q368v6A3K*)+aFQ z0~evK{V=*ZJ4yIUE$HlYxNPg)w&2!Op)tVS(rf}0EBujL~-974s(%dzzC zZ@|%5i*2vGB6_Zcb#t5LzLL4!JQ;?VW%pyh#twq};lUn)#a?6GlP+cviq+UDX)(Ey z(BpF8@!M|@7UeA;{eob!{a4*2({p)>sHT#x%=I^g{C)0pUqbl2^S|>c%=*~HqSLPJ z&>=CGo&#q*D$DGavj@+t41fX6J!I})9EiaeNMN0sKMgq1_3;}zq%_OFR?~u?F>@em zfvowp9G;?PmA*3{E9pGH@&3?rEHu$HV`g9+bKl*9Sr;6euJ{vyKT-nWcId;ejvx4= zH`#S0g^(@q#{)s#B{TG;XIvfNk2k6hr?M=0>g6Sq$cSb5SoZv`4wnUw*ahI0)mJxf z#)@N(!HVB}3wy5qE(U)4I24~pq@@1k9y~xJ6hZYxr=aDhUqq_RFNB{f4o%^g!ysgC z+gnLH*oC*!A)T%sOTR zmcQp5I4er9|5M)=<;rS_H>aOmAebrY?=#2~iNR6f$NZbFM%~3{qobn(2M@H0s5%GM zJZ=g7%?;0X%WL(NARP;Mq9=?uS!pz7%F9j^vk*v64;WPyhZX$Gw_(a$-jXr~m5y0c zW-A;@8#Y@;TTfF}tbQ$Q z^0Tj?eaSp@e(zq>EmW zD_tE=X&E}VJdGD`{|biM_rUEdk?o;cDudK=cU_E_B!TjVd6;?3depBv1-`m@&`A-n z|9OD?=lSQH0`H$12?=};p%-?@0w#z0FF+qfD#l|5-{J0e&rFo>iO(=Q} zsChhcUcJkiUhe9!DS7)?EVkGKXL+(bf(=bRv$?cz=;e_0XNzbnkbd#UkYYmyWTra)T_-BaEVQ?ouo{`+aCS@mzQ+>x_XMA)tk9`|E(G@YUV(+e9qPKt18OLMA!^?2whxelY z&Igei3J@CbN@~1T7LWb&aFiI@kNS^XjM<<5ARN^dIB@WQ=-_jETvk5V?DhBh{X(c; zyz?vA_2}I)&1FRXl}rtZWHbz4bv@Qx@DVII=l$?i)e)o%kwS<;(UNcxOxDHNDk&6< z1h&5X5*D^BMe_}xMD^Jxq2pV>AT+R3xJ!!H{hA6s$0Im%;a|ImP|*ibb?zx*zTW;< zHd!u_$Kw-|ghVfdA^c9;s4P?9>=l5fWiEF+;pas#$lME1jGH5R0BprS$RYT-_DGK1 zyC{)`uGt5x8uDY?kHO=+^mrIcu2=^r@s6G}r~Hhv=7c`DiIl)V-oPINywQ-3J)KGM z*0R}$+keBTZ@B;!P2?aEnowQd>^1OHvG`Mp2}~&rJ-!m)pSx`vc@>d|}P2~D5Mz`w~g8CXMiTS5oh_xU19A?a0iUbKv zG8*EgVOF7#MIWS_SGZ??*Y<6wtF1%R>BnK&$*a-(+eguN`=1frc0e#3*Y+2Ll_#qd zV{rlby)8|sz5F87zyAX0q@1|`s=KR8!267Nh^-dFZhakDF`o2Td67m!B`MftRX(np z$*2REOh7Xi0x&0G;!ux_7IS;8+gWr7OE*$*Ol9|+ zI+UGz0%|XND+&H$L`Yco?%gBWX!+dA%gaTSpDml)DWm;YMQZ)FXR|G?+T>R&2SN%3$nBmKm}pGu`ND$C44EBwskym$f)FNT~mZyxF| zy9jlcoQI)@o)+{8zr2fl%7{QqqCbM&C%p*MnbO37Q?_2b=dkpo<(TmwXQTS<>!FsF zqKBY<$FA*S^%VR1>DdR;>f37}EFXWI0IwMs)QKP7KDQFp9;fJfGw1Xb;sTh#L$eS| zj;WXP2ePgHc*1YWy;SDge{B<9Ir(!NtJ&{q(XmbHHWDfrC0?4NX($FfieAtAEtm$}Q z`xaZZww_*V*-+BtlPhSg1-3)}1aqQc>7ybRc;v5<7n<*@_hMf@$3xD6< zS4jA;!)RwKJpQt=k#+jq1i|};MuARi{JHTBz7Ifz=Ka>^dB1$+t-fNz^Kew%LtgHk1Dq}=}LNH zu1Omq@S=lFrnnqcrSPn1M(OFtpz8cn;ajs*beQxJT{`#e7RuT~t_mwg*&O4ttiHWY z-mU<$`63em$X=3o%7J5MlwfX!ml!`K%B{zf|Ga5TcA9-oxrl_*vTkE=hoX+_|7QpP z($+tn-_P7jY0FiJ8UY99R`$c;t|EFWMzha|oc1%a6FMP)e8MkkAQEi-lUBZ;FN4u% z#mr++yYxbal7wbdqmN?DIQ8-1eo;Pj!Pq-n31~*45Tjj9Gu;4t!;I5X1pR&eWc4_x zRECDxvr+wy^{9Nunb3wu5#4zZq3!z+*}NC=L)}OPLP(8z)=XnDV)2$$qI1hr zc=pz75gqE2k^U^<=cs>*w06t6m*T{a{trB5Rfvn}%*ZJScG_eIQPU_%DgrT9j1>K2 zKmR8B33;r3%X@I_1(#s(3V{YZQVmI!a*blM~OZ`QGTt3V=}zV4<2Lf z_lo%nT!-PTDkq_zhmzGT@UL6|_oBIi7QsXe`w#3F)p26a0e!weM213SU*Bm&`R#&l z3AU<^8z|1`(qlzO@1G2YP`YvriK#wnZwBW2jrBWXfL_48^`VRh>~QR!zZY24bK8&~p#t+1oygWH>-RzjuuAv%k+bdfkV=gw^l*q_C*$2IQlS z$z1mK(u{ozHvie-NDA7BEl8uii1c@2!*70w7yj^5)Gt_p*(;92%D21=O>aK~6$IDC zgV(8z21TbK2ROMIOPnnU2xk+70^n*)V^%|ykR;c_50TIZMn*)SR*Yn$pZhB+tX_Vn z(`9RV8td<8Bfo53$VLIOhr|Jw<`&9EpHTzX$;;&SW}PcZbrCPo%>bgE^0sP18HZCv z6<+_)khlgh{wr$0wt(wKeSc15pleqALM6&I&xn$NFOgfC&AonH@i(|p^!tw& z_!|!D*xQ+&^25zOJlwWn`8!bAbRu0{LhNMBTBM>IN3KYJ(LDguq5!gQyy*tm8HLdR zA7&$wlb2UGlW-+nqL73q>?VkDd88HBmLF>f;Qof!N=i(+mcBJbt62sjh-_Cx2ikPLZbt~Fm-5|0R z$G_hr>Mz`0k64W9inaqD09*MR^^nRjJmTG12LIbrU`2K>$Sy{Sl9_(5}qjW~-{n;Oqu?ec18mpX24bza?}FPvXr^ zQzc_zl-AD1>DSzfIme!cI9vTG3_h7iNm}*lPB&sC{PB@qc)8h%-FV&?=b`Ij_%=;g+dJ*PN*k?Jz%E@a=^(xwAmZ7^GuY zd``=sEAY1FtQ#p4Wjzvpq`uv@8D2sWnHh~!z`lnwXEA;8lhf&!{=m=rVtmN8= zQlr&3$6h}rf8ejZPeaFm&HD4WuS6Wpr+x(9iaEs7F>APtL(NpSIbs00eE*|c3S1}} zu-`z_D%m&Hnnf8d+k#K)S@&A4muY2^DRbucnT)EY=fl||?PDg?vJxUeX9e)eZ*Ibt zKl~7?Q?`Ro-o|FKPt- zQkuQlCyeU3C!k^Jg(B+jFx)P4o?(ty#$@XMCtLycnkayLg%@T6QMyeuQyH)ob86D> zvcI0a@iz0iveRnmdT>=yZH%mBFt%7H<(4<}g*(22oe%v&6!(a~&AJv&=`}1p9%p{$ zHdM@9AR_N`mxfnHb7eV2!J5{2HbObv`?%KY& z)>a{xepbd<8#PZoeZG4;S;S+v&K3gV`>tx40x5j*u{rpR7(k8~O1`?3ym0`GryR_< zgn}}45Y?spd(L#T&m{Nyao}$sLI0tkJ@7~G;qYSqiC4nu@e>UamJ8;{LR`kz`Z!qt zeH^a?ubToG&l1>O13U9;c>*z-5fI8Q)Ud+<#qbpsBTcA|@vk!(#p&^hARh<&TA#X~ zT!7r&iV6Ci*=yEg{dGS^$&3ahqM@To8%7|b-EA1{*e?dG$}KeV=UgaSzi=hWs%i;= z5CnCqIm=knrK@%&39B$G6A>smEoU~2o~rQM^Z%x+W51{NdvB)P%;%ht-2gZCF2n3| z&WB3!S^s>#zcfs;Gf>f@sP_+%TjrDJm20oxIDtR8*Do{h$8oCWb(f*C=>(BMaJrm1 z+^wAHOnscx-|LqJm?|PrvMRMq!drtzY)p|21tp{CV|?5(P%+DL*_qtsD@CB|5T3f_ zYIJOU#z^xi*<2%pZ2p@r!s%Dv3{PpL2>2as+ORt^a%3MO16_nryawMZM*q8l*{e<# zfiFGj8bhC4^vXr|T(ru5tx$mS~F@-3NQU$*XA-4qqG0C)_{x7Eh zCUOt586cY}a#eQad!Jku!So;9B>bJ*p2st{UW=i&-QxSPH%_MYTHf+L5$$JJAr+6l zHpHQG?AiH}>@HMnYKi=Rf8`9+5&~eq(rGLs(Q;%UvK3}N+GqRZ#aQ}6&`z!(ojy)b zHQzbqa(l)L{MoI)DfF4>lgmuVQ0T*`^#zGgB{J}rYp-9vz#mD}q3*1`ejNBqCa~g^ zkHcHuNPiwl$EUJkzmgMy>C+|fud4!>NTBmE$3#pyUiBA4YqqXDx#z{ZzJYjfL?D4N zlr#!_R=)j8ocNKi3W&i|eqNJdCj42kD0=t4GA0(0N+nP+s~MGz&4L-tl-g9!E8p)Q z?d!`94Chl+6P*W_;_|&@h%Cx<&G+JPvVeNbU zw#vPJ^9bm04?T;h2CHj9;%^oyVY-a|hwx)XC2}sS%g+H$t z8O4LRR13AYvD0=djhrLDQHD=@{v!IPDb>jK)1$qz#TTLLx2$trzipAae(l5!nVgOh zbFX6nmqd>?jx`5rcW_#!ITEk#rHF0}LH zrD7g=GW?9+gM!f-aQ1)<+&VTNnMq3APJlAEy*oDGi@*LB+dg|sI%%5I zpb=$Xq`Vmcv^ASnvV-{g?PoCNmo3DS zzyF>AHE(h%xBc8csLhu@d=lnf|7R4AoGiX>?4g16%mLJGUmw+xpeUAJSc(ks84d>H zPwjb6K8de~Zu(p&lQZNLSr|Tb8j}1OoGtOti}*hMy|^PZ)w{xK<}a27bb_=bxzpsHZ%f25lQa6$64w0>Jb+1)CgbR%kKvK&{gDOiR|n7=#>Dz}DSqtRy%{TCd;sg; zeU6cPH=s{~MnMEctvK}XGcfbY-@u<+6w~(l`#iU%!qm7*M~|4J60a4>fI&oE0n3Vk)g`S@f8m;hZrqJS$Nc^ryI zogl7hiz%ySpT{uX8xgL&|K9ufpa1zeUVQN-%^vj~a{vhe{=OL*0FCns!*6S-3~eX@MeskcNIGiDgzGm`=FAAx)X}aG+S1`ve-tir^R$gnuXES zZC#7u3w;C zoWpF4Jp4M5H>f79zFXZ-Y*d>!Z^jSi&*$HhLM0KIU9YtO4@w8X3n9K#PG{FIcotv% z`%&JO^Lj}@G)B}H5swVLaO6}>|NiYLnK)ZS)D}*A`@;Ka7q6{d9DKzEq)f{za-{aj zGHoX%~I7*LWHsq*aR1Vpw|Hv448KR*2PeC(^( z#@P+M9&d_IIEPGj0=S4y^-hAO_d=Jh90dg!qtiyFY~x9Bl+5s^i$UzoN} z2mZqDx_%w7{J84+3FkTP=qttF9VgCM6Sw``fIou>=Gtqo!`7|a4#@fQ9#n=e4m73r zn?HILU%m1u_N@6#dVCt^jdhqr)TaY7@vQlne9jG=P9M;e-vyjwUcne?HyHsLoFXz8 zVjSMPa|5c@EyIqb?=kR2tuZ>d-1#8qklH;pCNeOhL?fjA{XbnNoXc)ZI{SLQ-ci7) zxY(7g!l?>NOX&iw*Y1{J+!E<@k4h%Y!g06#6$|dX8ZCQkF#603(SP#cqIAjP%%-7Y zC$@-4zxktAgfR!X1Tfd3JV|J(t>B+c68AkEZi%Y@srJwJ?t#yjEQLYr^xi$u^(z^R zfm1I=DA*bk_>ug524~Q%AM|h5SU8CFrPnl2YkX=jy~aH*Ci`CHwVRkw52(4+HoivI~|`q{6DfZpqk&v0)!LTx%?xHI`K03eOuo@ z7*>&@)gaF=>U>3?_)CbcpCVHK`CI~og#%DjHA1_<0{t@Z&_j>l@yDNt1@87r-@ng0 z0CQxNcBGS28MxZ?(Z8|wjsN4?mH-|4K9m@eTKYII(Q=Q!;3wP`N)aie(c@X0w^$nKO{`oum8A{Q84@%J^Dw3e)LJ8 z-v=Ko#LsX0Ma-^_%Q;mJ`Yu3R5lH9WZxt!urVn4jy0@Q3<=0Euun7!`W%zVmsII4> zp5aHGBhuIT$SoVopb`y_#LHx}zq%J@rb4~`%pCYKa)r^YkLe(~;!r}t02@3-NlKTq zN{1pXzl2eKUwRHdtYu#f_U>4RnoVCZ2I2f0)Q)Se*@M-uK8D%X-6@R2`Wf}}M`fm9 zdVVV2EN_fz|2aQeLSY=1mx}Q@J_O=mQHr`odU@nDe&gSi?G2oEyf`b*N=wmG0LrS` z8up2dsTvt2Lv6sHiVT&2zcBOtS-@Y9b^Unaj}?St0DnZvvVHq@Tz|t2Ou*XN-Lx?R zeX}tDNK*?^ zb}W5gI@pK|Bn3Og_nWGAA~n0voDnAVWi zr82;N|Lp&_I|3?M2-~6a!}t!b8_U-jXlX`k!(Q8pxroYIGXsC{_+@6509`-g_?vLt z_3-D9KsXQ${E;&tiaMfYn?L^sY}&NBOYi#|;{YNIk;X`AfJa;$8id*S!N0J1;mg=3 z>RuAwq;#&M4@yg^uTO`4+`KDLHuGej1Z=1ET}{J5^C4bq>Et6BwT@TTH>~d~5EeqH zc%G<_OUBPa|0#zfZ_sFAumv&|Cb}*0IJcE%O8v=6&A||2w4!KVDXe%C;bUs;=Bic$zT$HennzAauvX0vuJ8CVnT}WrL6P zGkX?5vkS!8aM%^U7G**Mg6-`*3qhZ4;%k3iKc0W!+CQYA(7TJN&n58J+GAZmBDc*S zFd3zj&J%y9)j>#OeNv0>=38#T`yYJJK}Hzv^}7FnX8_DmN4;Hfpenxpk`Lat&;G*$ zAe0Ftb%JD*;nQKv713?XNta>R5od4;O|8E6PFQ*q>cA58djxRx8$Sd2Lnokm(@K|p z0Bh@w44M{U{5gfl9Xwhby163rnaz=&Gz*PvARYn}Dy!&v(e)mC^7pX$<5&6lElfZ} zX<<06d#hZXQfpAdN&VANmhQzv8}?#xO)IKfgM3o+d|ph=NySyevT>*=721N~ZlBxiA95j|o zhd$Qyo}1y1I{qRIn|nHgeH7j7>3**|uO4pWxj6zk^Pi1TCtQpV?z)a~0Ym*p)4K$z z+4)?<6Y^am44(K2Gy4r;5RaS#MZxY;mQjX4W5EQL5;kD)^&4T&2_V|vL#r_C(U~c@ zcWM!KH3zXrcK`(`9t`v+anz*8#JVQ2jJhKy5SalOlwuP6wa@vRpM-~K^gdcqm|80` z8=sBkrw6)zVQ|lX(8M#4H{@^z{ya*g@zV!^es8_?4sQLQpU1ohvMcZaii?XQh;Lks zJ)xMuesKUilp-Q~t2kVg;;(<_AE^9VN^yHTHGGXzIYL{gPA0=2I{Q?l<`(h}y2-Z^su%tJ@<{OpU|8$&NsT4p{jZ zk0Q2D%6Rou*RL%gGS4CmpZf#pv`s2$%lJuAdButqxNiP@mVtABZWVXmbr)vMn#EFK zB*oSdKgvOq0nl&>p~;PvJF$7uE7d!?P+#*uxw1^Ucj6XG} zK+24D^3g5~K9MX6o$LBVF7?D>`k{d82{)oJT||42k^1*s*N;?_CmwaBIFo~U)z=#O zk-taU4m)=2z*SdWgNlmEnD6sPKe`E*Tyimswxp$H^h)WvUmXA$Jw^R}yS8A%`!8VQ z`~O6J`4)3($4CKrs)P+sKo*H~-z+WtqPd9Q|`W^v)MM-;DOhxwm+j^|)N2!0o z;A!YT;VfSEagut_jDK}?HLkegDtx_eUCj4&$|)z~7r*#9>jc{3yXF%0mEOn%yuD%g zb=%ir-P`}bCXw#bXsHDD(mO@9DdH!mXJhDL$MbMU@wgeBDX`&pqsH%wK_3iRLa#&s z;gGj{{5mSvFXN6(gwcr-BY)Tg_;ZVU%`wGtyq!vVYg#9cK^i{+f5H@zn`SKgBu3W{ zN(%S<)udE$cH2zd1;hC3_U^^y-@gK1ELjrsxhGGaj0f(&k4ZudMXL^L;l7#y@K%~I z{(almW9?giXS(g?nhNeocWU^-fZoRGhryx-9)9#WjD}NW;#6NxdH-7twAZ7*Fzi+T zepn|XO^*6`*~}9Ynn4lROE?4b`cd6X?Mw#gv<`6qHx^{3@V03RM%Vt}_FjRn8j4q+ zv`m1mA94JZO+6pEgJ#LppEwEh^q-8srltm0UUfA-`DAg->o9QO06h7`V<;#n;DI0$ z5H-gnluomv1MUE*S5G%|-_A`;x=DR};%uYuCHp%D_Ch-KR%ZWU7=Fa*7&`ZKWR?zN zCPfDQ(6{>deRhzjhtZ$bsLNM<95r)6_a}GAIFyJoEEH%*hdqu{!?79Et zr5U%9Y}9ez<%OVxC?ctndtud!51?wp3Q_81vI8JcH%XLzBaS(b+qyxWhP`8Y??~{^ z9r#n=4cDW9fj@oXuN%64yB)fI?c$t{oqaV@GE2o-ZniWhl9EtgUyn;K{T|k>Umx>2 z&<5ZWk3Whdj+l#v2KNqDymaY_zyiEov;sDKs>j#7{ttX5qQ~AH>-8ExqhoNZt(7qX z3G7{n0aK5ZOs;{}nDu>cGui&PW&mW2)J7zl^v3GlQG-`>PYQ&C9(LrJT!tm8+-R$> z<0(yIIHt6@WnVR~?9%jJ$+(%k02VLs*BQ$%rRx2X_AtL*B+E}Xb^XGU-n($8t zjeGtUt+!0yb8>QU%BiPd-JkAqeO}5C9)9Q{%$qll5q~FO?NaY6E?K~VX#wxTpAcA`g{N%#3Eab{d3{pk4YsxJx8a>{Kb)z*56hps2U{1v9zAub zAH)e~&FAQ^h^Va^%RVfep>eyfI}U&pmuS0_nU8qmQd1B58RIn zE;x@f1*e3$GpM@}u^f;RfYTdM&)4tTf)y{^!vG(Fc0|3UbY}SC_h?L)cFJkqoNjoC zr}mn@wZa4RK?cA5iv{@d*}Fslj2<~|Z*9boIj3XP;qz!AADf!mnd-Y|IOfDlQ8?-lxp_vlor8j_FQxeZ9g#nkm#!Aw{}aAX z&h03<^oYOGo)bBI@9veQ_ki9Qzaj=X6A285QlyIbywD6uAnPteH`YXEgru#Ve zd$*xHy9}3oumNlKwZSjaf4^-vph`G~`#02KNo@;LeV2-CAP|=mP&z%e-2wib6knw4 zm+!AnxUS!bIoBXLy~siDtwbsL(kJo!m6n#`@y8xz(D3lX4`<_dYF0YWrsjCRT`>OM z%mAd65qW91kDxxTTRQbf*43l7Q7ps%7QsI-A2g>yZMH=Zi28KZVlK^`SA@#4iSw>R z(cCj}*87{VwmyK&q-dHlBKXV_pP$#X;N}%oc;c{rOg!3o#j3Fr;^=Q*c_vzPT4bV0 zIGciScYwdJ2-!u+l|0a7lmb1~^`kxiLF2xI{^L&-slPkDx83*+G1_KPGEA8=nQez! zeQw6@?&v!7oJvRMyF2BAHxBD@os^=v^iUvxf)SH2@ys7!&|$~(Fi`Md+r{sNkG_;~ zknz*J#m5ia%!^oVSsWQZtrX9^^j18xwN4m!Gcvp#^9hr4SWwXKn@iX{KfU+6(#Pw>Z*w#VR*OjA15DFV?M~)Ie>iSh7E1|l6Atd{<(3CzKO)c%B ztnl)dW=Hbs#`nnZsT_#KM5P(5MfRV?7w10ot_kMvBfBig$ z%$X;FKN=TJu<>gLp)=_##!tO|n)LhN?)muoKYwF#Rp$o{`D7Fi#N7FRf|8brH+Jsj zC>Phg5ub0A$JfarC*-5Pe`cr4R;i{2YN-(Tn> zUB6`cjBdJqF_3>ZT|Z*^p~~lrEgoEX({J$a7hgbnT6#=fKRd~d(#cuYY(Ss$eRlVp zb@$A5$pH}hPdoX;4nG4Y-tkXNJbONK&r<~Ht+vItz+U&!exeM2=Z;IU>4Sgi`iM#t zz)KnnbFRA!`GZDbZ(|e6MUC%?^O}3aQQzJaM2m?2o#}%R_($9gq~xnP7K{AW9bphI-%tDC##i@>bXp zKfDh|{OEpUl@8(WY5QSI?Awnnc}ye=? z-nr0NF{oH5W{_ug6=sq07EesmdL`Jzpf zHu7=1ckjl-4?V)PUNNJ8C&sThFb-$A6A#qq_?t>kGvv-eK$^{OYsIMVd>4mY{4-<~ zmvOIH`!BEa`=;$n)ufFdyvQ|wTf<&giBmr9@?VPkdXc126StH4{M6c8T^}DY zA&uD-rFywj&>7z!A9C?G2TVPRNl0nz+pdK`Ey>LvzlN=!zJ+8a_)O-V5SkVwK0hh} zC@X;Yr1QA+*}G7_b_qtGdKJc$dAI|W7+pV^`Y+iO#Inti>;_Li^9;^9>r4jsh}sqPnzgNg0U@YSwjs z!h|!g)n&h|Q%=$Ei~$)KpOu29P9l1fu$IX=KAh4&UHo1+?t4hoS>sN-3clQ8rZh7T zv{@O;5n)ZQ7v-=^$ogIs3XI1eo%WhB{L64{`6stKH(x6fgSfWC=OkL&x1csDnyCT zi-ur0s=lYM>HDRrN%;N5LgXZ?9gYM$(_CINE*pcX7yOtBM;81F2L40KfYpMT!Dc=eT+@jtiz zj5q%x26!~3L$EJuq7fZ%A8JwOUU9pQi3*h7Z%ydn&MYYHU;6hyin{t9oo+4Kr&HUO z*o5cacn^w4A0iAW_AUldeNW3z#WOSe<9BPS@ljO^8g-PPj4(~q`zMv8<7Z>?m<_nK z8(jY+Jx+^Z1oEx;=Y8z3h%uT+bZztS`l>$*ffCn0WeiDaSr~crg_!uAQ!uC>&G?6P zj=!Gi`q3x7zgIqQMVnswd&O%y;e-=#rlS=XEEWrBv_O>5A zju8HsjL237pmc%(#3~cCZymsY$pl6-}d9wKTaP;$TAm~d^D|)Ew7bM_M!KbU6 zv0_V*BmQy69)n9RxdhW^Oy{2&jK0p+pZzVGqX7CB#(T9&0mW?ZS>=G@k^w|-11fQ( z!rcJ^`;-Itc4of|H%>(RJzsr>&mRAkoK07qyYyk+yc>S(d6;$0@3|X5gdFjHwCXAG zA-O*Ov=y>U1Kt+u8g>&^>jvA|VbP{2@k2CJ?nFaXIhtyAvo-;Z25aKyB>9z^Ta2`V zQs#?n3xtr`z7^@IZNgSk6Qb)!k-xI02_LTWP?m+Zy*_@uNRSpm8r}0#4&6 zB9C$NuEg{!{-0iZcb(Wn(;Yz~$W)@70OTw}h{Qa^_kCFf@Z}UCACu+xb!DFrD;)*7 zCD<-rJHZ`QC=aPLJ|WBk}*9D!R~rQv%#Y6p{lGX1xoUF%wD z5s1G*8sZFg()N{z4uMMmD?!x0>K{P}(us8Vw-~@T{e$X$>ZMn%{el&JoMuaaA9Ze~ zfB$wK)C%`-SgWhX-xXyaYr8MRwLVLm8M0n_x=girk}n1271bzEHzFmMB+wG4>zCDU z9A;c_JC91Ywn(NQRZ(4~z3p|q(+-XIXw>+|_b7XC)BKBE{!v`FBHgZKcYFSQ#sU1d zr}}omNVz>`1CaPokP%2jaNcM#{+i9JvHF!qc}zAM@M~gzJ=)Vqgz+chUU&2}3mLaY zU=1Z*x;Axnby%|GOT77?cd)N=9iF`BI=RkEslQ#T?&(DK5g0+X00-V8H^cS+kbE|MDX@A}y~FT2re{*RQol zx_$$7UB9qR+#~k3pP7Y68Nczh(-58Ij}kQ?Br^$W-_~qfi?-Bs6pxxJ6|OB~k1Inv z=t015`bV;e*u)g`$Rm#m2hhk4pt+@m>rEn#AkR+@f*55oGc%E&mxunP{V`_D7>pl3 z4kJg6MN<7v?EdU^q^GAbqD4S_C@dotv%EAn{%zqk_;n{it@I}KGP{^ zF!cYd_a=YO-r_TO50p*;Qn|Lh{j;|*Xwq!nnMh=s|BZJ5i9|)?N#7|w1?{tkgJ^AQ z>(cMm*EjG%cl)5jLp$U&a!RsNn>TL;zW4$!z4Wr~KvGbc;X}64f?)-z7?Pcg;tVhH z{T_IN0gONEIt-d}1lsiI(HHKC{Sec2BL_zxM3S+3^=eM<-+AX<=F#82eY@*(WoM+| zH$VTrcrr@;TN9@1H{r-DkdifsIRm(bYK#2#63tlgRm>bL(y>Xy*UV0dQSY0Mfc_uW zBDw*_)&K#ZM3T}}y9b*W{u^aek2HA!9AKcEJXog=xHCucjc@?HZTNI>J+z2I=&*>a zba0n0TZVKIsZX6ZkJI;fKgtFV?)K}TmefxA6#xFJO8(8v6c38hJQ!Z!M@qO5*_$?E z(122l@=FV`>{K`$-Y*6p>x2IO<}F+B)mLBP<3%6i<4+c2?b@}R1$Fju`;Dh#(AY81 z>YEd!>(|1%ekBvmWL-bi7X58tyOr*D@_yx|)%4b%@iSW{q05&Wa~cM_k&#$X`oCep z^Vqv#v4YOy>V)dD!Lx;d;asbM< z8f6;$EBYH`nHOJtsfhSXy7XL!jvt6Cuf9MSdYiuLYuEMrqMN#YNfPyUg^pm~m(EvvEi^`|5;Dtf&C!fnEMgW|Ui zz{Ti;?QK{kBGsag7U7LI-^8+|%doq=JnDBy25N^$TL%mn5RbScA7GM&BARFd{(9r1 zwyqAJefBwj{^c+CAu}Tr!-fyTq)8JoYvxRh9WxpO2Mt2Ml70k_*<*B+MxUMIE_!W5 zq|r32)5%tvf$Y=!E-otS(tAk~r}NIAUm|MtY-o)wF1mhuyQS+lc*=Rm88nl1{XBZT zZC~7Rvi`{Tp&(ZK-9FuCM0lfMu+xRB=CGFD1tYbj_5hYW^Cz^_*U06k*vvo?GXVq+ zM$Qjt5fR@xmk{e79TX0rH`|6}^t5?KM!#akO1%5-yLjc**RWL7q@AUw6%`fOuwerR z4IV-XdZ&Mj4Iwj2{LSQEa{y5pLPI^j7y5kSi6{9w4i;qyiBpapGX~?vjYHXxG8E(& z2qVp8=R}_N>9cV72}kPDzdb>^e*H0Y)>Xn6w@1==>FwB9Bp=TAN42}EkM?RN%V{L~ zPjdv)Iq2wtIo>Ouo1*`!m+r@orSJ3FJ&!?ah!RL~sr{W1UifI$)DTcrRT4eNkx3jB z4#15(p-0Fk4VKXExroT?)~&-^Z@rBdUwjFlfAIy^hh1?@pMS9g#~k~exE@c2l9Q8- zE3UYLGlrs~LgZxUAR{A#KPl4I@7srp%1TjoY{N!T&+ifjw_Ri!dxh~O%9&E;LZ2Ug zxG=&I8rcc8!8ahtHgZ zyKg;R_p70V>H3Wp#-E&CDpG$-*U#kn2RbD2G*Wrv8(~MUU(WDrQ6+#9CHN^)f1)}2 zasgJo_#mhLPHqH>@GdPtrK4KkiHF5Q82VpR0?@^v!%ZoERb>Shy!R5Gd+vEGT=*es zYwNoGybBh*hg)v>SzI^(83DEU?!5C(#Jk{CTd@;Q|L_cK-naofn>1{$3t&$}5EV^9 zZvQ3fgN(gWIG%VvnwwitQ&WwyvcWMOjs24x$^ZYB zWBPPavW&u*!dfIJ1%#cqCrH9H_|Jb{z~BD%H+&#c-ar>xc5cpO^ypDI?6AXd z)KN!b!uatV0cnCS9^>y40Opg#o-1E`2w`z(+iW~tDP9GGG89~N<1H9|?1gA-tjDH} z8yUF#XyHd#^5s%&+^|8^{|&u*-FNKR(P7>1{3P7t7r(d-Kl$;Ggaa7Ck)N&`-4ps* zb4x2i!Z-){Dp-g!VY+_8;SN3QQe>4Lf>5A|!8pY>*b|G`)1vEEcv9cq-m_~K7@0u? z=3xMfwz7dJ+M4%PKCcd4*3t`2=4qS%S@*w_wkn zJqdlCgr9Vj_B(a`2v{6Db`19uT7`d=F!pFYx4uEcIs$Znw;*Kv`v=)Qq&P5ZRME&-QZh$amOF}(BcyCRZweFKibIqH+2dFC0M-VYN-PrYwisG)jS z(^@+%J9=*XUcSYjJoqzg`tU_pO7CE66ULo>4N9jR5tHD94yN6x>9tagT{dJGjz0QW z`8@4yC@+@|psK18mE!-El~tTB2LkQPdqu7EU_(M2s6d zPLIIttOvh8-zynEMJG!8*S_(85mCZ4{ZPP!RTg$bh8HR&C127DqfW1c_dmIlw^bpppUeo30 zq5eCOJzjABd6+qK7Shr)#K8{gQ8V$>=bhaUqVuB9PappkR=@g~Fn+(Qj8}4c7Dow+ z7OcbAL#IT@d{;(-VtQgE>j$&EA{_D;{eF;Db=soQ;xqseLo(0 z=n-t(*mYo!qWy&zU5L|9J58j+Lt%`wwlp_(%YYJ51{k#7pFj0$eD%_U67X}hxxy^t z6~>G!evN)(rytN&-;SewH1KC*xs5V@`XqzR^;94=HCfm7YwfYFAFWqs7LLGxDVGRC zY}E&TU@80B7Imx$ZxDRQjKo;ralU_R^3PU8(4dpJN7M}>l9qitH(=>M?ne2lMMz3c z94K|rZL0g|MHIOD3{V89_q+wN&>J_RQRq1d^{Iyj>TEeL2Ber06^9(dpZ+;{(j zJi*qL59$hh=R3#o)Y_3p9)a|XEC$88WAq8n3`osKqTew+40>iQAzN6$TU z=G7va=E=n&bJZ8HujttcJTx00f7oE^fF)XDSg>Z60dhaUmJg-{o|1$`z1h$nJVx|Zrs z6RCcsi1rWT{s$iHa>Oq#F2XtIoP&!mx`?&hsJ^CX-`v#DC+NuN^|0}a`f%B^e`f7F zH{&NEjVTxW2$Rm9uM4#7f2E|3+MKb<0@k^6r2dhafRrig=c_U0z9V)0mUlzfkGdhv zC>(Z-sHcxJC;n7LF;{-A^je8x>(y*+JQgG2Xlod+EDxBxgJ=Bd+d;-|yrS0MyK^&E z|NCKV|Ke?S>_pV+Z1d5-rAEVO%((Inpt2>wYa>1MhQ#Kpnkk@`8ji z*VfeFvB#glefQnZ?W(SP3>h*6mtX!puI~qz4dtZ|s_lEjaNM@8;x~SuNE81g)qKeK z9T9+2QDN|t&bbj&FT9y$*|c!@fE&M?!P|cp4qL`=Py5|~zYL`cnW-TQ_>0i>ThV1* zzd#@;j4>0#W?v%>99r}?zZOZ+6OkV4BfODdrKUS(&BO$#RH0v?`$h{q>)-z;uk*Il zRp<=OI@>QS=>ocU!9WX2Cm(@nm)(XmkpYl1kQ{`F*dge^coln7AYOahuNXjgYGd-K z)L*7{-cwILg}d&)8()33x=YVNHCudkGgfq@pMG!jiI-vg>DO>~fXV>HA`&#CKeR}NcE>2N(%D(->e)`X z1L&$@QU9GDkK>G!7{dMK{_!L>N;v{R9ll`GQx=9q?mph_BN;RZxZ+B8!C2SJGQJ8erd}Q|@D(NPlJ-f7Ix8h6B>HVrr4cs=HwdMf;B={$+n)Y#CigWlQ2ir15N_BaFW|5Bv< zOP{&31LJSPm{Y#b01>zT_M`E46(ezN`Du~Ue$M)ze=MSXL29iI{GsQ%ehmCIp?LI3 z$Q^o=$?@mBwps)|uXIp^53uXd!9h9T6o$pvBU1h3R5VrZ#@3Ht!{$$3l^cA*=siBa zYgpEFC!U&>kFh6ThG9pX$xJ`g<2Toj4Jk0_TYxsYF{KM<_n?*rqqLtEYsipac;TO& zKK_tH4#AB#2*aOuD$+ADcv7!BhTogzOoy#LLi_)57iR&njDPeAmtf{qcgO>K0F6JM z=Q$x(H_ViPu@)SmuDef_bgT#1|k!x+d_gfn*o zi=)H4=>gnYd>v*32b}}pn#$wBEjQncH{W;@jWOuAXv^)Un{LDzr=Nz5%uG?=Q^apf zI1t$zSb$1=bHe+7{?r{<@xr~XXn%z9U;BI6e%g;}KAlDWjwb%Buia<;?Vl7_RjnC? zY4r)!^&`w@^ikKsmot!2|7%#xuPbHYU!IPF+=@}$IUunrk(!!qKlu_BJ0PcZDbKbn5V z6#Y#oecA!UV}wLtF=fgWTyp6pxc~kKB7R2fF*n_K1HSv+3y__Y!x6tx-)}z{WX0rS zkBUzp`z5}5>7lrcpHtHPWc(e8c*G0**=POXZ1b7=ej2CM6s?Prb|b}?q62?+UB9*6 z*7eKjKM}>_&SK!ttVN;-JtJ3n4SYh8AOKJAkt|pBmNlZje;qrQeZUIEDo1?3ZMnzs zx`d4eT3g}E%)zi@&&Tj1&yr)>gzzIMCExVFsnhgzXd8;A*%JUIMn-D)2%WM3b*38B zYYre@BW(|~acckUv(KWYrWXDCm*CoKuf^rxy9`Ce{kX<&>?LB0L}v=d1*Y_oBFo|j zZ^oK8pJK4c2}<=vGa-qUB557r|YM9F=Xa7 z!ntN39Bi>tedlXbjL}|8cTr6eX}&jw@4=omA7Rs?S6OV8rt+vvGYp?f4OM}K^6Q2g zY;WcJI(XK}77=&g^_BE^XV9)8pk=I#sN&l62&TOm| z;a+tBG`dTlUD+=uWgUw4Kl$;GQC?oo>HeU>WsK@KHq`f-6hGb%Iy|J&x9Gkf@mMI; zjEV~=WdMFNue^i5)fbFE-Z}qRz+d#hk7lm+7N*vUi0ZQ~`}9E9PoMZJ89NU-gJ+A> zzd1r+Re_C%&sy!1a{yG|i+ZAUZzZ;@ScEN~{s*-p^3w{ghm?y_{ibH0VSZtg07On^ z(&I`d&B5@a&qe;w3H&Dl`YgYc6Srp~F#G+HEIpBD+5Em`ux^8d2|x4+aRBs!sh_`l z_ikp1nK^T2m$uA^e)~p|?vwMN)G?OfAIRt)*TocRertU#7T$Xkwk>`gNvRnTch5LP z6eY%8vV~}@+QmPkR9{W;@^AByl9|`Y=j1F# zM0~;m`c0UHp+}s-BCLuq_I6J9Wi&VD`3=f&&E+g=jzJ&i`G|3^l#Zf&Pi6sn>;RZ) zSN#8_mtV$hKmP@G?A(b@KK=+JM~>`LCJ^jpwVK{;^-;>$Sg`}|-}M8OuUv#=e@4{Z zle7J;7=OmKIP81BJSdDmc1fV8{*IL2K-9VRr*YYEBMLKw!F%-7KLNUaR5p&7eHpwN z1I2SSaepv!m`1J{dvr9vwQ(ORR(_0aBHGi`UZAO77;mzOZIk=bVbXVH5dziNS|cc!Oe$$YU6q(_oViH3dTD;*iD}g6nxwtm;2T%C2?g zT=x1P5Jl@$zaJ}CtiW%7`+Ge1{PX6|e)F5(;qQO{YnLRm+zwk$M;;R?8rsow5OYuU z#ufPB?)j+Myow1PqP%)I#5Ll?b8f()m)t6~;P*qTue<&ISeby?&vza14V$|FVQ#N! zC{8X%G6R2FLUjFFTU(GbU@D46>-63>@lF}@70I(NqJ2ZfcI;a55q2zj5Bqj(5U(dF zDh*NJr=;n%w!J2Y3D}WSrVY&G^lbE>d;|v1I8mhfXaq(w5A**NV?V&DO0a&6FMxsiP6%RU7B<)&#e^=EqTp6mK)N-_o=b|n;V zs_Y;@7x(bW`HI$tTI~L6F?N0V9xB!@5hYm-^Ep!O?-eP0SWnTpIi;#KRBlS%&}qHC@>6)u>D-N zcIClLwe9iX)mLA`FMjnatcW3VO=;k-ZvTHwsA<&oeXU;av16f?Pf_!)d+TW|e)Kl9 zH#h2=V2*1MZ086t{fb{>+-XRUI%x1xX8T-rJ! z*MGuU$SgffMCfLY^dzkv7MWGG$h>y1ScKiH7Nc>`7S66z?%(@OD8N+mfo!Cki$3i# zqG$FSg3_r+iKssZX?gwlIojJ=VM7*mgI2f`z_SI4Ui$H?O@;0-@J%S>N0{?6#V!ZEh{ zB7YX<0i7Ig4buIJ&hiuJxvrmx&c2Ki44f{azc`PomdqJf<=0Du;eUwQZEKlTM@SoFY8P$}w5uc-Iko;xU_ zM`r&aIQ*u2(Qo`r9xh2VwvkAnud~$OGXBWA-%grgID(+?0R4T{yz|b6(^FkPkxjIV zFT6>`*z)O8RBik}9?vCnp-yiD^1OjZhS*63!Z^CSph|jcw64sKS z`d+T+T1IOy04X*K@vx2i-(m*RbSFT+qr$5yx^tk%dSHo#*u+CM#o+`LTc)DLN{V9L zuugdadxQae{q?%IjsLuJ&&92`-h%NHCh+KPSB$?e-~h2+0|7|%x$doJ@cEPfk5zk; zY;8XKM|(>H3P&D_BYyZ7jx6mC?!n%gKJ1C{ceDa*?Z$^=a{G~CaP$`jo2Jwtmjb`$ zO^mKzhzw7~-mT4O+PgqJMi?2j?~HocG*0_IzO2uQ`;pd-Q!?^UJZ=K7<`NAT4QJ8M z+C*teFDGm;0f&Po@uq6<2j~k%Bqv5jt?9M8swxo!QHotMD6;=!l?MRqg1^?I6}Y4a z&U@13L7W%DW7`F+4VH#k7fLBTYh2N|J{H;BMYD?Uz}bSN$=f5 zUB94s-u8whv@|L_fyWV8u~BGguu^?RV*(YL>QlTa$Qm$GMEY4M8gm%@BHB|1K&4n) zbEEz|a!-NpL|Bzn;F={0A_s%QdhcE{YkPR)P?GAg_yuKlXXyt*H3&mJrT~bdDkest z>Fdaf0tYIn#aj2(x^u>Rl@pM}9p_(n9d5W`J_-s7(Ae0x-$^TbD|0YbLU%6v5T8AM zJE}G;V`reaL@?HL6LsbI)349yD0ov0tr?`kf5c+R>%5(KnZe`!D`FR2D; zX-Nsw^&>Db)UKeR+6((Se?;V^!5#77a45hAlwQ~$`NOAhnosGzmza48@Dn9K5CJ`l z3E4_A)s!bQCJOo9s4^`lgx~D*Yt}lysv=_C*X-)SN$z2n28WI>SOB0cg@_xtb8`r8 zzY`C$Q@0(!Nhh6zU;XkIIONbnINfh(Xuvn&L(yyfmbz-J_}6_{^ZFA!^_3hWyn^}O; zS?%v6sO_~3VBo-k_~kEe!*?&ZfXjnKru)5#19bY_G}M#q<6)1DAH0a=&;KuKHh;zG zJ|X?C^}a|Ysm`DEgFm2j(p+vsxn1x?Fb^dn-x#mzpc@O<~r4c4Kyvp4wmY2YS$GFn}~knXCQazM5N`F@K`R@_5tp=Sk8Zei5q)_Y@409*R6h3$kQGW63=Joca++0>5+>XC*VS@p;M9ShfRp$6At zbp$$9pX%v4Fb(v4|MJUm%Pl{}puvNgltb#x9b7ej^o3Dbkb@2dvAnK&=^^a+{2ji& zZsMFA4TO`RvEH&dr?Og4M$v!>q`#+Wz1w0(qH6t)(nHtYzZ=}Z9$JM3$V;JtaA>;=m{ehCy9f2$b~m!{Jg7qC?(NSU9r-+L>s@6^1Idc#^H9h11+Kt8AWNnzhBlq zaUIeUrt3!$ySWCauNI|Onje`ZV^BEy5EKfd&+1pki#(JGw3AjsTdQsF-(dcc?-YPJdfw+ZdTh0mVtAN}A2tz0IkksLlc9c(!bOs)Y>l;vj>^u-?ZngDd*{))y z4iYTna>2|p6ocraqrLyA^xy41$FqymsRJO!o_F4U3;p^Pqp`86&qnij6?n<$>GCyJ z?!c~PA7ayoFQH=17cAO9?WH8=IIk%Q6=LU5H1ZG}cE#;1=|s+e#!!3fI&}3~#8dA( z4~1L5-{}-Ioi~pVbNPMwxR5wL`N=!s_xlp2>ldKDe5(r8HwL3moQlFxQ<2$ku%zCm ze!d7m;eeFV3I>CEO%FZAcfWoT;Il+MjTRpd=+gTV@5xJ19JY)>&JvNG>p|K!!KXxm zcRcK)7^RAHh2Iv+?HPb$4nWl>N#(MT$JtL*y3*F|O6J(91E9g4=BA|mV*I`FVf66n z);8BwpmO~(Z2$B>*u8uqI{~_DMAzje$8AP^VfeK4Gx^*bG4agnkdl!bv&EMvvHq;|fxfVsEed5JsBt+LQ7}R*bzijT0kUjKx z;jFznHF`TcU&$?~&+mtf-2|%}Ay;^HqqI3Nx^@H@8q<9tgmu1ueM(Q$+kvW#{46I% zQ-8cx9MUKL6q9j4ULV!Go*u7lfJny=?4%!N$fnn+B7*pXM#WX(B=_ywgtc!xiSZ{~ z$O5pP1r|rt?{@30QwLz^z<0NgzW-5t5j~QUqpv+*@NaHZ{&$=uOeAf%TB#x%b@L5MEDq(F=@ zOH#9WHMV^8GIo6V9vUmQW6Uw<@XtFk?0DLH33CA5X`>~|2;zM%O6@tyiK|xRoaiJ+ovm#+`l*bG}gq(A%=y@!Zf@HNKl;h?nI@ zMp7+m%$Ec)=$bWF@4=qcpJMB0Z=-UB=^ZZm%@tr_eA!PUeF)I zjy@NoPq-Kv#RGYZ&yeNr%{FDC9@`nWpYwZE0~^LqDL!-NHPxeP!%}Sf{2dYTKSF)Q z4t^XV`Wd;oIPQ{*MSxFZ5H1nAenjtGdguj6$|5fPM$Y7n48$VOR5&H)j1-EQ!W$Tc zA=#~{R;Ca(9pf$G< zi$)K1{mA%R;m;p|?BS;&7-%x3xiww2N2csLDW^`M7Bc1(H0!;RW1#I--a!h6%(;GE z)6pYqSf?=~97A3MS<`c*S9B#{O;UY9u{#NAfAaB)NfK^23@r?^u4gAoWvKXf>)vYY z-n>#~qau51tFPht8UDFAr|u&@?1;1u&e=CV127J@&_11$$6m_3fdqUy#gP zMe(GI#otS3nlCw-r^t*$pT8%=m3)I?*(%fHU|4rzl8sko2Vuy2$&5kP>Y=dFCe%xS zpk`8Z@o4ZCi^9Q8v|XT8ZYG-TYjX z{?ll((edjL-rr9j-o9q=29U=RTHg66R$#}{_l4oVgo<^` zIND1Vom9rP!ZLG~M#fRO9mk%3Hj=Xop|!MjPuFi}q^@6^a6Z|CjzU_=4Dt7yq=6G3 zU?9jwZS2>F^?F{@BQkXh3p5=lV5$wn3gVH6o((kg*~oek9Yb z#ocF&3md_g8KEdR5no2IorOcm=&RQ)6(#6;wAAk5_u}Ca)W^=nrc!2RL?+D$ja0Wa z_c~!rpLGE2ZB@DIN&R(FXW8_@i`Xq9Qgcm(F0Gvsb2`r*%nO?G+7#*YhK%Jsa5DT{ z@$Z!MY)Jq~j-eX>-~L$W=}x^L%lJv#j*jr&9UHKD(JQQbSGQ}EOk2Gqc$p?0B`o@C zO;2{)guzdkIT@p7&4Jb$umOKv)b(q%fWLq+T5n1Y3MYJ*LBNoWA(<(~jauJq_etZX zVKhat$$gnhKQc9!yaYi#vO}NOx3T_m#vpg~71bK#(OrVLMruU8&uqS|5S+y4kp6aC z!#>nj??mmEuTZyj4Vw0B7s08Hos)-3rsNdZCxwk&fyjHLNP-n#?`8~s5aC1apwTFqIET~x z>;c1(?9VhAdhKa`PYpTV-!~3%Z-RYJ2SxQe9r~*E%d!5w=dtbcx6mY_KZ{+a_#^xO zy73!HGzHE!kr}0=rQqlb&J~vIqrr%T==ueOqwjynMNrcQGRL2>a%)_ppkBv^^!o{Y z0ZG>TA=vo0%nkt6{`zQ*>=Mv>qD7xjSl=jA%(KE9dHTek;}UvkAewPX5>%JOKB7HH=T8_uwGeX#j=&(1g$_RKJIE*= zgp}kYg@s|2n8vSl1_E}4jXNO@peK=#hH&U+Y+3v|zIyp#RIK@2zA*89HI5WtMsOMB zlZ0{S4H?06;uPs~MQWc}G?42vUR((VdTmGFN)Z!toqB5g64*=SIfh*;7UAo+{w~t} z575?BFOg@FNm-Ovvc?W;h9sqYKQwAf-%HBshvUyV9{EE@i`2hOr}yreu3w<7RXFI; zNE`GWmh=wmwYw3e4e(AHKCEmSUbD~ z9($#rtN1b?48DG6CF;w!h>U3+s{@moP*`LiDtDng{8(;3N7VF6WLB$~2SjE#;(erM zk>j*`>pfl94SBHLvEj@n<{+*|Vi0rNeBX zH`{!6X=}=9$$1hR@lH|SuYTkIuxt53E~`|%*R0vdYq(anb+G7~(GZTumoBd76!e>N zEC!7ng2^LOMC#veQ}ykMt{>?IdXYEw0)$0IK@Pw^h+`n^vJGgZ{>Bn?>2V2Q7Q6#QT&JgpAyK zWlJx@upQ(-#ul+bAx6IseUT|&1f>3x=7@}RHnRH<r8Uu!%zEgdB-jb#rU$>nE%T3Z(BKKJ}-t(k;Gsf9{_cl6+p zlOs%taR&Gm7zS@-q5C}p=o0844q{XFZhZRaFR=CF*Eogh2-q`*b4Yf%Wb)xCn{g8F zfTtG@ki#OOc4m4FwFeSrkcp)1>WVk+ZpyE6t?FTQ+g1O51lvD_}Uh+mM@7fh@m-#w5LW4|V;-y-G^WL++S! z(N0cBAK-zW(sO^GM|Ks9h}4McfQjfE+j+)BpD9zO^Yc@*=K5Wg8=O?HQ&it4B7Aez zPLB4$rh4-pQ9aIkBeqoDV)E9^2yZMOncr6A{(`|W-B8Rgc2#5J7QKs;qqcT{_MyHTX|GzGcpl}EAp zqgN1UYT!)3=p!C8kyZ!4L6}QM`T@| zbg7e_0A0VJxUczRFM*a)B!0co?BR!uO+<55Su<;Wv$dy%^?F{>y97E0z@MsgQlz{r z47;JehUXb5!c$9*QhYW($jv@gAJ$>G&=%RHNJms=Z*Y6+geT;vf^t^Cm&$w)dE#sq z44)*<=tz-~4&)Z0q62=EyAYj}(rkk+BA&ZKuH+($Qeac^e%HE7C)bfHQ8VvO{TY zs6(?TBOCYZKtttrzAk~rS{~?P!{gMS`t~UiJ$Mb#)E`cGUDa2Hsg4gTvK^R~TZBwu z^rRO^K`E=>K&By6bS*#%T)}V)|4rFq^_WI&%802j`6W36Q52J0)W$fhC>F~|#Q$w) zQ|oHlzuz4IMgHBQE`9&bt64tVc}R^A)!y2Kba7$FopL3HAAL4_#O)SnO-Q?Le>;Jm z>}YrNSek_(gW2%@Ke7CUzli9+R<1J>svp*(PKs&x;xnzF6lJsKal}t69>je3?IJoc zsisN&CC79#)V(OmAps0eVs!lo%tI0~N1Tn2_7Xw?7rrz@ldq-FUXy=`dO^ zuU>L;iZJ+M-VeziGKN9s4Ds)@oI=?JV8ab@b|FWG6(%_}7>A5eVKrh67^bkOJ@VT} zj&0zd;z<3YB7bL^jtA5Mkg?MYG)4XvGX7+rYt$$2Km6!(G5P!-BD?=EKA63+bKhMj z5G#6j7xC|i0?h3>c=}OXyXs9Vv5dMVpT5PX!oW|WIs>}lQ^u5DGzdcvKMR9I#P{d* z%$U|IWC(hMq+FIB?FSY#2?NrdN&8n!bR3kd(cP<->0us#29e4)R_{hVA@miyIGv|pVJhk{qVM6~v1a#_C`8RPHO0~rPc!~I#aR!`}Pt*bCi@?PqWlsbpTXjHP@Dln*WDr5?qqTTbbja8*iZld%&mnAI?}iFD|ZUbT^S z+V|*~M?n0IkR}ypDae&XBxE)m+SGdw@Q`(e0 zUE;=(#_gfOA$L5v541*JDRJ;Om+N=O_* zF=@V)2(wgl`7p(d_~zHDVwMHQfRXta$ERvYkSP%)q7l(wNBzzJC!)*LYYxDh>c^Vb zp1|f0Uq-S^n~$cRa)(a9Q9pf%>ncL8_xDF4X8GNmLwB$N=j-5FUl`8v7w*II=kFEQ zXP-VRfk@-mPrYpW`FNgu%!!vFYv4#e#I2$>HbFL1$4@iseTl4xbmpfp24~lc`{kE_ zT#t4Af9CQ4ZGe3U}4!)jVz2Tvy4%OWYGDO+9Z441V0OW-0E3 z42dn5uDOBGhjj*ELi&9f+1x_TDjtlil0jV0)7M1B#XNxeE-%eXKv%(HV^md>g~%fR z)GR|avUg~ahOOGxg7thrIu=FG9;8z<9D`->N(6hbt%T4zYAg3TC0KVp2z((@j^)qa z!@X4}U_^(NBL7i8d64(++xPP#PNI?ic)f7Eh(Fc!dv|WYXOG>EZJ)g@M|XAL)cF+Q zwg3<76i=AN>_wDGQFJ$Id^h^9kY4XwQePo9)~uwxD9q87eG;MTM|1feAN<44LfDgv zwtaiBZ`Wp#5w2toyq0~nvS=ZLXN)67pZ8a665E=!n55XpT;*gS_uuJp;>)CD9~(EN z^fXs5!MXyZX67=#pfMXr?K|!!g*|%oRrQQDY;FK5#>@evR)8hrrI>X*tAu$xk*U6B zMRkh=)RG4`F#!Gh#`w6Mrre1iAd&%Ci^Jfx1M2|9&0P7?Lujhp8P)D1z|SXY{y8`N znU`~T{k8{DxGy+?h_pS%^TcEP4D^X8zIE~I`1H|VipaPv=8zOCAbSZ1f=sw(-w()L)hX68IaG-z=UZQwRRKsOwj+VWWfIyItJt)Y79- zQyoI(M^B=5+t<7+A0k6jC5@YbTNu568=PUaFLl8lYOiTJLlBM5(zQv>$U%C3KV*p7 zJwyDT2wPLqGQ?|AO@pUQ3OXqW{cW$uYc3ZV{XlYt9-SFTmS3tlN(@CG@l{o`j{ zwWaxy0H30_0d0E%HV3NM(tWe6(D?=oXXMBbwHQ=joh}FMR|h~|yjs-!TNb?%4f<(v z%IlDeZjm)VrTqtJ?6x
mubTsKYTcGA+n{}C%*xSzo=r}1mH42sg*ktbfvQ9q-g zlHb^unwKtG~rpo6(#!SiSpHD0nm@&FT(J>>AyG2++@ z5=y+$o5tJQ{eGU|Pf10Kh>VLL`8l>M{5LP{xUn0NQIooDZrNB&zTihFJ>)2a+lApZ zH$?IHTdclvM3#-;K;QMWpRxop)D$#eV4g_%)eISK6QS!TE@Amjpn7+?i1aE?85(Un zQ-V*EtvIILQe=HEGZk5$B>U2Yk>?>bzXWLo1CTBZJ~=&85}MF|s=miSEH3PrR@6}8!Oe#9@?Rg(I;JsiRWC8l&pMaK#nEl9Ug6yY^du1Ek+Pq|sb+oLP_M5+hN$~w$r!t@v>5eaMN{6BPH zFT#Lz96(j9wx6nZE$lVCHOZ%|hI?d`H#7uHvQWodKxA~+Oh;k_b(i{I>m=&;jV^$i zl!U4cE6`Z6jmZ%r4sf7V9Nx>2H+W31ifSa%p%@V&QSCnG*JS*(xwq(^o6xXlyD)zD zdY{sJN_nSVatj8}IEm5npiPL>bOJgy5H{<3qu(FWH|I2~^+zp3@$=l|eJIRL)`7pC z>-tHGZ(!#R4+7Ly^vJdy43ZJUNzv;dK0a>>eECH@tV9YxzN`Y~A(Rx}A)fcAU3obX zD9JXAQCS0-he6#Pl4PH%o?07G+bZN?u>|RkK~+^N9Z?iLW!KYt-7#pU0(*LlH_Ngzm z^C_`J?ebqCtN&15)Um7H zghQbSGT~n6DB2Y2r@_x1cOvq|e?g3;64)uAlhZHPs&Mtyg$1z^L)Lg{KR1 zdXjwb7nLBrc!+pULqs-{#~X>fRY%!CTZ^r`0+SJ#nsJ)GH79if3~DdU#1Z6j5M+%X z)@KFmeRjR2XVQObh+z1&Z~#>Y5_P1Xd-=NIo1B6Qk1rcsfo8gIIv+)+5K}GS&rleO z$OhCXegVVqT}pt2Iswl<%Y`fFip;xDXAe9?h#4~8)y zy&f5vX*%%Nb6r1@^loiYuw#c#sZGrV1{#CnBzt%XDQCcNWcD8hpZGUrjDfZ`@mhks zJ!Hso8^b(dov~M@|5R6NoB>F1O``H)gW{XXPCYu0za$Bv-}mY}1d`^Hz&zo0G6hh?(s`YaT%Bq|fgx z2M%l(fZiNU_R(gR;!K;xn;^17I{3YeSYz&niGy*VW8{CB+t{Ezur5 zqH6}Y7nbQhtNhALfPIKZ=k?Rma{9Md^+o}0=7gRx>1RfM=?rA_mxgT6jvJt%QSWm-0~+C_!JdyFxP_xJvBx?eO-?kkqztp?--)6z(|Iq#4c#}U`V7L1uszai z_ULb={>JYSpg6L)joE1;C;qyt>!&e-Ust1`e2*NxP0q?k&d_nl5ynqjow6O-E~<-0 ziSmc742GSJzNMq--;{6$Y~E z{NTvHpG8C6jJ>y1eL8zyYV{F7y6C>2FhPVzSK4u2BVv)6bN!!@HDDMMcsfBzr}&47 z>W3xKhk>d~gVQ(sbO~(g1W>O&&$kZ+wCc+unC(5*_2ZG>))2OAQIM2bg5oh#kTZA` z)Rc7Y{o6SCe;GK7uEwL8QeL{@+7_Nvy_d(ii7~ftvkDVO=eA;) zM|&+X51946M`sF(K=_STp79tmYL9({SJmhFl?dZkRMi0vIt^Wo7z#2x~XTLLC6zI3lSamY=97DBc8N17>#62Qq;~r~h{2{QvBI2ap`sdFKB*%xpqf zghh@75g0@g1Sx~07$wpsj}9l<%C>yxv+i83OLWzpRi`W4b@J)TK|YtR?tHfFQzR*} zD9V(X69j?*1QRIayZ{z?7mHmCc4lY#-TVLdzt^vOdcrPtk%X=4otf^Q*zf!E|NZIr z!-_YobziH%uZcU_Y$1#Ve_;^j+;BU5?BD+tm9iF{-iS2l#BVop3|2xT~W4W!C;QhW0uv*+!4oFBb0E+GzQ@AC(0tkFIq&b*{JXJ%SWtl5{%ZxpcqptYfj*WmhLK#1 zR70wa5d&DqcW#6}BCp89x&9j|Rr1*ihlI9fss8qN{*>s@4EU3pe-P%bx(n|7gZ~As zlc!VKFa27{d_N>R`%JW-M`uM*lt>4f*g$Ex0`n)Gf({e-8-uxi!zJYk4w9 z6*p3dt)$!-^z(6A50ZV9(C5cd>+Gf!hjidiTPbB7%cyWhBa#VfZFiJ6MgEONK>okr zVZ6c_)uk1Tt5FST(XS74p$_2rx;KD=f2{3eKis$49Ls|d*vR{jwFkaACSu|dw?BX^ zU;$3uK(+7hIaWh;eE$e^n&Gp-JBstfQT7A{|!&C2uir1mrj*CU2{=#7*NC1jpr~67! zps*NbE6{#NtVdA$i2(@W!5`-Pc`<7yv+qQvRfoQx=a|isd;Eo)pJ%{gyd_{4Rr~C5 zU=AOLL6C^Z>vMc3kSDCwAh;mN_nh>e6*x=|!WKbn3B>M9>`o=!2g3uHDg??(1CCiL za7+aNn)owT+zcIEb8Q;S0->c9cE0i$>|OU%W_$3(AOuGGn%EV2^1x1b|Iu%dNefOZ ziHY`OL)7j6?k{OLM5PY+llvUg-_iJH=x3Cb`YRV3vdzwArA)e;?iAhA!xxN_%*`7x7CBh zHAwH}+ccl&30qA_g2Hu4d_NJC6bW(x0m-QVRSaeqwgrHo@0dBCMjheePNxYm?e*s0 zeie>v-7umVf9G2WjFhq0*vz;PuqAr%$bM?}N&Z%4>Xf|Y-+Ub=%veB;JW<9}UswAZ zetZK40!l@uihZ1z0PjQX-_rq<_&fW#erUo=za5H`Z>L~m89|Nvq;?BP;}g)! zWC>9Afv5kNf*_O1lP<46i^#~yZg_0o>jpk95MtucNb=NQsp|od4xFa;aL^9t`H|`F ziFddNJb&h z#oz(}4P97q|Cfk+E^P%Me?88md-czMPx-^|X0ilbDscgf`X6}jr*T)LYx+ywqPp^P z55df9Z_(9#nPz<49_vQOZIKUCd&wxB3arE_KLxk|im-SlsEC4gW?E$*|Kp3CLP8ZZPP z6yf(d*yjryur-=JNW==*?6<{3F_3-Y7l1@zk@fpMr(M`j_77wQ0?+l|xF8Sn+}QZD z;G@3?!x;phC_96QDWyU0z z*KhaX!vAV5labbUWxdd;2>yP2( zKl?JAI=F{i0%0q-E^N1;p6`znWVbx~Jx| zpQsAt09(cB^+y6u4E*_&dWbZWB<_iq9EQ8+iY$y&55XdRuhwmwM zDQ=m8Pvn}c@i8S>;Xt4vCZX>WNoMVd;VThV^EIiuQ2F#GLXYL= zwdMvkuWx{Dy6p^afUw5`YqGo5eRlJ_1i_~X>}en0PZkS#X*1ue0=sZ&f)crYF&0++ z`4<3sp%-a>-yIKqlS*5&ga8sdV0K{dx_^RazWVF%vnT&AfySl09?$4~BSA1K?XLve zu^sQj;h()h^j@yGM(}qoSPIKN@mURiNJjXD5SfKPrXQqHNw5j1kqNGFJF}wz(>n9q z>@%D(*RM9qk2}}T(0e1Z5T^T11S`qUM{~beEYkZCux+IuGxIoo2$=q(V_dFh0-Kfu z$B<%BuupSv86Z;5KG90++2}oLd>r0k0(w~UA9COi!JTJ;LD$CB{Ju8vP4LZF3HTbh zd}uX#LI`j_4wBV~wd9!Xz?=hx%|yr=|#aRsI>x(4p~ z&wmG#7c8s610bkIUNho+1)lq(&nxr!RsEwlLqyJpe>55afa$*7ul<<5t4RI4vN8eqi@6PpmOVfVUu>Wh#^+TGn zzHlYUUu6Uq1u~ z-(N$37b%8Wn#`)U!<*lN7yjFqVBzZf;hJClGE7@?ogVvLDvk)a<5B*b*3ebbR4tA| z?-3=yeo9?_t_VlpAE(SLy!8PZh9Xm%KJ5$2#B4msWc$(Pv}AVNxFQfW@{(zT(AqwU zn|<85ew#)y*H4%Gp7CeFk;-Ca$rOmc(D?bfb(iV7X&ko>+>tv}iIQAQ+GBV zSgmOz=)Ujp@@s&SkDm(@roGAe8+jH4F}Tsrz#Cb{9UA;$Bh5-_h z|D;CuQskaVe*ZZCA5feNALA%;WP!pM(UC11;N-!bM3#z_dCTwm)Hzjh=VUe@n*Zny zeEcha4;#Mw-(l-B-_g0$FqfG=LvwcLE04qe4KERi2u9112alr2IIw}Ipw>2D#kgqy zMiv34Igf68k49LfIsMQj!up8zsk13CT3h?e3^ydQT0ZUf$D|+nI7aO|^QT~LSDthJ zmDF6n4GrnN({uf(-e3A~sB$e7&>V<#exD-z6=og=Q>Dj3z~S;2MBA;a@~nkpTX0RF zjni?S0h@0l?mCL^vv$WcT~6IM+FDel+)N(cbPmROdY>cyTB8R}G~YG%lTm*!G1wz3 zxCg2I_C4`)6X-n(dLP~XE_ACkeQfInICW?*^-GWtQtKup0$rJv5fc}^03ZM;;G(~O z%a^|fUCUO&JKy^{jeXL?E<{z)5SmB$92zdN_Q$Z`=KEmD-JgQ4<*SHn6#eORox!j)M1p<%2^YW|e4a9Dt;Qce!Rl9@U1^3xzv zs$7(h@?5{dsOS3OWS>*sGB{rB0-;=o3I+GdmRnDc?v7iI<7y|K0A$)-*|PE2j3z*t z{5jXqYkwa({sR&Swn`6Ecx?9T2)}0q01Ae{2!kNtlv}{Qy|EH}D@;7j|HtOLb`g?! zd#)95cmO<69pTT4=xg^i52eAAaB$O`u=mYpm9~G4(%*Rfkvr38i#LsMSsU*1q80$a zW^g3RG`(i}vK!&uAN&~=%HSgQGlquJXe^36N=TM)rrjQZ!9Amz>xY5AqHKq~#br>$IrmUup%mGSj~Osx zhVaD}8nJjXS%9N9rjmK03>c!Ki|NUH}7!cfi1*eI((N!M_U3y!vMP4kd>U zy;im%?fYkD0A$J?pvD*pvu7_N3U3(|^e^bO>%d+e_K zKRKipuo$*rmnQQd9g0of@A~{cmKX~!(PM8+{uuba4b}-y*gSr~LLs2)Jl(=eZU7hd zfZOmR3~06X_niVB-wE0oK$E2);%YwK?Bm(m0F&a&D%^3wkLEi9yF4@q2j6`KcCGml z#kmS6kI^~^)NwCpuW87;yRkad3&M0v#=RO}xt10yg-_{*53D z%KXeP1DU%@eV*wcN}E9py#t1px_YjkF3atgGoYt9PyLodFwC_lX1J)P`Ic323>uH+ z#ih9h%x=KV^x*q`ti3(1zsHKb9GUuBdxwFWr*~c_i0QlxjTZ@mz%B4`I{T~;h^+y4 zG?-iFn;hUFQq4OW_-N`EP8@>mO4FltdSd4XGoN9)LMF+zA~s=5gS#ST$;CEVaM6Bz?;C6RE2d(L971G^-95M=h%Gr0<`> z`jZ|BCn4b$ASfrcw<^5*Ad4lP`ojPqC}9X60oi$-5&%oo%453r)|{EJcseekF5Z=eAhMm4M_(o zAbdW~HbhqEJ!^kVW6TA8{-gzK8+#JhJ0h15<3#A*PP^h-n6Z2n%vMSei^C?*UYKRT z%JBgIc@Y3vCJlllIx`3py5_>_fAuG@^q${FbmcjG-|VW3bz^BV<0BUzDgu|OM=lWsJ|LE{yI9!+no-9#Q z5ovu-aK=H``Aeqqii=-_)zk=f6Q$2F5eND6VQ5oqzG>T4=jZb|tC^{GKMXBhSBR#x zY2xv9UB6-G)u6^eU|g7^3xUE!f4?T~46M~)>iBIhehnWV58~iaJbpsCs@q?D6!yLK zER8WYi!iw>Z6r48~Aloe{ zakbnEYLmU{fq$W->=Uqe-P6$Dv&+uVtJOS2xnkoY^d2Pw5*$<3wcylHs_&6tUy}_`Ot@s zwzfERpiKmjgU5CLzbf^IiMujs{7w6Z;Y<;G^VOb8KxM>*N;_=pUqHWA1^M-)9yB5d z_qzT-fOIC>7}87=wGVZ*ou{=vfieu8{`)wvXKA_Bxo80x)8F&rzJ6Pt8^mV3$E?Ao z-(MH+a5Ipj(c{a-3tj-Y@d4#<($I)iU;K&^1iu44 z8-Gd`!O<-nlzVWT7POx+dOYnSP~dRm>$G*wUkXd^{?Qn`z;M&+3>y+qSnhh>ylCz;499PVkR>a<$MVbhJWiYfH=xNZP-kEUW&Szfm9x zu;)kt4)?V|+k{0>Qj4+B*F$lK9RmyD+%9+PW#EAc|xNTVbF zsMUe@=h)mwvptV#Q>O3I7DJ9Z12rH~p!iO3&jbQJ4h$Mg!|d||lky8}d9I)7_h+@` z3fshmgKoAw_g&ck&MQ>EfrChMHT-+wC^DR8)TWfp+#4QHR_L$7%&UGuDW562fr~*u zmUSzalmJLu1o@7MaK#<}92Vd9%h0=T8ywj15_GSBUYTPXp*&P1_aNbW)d(CSJJ0&R z|6|zp{P$t`eV>Ob@A))Y1X!(jHoXS;9_7**7{)YNMv+Y`&bNcwg+;Y)lP*Ba2VjeT zsDEC&0F#seK=Tp#7_|Sd&Ko$UIsY>nelTOuKfD0C2d;vy`KzI=V}W|gFjTfa3|kKL z!tTB)WI0qg1!*Vg09ef%o6f$?x0@hc+(g5GMzf!5_!00Z0P+gt2yD#vhc@V^>AQrd z&kNXPz~9ff52kP5XM&EvN$I&&fcn0+HVmV$S0klohkdBEf^a;dfWP(G?<#llWvb8% zbFCDh6E%E$EOx^2ceoQ3&Ei`gRKWjbnunn&^NUq8F-8D<`Ew}%5-|d%ke;$&IR#Fz zqYg<$_PqX2(DUvZ7&y{xs|#y&6q;DUz~O!H*0=r$cD(X9T=&V}r@8`M0HZE9#zGh* zyHHz}wk4+I2G&G1_+?!x@VJ&%g7zsCSH1vaFqZ90yFcpR|9V|nE>Bk<#6 zq3!UqoqoQq0wnO~Lhkz))~u)4fFooKEtlm3@Z4@a&!OgyQ-f})E`4rP5^CSkts5x* zbl{zrNiksYT8_uIWr3e2FDv1X>uUCOx52V|J_B=ayc60wXHXUjIUdiqmLI7AkQb~Z zK#ix|1KbekbFRNbnOJwh;IRYH^TAqj5m0iYk5(^ms8cvOIH|0OSO4PoVecDH!;N3~ zPb95%o?bSk^<&ddSS_9PLt=?A)QSFQ-A||1vagap-jWNTy{(l;@AB+C)c)m?uI7e5?g`@wjB|0@T4+xLx-ZvDR(vBT_pJP{W!1B={fYvLk6YCCVfjw zp7Q!+0bu?-V9;}ckH>WazN5{J&mOYoH`xJG{A0kb>jSvOmyfx=z1yB^X}TErxE~9+ zwxX%8tV^TusXNaFymOygos|ojYo7oMZhnxOyk=c{Eb7P-B-BeMzjq%6Km#AyJA%1gxBpsI zWnn|#9g;oXvg&fln9-qXvQUcsM^*#h#0C=27beCiVM2Qgw6?Tp;!SGbQ=fm}cxKH% z0-@)4AN2MQY64E?7DRw;+I;~2@y%^ix@*{X(*-FmgDrwQVEQbR#*3SCVvykS^rCiC+!SpMyC#w?!rde(8V+or}CI~o|QjtoG znQnUO;;ZR`T>aqhz<%Yw?RfEraAfmablhiYpGF`?b8&FTns5AD=w=%jGvN`|1X5bM)S&3pIO~)1JoYi8%Tl3A`=d5Kp@4r# z2>|-txPJgsbnk864uA8=Q{YXR2kjFkY5`ylk=~2K?0UrfQ z@7~R1>UY2OoU-~(sr{|GOVurJa4aTrLlwYrXv^aJzMwSz=cv_P7xNU861|Ca-e~>T zp#}f>hykQ6gr+P8F8ZlJQJH2FVd*`erods(#&xju>2Je<_g@EUfyJh(32|nfdQB``$^vp}u)paHgAg^`0O^y8CGsM*`5%z!KJ|7`+(=YnPI0u)9J@cL_5f;$!H=Q;~; zwln>7aZ#BT!Ms)XP|*bz32pq*|AxaKzOF03QZWMZ3DsiQ{@nK|e}C)m{SO^kZ(s?~ z0#??AZe^BL>j=qCKs0tI5&^$vTn}};H6KE|GOwxcAN~2$y&#n-3r;!`H6u0(?K^ZF zO4u(9S^yw$o?E*fzVqa>#NLxrz`}+mbg5j>n@KwaB+}$LYx-kA&!?20*5G;W+C%f6 zfKJD9r2TcopX>NRSijx#Ouc_-&H6CJ^KyyYzTw<6rM<#)DZbJgpUFOnEhtp(;5OLt z(xVFa&%n^B6C|+1wssJ;f_n`7b_M(;cYFz!-}?oaJbx*Xx@59jWm0^N)an)Id}hu? zkp(zAOCq8RhClxNn?3=vK5{GUeEBhW|FOR&zWy*>dyR_^g~0OzHH%f$rHDq^ws{VCL6X6$NCtey(7^G+%4 z_|XEe83y(LiRahA<4?b=EFJB`0s zh@Y*kJ(b2|&C7}-4g4tz_z?mBbX7cLJYCxhMgW{kKECmEDUg337c#l!^PBpU>Ef^An#i`wU+?CTgIE{ z|BrkBg^X(rao?1Q?Uv3uD)fOo-IwtF@pBzKa)Nw+s{X?mf!ZE_`AvB8CogCYe2Oya z(q0snIKXt`%!P^0G?RA2NWKZqkuT4_IF|9YDqw}&xraeN1Z)fX{|uF$zHWn% zo5#o3rUlADK+l=2=LYli=kpS-4(>g^;{(|F>SOBqDvjUYOBx@)1N!S!8j+!S(X7X7 zxa7Vs5(!P`{3~hSFabX~HmzFY*BYxPp}J~dMCtx<>jP*?0HEaU=$JSvUJ@s6bb(0& zfSHSy!~I|Ve?;Jk=ANv|t_YI)IIph-{nRjMlm>ub_^m&LYkujAdg5&y+6SRDW&4Cl zlqkZK4K=hUe~&)JLxfC0od<>w>dTU*<7a4?^v zW4f_N`}CT)L!TdpIXki|7Y@99ZCE$!`ab1H!(Q!KG|aR?Jb^0V!iK*4l(~yxs@kfaPnm#W(5*5ZMvRq>hUsq^=B<#Wr;w{NN(Yb<^m^mD?}UzpiygB6h*&LZFeGQ!h=IJ_i|ZvtBQ&%g;3*n@t5K{7ZGW zg*7n>n5gd{WdML{--ndI*>&Iu6xD60Kz*#g06%XZ15*{qMBml{w~_c7FX-iUMksBL0?_tPmJ|A#)TRs=KL}9Z-sy=v{m5g=|5`!#I`)y$MVb|ME!@z^w$AJN#GwSoFTC9 zKRy7Dto@nn={*H`Ho4Q^&Go|#I2CZE0jz8OBk=JSO@E!|&s*ytr?UVOZ}HCv2i|Yr zLx?1qXM%}01^%pN9d)1UuaaaPUIrz1YS5;rYWD@GFAUC2a8IN#N4R4=x>9D`3W20q ztb>DtN-0D}5M1)$Z^i-`>2uSdPYVFoGH|E+@?(+SuRxENMCc(K)J7W3n=&s%_6^y0 z0OatH*8b`$?K*fIj-MQ$6yfIXqwvU@jk0g>jLZc-3=cPY z@PGnyWcJ~4vV7ESu~?LLCZQe;rrc*=n!zCEwNN<3eEdn^ry6u*nu0sl{+>p$`U&|y zedsjc`F#6*8Uec&$!D`s|B(oZjB|yfY^C}9cs(3XQjUkzaqo-y^XJb|l6{)Ga4jq# zJa7k?XFnH45b7L{?;y|i`OXi0Hs47!y3g+;QopHS;0YEAo^y`pJP#4-t1Y@_`O+m% zKJmzZ^~>d;v~4ZO(rMDH2aol^&i#kUJ$Ut<&As1v&cQe8z4diCFsLruk0M9x{G!O=|Nsu=>Co51OM~TxhH~+H)fOHm|r~%%y1-Q6K z!97wz01X5{S{P6eKI51x1bp-OhMPWmYtO;M#qDd>z^b|JfhWuUj_$*B0Uv(;_5FYI z#EW~B73X`d9n7r>2FM6})H3Q80b5|;7Sv;71r!`W8zE720B(WK@Tml*)?7{q=9 zpo0T=*ZdW!8ItEbB%n|1p*yn*IecW7t zdRBt_xRS9i?GA|9Gp0|x{)QVSzWvU-g}?gNk6N$4VvcvmirLVS_vJr4wPw!`o_+0r zc9lJMQ5nFJ)>p!z$U?wq^g(qW&pE?e#2UV2+yp)zu`npH;3%8NHMG4AJUSMDk@cAVM zeq;oO)KNeb02Rj)h@AVwb%5UtfMrTsHzNd~2_XQ@`u?NT_;8j07vuODMi&D(i#Mv3 z7`<2ogB(M_mNr*qlkPyHTM_{G-}i}`yY}pZZQHhq;c_`>^`+dtbJw=r`}QAE+S=#f zm+{F94DsC?Z2R$Ob|oeT?c{ufF!$#p~9sgMq=p)=*jJJ9q8c*xhru*Yl_e zz-Vv;`bh=iQ%WG9d5_Hir`3Jb_(ccoL#*9PjwUxCcTIN}>`?~bqXs}9srg<{tIIlT zY$VlmW3fgr>h&GK<-f7Gz~U@lN7fJ!>DP}IEtuaqVdA8&H=p>&wm_Dn?b~;}f8g-3 zeg*!JwLOv#98?<;0wVYa81N_nFyeoPP5F`o>T(SeJ{o~(-pE8BtqI>KS`VWz>*b{m z?8^e+{0Ip#N}-Y!9Tpjnqd9ZtOxw9@_wwV1_KV%ScW*g#thcDZkHGKY?U(}ian$x~ z^1D%c*H<^-hg485YQl$(nh3OI9cu>M%>?B}VqwZrUK6-1051QHwY4ykKx39AAXi>@ z?V{J$zB;^V)0VeR4xT=$z<-QEf0#jEV6(oIq1mGh05{U8&6?UH(byw7r`g}?GRQ~q zCoca47tOVxAmA_FdD~5Iyz^dL|G;Sz$dgXsu9RWYHwvJQ1RyfQ;u#5un+?jHt*?F= z=$8e+C3lSk#HHCG-}fC~J?+Ccqs5y6kbu#d*_T0nSpZ!A8^i15mI&9oj$`2;i!lPA z9LMKh{<|yyey*?8XzLSPtzM7IYP{kgmqC63{r!Id1^~_r8QQ=)qcH#g002ovPDHLk FV1i%}lzNktv& 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

T?B0 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 literal 0 HcmV?d00001 diff --git a/images/mapper-icon/Mapper-large.psd b/images/mapper-icon/Mapper-large.psd new file mode 100755 index 0000000000000000000000000000000000000000..6606ab81aace006d0f904655de37d59ccc822649 GIT binary patch literal 2932779 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

Pg=AAqXQccC4Ms$2w6t3}w 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

e+eGt_j@sgPP^4C~MUP`T?R#R*6TTiW{ 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

RX>_8Eqn^18<6oYMuvqRIQxzUBO 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𐌜mDCpF>X)>k!TDyvs5 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

&{FywkMP> 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�K#v%oZ8Yg*aAe^vSH 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 v1*ik7gE@V4RY%7kTEtLj{| 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

GpJfD-_%M#+ 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

TMRS{Rot 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 ICjQ(11>0FCF8}}l literal 0 HcmV?d00001 diff --git a/images/mapper-icon/Mapper-small.psd b/images/mapper-icon/Mapper-small.psd new file mode 100755 index 0000000000000000000000000000000000000000..eaee18ba760d997624c6d0b4ccab45335a946796 GIT binary patch literal 1388453 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 literal 0 HcmV?d00001 diff --git a/images/mapper-icon/Mapper.icns b/images/mapper-icon/Mapper.icns new file mode 100644 index 0000000000000000000000000000000000000000..0ae8f58b0e8d6ea5beb2be5f8e53533a4561529b GIT binary patch literal 278110 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 literal 0 HcmV?d00001 diff --git a/images/print-mode-separations.png b/images/print-mode-separations.png new file mode 100644 index 0000000000000000000000000000000000000000..7753a5304832ec6aa12133c1d7e9b42cca52ab4f GIT binary patch literal 1073 zcmV-11kU@3P)6IU33znQUv<2W}bv6C1GAZWQrfCLiif{GWY`UqY29oj|PMOm{e1;I8I zP*p5I1aXNF5nygfNFfv@ElG%zm>ApRyT>zK95J$z_%dTV_F4TNpPBjQzn@>4Fm6+{ zB&6ef)lLVn&gxsH+1@2@_-$Z(;6EXI@wsSkG7#{Ql{`72tzkx*52T}qSP-(0VJFTe z0|6^67SI40WsqIX2hz}1`5@#$cFQPD1_DAX7#M⪻nlL17*p4WJSosj7UgL1_G9O zF9a9vUIuD-hf=-K9cBJYqDEQop$`bKC&HQ~4hhLmV31vIJV1u@DoY_2baa~bBh6nchK617$h{lj!0e!xR_2b~r7|I4ht zRa6=nbG#8n$tIA2F~-$%{IJBl*^^YfD~b9y&$DETFXqY5G8rRcKkQQ^u5f;qDc}a9 z-}58T&(M3`l~1^UO6(;QJ@j|d1yTw%LbzfwlQ#6!8`S;>znLF2z|b{bh$=hFWQ6c` z_CvXwj9%buv3kRVUhq)J!k-$k99t^pPcE6gNAbGDUne*Xco~q9D_X5q4W&@8aq)M4 z-I4})$Sn~&3XU#%8>k_j!V~U~aWzvmr^SfO@a!n3gp#7H*B{8hc+1pHM%P%b=7vYy z5kR6(YCzffIdqTfWm4y+te^ar?*IqRFd+@C&OY>x8A~_J@!IsTUi!DSr!JMagNzHg z5mvL)emvo>S#jlhH!yY{_lyT31IZ|zRvPVEPaS27)C6OIpPdO}^#zhn8#ar8g!B{V zUAUWXGSj=~dD9Y3Z7!=RqftI&nkeexO55$ z;#ty1I4K5P3d-W=4ijjn!^=RNPimzgun#oFWAj+JmxIEq%pr*vUyMkGbdKx}T*o*i zPS7(vjT0?C{JU_kv791NYm@<(xx1eu<@f051vDpZ=Gi<;XOpW{`kHpN* zQHuix8LtQ=Bg>y@M77yma2z;K@^u}eEXe)V3j0?CtseUu3zR4Kl8F`qYJ}Bl2O4iJ rpe5#4SZpC61EaoHt3$t6U#tBOX`D;yd`}gQ00000NkvXXu0mjfm*CvB literal 0 HcmV?d00001 diff --git a/images/print-mode-vector.png b/images/print-mode-vector.png new file mode 100644 index 0000000000000000000000000000000000000000..443cdc72994832eb3e878580d5936c7c552dd3ae GIT binary patch literal 2932 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 literal 0 HcmV?d00001 diff --git a/images/redo.png b/images/redo.png new file mode 100644 index 0000000000000000000000000000000000000000..3eb7b05c84809454c095bcb61b27d83585540bb2 GIT binary patch literal 1502 zcmV<41tI#0P)HR%3`p(HB`no_vu~6N}ZlRFC*?c+Y%$zyD-}&au z&JZ)>K^AeZ6L@^ummZ&X*Yn)70D$d6!LJ^l=6+BDv~c!{RYJijk54Ok5CT{{e~oil z-TFEbX!ZECIrm*akb>H(dS&g?FP4)K%^sh&_`V4c2m&fb&2G#rtri=XzfzzG^{B_E zHQpZqA_x*72n38CJd|Gu&#E_aHK*$b&n|7-ZLgos|A5D*S!OO3tj^fh z_!0W`3$WRQ%?5InVvwcc=cez&6S48H4!ouBxMu;6Pg_j_`(_qbYqix+<`vH*0k)O-56 zud&1uzgHhmFx075FBE*UbpHBBSI%oxLe?+@Zf!Q;*6vT#lyW3w4JY9MkgFEMG%bvd zj938nr^2Tc@c6W~RmHXIm(1Ou1kFAG0Fw%UlRqSTi54)VcO>U1an?Yy3vuG~@rZ85 z-uG|Ozewj~6o}vV-Rqv(Ci;8JElAxFv;gud8$jGKcnWCQ?Erp*KC zIXKaBJYt&WcE4BOor#q#1Dk6q78K>?<|1J9K#&Rskgt}(!EXFJ*vh>lSE3{1Loyf| z&3UuoJ;5w7Y;*zuDqMB2!UCtx{28%r>ovbu_h-v=W&y&2n({i=gf#-m76=0Q&NB3m zb>eW#zGx^K*vpKg0NMp9e=$o8=`Dj;l=Lz_SWyF}Y_f*liLBCL1t~h-HRlkcb2k zDMX|u0swmZd)fkBa>Y+ujj{N7B|et!O2BRM{{EheXKZP~kP#GW?m+0WbOJ~ZO^HPi?D-I-Z@Rh)4kw5h(x^0Lp=##*zNcjveFS!C+x=g(!SP+wgD|a?&Pu zP7Fa!$fU164o-xU8bl<3l(%90fD)HVwznQAX`EZL=V6*OcF^rX8}#?vph{K*-aJ52Fh0c1LTj{ z_25L4$sFBHAhdJc-HYSJHET3+lQ}F#GpoxADq%u{49a46Bi%sLRrS`#vj<^xA}r`> zlilY~RjH~x|6iW>eV-5Df8A(1KMf5Hk>`0D5$#nJcdPX^Mz@e_oS2;0erLOgL`^<=&b<;2L}&IDZh%x<0tFu>yb<*ITQ-PvMjPJ z3rkB&AR?%$imIwA)Ya9oVHg-6A8${m)0Y8!lS-xd%$YL)upz{z00RR9pD2p*WkW+l zO-Dxu>$*;sWszYR5JDgr41(yTKV}9q!!%72LZG#^70G0hQ>oOuEy2LRz$cof{l2ra zGm=au;kqs{GkiWD&(F`(+}s>iR#xD79sod56zIB++S*z~qfrJxs;W|Zdpnw%n%)jz zaB%RTq9|W>c6LVg@81u{aX1(ZVrpuNMn*azkP%< zUpaMjbRdyPaC37rG4u8TQmIr#O8HeoLqkn6nS^cI91e$Rcz76Nt<2CU8n*q3Utu&{v2%1Y8S4VGnX4`66$h+Nk_7LUhIwzs#l<2V!wg)lrk zj0fZYg!9n?+#2IQ9_H|+S^&U-0|&s&uq+FHzkhoGp66+rrhQ&tUk_c^iJ37uIZ0#V zqi{aTZ7RMVVEs}Z)^__FCZ*gOfQa@60)h5@`}VPAS){5eKX~wfeDB)`)aU?oFaTb= z5(oqV1qxJX2!7_r*O$KDRA|dQpeV}6@pv4%u48p|6;Gc&CFw}~vgua{AOL{za?g8U zU`<{?g@yov@FNI(wz0Ugj8A)ddbW(f2Z=-iCBq;g1TvWn>TBz7f~n_kjZ3l;lc%Ub#)=UBhV45b1#UfnS1pu5se;(c4 z-MD=DGG4rRf!5a6-FNQXdHZ5?_Uu`lJ9iF_WdSF6`dD8`rO2M>rhD=;)|+_3BkNEepY55N(GJ+1=gU+D`zOd0{cX zSSf^nr0P1|xg>gwt+Jv|K}1XNW8gWq znb-*6_U!EJhkN$y;bL)x0)YT#W@dgYIIl8~2Ncsl=?6eA0!|TdEx?nn?w$p>7Nog? z>F*C>`0hgl!y%|XA6HjZ(UT`nZodKGy6%-sCi6w1P=F8$Dl02FoleuEM~~3f)&`jK zz|5b3XMYClWq_1d#o+a0`r5lk`S;)pRv=mtW!tvN^E_lS8Mv-{Wupj8nx=U#o6WXY zRaL=p9ID@2k9&W=hnSW@&5Pdw#&f_I1bm?_LqEH^2lp3S0Fj4JRmtb`;pEAaG%_-B zkC`Xm$OA$MDW$xaPN$L2=h-w&?25&>v9S?1hrh>cA-pC`+Y-My*M-KWRuq<&m>6&z zhtugaq?8wh5I+_NW&PpCjT<<1>eT%5^6~+{-``MP{xcXQ1CeNi0>K@)I~@c8h-!;a z$oomO*GsHG&3`ET~*bKy}iB0rd{z`L-LoS zM~~L1stQY5?AQD#BENX)ji2447o$4|?2oxP1S$j98jU;@bT`)}(tE;PA zG7PZiQD$>i#zP`S(E!*<-mhAB1!x3hNB_(`BkgmfExhzE@6&to>-`)KV zW##4Ux;9yc1qS0#+aWxD{CH7H`J4X!{y)A^CpH4OdGqGz@#Dvz&&|!X`ThQ#M8rOy zj||fwK?*EO0v^Nh97t)yD6JxwdjZX_!t-1bf?!F>jg5^oF)=Y~+xBla65kYH9pc1^ z6W?aD*=o=88X}PhOvB`WKLE>?R4T1vb+rW3FyOi_gdk{|#+H<5X=x!TCC$vtTnF&$ z{{H@3?>rf8G?PXV4^6>Uwe9b7XPb9v;W(_ Y0bEjTJ%m&ch5!Hn07*qoM6N<$f;~xXI{*Lx literal 0 HcmV?d00001 diff --git a/images/save.png b/images/save.png new file mode 100644 index 0000000000000000000000000000000000000000..17b1274e6dbd233e0f56ab845ee3bb9831a1206a GIT binary patch literal 890 zcmV-=1BLvFP)dM|bP2XkDem`LSnYU0B5#{!+cb8q>On?Rwh{BCmUgYJQ zpHhGSovib*BMA8J)KyfK=N6}OuOk1!ig4xaPY@C2H>I59X~>5^fhuD2#xLqM&dbQ^7KY#b}`+}s>MHZfaBz@`K|0d9cfMn=He!2+yE(vb3(;7A0l zl^z0REkT#S5EHtFhX*)rh!bE22v9r%C%6lY3?iVO2lQlifvO^fChS9?>|J0AP1wf+ zWkuHmg#_%$dtlf$bPZp7?|T%olP~)Z*|Q_%w@Iq>P(RSLuFwPGdB6=W`@hlI{TY>f z$6+xt5)zzU#Ed_goXRAE3JDmGfSYY+_ZO}#y+pNIB@9ENC?X8QzGZ7IaU5feq0wmY z+3M#=^@$t-GuQ)~+XWdqG1O``qA234ufJh;XA6Lt*$cdSeVH%}F~-npwX)=K94Dp| zlTN5hV8~fu^8`{aRw@<3Fl2XUi`L{40NYz@SZisw+quMk8Qd9=_(UoA5&}I0oPe>h zF`_8f6o7++gMrD7F$q^kKowBpqHSo*U;>BH0W_P+xhX&U%z-A_{&|xYQW>b z8DJb3C81wtbkZ^Z1scFUu;AH^(GUqo@b?!El-*1o0HEJDptg2<0pmCbqKem#dezS?F+s%WcnB#ryQC1VV*1`CE4JUiWW_dZ+1=Y8{5Aq? z`ogk%9{!ElWPGl!uEyr>AKEsfWUkQH)%HMg(tg?M(UX8V+vifanie=~8_4Qm=x9jfwf?L$S?&i;?Q-)l zj4=BA)4P5}jV2R9!4UrX!mHBI@K~HrH%KfJr4<4F|`Hd!2iKJ1_s5fF<@@J&R(7z0Nq+b9r(>ap%xXC4UHds);(`th0$sU z979!k4n~IDXluJNu0**9Zs0D zSyF5e;xZ^9m8-F#(v*l-x?c0@Jx$rM>|AgcGxz@^!>uPmA ze-xSqlovaoX&ML!s%FjL&wlaMhB@;VZ!RjGJ9kFG+>HFvdE>6`mLRFEe`r`$RcA(e zs+67MB&Egq-1_x(q<_EFE#vuFvjU3 zQ4yjjV_$JmeGo$0m6-{^J8Bm2zkTxAH~?^}s!^-O4ELZ9LR^~cN zfy5Y|K79@xm5`TZht*<0n%x9S2zW-pF$zV|AP5pHR%_G|FjXZZ;0TzitSKo`MOIN( z;)Kzt1EmCRw+~enxtLX+0Yam=c=;j@9DGaE5);T##vXg)&7&J-RjCr=qTOUPYES?1 zaV{R0!E*_*0fEO8!t%PMmSe}>-&3R$! z1fg&kzy95B7>&j+L`iH`Wwn)nGy&6epnB~NlU>oyZr-?NZca`<1_u4t$B^R~Zd*`< zhL>KCb@udLRYmy;Ns~Hx!q237?y2(P;<877zSS5G2{0IV$dZDtt}$d~+t7aX3f_MA zyUtE)P46oVn)eF*$qFY2kknUc->~`Mc2~R2^qo9N!7>r@fJ$Ld(qsbWv2G;@P zCk{vYrur32X56=BHQ&?iL1wxYlv4P{BM{>Xii$FE=8ibetMb&ia0gLm0BCvGj_EH_sE&t)YtLb3B zF9FPf=UCE1N5^qc6%}zo0wt3Nmnv!CIR;Ts;7oU7^ZI(#XfPZ`lC$Rg{g+@>?t54A~CaQmmyb>+U2zZx~Kz3bL}zIDX=!CWsMK z%+5h>UMlQ1BXoSC5{$uOHXtk8hD?VQBOVWSKE6x-+rEFunYm_|EP5!ih7D_0=w(&i z^PLqaD4u5!C1w4cHS<|lrsKlb7jf{=JK~%FIxdb55AF8({QghQG?gq|SjkaF@XVflf+)p)hj1EiGT| zZ)rMyL=B_C*suvkP1NQ>%8FZ1G*Bxa^l`~OZH`?0*C>KPPs+^ zgcBZ&MZ+!bp;0X}+X_$>u7N?$?;B_W5C9OGvNtj_3;>^S4gj~HX5(73 z#l9Z^C}lFBMo%>!sK9?qe9fg~px>9kw;7!huTAmqW&Z&pdN>M(u2oY20000 + + + + + + + + + + + + + + + + + image/svg+xml + + + 2016-10-02 + + + Kai Pastor + + + https://github.com/OpenOrienteering/mapper + + + parts + puzzle + + + + + + + + + + diff --git a/images/symbol_point_explanation.png b/images/symbol_point_explanation.png new file mode 100644 index 0000000000000000000000000000000000000000..87a26fe8a61a7810b114a2c552adce40d310ff1e GIT binary patch literal 3441 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 TqwS3D00000NkvXXu0mjfse_L8 literal 0 HcmV?d00001 diff --git a/images/symbols.png b/images/symbols.png new file mode 100644 index 0000000000000000000000000000000000000000..579f75b093e9ff6c3134cd6038abd24f98ccb327 GIT binary patch literal 252 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=ffJ!=5gVArXh)PTS3U$U(s6e$+PR zj*R2H7KPj)jDE-e+0uLW?v|DP)I5PHTi{hu zP4`ymVg~kt2AKxV0295m*rKTntCSul`rOIb5$ygai%V)MQy{CZy7k#>#iw{V=UzSV zY^VAH>BelA_Qc)g47#=7+h+PVGFu$b?r1oD$?^l|2LFzSY!(c+8}eBC4oDvI{Bd^v z2GLi_^@rkC{Jko@La6U*k@a`Y0tWU7*#oZ`(^M1I{!!c;1N07qr>mdKI;Vst0B{{( A$^ZZW literal 0 HcmV?d00001 diff --git a/images/tag-selector.png b/images/tag-selector.png new file mode 100644 index 0000000000000000000000000000000000000000..c7a9c05c57667cab25f152a1d853c7dc16e4caeb GIT binary patch literal 661 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 literal 0 HcmV?d00001 diff --git a/images/text-align-baseline.png b/images/text-align-baseline.png new file mode 100644 index 0000000000000000000000000000000000000000..c86af6c8f0ed2aaeadde1d89e17b0ec601c3cac8 GIT binary patch literal 1259 zcmVPx(rAb6VR9M61SKVtIRTTft-1*#(>F#DX+s4G$BsG?XR06RoQt(C5Vks62f<=PV zmr`4#zUZIeLlJ#Y1ocVqN%|!E;D6AU;>&_7OO_;?*<^M%&Ti)8-a9@x6J}?UxM@RQ zTsWNBJ9p0copXM3&K=JyrmOkT)(~ym+$FXkaiH>^Y5V zLI~#O<|><;o0k}4_eZfS9wGf7&(6+fY}*E7Y)?4nd)jqfluD(XuInS0U{nC*`T6oYW+0Pah7K+>3+d~d4%L1kJS4!z``*CApVq#3!^-mucfI2xj`Lg3UDZ(`xjm^Pe zaBp{a_ulI2s+r7yEX$B2=>-7lBLh$rGex{!uV(_N1E}|Uy>^m}oO4tv zm6L>!cODr)Hk-Xwtyb0D-Q6MMrfK?=((j{vl+qt9%VNna6^lh(mgSp|3SjE&*|Voj z(@aIyY&Ki2>wXt)^gQp|_4V~uJWGtRs69UoVCu*KG)=p?xVShTu|IO|I1U`gsRQW6 zwznO}S@V5AMaFWud`eN2kB$mJD3wZAB}oz}r9<^^wOW6Bo_8<#faiJNY;SKn$!w{r zDhPt`)h@Mf`5+(qA1E+TU%Mzb%#c^@B3I=Tf6Uh-jz|tac+8g zdb!)}?hz>h!5Bj(lgV<<0bp-Ex{h=t5ePvLAd2Gi0CE8ALjlOLeEt0S^W)8Ca}PiS zf>Mgr)z#EFAg&L(m&@fQJkNWNbN=6`OSWwbQTn1tD5bD0tLD1yE2GSKO6l*0 zVZ17eVsf@X5QH}Y+yTIbI6w$_{mhv&`7=vY514`*v;cF{~Lc#!~@H$!-D5YQY z`~95*=1YYT@>(hbilTg?X7;7f?RK{qV-Lcn6FC!NeIy8lhmrl!@As{IK5y*P zWAe6b-(`&b5(iK+4C6V^^B@QUqDB%m5yn^pz)1i~EMk%Xz(Sz_JjU2xl+tG;X_)7t zD1s33tnd2;09_$8bXrlAFM}YE6Dbw}h`#Ut0H75fF0@dq0OZiF55Nt@33Wx1qz}TZ zM45@MDW&u_fIp)MR3LDk@K>P*z!l;z(GvzBjQVjZ#%eAmNEp3EJV8Pp;{-p<_&-=2 V5w@i?!#)52002ovPDHLkV1kbNTbTd= literal 0 HcmV?d00001 diff --git a/images/text-align-bottom.png b/images/text-align-bottom.png new file mode 100644 index 0000000000000000000000000000000000000000..4dc59be1a7cebf1990fd3277d959f39cb2ef0b74 GIT binary patch literal 1263 zcmVPx(sYygZR9M61SIuu5RS^H}zWwya)^_YT4GE!1N~jv8C{hR@6p0H6Do{m5B_t{o zp>nB8BUCQ%Cvd0`96(6G35gTx3BiH?pqGe?C5)_CNt|`Ew!_-lkN0*tWY=2nCc$Z= zUa&Np_1m{IznS^%%v<39{^L%wIh)OXF+DwfQJ`_bkv)O#xG|hVe=$Qf_guJn`vNBey)zItp`c9*o z5Q5p++0xF=&Q-?PgJJCQr%3-NGcz+O(=@>t>x<`keQnz|3WY*ORn?(OFf4%L+}zw; ztJNBCcoYaqDO6RR0Z=+K0II64E-fvU8;wT7Ii)nQHZ?Uht|-c_GXs#z~@?F~3E3;hsbUJ;fTrSH82L}VjbzOHUr9XuGD5XCchQZ=l%IEW{D2lfq6~N@BOP4O_ zx}J!vUavQ7+x|Y>=s3=ITU%R=XqFgbVS9cWz~rd`D2j4>VPRo3WPj+~vMgAZRRz$A zY;RhYwduNUf{evt@w_BSADY%|aR6RiTwENDk}uSaMx(_Ts{oje3S;bHv)ODO)t)n%Oc}sSL!SpSnanS% ztE<=6*VhN8ogfHM6s7BVo*Uio`-jH^p6A8g-QBcp+XJK8bzN+3Za#1v=h`siI5Rah zwbX96`$P&sFvgHdrP7|~0YHB}ybg6JAqbA+!1Mg`05Sl~69I^#c=O7YE2H&#y$>J+ zK`F(?#zx{C5Y@-s%VaX+j^n)VdEPfCav+^ff23)eXj#^=Bljd7UkfvnN~J_X$gTe> z!R+PBmnUkq+CUnIjWWJxfNUHGNs^v&U3Vtvph*C-EZ?1+oE)iEs|ka;uJ7*e?^{vB zaVOz_S(fEoE|)lvXqr}b9B0jS-8)ACAR{9qS54F8!t{laP)cDKM#Z-6SB9DKl+r&m zO?#E+`S@%B$8m20SOdTYI6w$_{o=)oqw&_u7=vLLJxb}(JTk|ceqC`!83Y9(sgZnt+CV-JI-6FTD}eZ&vM3nKfo+wB_JY*ss> z$7D^@yvG>(H431hY1(s+VBz&}jmlLWvG`*F%gYR<<<7`{bbjD%i<6W&S2 Z{{>te5w?pI`s)Ay002ovPDHLkV1hi#U-JL} literal 0 HcmV?d00001 diff --git a/images/text-align-hcenter.png b/images/text-align-hcenter.png new file mode 100644 index 0000000000000000000000000000000000000000..1a767dac33051199e3203b6f2726ad1ad67f877e GIT binary patch literal 1336 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 bJMTW@o`YMT6+WLI0P>@!tDnm{r-UW|4yS)= literal 0 HcmV?d00001 diff --git a/images/title.png b/images/title.png new file mode 100644 index 0000000000000000000000000000000000000000..81449cc177fd7e7bbeb4ec948f18694498ae83ed GIT binary patch literal 46905 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 literal 0 HcmV?d00001 diff --git a/images/tool-boolean-merge-holes.png b/images/tool-boolean-merge-holes.png new file mode 100644 index 0000000000000000000000000000000000000000..6cd170e88f98b357727cf6d4ac121cb7a8f6b86f GIT binary patch literal 417 zcmV;S0bc%zP)kw!D2NXFt0Pc2tE6`5|c{L z6FKJ_|80M}4QQF9&DP?IT7Y$*wXUMox>0u4Ghq@yE^rX34KH(m6XAhB0<3Me72$ys z6Rmf+S_BEXj?-1jDJ2N2>)YyPs3%euGu=&7vi16btkB*ERtL`5=ZV%`Y_HBcMG(Au zCEG2c2k$nb9U?e5+X+{SklPR51{qEc@fyt-Gfdp%lRvpR$F5EEW`6q#_g*^uZ?3m!hCW5Vz}ITK#RC zGd|=tljQ96z+umx%*lN7W#-F7zzUaA3QO<%{l0)Lul6dA<-xxu3)~inSnT+(eSyxB z{)Vp+^zWUG84)Gt@?hqiIBx;~kUXcC8`Hzi+8{*c{PBc@2zkf?twaCIk$@g{*8(A! z^Zii{t3-d(^lnTKtCd0UBos9Ok_dw*Bvga7$=Cq^A;{Po3|Q)aapoJZ1eg$@hfiSB zGK~z>#zg=w`XoZkq3gRt005BtKl5d{I}Fvd2#8Qhp{#!Jg-uH>dDf#N>$tilNtu_a z9vy+KZi9UZh-0A6S@ts_FE>4U3bOj1=mXUTK1#bfiUEG?tbHKoqr`` zCb2UPjIp-^;B92}Et7Q%K$!Tke?~u{olK9Ofvj#KK=jV2L-O9U%Ipou-VFoMjz)z7 zN1NsGzagsVX~sx7EmIMfAgCzj;@b)ngJBVeyEdTzJO|mk<`Dy7t)@#rmUgJ_jPqC_tP*@~%t4P&Kz2VT z`H(!jGEF)n(;%1ycCbtaW3;r5Fro8R;8~aq@;c9Ix#kta#LIx53_w2mKp4zzqRRQ;>U?1%L@yY+M4rVYr@f?;T$nOn0W*?hn(~!0fRpLGukx ztlEyt&V{okB|1BEV{ggCUOh1@JNiyf&!FG$i-m2u-?@}hsAuQdxa_=%ed412g+*7swbYW@grCr?8gULb`c3<)JhJyZs2#1z* z@6fYL))}pRlCdC8*K2!y(%!$%+Omz#bm8c>J0SgFsjghc-+yfE3AZ}k1|T~x2<5R^ l(GQ=Nw&z>>(_=w%b|B7(3NaTw!%=x^I} zc}ORnq?4ZRw1F9VGU>cmm8w@2h7m&uL8Y5;QkC<`2u;Oh&wK1IZM zfbx$f*gg3ATTj*(&I1;dd=eU< zTYwtK?UMp>y z4UN1yb;d2H>pC)S_3jR2+x6Y{O%i(Jg;x=%t#WW3Q$HBU{ghW9g3f4ir4d39-#bnn zZ01-x67u@2*OnEPI(K#3dy#LPJr45bW40%pRckvU&-)h?0_4r-o$dMT>-F60`#-ej VqK!(wMxy`#002ovPDHLkV1l0_XaoQN literal 0 HcmV?d00001 diff --git a/images/tool-connect-paths.png b/images/tool-connect-paths.png new file mode 100644 index 0000000000000000000000000000000000000000..273e6f45ec8daeb10b666b4c9bed8b565db72871 GIT binary patch literal 1191 zcmV;Y1X%ltP)Px(VM#WU!(Qsz4_ofa8E0_ybr3?g8V#s407rbp=qg z!Cs&b2)%ji1Sfrm2(~)#9C{4^>(L6Cxg{p^kNEA^y8zR`fGK;f?g~KB22TO~KD3KbNygQ z<616qM75C;;kI*)KRc7hK=Z}7!88J4EM<0#gL zQpy`!0%)3c3b-8%1{;Sm`#G(gL%o=c7 zO8HDWUa6tc?{>Qz$esBBqQXH!!X?d|QP z)9E%LMA0w|vpTL}!+(8|NCdCfi>~VcLsH5sFMG(?{|@Q8j@RoY5{Y1!Gn)W3O;dr8 zq9~-(X)2Wpb}n}tmn)SD>2w-JQ2;`=*QOQd^!a?aTrRTNY<2ee-MZTvL)mN=m&=9E z=fgftHvtI0-w(k2{5*E4)hkA9O>7TQ3*flN;{jl4X$fGWjsO$3Cbq}%S^&+54TjtlLTGbUF!#!NSK;C=W`7Y##9}cD zg#xKm3Si*5x1nJerVv71SXgLNRh8A%RV>Tu6hf2@!x(=F^MPnIiV%XEH*d1MysS$p zwdVo=2qEq)FE4*wE|>Rqb#<|_vQmXOCWJ^ChVf{toC_ho1U`#KqjYq1Fg!fW%*@Oh zaMmykYg;WDa6K3d5|783nwmn__391zv?Y^L<~2>*)RH-!PGYeb?d|Q1jEs=UWB|6; zl5K#v=61UqRaM37^^#7f$!4?6&(Bw3{@zFp4LBSQT3T8N1OkM^VG4x;$z+mZvA71D zuVubvTWGL~hL%jK$dJ`D^=DR=iUsR6RBr`h^C|39{hzX02|(Sw@94qyNP002ovPDHLk FV1jVdI9>n% literal 0 HcmV?d00001 diff --git a/images/tool-convert-to-curves.png b/images/tool-convert-to-curves.png new file mode 100644 index 0000000000000000000000000000000000000000..bfda2b77222f5d45b6c7352f9754987a8ba0b663 GIT binary patch literal 1557 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 QtN;K207*qoM6N<$g47g$^8f$< literal 0 HcmV?d00001 diff --git a/images/tool-cutout-physical.png b/images/tool-cutout-physical.png new file mode 100644 index 0000000000000000000000000000000000000000..adc8029197cb89a37ae87ee0d014caa2a49d1bda GIT binary patch literal 1928 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 ilD}&Cy%mD{KG&03B&m zSad^gZEa<4bN~PV002XBWnpw>WFU8GbZ8()Nlj2>E@cM*00`$vL_t(o!_AjjY*oh@ z$N%5VoH^&(zTQ`C2W(>-2a|@y1aN|5JHbIpB|;!HNt3iy)vB$UO64JMZ6EsFMV0zg zsjZ@@g_sgZLei1~Wk~`qiwyzWgs^zwdcnTFKKGt|rVl1o5QHeDRXfsoIhy(AH{bXF z{$~#GKOXd-2(oqSmX(0s3Q}!KV+|4AAm9*zy+t~;W5?@%bN*`pTb|k62GCZmbrGOH zP)bcQqFlyU1AuyBI7FP@-0|A3!8@%N_jK}YPsg;@-_p=I5u($c`0gZMQsrRKJUoR{uXe}%%+?kUb@9OT}eORlh?<(j504qN) z#61D{t~;x>wj3w3Jtvm)>ci{Sf4`%>v!to1slB~({p#-SLz;joK=IFu@o$%4&BJR; z(!TR-42ZX`Yqi#{ZLO%PtVV8bF5Y^3@1vX>mjIm5S_edgZCf6u9oCtf~TI| z6fY|)|6WmX;jV^;#-F_K+>6yYIoYsn8;L{$=g*(V@bEC2moCMoO;0T_4E{=_qWiSc z?iZHe`5*oMxiD0lLocX=)|?m-7Xsi?`ny8=Wie5JS~uX<74B3K1Q7@y8ycr*d!kD#E)L1kGSU0v;1{@|+lg^uIk+SRKF z!w`<+Ad|^}a}FsbZrr$m{QP`$ZPnO^d3fmFJM!!VG^WRS@?C@n2T zO-&7EW|GCBuNNQs$H9;92oQ!U#)N=rN<@K&i7Wrang{Ce)hC}sS;YbbUI5?oA*Bh^ zG||&@0tXHrz{uzbYHRD@c^>-udg1#XR;_4(Wm)h%7h{Prbag!e(=s~-2K!$I@bVqI zKr0QXxh^4M@B;;Im^wEvSI4XvlF1~dr>Eijb6V;<+lz}I52B!;7|WU;Ktn?#wASeD zJph26c8d|Hl7ec~_*W+a0C4c|^zq&+p zQ*Z%1&x7xINTpIBFjOw6L{(K4>T2syT2czvbwNbnT!0uM3`0y#PNJ-=9PRBLrCjhA zT3T94@8Sa*&;)LlV>Ds=0|OT_wr#_Z5<+lzo(IqOQBqP0DGgk@bP=Q1M{xFhAFd~^ zqq_P&n3f45f)E0nbBvCTqPVCS53OEXAPlxWE62M3vpaGCXnb(v&zhQQP*zcj8%YOO z2Crax>iWAeHh$RgqBXU(waCuOMsj8bLI@O>lt4-o;}hc;OC*p?&Y-%g8tsp^qqw*P zfQC|PzEv$N3o*-r=Xz2Y#*Huv21iG(C+9`@X_`R*5kM3{#wv~^5+5Eue8hZd?L%wx z;|t=To9$P*pbDlmVMu||(NUOEqM^PKOP4moaU8g=3&t22dMtCt+A|ZGoG6Z+qRKRPNT4}5SuqW zJzqJ;bv~m34j}}z)=7VY| zyXV^3b7xUrUXCyf;dvfh*M;l4^O<9efpdP#GnWO1!ong{R8$~}B1EAAfr(puz%T?{ zH^9tH8lLNd7>6Oq0D#@Q_a5!q*l{9}Sg|mbO39cNL!=@&jstPiegzlv073{vVFV!r zq?E|d&xh6;!^1=P@WT%C>kNXH&DU0^(N(-#cR8X2rzVKG*eowbn(9 zDBwa~+xgpXOn-Lb)b!NhbUOWBZ(na`MMVY0<8e5SJD+MH=E`7M7Oo8q;r$Pe;lhQF zCdS9ce?2iixo=`Daq)Q1N&8D*%R4rAvIBqlyIQ^aD`iXWU$&*bzTuZ&+xDzcRauE^ zSBDVK%|mHvF*xT)CX;hEeevS;bLY<;>+3yrVtOXkeY&Uj@|XHAXj#`H^0MPnTGEQR zl2U8oI~g}nVreWZ`;XgyynSKI$`;sm8d6Gd#*wm9=)Z8@*|GD__9vG=+3SSPYcbAx zcy^3)l8k%=Nqg2egb0otI-+j_Xj}gX8A4jZ6eh)(CA79!1WSWV&9qcnk&1K)art;d zeZwv$NRy<{LP6?C5MVnLIjc&%P0a{uR!d!#KI5$S07m0WXrw(>^?Z z)^mnNhTOry!Dzl8XKfpKxp^dD2x4TAB7;a7T0;^+G9sw~rImktWawJ;yYKAVaOTXZ zoG6TfkWFU8GbZ8()Nlj2>E@cM*00S;bL_t(o!|j*PYZOTo z$3I=&Rh{YSand!D8I5CpY_b|rgoqN>-?)fo(G9LEYQz=e?=bl5pdLKzKd|dTybFRs zRMZuAL4${d74~HCpx|L8{$xds5M(7$vIi^Dj+4&Jp>1`~>o~f&oB{^?-;-7Qjs4+e+1IVB3ON%!@^gLKMJq;3m)yG*$wT zkg}^Mms54Fd!Q14&A@q}2iQ`9ey&BSnmQ?&Dnt|Dmjj@HH1HJo8)z$6z1DGdcWa#m z*p*6Uv~6!L2jDy4_fY!|Fs~edxDcCG`@R5J@B1n(#GY~hegrOs+C4yL8Tu`4RaJpw zS)(v~tyHZU)o}q5fDOD3`R)R<0jm`C8Md9@uXQHu+ZzN^YlY}41>gtZauNSuz~WK> zVvf`Pjpu#hTa!rG3CG!53cxzxS`mMbSsCNm!gkNAE*vUpS+u%t2B?n$$O41Fe?>Ze z1WW^*DD|(TJhV$|T`bnEb+$pN{ZRm$%-SEzZUC#Is%Kn?MRQ%ZXmCk9ZpEP^3Sbq` z8zFE3*f>_uft4E)2|ZTa0+xAR8kkcIpvjcocM$+D0nc2YS-nz6b_Btcs43c~b-GE) zL&X3(&4)IgT{9nQp}Bz&bLymwOrBR&g)hX4VgQSPTO|Nop>OL3!4Yw z!(o6<;GDU)fiB<=;NgdDo$Ek*sE>=LTz{;dwL&zeY#V@ohK5+z-~VsNoEyR4Ig)m~H$ERMP8;}L%`DZi#Z6_{e`H#p9prgVo_$kGNWZy(qC)nH4@$jNMW(EYIKvBGRTzX2zJc=REMlV-Gff$8Rr z`tm{Wx&wWuQntO_ sx2$^r$q5`flV*BEh52&w$79m|2YOY8T%DuW#sB~S07*qoM6N<$g0;)D#Q*>R literal 0 HcmV?d00001 diff --git a/images/tool-measure.png b/images/tool-measure.png new file mode 100644 index 0000000000000000000000000000000000000000..1b500cbcf915bedce1effa95b71ecd30e5af9501 GIT binary patch literal 1574 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 Wy*OQewa(fA0000cV0Lz zyfG4uSL!k%FQyTZneL*TKZF4Xl`oc=x!_3ChfZC zJ~A2SqI(q2tzH@w_c@{QQCAep3n9xV{_~uPPvQ@uDYx^gvyL5=#az7|qQ^VQNMHgn z99nt{xdNrZM75=qR+|auPBVAzhWYgB5Q*R*Z)pGIapmNi5VEzzFCa)X=PU6c>Kh*BNQ;F|myd3@2Zs>id4nIbLR@j=f-HksA!1gD z>{U+je9F)HcopX^hZqVraiqn{w>UZ9cbghTf<4M83tA2!3y@tM@mh4{Hr_t6oijgr z@&9&(6Pg5vRb%;5jO8z3R*1Z=8>CK*^1VAihQpkCx}LYD5_ANk>{0%);-RAD`Q90` zFol6r&N^Iu)~jpn9Cc2pK~;l==V`8Y4@MhnX4h40!I_5kpTZWOzGK7Mvo7Sr6+$aQJk z;?D;FhkWr<*Q}8k8jkL^a`koyF&v^z>n})rJ%~1~A2A%_>g^CmcUy^}p=;KdeI^Ug zEtODFTTit~OOJOFyL=p5(QLuu`5}z@O67Tr*EL5}2S> znBKH_K8RLfnvuW+0L?W<{3(4dKm-*HRs#TYkx3eb=%%__9tameqY%v&t_G`t2&!BF z2_akCGwBqStMdKdtQtl3DzO+fNGNjwR`;bMG7k(OnbY$!xc~xl1ZEOTd7V-}Fo3%$ z6*9RZ+c^cKTmS_afcDKmtgebZQVG?TQUE-|GgK*}xd3~GY3}(37@3UIYBMpIF2kEtZyI8? zxHqY0FkMEg&BVxLoO`|j_AaIP62L+A3_22AbdTcPIp0z{;#JH4dqaq|+*C)r3RSTg z=T0*h-J|G8a8Nz70>HIcF!l>$cy9G_=Wdwe`|24?m+@K5S`frq;-AN?45rICzOSA; zcf)vY^|D_WThUP$4M{ujF2Kt(k1$u>$VV?V(dqILbbo_gm~SkFwBzOCJ}E`%u4g&% zq>Z<}yoEB@%jd>yJASX`{m%9rKhUQ2@j+0}hnF=x(_-NU$LMl<@ZHzZru8rOhXeU+ zx;Lq&BVNT|x{SwmHS$D58K*Dx5es^GP3z0quK;*+e+xh@P*b6pLzWR48S~;zT6q1C zoh>D$bO+^JiEQEKoSOS-IZ9cYt@0#dM#f($H7?P}*+d2BMLV%AwY=zT;nXs5KDx7wQT2`h0000Eaj?aro`DK)z-L0T=eQw%nZa z8krX!7u?e?cQEHsY{#YhQU{ZAyX4QzHz<^U;U{+Dl$TD~7E9k?%f82tZU=ki&g(V2 zSMH%1c)fJPvBw+>G`g4$C@sCShX1gDj@aXFwutMZ3>Uud{asS+@}wgpS-{EQSOn_< zHvXBvI96e{p^aSVw#{C1i*-vI>JzOdL1*n2KC^ z{ma;u4s#@}FVdQ&MBb@0QtL4;Q#;t literal 0 HcmV?d00001 diff --git a/images/tool-touch-cursor.png b/images/tool-touch-cursor.png new file mode 100644 index 0000000000000000000000000000000000000000..3c0c418e5cd4d44aa15c754bc884aad6c8435c6a GIT binary patch literal 1167 zcmV;A1aSL_P)ne~Dvk6q;#k?SM?ig%FSok%U0;+O@$ho*tiHL5;Cro z5VcTnkr>1pvJmRRE<~=YmUbEv$tE$-b|K`MZqh*~qLadO^3!zY-E&>co%oo{@6(Dt z7>1d5?>XQ3x!?T`Lk*8*S=RxasIY9EbAGB?o2&|_9{}iAKmF=ERbqMJ`%9ej3!VX3 zmUSM$5CE#iXc4d)fEmvDcufG5p-}*aa$eR*1@IaG2f%bO;ChjblWL=`Hh#uA{{%HY zwrwwjLLmddYbub|P$=|*ZQHSu8Bmdr0oVm_gL8fk|G;Be)>i|Fp3=lp=9o}Qjp_V)HZW{kZ(H#c|RV*+e}2+rlzJ=A;h)6QH^QkV@UbjFG0Vn+lwBt<>h5LI5?Q;=;&x| zZ*Tw3i+5#vM)~S5?15Cdqo(URlAD{Dn3zCYTiYA0k;pq9L5#bJ%uw{|FT-xRW?>8r z64^`^BO@b+(&_ZnV?N)_#l^*29?RjkEbF@F;`U3G07wZ4a?p7AFa`z&o^EJpxY^y^ z{kR9`d0!_qSNbnh+C@Yl0y0h(EiEnR>+6H2X?8FetoP6hsbV}(1pomeiS4Z|SiQYC z+u#3UAQ1SX>Bx~oUg}^}eQh!gQWAu4z*r7m!^3E7Y@Bay zZf<=<8DJm~grNNl2$B2j?(X8)(W8jIAN8Gl>Eui}91he9z@Mkak_$Brk|anH1d*!@ z1d@b@nGB8}JB~ANoq0772z=Dl)#a<8vix}f>n=JjUjdRJN2urpNaRk1AOR@>pU*%f z5JYVWQ$T4B=1TZPV7=zDeU}NJqOkKW=wL5pgwyiU0z!Hrb>l9 zW`_}E}>{UCSNF?Uh*4BR5+k3FGx@!Mi!>P+Fu8a8~ zSqa7RJ%A|ZJmr#P&*-}T^3KjqA|8(?T6Qk5Z97&(&)3jN5&vp3=Xo2yjp{$HjMoWQ8Y47Fs_P(5#-{T+cy=VU(0=Vr23Vn)*n=t&##vteH1lGz-Hp)1QD^r zHWv@PAaR6q8t{8Dyt;O)o|-Ozlxjp>d*mDC(WOrnj*Be=;v5?9`Hhx`BKt8w4(JRZ4cn-0$iU~jub!Zz&-7OsDwq4}#34f;`k2mr+g z^(FyaFdk~I68J-4#t^FtyX>QgQ_tw&zx_*nhcccw`e^GWeQ{aX4OS|6}Qz#}-6Ce5dV?@56Wl`02MnQvgJ2cYp?{ra?1kFp8f! zfpJd*LH=2G*~jqA8tpywT>rcX%U5jFYub0oPS~F;%YR#R5l1QaW^rj^@#nODKSnGzZxMj0m z&ibsmeD=-P&K~_;+Nt^?c4YPc7O02sWde6Rwk|Pz;lWF1kAJK8P{+mhj%KHHeH51Wrp|^FbzWS*x zx-%Z5F)B-KQGQMAdU3LcmCKw@9=7=S%ni0U{R(0)WecVmQzx-}zM=F~R5vtmN znsJJgux-0$TOQIK8f2dsIJqxng&IJ@s7d04K;a{^0GP0rE&77-yw9FF`r6g_KMff}Ak zUA^Logu$vHGd7F}@5~B7Cd?8M`_o$(=di&4W;JWPYzd#5mEBqe_XMLh-EI|W2*AN>@ z_?FKvuhS}QL?R-SP&t>Pd9f3XB8fyk8x_#In{a;i1P7Ni)zy|)g@VD;Bi6`B=IPHo z%#Q)1swSuD6o^|z;-y?Df=MLu!nx6WeH(3+)gd<&F{g$GV)Nti%z+)d*~P@igiLPK zsH%#p=5}rui4|WL{#FQ*GXt1szsuUDrPd>L_2E=1?nXz4&B^clf~Vd(PAa!%(gRgB zIe;4pPiHQGxqT7#laI2lv4PcqSg@y(s=yL1V+P&hYN)u1o}rFLB^3fDwn z^(rdv`8YLqHF5hbbu9FK#$qvs_8#QKuU_Fwv1q|{kUxUS9Jmq0HHlbNgD5-j;W zPyjO(Kz><~cy7!`pjdR;08>Df5}#0>;RF8*=LG0fU`oJY00000NkvXXu0mjfTzv$L literal 0 HcmV?d00001 diff --git a/images/view-show-all.png b/images/view-show-all.png new file mode 100644 index 0000000000000000000000000000000000000000..00e6b83cc005014c81fa510adbe3c9b7d8379adb GIT binary patch literal 1256 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 literal 0 HcmV?d00001 diff --git a/images/window-new.png b/images/window-new.png new file mode 100644 index 0000000000000000000000000000000000000000..e091702e33f9ff7debfba272eb848dbd246acf84 GIT binary patch literal 671 zcmV;Q0$}}#P)%-6o#L3=gzE*u)}6qBJ!a`AQ&5ovCzUFVPYdzR>Z=D zA46hCVPZ@yXzi@j*3yJXC`7WFk#(1KXLp%2D7{&Nk&>)AX#kpOaZc9{OZv$9aS$Uo$$znHwa?v*m`69XD65&7%5v9=xC|8Dv zck)`Q%)VG!diux$)a&)d<>h4&>5{*GhV&h{58x`GHP9wV1SX5hth{`+`4HF#P*o8T z?md2nQ|;LQ=FA4S=RdJ9x6ODV#Ix5BlOf$JlGNUF`I1jADvK(iJ^JGKXtrbXj9+JV zGG%(K!9<}+aN!2lzlF#UY4amSnxNZU3>9hvxi)~QvEhyZ!c2v+k$_xQur`b56|nw1 z#!iD)ux=PM#(F+9H24Fc(+LD#Ks1yk2tqs)BT`1)CazgRh%xdLBtz;9cuDm)fU5H3 z!JW?B50o0j?Lk@v*#M(J25gbQY=JCLt?t4g-`fDR3kPt&*;Rxuh?K#tBl;Ey03T%@ zWQMI`j0k&eBj_4{OaT>CKum;c45T1~AQNEjQu^@*fVKpjbKL;|;5smZFo{SEI8;Va znZuI;&~pHQe5(|Y{YAl;!=!t222Rvr@1s6FPT(&n=Kv=G9DmR+ot*^E1VFz=aCQ?o zb%65`{Ffgh(|5;XvH&8Y&N+#qs4u3@IYdN(yafi*G+kR=UA^D6o6$d{sw7GB8i)=Y z2Z0eF3xt4AZ^qMXtqHILd_BHp(<+bN+?-vjQd+-AzX0iyL}k`Ue{BE&002ovPDHLk FV1isSCa3@a literal 0 HcmV?d00001 diff --git a/oo-mapper-version.pri b/oo-mapper-version.pri new file mode 100644 index 0000000..4925ece --- /dev/null +++ b/oo-mapper-version.pri @@ -0,0 +1,4 @@ +# Generated in CMakeLists.txt, do not edit here. +Mapper_VERSION_MAJOR = 0 +Mapper_VERSION_MINOR = 6 +Mapper_VERSION_PATCH = 7 diff --git a/oo-mapper.pro b/oo-mapper.pro new file mode 100644 index 0000000..207348d --- /dev/null +++ b/oo-mapper.pro @@ -0,0 +1,155 @@ +# +# Copyright 2012, 2013, 2014 Thomas Schöps +# Copyright 2012-2016 Kai Pastor +# +# This file is part of OpenOrienteering. +# +# OpenOrienteering is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# OpenOrienteering is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with OpenOrienteering. If not, see . + +TEMPLATE = subdirs +CONFIG += c++11 +CONFIG -= debug_and_release + +include("oo-mapper-version.pri") + + +# Prerequisites configuration +# +# addPrerequisite(target, subdir) Adds the given subdir as +# prerequisite to the target. +# addPrerequisite(target, prerequisite, subdir) Adds the given prerequisite +# name and subdir to the target. +# +# Prerequisite directories must create a .pri file in their output dir. + +PREREQUISITES_PRI = \ + "$$LITERAL_HASH Generated by $$_PRO_FILE_" + +defineTest(addPrerequisite) { + !contains(SUBDIRS, $$2) { + target = $$2 + subdir = $$3 + isEmpty(subdir): subdir = $$2 + + SUBDIRS += $$target + export(SUBDIRS) + + $${target}.subdir = $$subdir + export($${target}.subdir) + + PREREQUISITES_PRI += "include($$OUT_PWD/$${subdir}/$${target}.pri)" + export(PREREQUISITES_PRI) + + empty = + write_file($$OUT_PWD/$${subdir}/$${target}.pri, empty, append) + + $${1}.depends += $$target + export($${1}.depends) + + return(true) + } +} + +addPrerequisite(src, libocd, src/libocad) +addPrerequisite(src, clipper, 3rd-party/clipper) +addPrerequisite(src, qbezier, 3rd-party/qbezier) +!android:addPrerequisite(src, qtsingleapplication, 3rd-party/qtsingleapplication) +!linux:addPrerequisite(src, proj, 3rd-party/proj) +android:addPrerequisite(src, proj, 3rd-party/proj) +CONFIG(gdal) { + addPrerequisite(src, gdal, 3rd-party/gdal) + !linux:gdal.depends += proj + android:gdal.depends += proj +} +addPrerequisite(src, licensing, doc/licensing) +!android:addPrerequisite(src, printsupport, src/printsupport) +# Doxygen: Separate test and prerequisite, or Qt Creator gets confused. +DOXYGEN = $$system(doxygen -v 2>/dev/null) +isEmpty(DOXYGEN): addPrerequisite(manual, doxygen, 3rd-party/doxygen) + +write_file($$OUT_PWD/prerequisites.pri, PREREQUISITES_PRI) + + +# CMake toolchain file for prerequisites compilation + +CMAKE_TOOLCHAIN = \ + "$$LITERAL_HASH Generated by $$_PRO_FILE_" \ + "set(Mapper_VERSION_MAJOR $$Mapper_VERSION_MAJOR)" \ + "set(Mapper_VERSION_MINOR $$Mapper_VERSION_MINOR)" \ + "set(Mapper_VERSION_PATCH $$Mapper_VERSION_PATCH)" \ + "set(Mapper_VERSION_DISPLAY \"$${Mapper_VERSION_MAJOR}.$${Mapper_VERSION_MINOR}.$${Mapper_VERSION_PATCH}\")" \ + "find_program(CMAKE_C_COMPILER \"$$QMAKE_CC\")" \ + "find_program(CMAKE_CXX_COMPILER \"$$QMAKE_CXX\")" \ + "include_directories($$QMAKE_INCDIR)" \ + "link_directories($$QMAKE_LIBDIR)" \ + "set(CMAKE_USER_MAKE_RULES_OVERRIDE \"$$OUT_PWD/override.cmake\")" + +CMAKE_OVERRIDE = \ + "$$LITERAL_HASH Generated by $$_PRO_FILE_" \ + "set(CMAKE_C_FLAGS_INIT \"$$QMAKE_CFLAGS\")" \ + "set(CMAKE_CXX_FLAGS_INIT \"$$QMAKE_CXXFLAGS\")" \ + "set(CMAKE_EXE_LINKER_FLAGS_INIT \"$$QMAKE_LFLAGS $$QMAKE_LFLAGS_APP\")" + +CONFIG(debug, release|debug) { + CMAKE_TOOLCHAIN += \ + "set(Mapper_VERSION_DISPLAY \"Debug \${Mapper_VERSION_DISPLAY}\")" + CMAKE_OVERRIDE += \ + "set(CMAKE_C_FLAGS_INIT \"\${CMAKE_C_FLAGS_INIT} $$QMAKE_CFLAGS_DEBUG $$QMAKE_CFLAGS_WARN_ON\")" \ + "set(CMAKE_CXX_FLAGS_INIT \"\${CMAKE_CXX_FLAGS_INIT} $$QMAKE_CXXFLAGS_DEBUG $$QMAKE_CFLAGS_WARN_ON\")" +} else:CONFIG(release) { + CMAKE_OVERRIDE += \ + "set(CMAKE_C_FLAGS_INIT \"\${CMAKE_C_FLAGS_INIT} $$QMAKE_CFLAGS_RELEASE $$QMAKE_CFLAGS_WARN_OFF\")" \ + "set(CMAKE_CXX_FLAGS_INIT \"\${CMAKE_CXX_FLAGS_INIT} $$QMAKE_CXXFLAGS_RELEASE $$QMAKE_CFLAGS_WARN_OFF\")" +} + +win32:gcc: CMAKE_TOOLCHAIN += \ + "set(CMAKE_SYSTEM_NAME Windows)" \ + "execute_process(COMMAND \"$$QMAKE_CC\" -dumpmachine OUTPUT_VARIABLE GNU_SYSTEM_NAME OUTPUT_STRIP_TRAILING_WHITESPACE)" \ + "string(REGEX REPLACE \"gcc$\" windres CMAKE_RC_COMPILER \"$$QMAKE_CC\")" \ + "set(MINGW 1)" + +osx: CMAKE_OVERRIDE += \ + "set(CMAKE_C_FLAGS_INIT \"\${CMAKE_C_FLAGS_INIT} -mmacosx-version-min=$$QMAKE_MACOSX_DEPLOYMENT_TARGET\")" \ + "set(CMAKE_CXX_FLAGS_INIT \"\${CMAKE_CXX_FLAGS_INIT} -mmacosx-version-min=$$QMAKE_MACOSX_DEPLOYMENT_TARGET -std=c++11 -stdlib=libc++\")" \ + "set(CMAKE_EXE_LINKER_FLAGS_INIT \"\${CMAKE_EXE_LINKER_FLAGS_INIT} -mmacosx-version-min=$$QMAKE_MACOSX_DEPLOYMENT_TARGET\")" + + +android: CMAKE_TOOLCHAIN += \ + "set(ANDROID 1)" \ + "set(CMAKE_SYSTEM_NAME Linux)" \ + "set(GNU_SYSTEM_NAME $$NDK_TOOLS_PREFIX)" \ + "set(NDK_TOOLCHAIN_PATH $$NDK_TOOLCHAIN_PATH)" + +contains(SUBDIRS, doxygen): CMAKE_TOOLCHAIN += \ + "list(APPEND CMAKE_PREFIX_PATH \"$$OUT_PWD/3rd-party/doxygen/doxygen/doxygen-project-prefix\")" + +write_file($$OUT_PWD/toolchain.cmake, CMAKE_TOOLCHAIN) +write_file($$OUT_PWD/override.cmake, CMAKE_OVERRIDE) + + +# Mapper build + +SUBDIRS += \ + manual \ + examples \ + symbol_sets \ + translations \ + src + +manual.subdir = doc/manual +symbol_sets.subdir = "symbol sets" + +OTHER_FILES += \ + COPYING \ + INSTALL diff --git a/packaging/CMakeLists.txt b/packaging/CMakeLists.txt new file mode 100644 index 0000000..6e2a6e9 --- /dev/null +++ b/packaging/CMakeLists.txt @@ -0,0 +1,529 @@ +# +# Copyright 2012-2015 Kai Pastor +# +# This file is part of OpenOrienteering. +# +# OpenOrienteering is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# OpenOrienteering is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with OpenOrienteering. If not, see . + +message(STATUS "Configuring ${PROJECT_NAME} packaging") + +option(Mapper_PACKAGE_QT_ALL_TRANSLATIONS "Add all Qt translation to the packages" TRUE) + +macro(deploy_qt_translations basename) + find_package(Qt5LinguistTools REQUIRED QUIET) + get_target_property(LCONVERT_EXECUTABLE Qt5::lconvert IMPORTED_LOCATION) + set(install_translations_code ) + if(Mapper_PACKAGE_QT_ALL_TRANSLATIONS) + file(GLOB basename_files RELATIVE "${QT_TRANSLATIONS_DIR}" "${QT_TRANSLATIONS_DIR}/${basename}_??.qm") + else() + unset(basename_files) + foreach(_mapper_trans ${Mapper_TRANS}) + get_filename_component(basename_file ${_mapper_trans} NAME_WE) + string(REPLACE OpenOrienteering_ ${basename} basename_file ${basename_file}) + if(EXISTS "${QT_TRANSLATIONS_DIR}/${basename_file}") + list(append ${basename_file}) + endif() + endforeach() + endif() + foreach(basename_file ${basename_files}) + set(input_files "\"${QT_TRANSLATIONS_DIR}/${basename_file}\"") + foreach(arg ${ARGN}) + string(REPLACE ${basename} ${arg} extra_file ${basename_file}) + if(EXISTS "${QT_TRANSLATIONS_DIR}/${extra_file}") + set(input_files "\"${QT_TRANSLATIONS_DIR}/${extra_file}\" ${input_files}") + endif() + endforeach() + list(APPEND install_translations_code + "execute_process(COMMAND \"${LCONVERT_EXECUTABLE}\" -o \"${CMAKE_CURRENT_BINARY_DIR}/${basename_file}\" ${input_files})" + "file(INSTALL DESTINATION \"\${CMAKE_INSTALL_PREFIX}/${MAPPER_DATA_DESTINATION}/translations\" TYPE FILE FILES \"${CMAKE_CURRENT_BINARY_DIR}/${basename_file}\")" + ) + endforeach() + string(REPLACE ";" "\n " install_translations_code "${install_translations_code}") + install(CODE "${install_translations_code}") +endmacro(deploy_qt_translations) + + + +if(APPLE) + # Set some Qt4 variables to reasonable values for Qt5, too. + # (needed for DeployQt5.cmake) + find_package(Qt5Core REQUIRED QUIET) + if(NOT QT_LIBRARY_DIR) + get_target_property(_qt5core_lib Qt5::Core IMPORTED_LOCATION_RELEASE) + get_filename_component(QT_LIBRARY_DIR ${_qt5core_lib} PATH) + endif() + if(NOT QT_BINARY_DIR) + get_target_property(_qt5moc_bin Qt5::moc IMPORTED_LOCATION) + get_filename_component(QT_BINARY_DIR ${_qt5moc_bin} PATH) + endif() +endif() + +if(NOT Mapper_BUILD_PACKAGE) + # Don't configure and include CPack + +elseif(NOT EXISTS "${CMAKE_ROOT}/Modules/CPack.cmake") + message(WARNING "CPack not found, target 'package' will not be available") + +else() + # cf. http://www.cmake.org/cmake/help/cmake-2-8-docs.html#module:CPack + # cf. http://www.cmake.org/Wiki/CMake:CPackPackageGenerators + set(CPACK_PACKAGE_NAME "OpenOrienteering ${CMAKE_PROJECT_NAME}") + set(CPACK_PACKAGE_VENDOR "OpenOrienteering") + set(CPACK_PACKAGE_VERSION_MAJOR ${Mapper_VERSION_MAJOR}) + set(CPACK_PACKAGE_VERSION_MINOR ${Mapper_VERSION_MINOR}) + set(CPACK_PACKAGE_VERSION_PATCH ${Mapper_VERSION_PATCH}) + set(CPACK_PACKAGE_DESCRIPTION_SUMMARY + "Map drawing program from OpenOrienteering") + if(NOT CMAKE_SIZEOF_VOID_P AND MINGW) + set(_env_lang $ENV{LANG}) + set(ENV{LANG} C) + execute_process( + COMMAND ${CMAKE_C_COMPILER} -dumpmachine + OUTPUT_VARIABLE HOST_TRIPLET + ) + set(ENV{LANG} ${_env_lang}) + if(${HOST_TRIPLET} MATCHES ^i686) + set(CMAKE_SIZEOF_VOID_P 4) + elseif(${HOST_TRIPLET} MATCHES ^x86_64) + set(CMAKE_SIZEOF_VOID_P 8) + endif() + endif() + if(CMAKE_SIZEOF_VOID_P EQUAL 4) + set(_system_name "${CMAKE_SYSTEM_NAME}-x86") + elseif(CMAKE_SIZEOF_VOID_P EQUAL 8) + set(_system_name "${CMAKE_SYSTEM_NAME}-x64") + else() + set(_system_name "${CMAKE_SYSTEM_NAME}-unknown") + endif() + set(CPACK_PACKAGE_FILE_NAME + "openorienteering-mapper_${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}.${CPACK_PACKAGE_VERSION_PATCH}-${_system_name}") + set(CPACK_RESOURCE_FILE_LICENSE "${PROJECT_SOURCE_DIR}/COPYING") + set(CPACK_STRIP_FILES "TRUE") + + set(CPACK_SOURCE_PACKAGE_FILE_NAME + "openorienteering-mapper_${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}.${CPACK_PACKAGE_VERSION_PATCH}-src") + set(CPACK_SOURCE_IGNORE_FILES + "${PROJECT_BINARY_DIR}" + "/[.]git/" + "/3rd-party/clipper/download/" + "/3rd-party/proj/download/" + "/3rd-party/qt5/download/" + ${CPACK_SOURCE_IGNORE_FILES}) + + set(MAPPER_MACOS_SUBDIR "") + + if(WIN32) + # Packaging as ZIP archive + set(CPACK_GENERATOR_DEFAULT "ZIP") + #set(CPACK_INCLUDE_TOPLEVEL_DIRECTORY 0) + set(CPACK_PACKAGE_INSTALL_DIRECTORY "${CPACK_PACKAGE_NAME} ${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}.${CPACK_PACKAGE_VERSION_PATCH}") + set(CPACK_PACKAGE_EXECUTABLES "Mapper" "${CPACK_PACKAGE_NAME} ${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}.${CPACK_PACKAGE_VERSION_PATCH}") + + find_program(MAKENSIS_EXECUTABLE "makensis") + if(MAKENSIS_EXECUTABLE) + list(APPEND CPACK_GENERATOR_DEFAULT "NSIS") + # The title displayed at the top of the installer + set(CPACK_NSIS_PACKAGE_NAME "${CPACK_PACKAGE_NAME}") + # The display name string that appears in the Windows Add/Remove Program control panel + set(CPACK_NSIS_DISPLAY_NAME "${CPACK_PACKAGE_NAME} ${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}.${CPACK_PACKAGE_VERSION_PATCH}") + # NSIS start menu links will point to executables in this directory + set(CPACK_NSIS_EXECUTABLES_DIRECTORY ".") + # A path to the executable that contains the uninstaller icon. + set(CPACK_NSIS_INSTALLED_ICON_NAME Mapper.exe) + # URL to a web site providing more information about your application. + set(CPACK_NSIS_URL_INFO_ABOUT "http://openorienteering.org/apps/mapper/") + # Extra NSIS include + configure_file(windows/custom.nsi.in windows/custom.nsi @ONLY) + set(CPACK_NSIS_DEFINES "!include \\\"${CMAKE_CURRENT_BINARY_DIR}\\\\windows\\\\custom.nsi\\\"") + # Extra NSIS commands that will be added to the install/uninstall sections. + set(CPACK_NSIS_EXTRA_INSTALL_COMMANDS "Call installAssociations") + set(CPACK_NSIS_EXTRA_UNINSTALL_COMMANDS "Call un.installAssociations") + # 64 bit build + if(CMAKE_SIZEOF_VOID_P EQUAL 8) + set(CPACK_NSIS_INSTALL_ROOT "$PROGRAMFILES64") + set(CPACK_NSIS_DISPLAY_NAME "${CPACK_NSIS_DISPLAY_NAME} x64") + endif() + endif(MAKENSIS_EXECUTABLE) + + elseif(APPLE) + set(MAPPER_MACOS_SUBDIR "/Mapper.app/Contents/MacOS") + set(CPACK_GENERATOR_DEFAULT "DragNDrop") + set(CPACK_PACKAGE_EXECUTABLES "Mapper" "OpenOrienteering Mapper ${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}.${CPACK_PACKAGE_VERSION_PATCH}") + set(CPACK_PACKAGE_ICON "${PROJECT_SOURCE_DIR}/images/mapper-icon/Mapper.icns") + set_target_properties(Mapper PROPERTIES + MACOSX_BUNDLE_INFO_STRING "${CPACK_PACKAGE_DESCRIPTION_SUMMARY}" + MACOSX_BUNDLE_ICON_FILE "Mapper.icns" + MACOSX_BUNDLE_GUI_IDENTIFIER "org.openorienteering.${CMAKE_PROJECT_NAME}" + MACOSX_BUNDLE_LONG_VERSION_STRING "${CMAKE_PROJECT_NAME} ${Mapper_VERSION_DISPLAY} for OS X" + MACOSX_BUNDLE_BUNDLE_NAME "${CMAKE_PROJECT_NAME}" # less than 16 characters long + MACOSX_BUNDLE_SHORT_VERSION_STRING "${Mapper_VERSION_MAJOR}.${Mapper_VERSION_MINOR}.${Mapper_VERSION_PATCH}" + MACOSX_BUNDLE_BUNDLE_VERSION "${Mapper_VERSION_MAJOR}.${Mapper_VERSION_MINOR}.${Mapper_VERSION_PATCH}" + MACOSX_BUNDLE_COPYRIGHT "${Mapper_COPYRIGHT}" + ) + install(FILES "${CPACK_PACKAGE_ICON}" + DESTINATION "${MAPPER_DATA_DESTINATION}") + + elseif(UNIX AND EXISTS /usr/bin/dpkg AND EXISTS /usr/bin/lsb_release) + # Packaging on Debian or similar + set(CPACK_GENERATOR_DEFAULT "DEB") + set(CPACK_DEBIAN_PACKAGE_NAME "openorienteering-mapper") + execute_process( + COMMAND /usr/bin/lsb_release -sc + OUTPUT_VARIABLE CPACK_LSB_RELEASE + OUTPUT_STRIP_TRAILING_WHITESPACE) + string(REPLACE + "Linux-x86" + "${CPACK_LSB_RELEASE}_i386" + CPACK_PACKAGE_FILE_NAME + ${CPACK_PACKAGE_FILE_NAME}) + string(REPLACE + "Linux-x64" + "${CPACK_LSB_RELEASE}_amd64" + CPACK_PACKAGE_FILE_NAME + ${CPACK_PACKAGE_FILE_NAME}) + set(CPACK_DEBIAN_PACKAGE_MAINTAINER + "Kai Pastor ") + set(CPACK_DEBIAN_SECTION "graphics") + set(CPACK_DEBIAN_PACKAGE_HOMEPAGE + "http://openorienteering.org/apps/mapper/") + set(CPACK_DEBIAN_PACKAGE_SHLIBDEPS "ON") + + unset(FAKEROOT_EXECUTABLE CACHE) + find_program(FAKEROOT_EXECUTABLE fakeroot) + if(NOT FAKEROOT_EXECUTABLE) + install(CODE "MESSAGE(WARNING + \"'fakeroot' not found. To build a DEB package with proper file \" + \"ownership, fakeroot must be installed.\")") + endif(NOT FAKEROOT_EXECUTABLE) + mark_as_advanced(FAKEROOT_EXECUTABLE) + + message(WARNING + "The CPackDeb generator for creating deb packages has some issues. Run\n" + " make deb\n" + "instead of running make package directly." ) + add_custom_target(deb + COMMENT "Building a DEB package" + COMMAND sh -c 'if [ -d \"${CPACK_PACKAGE_FILE_NAME}\" ]; then rm -R \"${CPACK_PACKAGE_FILE_NAME}\" ";" fi' + COMMAND sh -c 'mkdir \"${CPACK_PACKAGE_FILE_NAME}\" && chmod 0755 \"${CPACK_PACKAGE_FILE_NAME}\"' + COMMAND sh -c ' + umask 022 && + "\$(MAKE)" package && + dpkg-deb -R \"${CPACK_PACKAGE_FILE_NAME}.deb\" \"${CPACK_PACKAGE_FILE_NAME}\" && + ldconfig -n \"${CPACK_PACKAGE_FILE_NAME}${MAPPER_LIBRARY_DESTINATION}/lib\" && + fakeroot dpkg-deb -b \"${CPACK_PACKAGE_FILE_NAME}\"' + COMMAND rm -R "./${CPACK_PACKAGE_FILE_NAME}" + WORKING_DIRECTORY "${PROJECT_BINARY_DIR}") + + endif() + + set(CPACK_GENERATOR "${CPACK_GENERATOR_DEFAULT}" + CACHE STRING "The binary package generators (ZIP;DEB;DragNDrop;NSIS)") + set(CPACK_SOURCE_GENERATOR "OFF" + CACHE STRING "The source package generators (TGZ;ZIP)") + mark_as_advanced(CPACK_GENERATOR CPACK_SOURCE_GENERATOR) + + include(CPack) + +endif() + + +if(WIN32) + set(CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS_SKIP TRUE) +endif() +include(InstallRequiredSystemLibraries) + + +# Cleanup obsolete cache items +unset(MAPPER_LIBS CACHE) +unset(MAPPER_QT_PLUGINS CACHE) + +unset(MAPPER_LIB_HINTS) +unset(MAPPER_LIBS) + +if(TOOLCHAIN_SHARED_LIBS) + list(APPEND MAPPER_LIBS ${TOOLCHAIN_SHARED_LIBS}) +elseif(MINGW) + list(APPEND MAPPER_LIBS libgcc_s_dw2-1 mingwm10) + list(APPEND MAPPER_LIBS libgcc_s_sjlj-1 libwinpthread-1 libstdc++-6) + list(APPEND MAPPER_LIBS libgcc_s_seh-1) + list(APPEND MAPPER_LIBS zlib1) +endif() + +if(Mapper_PACKAGE_PROJ) + if(NOT PROJ4_ROOT) + message(FATAL_ERROR "PROJ4_ROOT must be set when Mapper_PACKAGE_PROJ is enabled.") + endif() + install( + DIRECTORY "${PROJ4_ROOT}/share/proj" + DESTINATION "${MAPPER_DATA_DESTINATION}") + if(WIN32) + set(PROJ_LIB_SUFFIX -9) + else() + set(PROJ_LIB_SUFFIX "") + endif() + list(APPEND MAPPER_LIBS proj${PROJ_LIB_SUFFIX}) + list(APPEND MAPPER_LIB_HINTS ${PROJ4_ROOT}/bin) +endif() + +if(Mapper_PACKAGE_GDAL) + install( + DIRECTORY "${GDAL_BINARY_DIR}/../share/gdal" + DESTINATION "${MAPPER_DATA_DESTINATION}") + if(WIN32) + set(GDAL_LIB_SUFFIX -20) + else() + set(GDAL_LIB_SUFFIX "") + endif() + list(APPEND MAPPER_LIBS gdal${GDAL_LIB_SUFFIX}) + list(APPEND MAPPER_LIB_HINTS ${GDAL_BINARY_DIR}) + if(WIN32) + list(APPEND MAPPER_LIBS tiff-5 lzma-5) + endif() +endif() + +unset(MAPPER_QT_PLUGINS) +if(Mapper_PACKAGE_QT) + set(QT_LIB_SUFFIX "") + list(APPEND MAPPER_LIB_HINTS ${QT_BINARY_DIR}) + if(WIN32) + install( + FILES "${PROJECT_BINARY_DIR}/3rd-party/qt5/qt.conf" + DESTINATION "${MAPPER_RUNTIME_DESTINATION}") + endif() + list(APPEND MAPPER_LIBS + Qt5Core + Qt5DBus + Qt5Gui + Qt5Network + Qt5PrintSupport + Qt5Widgets + Qt5Xml + ) + set(MAPPER_QT_PLUGINS + generic/qevdevkeyboardplugin + generic/qevdevmouseplugin + generic/qevdevtabletplugin + generic/qevdevtouchplugin + imageformats/qgif + imageformats/qicns + imageformats/qico + imageformats/qjp2 + imageformats/qjpeg + imageformats/qtiff + imageformats/qwebp + platforminputcontexts/composeplatforminputcontextplugin + platforminputcontexts/ibusplatforminputcontextplugin + platforms/qcocoa + platforms/qwindows + platforms/qxcb + printsupport/cocoaprintersupport + printsupport/cupsprintersupport + printsupport/windowsprintersupport + ) + + # Cf. Qt5's qt_de.ts for dependencies - qt_de.ts would not load without them. + deploy_qt_translations(qt qtbase) +endif() + +unset(FIXUP_ASSISTANT) +if(Mapper_PACKAGE_ASSISTANT) + if(NOT Qt5Help_ASSISTANT_EXECUTABLE) + message(FATAL_ERROR "Qt5Help_ASSISTANT_EXECUTABLE: not found, " + "but required by option Mapper_PACKAGE_ASSISTANT=" + ${Mapper_PACKAGE_ASSISTANT}) + endif() + message(STATUS "Qt Assistant - found") + if(WIN32 OR APPLE) + install( + PROGRAMS ${Qt5Help_ASSISTANT_EXECUTABLE} + DESTINATION "${MAPPER_RUNTIME_DESTINATION}${MAPPER_MACOS_SUBDIR}") + else() + install( + PROGRAMS ${Qt5Help_ASSISTANT_EXECUTABLE} + DESTINATION "${MAPPER_LIBRARY_DESTINATION}/bin") + install( + FILES "${PROJECT_BINARY_DIR}/3rd-party/qt5/qt.conf" + DESTINATION "${MAPPER_LIBRARY_DESTINATION}/bin") + endif() + if(NOT APPLE) + list(APPEND MAPPER_LIBS + Qt5Help Qt5CLucene Qt5Sql + ) + endif() + if(APPLE) + set(FIXUP_ASSISTANT "Mapper.app/Contents/MacOS/Assistant") + endif() + list(APPEND MAPPER_QT_PLUGINS + sqldrivers/qsqlite + ) + + deploy_qt_translations(assistant qt_help) +endif(Mapper_PACKAGE_ASSISTANT) + +if(CMAKE_CROSSCOMPILING AND MINGW) + set(_env_lang $ENV{LC_ALL}) + set(ENV{LC_ALL} C) + execute_process( + COMMAND ${CMAKE_C_COMPILER} --print-search-dirs + OUTPUT_VARIABLE MINGW_SEARCH_DIRS + ) + set(ENV{LC_ALL} ${_env_lang}) + string(REGEX REPLACE ".*libraries: ?=?([^\n]*).*" \\1 MINGW_SEARCH_DIRS "${MINGW_SEARCH_DIRS}") + string(REPLACE \; \\\; MINGW_SEARCH_DIRS "${MINGW_SEARCH_DIRS}") + string(REPLACE : \; MINGW_SEARCH_DIRS "${MINGW_SEARCH_DIRS}") + list(APPEND MAPPER_LIB_HINTS ${MINGW_SEARCH_DIRS}) +endif() + +# Install all libs +foreach(_mapper_lib ${MAPPER_LIBS}) + set(_mapper_lib_id "MAPPER_${_mapper_lib}_LIB") + find_library(${_mapper_lib_id} ${_mapper_lib} + HINTS ${MAPPER_LIB_HINTS} + PATH_SUFFIXES "../bin" ${TOOLCHAIN_PATH_SUFFIXES} + NO_CMAKE_FIND_ROOT_PATH) + get_filename_component(_mapper_lib_ext "${${_mapper_lib_id}}" EXT) + if(_mapper_lib_ext STREQUAL ${CMAKE_SHARED_LIBRARY_SUFFIX}) + message(" ${_mapper_lib} shared library - found") + list(APPEND CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS "${${_mapper_lib_id}}") + if(IS_SYMLINK "${${_mapper_lib_id}}") + get_filename_component(_mapper_lib_real "${${_mapper_lib_id}}" REALPATH) + list(APPEND CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS "${_mapper_lib_real}") + endif() + else() + message(" ${_mapper_lib} shared library - not found") + endif() +endforeach(_mapper_lib) +if(WIN32) + install( + FILES ${CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS} + DESTINATION "${MAPPER_LIBRARY_DESTINATION}") +elseif(UNIX AND NOT APPLE) # Libs on OSX will be handled by fixup_bundle. + install( + FILES ${CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS} + DESTINATION "${MAPPER_LIBRARY_DESTINATION}/lib") +endif() + +# Install all plugins +unset(MAPPER_QT_PLUGINS_FOUND) +foreach(_qt_plugin ${MAPPER_QT_PLUGINS}) + get_filename_component(_qt_plugin_name "${_qt_plugin}" NAME) + get_filename_component(_qt_plugin_dir "${_qt_plugin}" PATH) + set(_qt_plugin_id "QT_${_qt_plugin_dir}-${_qt_plugin_name}_PLUGIN") + find_library(${_qt_plugin_id} ${_qt_plugin_name} + HINTS ${QT_PLUGINS_DIR} + PATH_SUFFIXES ${_qt_plugin_dir} plugins/${_qt_plugin_dir} + NO_CMAKE_FIND_ROOT_PATH) + if(NOT ${${_qt_plugin_id}} MATCHES NOTFOUND) + message(" ${_qt_plugin} plugin library - found") + list(APPEND MAPPER_QT_PLUGINS_FOUND "${${_qt_plugin_id}}") + if(NOT APPLE) + install( + FILES "${${_qt_plugin_id}}" + DESTINATION "${MAPPER_LIBRARY_DESTINATION}/plugins/${_qt_plugin_dir}") + endif() + else() + message(" ${_qt_plugin} plugin library - not found") + endif() +endforeach(_qt_plugin) + +if(APPLE) + include(${PROJECT_SOURCE_DIR}/cmake/DeployQt5.cmake) + install_qt5_executable(Mapper.app + "${MAPPER_QT_PLUGINS_FOUND}" + ${FIXUP_ASSISTANT}) +elseif(UNIX) + find_program(LDCONFIG_COMMAND NAMES ldconfig) + if(${LDCONFIG_COMMAND} MATCHES NOTFOUND) + message(FATAL_ERROR "Could not find ldconfig command.") + endif() + # Add required symlinks. + install(CODE "execute_process(COMMAND \"${LDCONFIG_COMMAND}\" -n \"\$ENV{DESTDIR}${MAPPER_LIBRARY_DESTINATION}/lib\")") + # Create DEBIAN directory to make dpkg-shlibdeps happy. + install(CODE "file(MAKE_DIRECTORY \"\$ENV{DESTDIR}/DEBIAN\")") +endif() + +if(UNIX AND NOT APPLE) + install( + FILES "${PROJECT_SOURCE_DIR}/doc/man/Mapper.1" + DESTINATION "share/man/man1") + install( + FILES "${CMAKE_CURRENT_BINARY_DIR}/linux/Mapper.desktop" + DESTINATION "share/applications") + install( + FILES "${CMAKE_CURRENT_BINARY_DIR}/linux/openorienteering-mapper.xml" + DESTINATION "share/mime/packages") + # Cf. http://standards.freedesktop.org/icon-theme-spec/icon-theme-spec-latest.html#directory_layout + foreach(_size 16 24 32 48 96 128 256 512) + install( + FILES "${PROJECT_SOURCE_DIR}/images/mapper-icon/Mapper-${_size}.png" + DESTINATION "share/icons/hicolor/${_size}x${_size}/apps" + RENAME Mapper.png + ) + install( + FILES "${PROJECT_SOURCE_DIR}/images/mapper-icon/Mapper-${_size}.png" + DESTINATION "share/icons/hicolor/${_size}x${_size}/mimetypes" + RENAME application-x-openorienteering-xmap.png + ) + install( + FILES "${PROJECT_SOURCE_DIR}/images/mapper-icon/Mapper-${_size}.png" + DESTINATION "share/icons/hicolor/${_size}x${_size}/mimetypes" + RENAME application-x-openorienteering-ocd.png + ) + endforeach() +endif() + + + +if(Mapper_BUILD_QT AND Mapper_PACKAGE_LINGUIST) + include(ExternalProject) + set(CMAKE_TOOLCHAIN_ARG "") + if(CMAKE_TOOLCHAIN_FILE) + set(CMAKE_TOOLCHAIN_ARG "-DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE}") + endif() + ExternalProject_Add("Linguist package" + DEPENDS Qt5 + SOURCE_DIR ${PROJECT_SOURCE_DIR}/packaging/linguist + UPDATE_COMMAND ${CMAKE_COMMAND} -E remove /CMakeCache.txt + CMAKE_ARGS + ${CMAKE_TOOLCHAIN_ARG} + -DCMAKE_PREFIX_PATH=${CMAKE_PREFIX_PATH} + -DQT5_DIR=${QT5_DIR} + -DQT_TRANSLATIONS_DIR=${QT_TRANSLATIONS_DIR} + -DQT_CONF=${PROJECT_BINARY_DIR}/3rd-party/qt5/qt.conf + BUILD_COMMAND ${CMAKE_COMMAND} --build --target package + INSTALL_COMMAND "" + ) + ExternalProject_Get_Property("Linguist package" BINARY_DIR) + # Copy the linguist package to the build tree root during install/packaging + install(CODE + "execute_process(COMMAND \${CMAKE_COMMAND} --build \"${BINARY_DIR}\" --target \"package-install\" -- \"DESTDIR=${PROJECT_BINARY_DIR}\")" + ) +elseif(Mapper_PACKAGE_LINGUIST) + if(NOT Qt5LinguistTools_LINGUIST_EXECUTABLE) + message(FATAL_ERROR "Qt5LinguistTools_LINGUIST_EXECUTABLE: not found, " + "but required by option Mapper_PACKAGE_LINGUIST=" + ${Mapper_PACKAGE_LINGUIST}) + endif() + message(STATUS "Qt Linguist - found") + if(WIN32 OR APPLE) + install( + PROGRAMS ${Qt5LinguistTools_LINGUIST_EXECUTABLE} + DESTINATION "${MAPPER_RUNTIME_DESTINATION}${MAPPER_MACOS_SUBDIR}") + else() + install( + PROGRAMS ${Qt5LinguistTools_LINGUIST_EXECUTABLE} + DESTINATION "${MAPPER_LIBRARY_DESTINATION}/bin") + endif() + deploy_qt_translations(linguist) +endif() diff --git a/packaging/linguist/CMakeLists.txt b/packaging/linguist/CMakeLists.txt new file mode 100644 index 0000000..a9e9344 --- /dev/null +++ b/packaging/linguist/CMakeLists.txt @@ -0,0 +1,238 @@ +# +# Copyright 2013 Kai Pastor +# +# This file is part of OpenOrienteering. +# +# OpenOrienteering is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# OpenOrienteering is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with OpenOrienteering. If not, see . + +project("Qt Linguist") + +cmake_minimum_required(VERSION 2.8) + +message(STATUS "Configuring ${PROJECT_NAME} packaging") + + +# Find Linguist + +find_package(Qt5LinguistTools REQUIRED) +find_package(Qt5Core REQUIRED) +find_program(QT_QTLINGUIST_EXECUTABLE NAMES linguist${CMAKE_EXECUTABLE_SUFFIX} Linguist${CMAKE_EXECUTABLE_SUFFIX} + DOC "The path of the Qt Linguist executable" + HINTS ${QT5_DIR} + PATH_SUFFIXES bin + NO_DEFAULT_PATH) +mark_as_advanced(QT_QTLINGUIST_EXECUTABLE) + +if(QT_QTLINGUIST_EXECUTABLE MATCHES NOTFOUND) + message(FATAL_ERROR "Qt Linguist executable not found.") +endif() + + +# Configure CPack + +set(CPACK_PACKAGE_NAME "Qt Linguist") +set(CPACK_PACKAGE_VENDOR "OpenOrienteering") +set(CPACK_PACKAGE_VERSION_MAJOR ${Qt5Core_VERSION_MAJOR}) +set(CPACK_PACKAGE_VERSION_MINOR ${Qt5Core_VERSION_MINOR}) +set(CPACK_PACKAGE_VERSION_PATCH ${Qt5Core_VERSION_PATCH}) +set(CPACK_PACKAGE_DESCRIPTION_SUMMARY + "Qt translation tool, packaged by OpenOrienteering.") +if(CMAKE_SIZEOF_VOID_P EQUAL 4) + set(_system_name "${CMAKE_SYSTEM_NAME}-x86") +elseif(CMAKE_SIZEOF_VOID_P EQUAL 8) + set(_system_name "${CMAKE_SYSTEM_NAME}-x64") +else() + set(_system_name "${CMAKE_SYSTEM_NAME}-unknown") +endif() +set(CPACK_PACKAGE_FILE_NAME + "qt-linguist_${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}.${CPACK_PACKAGE_VERSION_PATCH}-${_system_name}") +set(CPACK_RESOURCE_FILE_LICENSE "${PROJECT_SOURCE_DIR}/COPYING") +set(CPACK_STRIP_FILES "TRUE") + +if(WIN32) + set(RUNTIME_DESTINATION .) + set(LIBRARY_DESTINATION .) + set(DATA_DESTINATION .) + set(ABOUT_DESTINATION .) + set(PACKAGE_FILE_NAME ${CPACK_PACKAGE_FILE_NAME}.zip) + set(CPACK_GENERATOR "ZIP") +elseif(APPLE) + set(RUNTIME_DESTINATION .) + set(LIBRARY_DESTINATION .) + set(DATA_DESTINATION "Linguist.app/Contents/Resources") + set(ABOUT_DESTINATION "Linguist.app/Contents/Resources") + set(PACKAGE_FILE_NAME ${CPACK_PACKAGE_FILE_NAME}.dmg) + set(CPACK_GENERATOR "DragNDrop") + string(REGEX REPLACE "([Ll]inguist.app).*" "\\1" LINGUIST_BUNDLE_DIR ${QT_QTLINGUIST_EXECUTABLE}) + set(CPACK_PACKAGE_EXECUTABLES "Linguist" "Qt Linguist ${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}.${CPACK_PACKAGE_VERSION_PATCH}") + set(CPACK_PACKAGE_ICON "${LINGUIST_BUNDLE_DIR}/Contents/Resources/linguist.icns") +else() + set(RUNTIME_DESTINATION .) + set(LIBRARY_DESTINATION .) + set(DATA_DESTINATION .) + set(ABOUT_DESTINATION .) + set(PACKAGE_FILE_NAME ${CPACK_PACKAGE_FILE_NAME}.zip) + set(CPACK_GENERATOR "ZIP") +endif() + +include(CPack) + + +# Copy the created package to the make-time DESTDIR location + +set(MAKEFILE_DESTDIR_VAR "\$(DESTDIR)") +add_custom_target(package-install + COMMAND ${CMAKE_COMMAND} -E + copy ${PROJECT_BINARY_DIR}/${PACKAGE_FILE_NAME} "${MAKEFILE_DESTDIR_VAR}/" +) + + +# Define package contents (by install commands) + +install( + FILES COPYING + DESTINATION "${ABOUT_DESTINATION}" +) + +if(APPLE) + install( + DIRECTORY "${LINGUIST_BUNDLE_DIR}/" + DESTINATION "${RUNTIME_DESTINATION}/Linguist.app" + USE_SOURCE_PERMISSIONS) + find_program(QT_MACDEPLOYQT_EXECUTABLE NAMES macdeployqt + DOC "The path of the macdeployqt executable" + HINTS ${QT5_DIR} + PATH_SUFFIXES bin + NO_DEFAULT_PATH) + mark_as_advanced(QT_MACDEPLOYQT_EXECUTABLE) + install(CODE + "execute_process(COMMAND \"${QT_MACDEPLOYQT_EXECUTABLE}\" \"\${CMAKE_INSTALL_PREFIX}/Linguist.app\")") + install(CODE + "file(APPEND \"\${CMAKE_INSTALL_PREFIX}/Linguist.app/Contents/Resources/qt.conf\" \"Translations = Resources/translations\")") +else() + install( + PROGRAMS ${QT_QTLINGUIST_EXECUTABLE} + DESTINATION ${RUNTIME_DESTINATION}) +endif() + +if(WIN32) + set(CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS_SKIP TRUE) +endif() +include(InstallRequiredSystemLibraries) + +unset(LINGUIST_LIBS) +if(TOOLCHAIN_SHARED_LIBS) + list(APPEND LINGUIST_LIBS ${TOOLCHAIN_SHARED_LIBS}) +elseif(MINGW) + list(APPEND LINGUIST_LIBS libgcc_s_dw2-1 mingwm10) + list(APPEND LINGUIST_LIBS libgcc_s_sjlj-1 libwinpthread-1 libstdc++-6) +endif() + +set(QT_LIB_SUFFIX "") +list(APPEND LINGUIST_LIB_HINTS ${QT_BINARY_DIR}) +if(FALSE AND WIN32) + install( + FILES "${PROJECT_BINARY_DIR}/3rd-party/qt5/qt.conf" + DESTINATION "${LINGUIST_RUNTIME_DESTINATION}") +endif() +if(NOT APPLE) + list(APPEND LINGUIST_LIBS Qt5Core Qt5Gui Qt5Widgets Qt5PrintSupport Qt5Xml) +else() + set(FIXUP_LINGUIST "Linguist.app/Contents/MacOS/Linguist") +endif() +set(LINGUIST_QT_PLUGINS +# accessible/qtaccessiblewidgets +# iconengines/qsvgicon +# imageformats/qgif imageformats/qico imageformats/qjpeg imageformats/qmng +# imageformats/qsvg imageformats/qtga imageformats/qtiff imageformats/qwbmp + platforms/qminimal platforms/qwindows platforms/qcocoa platforms/qxcb + printsupport/windowsprintersupport printsupport/cocoaprintersupport printsupport/cupsprintersupport +) +# Cf. Qt5's qt_de.ts for dependencies - qt_de.ts would not load without them. +set(LINGUIST_QT_TRANSLATIONS linguist qt qtbase qtscript qtquick1 qtmultimedia qtxmlpatterns) + +# Install all libs +foreach(_linguist_lib ${LINGUIST_LIBS}) + set(_linguist_lib_id "LINGUIST_${_linguist_lib}_LIB") + find_library(${_linguist_lib_id} ${_linguist_lib} + HINTS ${LINGUIST_LIB_HINTS} + PATH_SUFFIXES "../bin" ${TOOLCHAIN_PATH_SUFFIXES} + NO_CMAKE_FIND_ROOT_PATH) + get_filename_component(_linguist_lib_ext "${${_linguist_lib_id}}" EXT) + if(_linguist_lib_ext STREQUAL ${CMAKE_SHARED_LIBRARY_SUFFIX}) + message(" ${_linguist_lib} shared library - found") + list(APPEND CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS "${${_linguist_lib_id}}") + if(IS_SYMLINK "${${_linguist_lib_id}}") + get_filename_component(_linguist_lib_real "${${_linguist_lib_id}}" REALPATH) + list(APPEND CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS "${_linguist_lib_real}") + endif() + else() + message(" ${_linguist_lib} shared library - not found") + endif() +endforeach(_linguist_lib) +if(WIN32) + install( + FILES ${CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS} + DESTINATION "${LIBRARY_DESTINATION}") +elseif(UNIX AND NOT APPLE) # Libs on OSX will be handled by fixup_bundle. + install( + FILES ${CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS} + DESTINATION "${LIBRARY_DESTINATION}/lib") +endif() + +# Install all plugins +unset(QT_PLUGINS_FOUND) +foreach(_qt_plugin ${LINGUIST_QT_PLUGINS}) + get_filename_component(_qt_plugin_name "${_qt_plugin}" NAME) + get_filename_component(_qt_plugin_dir "${_qt_plugin}" PATH) + set(_qt_plugin_id "QT_${_qt_plugin_dir}-${_qt_plugin_name}_PLUGIN") + find_library(${_qt_plugin_id} ${_qt_plugin_name} + HINTS ${QT_PLUGINS_DIR} + PATH_SUFFIXES ${_qt_plugin_dir} plugins/${_qt_plugin_dir} + NO_CMAKE_FIND_ROOT_PATH) + if(NOT ${${_qt_plugin_id}} MATCHES NOTFOUND) + message(" ${_qt_plugin} plugin library - found") + list(APPEND QT_PLUGINS_FOUND "${${_qt_plugin_id}}") + if(NOT APPLE) + install( + FILES "${${_qt_plugin_id}}" + DESTINATION "${LIBRARY_DESTINATION}/plugins/${_qt_plugin_dir}") + endif() + else() + message(" ${_qt_plugin} plugin library - not found") + endif() +endforeach(_qt_plugin) + +# Install all Qt translations +foreach(_qt_component ${LINGUIST_QT_TRANSLATIONS}) + install( + DIRECTORY "${QT_TRANSLATIONS_DIR}/" + DESTINATION "${DATA_DESTINATION}/translations" + FILES_MATCHING PATTERN "${_qt_component}_*.qm") +endforeach() + +# Install phrasebooks +install( + DIRECTORY "${QT_TRANSLATIONS_DIR}/../phrasebooks/" + DESTINATION "${DATA_DESTINATION}/phrasebooks" + FILES_MATCHING PATTERN "*.qph") + + +if(WIN32) + install( + FILES ${QT_CONF} + DESTINATION ${RUNTIME_DESTINATION}) +endif() + +message(STATUS "Configuring ${PROJECT_NAME} packaging - done") diff --git a/packaging/linguist/COPYING b/packaging/linguist/COPYING new file mode 100644 index 0000000..94a9ed0 --- /dev/null +++ b/packaging/linguist/COPYING @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/packaging/linux/Mapper.desktop b/packaging/linux/Mapper.desktop new file mode 100644 index 0000000..69a4c65 --- /dev/null +++ b/packaging/linux/Mapper.desktop @@ -0,0 +1,28 @@ +[Desktop Entry] +Type=Application +Name=OpenOrienteering Mapper +Comment=A free software for drawing orienteering maps +Comment[cs]=Svobodný program na kreslení map pro orientační běh +Comment[de]=Ein freies Programm zum Zeichnen von Orientierungslaufkarten +Comment[eo]=Libera programaro por desegni orientiĝajn mapojn +Comment[es]=Software libre para dibujar mapas de orientación +Comment[fi]=Ilmainen ohjelma suunnistuskarttojen tekemiseen +Comment[fr]=Un logiciel libre pour dessiner des cartes de course d'orientation +Comment[he]=לעת עתה, אנו משתמשים בתרגום הנוכחי במקום בקודם +Comment[hu]=Tartalmilag ez az igazság +Comment[id]=Perangkat lunak gratis untuk menggambar peta orienteering +Comment[it]=Un software libero per il disegno delle mappe per orienteering +Comment[ja]=オリエンテーリング地図作成のための自由なソフトウェア +Comment[lv]=BrÄ«vpieejas programma orientēšanās karÅ¡u zÄ«mēšanai +Comment[nb]=Fri programvare for tegning av orienteringskart +Comment[nl]=Een gratis programma voor het tekenen van oriëntatieloop kaarten +Comment[pl]=Darmowy program do kreślenia map do BnO +Comment[pt_BR]=Um programa livre para desenho de mapas de orientação +Comment[ru]=Свободное программное обеспечение для создания спортивных карт +Comment[sv]=Fri mjukvara för att rita orienteringskartor +Comment[uk]=Вільна програма для креслення спортивних карт +Exec=Mapper %F +Icon=Mapper +Terminal=false +Categories=Graphics;Qt; +MimeType=application/x-openorienteering-xmap;application/x-openorienteering-ocd; diff --git a/packaging/linux/openorienteering-mapper.xml b/packaging/linux/openorienteering-mapper.xml new file mode 100644 index 0000000..56059a7 --- /dev/null +++ b/packaging/linux/openorienteering-mapper.xml @@ -0,0 +1,35 @@ + + + + + Orienteering map + Mapa pro orientační běh + Orienteringsløb-kort + Orientierungslaufkarte + Orientiĝa mapo + Mapa de orientación + Suunnistuskartta + Peta orienteering + オリエンテーリング地図 + Oriëntatiekaart + Спортивная карта + Спортивна карта + + + + + Orienteering map + Mapa pro orientační běh + Orienteringsløb-kort + Orientierungslaufkarte + Orientiĝa mapo + Mapa de orientación + Suunnistuskartta + Peta orienteering + オリエンテーリング地図 + Oriëntatiekaart + Спортивная карта + Спортивна карта + + + diff --git a/packaging/src/CMakeLists.txt b/packaging/src/CMakeLists.txt new file mode 100644 index 0000000..5aa34d2 --- /dev/null +++ b/packaging/src/CMakeLists.txt @@ -0,0 +1,36 @@ +# +# Copyright 2013, 2014 Kai Pastor +# +# This file is part of OpenOrienteering. +# +# OpenOrienteering is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# OpenOrienteering is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with OpenOrienteering. If not, see . + +message(STATUS "Configuring ${PROJECT_NAME} source packaging") + +set(Mapper_Source_PREFIX + "openorienteering-mapper-${Mapper_VERSION_MAJOR}.${Mapper_VERSION_MINOR}.${Mapper_VERSION_PATCH}") + +set(Mapper_Source_FILE_NAME + "openorienteering-mapper_${Mapper_VERSION_MAJOR}.${Mapper_VERSION_MINOR}.${Mapper_VERSION_PATCH}-src") + +set(Mapper_Source_FORMAT tgz CACHE STRING + "The archive format for source packages (see `git archive -l` for valid options)") + +find_program(GIT_EXECUTABLE git) +if(GIT_EXECUTABLE) + configure_file(Mapper_Source.cmake.in Mapper_Source.cmake @ONLY) + add_custom_target(Mapper_Source + COMMAND ${CMAKE_COMMAND} -P "${CMAKE_CURRENT_BINARY_DIR}/Mapper_Source.cmake" + ) +endif() diff --git a/packaging/src/Mapper_Source.cmake.in b/packaging/src/Mapper_Source.cmake.in new file mode 100644 index 0000000..b26b4de --- /dev/null +++ b/packaging/src/Mapper_Source.cmake.in @@ -0,0 +1,64 @@ +# +# Copyright 2012, 2013, 2014 Kai Pastor +# +# This file is part of OpenOrienteering. +# +# OpenOrienteering is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# OpenOrienteering is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with OpenOrienteering. If not, see . + +# Synopsis: +# cmake [ -DPREFIX=my/prefix ] [ -DARCHIVE_NAME=prefix-src ] +# [ -DOUTPUT_DIR=/usr/src ] [ -DSKIP_CHECK=1 ] -P Mapper_Source.cmake + +if (NOT PREFIX) + set(PREFIX "@Mapper_Source_PREFIX@") +endif () + +if (NOT ARCHIVE_NAME) + set(ARCHIVE_NAME "@Mapper_Source_FILE_NAME@") +endif () + +if (NOT OUTPUT_DIR) + set(OUTPUT_DIR "@PROJECT_BINARY_DIR@") +endif () +if (NOT OUTPUT_DIR) + set(OUTPUT_DIR .) +endif () + +if (NOT SKIP_CHECK) + # Check that the working directory is clean. + set(ENV{LANG} C) + execute_process( + COMMAND "@GIT_EXECUTABLE@" status + WORKING_DIRECTORY "@PROJECT_SOURCE_DIR@" + OUTPUT_VARIABLE GIT_STATUS_OUTPUT + ) + if (NOT GIT_STATUS_OUTPUT MATCHES "working directory clean") + message(${GIT_STATUS_OUTPUT}) + message(FATAL_ERROR + "Source package must be created from a clean git working directory, " + "or you must specify -DSKIP_CHECK=1." + ) + endif () +endif () + +# Let git build the archive +message(STATUS "Creating ${PREFIX}.@Mapper_Source_FORMAT@") +execute_process( + COMMAND "@GIT_EXECUTABLE@" archive + --format "@Mapper_Source_FORMAT@" + --prefix "${PREFIX}/" + --output "${OUTPUT_DIR}/${ARCHIVE_NAME}.@Mapper_Source_FORMAT@" + HEAD + WORKING_DIRECTORY "@PROJECT_SOURCE_DIR@" +) diff --git a/packaging/translations.cpp b/packaging/translations.cpp new file mode 100644 index 0000000..81b2e85 --- /dev/null +++ b/packaging/translations.cpp @@ -0,0 +1,14 @@ +/* + * This file is part of OpenOrienteering. + * + * This file is not compiled. + * These string are used for packaging and desktop integration. + */ + +#define QT_TRANSLATE_NOOP(a,b) + +QT_TRANSLATE_NOOP("OpenOrienteering", "Orienteering map"); +QT_TRANSLATE_NOOP("OpenOrienteering", "Software for drawing orienteering maps"); + +//: For the moment, we use this existing translation instead of the previous one. +QT_TRANSLATE_NOOP("AboutDialog", "A free software for drawing orienteering maps"); diff --git a/packaging/windows/custom.nsi.in b/packaging/windows/custom.nsi.in new file mode 100644 index 0000000..5a4f376 --- /dev/null +++ b/packaging/windows/custom.nsi.in @@ -0,0 +1,79 @@ +; (C) 2014 Kai Pastor +; +; This file is part of OpenOrienteering. +; +; OpenOrienteering is free software: you can redistribute it and/or modify +; it under the terms of the GNU General Public License as published by +; the Free Software Foundation, either version 3 of the License, or +; (at your option) any later version. +; +; OpenOrienteering is distributed in the hope that it will be useful, +; but WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +; GNU General Public License for more details. +; +; You should have received a copy of the GNU General Public License +; along with OpenOrienteering. If not, see . + + +!define MUI_WELCOMEPAGE_TITLE_3LINES +!define MUI_CUSTOMFUNCTION_GUIINIT check_x64 + +Function check_x64 + StrCmp "@CMAKE_SIZEOF_VOID_P@" "8" 0 +5 + StrCmp "$PROGRAMFILES32" "$PROGRAMFILES64" 0 +3 + MessageBox MB_ICONEXCLAMATION|MB_OK "The x64 package cannot be installed on a x32 Windows system. Installation aborted." /SD IDOK + Abort + ClearErrors +FunctionEnd + + +!define SHCNE_ASSOCCHANGED 0x8000000 +!define SHCNF_IDLIST 0 + +Function installAssociations + ; The application + WriteRegStr HKLM "Software\Classes\OpenOrienteering.Map" "" "OpenOrienteering Map" + WriteRegStr HKLM "Software\Classes\OpenOrienteering.Map\DefaultIcon" "" "$INSTDIR\Mapper.exe" + + ReadRegStr $R0 HKLM "Software\Classes\OpenOrienteering.Map\shell\open\command" "" + StrCmp $R0 "" 0 +3 + WriteRegStr HKLM "Software\Classes\OpenOrienteering.Map\shell" "" "open" + WriteRegStr HKLM "Software\Classes\OpenOrienteering.Map\shell\open\command" "" '"$INSTDIR\Mapper.exe" "%1"' + + ; The file type associations + WriteRegStr HKLM "Software\Classes\.omap" "" "OpenOrienteering.Map" + WriteRegStr HKLM "Software\Classes\.omap" "PerceivedType" "document" + WriteRegStr HKLM "Software\Classes\.xmap" "" "OpenOrienteering.Map" + WriteRegStr HKLM "Software\Classes\.xmap" "PerceivedType" "document" + + ReadRegStr $R0 HKLM "Software\Classes\.ocd" "" + StrCmp $R0 "" 0 +3 + WriteRegStr HKLM "Software\Classes\.ocd" "" "OpenOrienteering.Map" + WriteRegStr HKLM "Software\Classes\.ocd" "PerceivedType" "document" + WriteRegStr HKLM "Software\Classes\.ocd\OpenWithProgIDs" "OpenOrienteering.Map" "" + + System::Call 'Shell32::SHChangeNotify(i ${SHCNE_ASSOCCHANGED}, i ${SHCNF_IDLIST}, p0, p0)' +FunctionEnd + +Function un.installAssociations + ; The file type associations + ReadRegStr $R0 HKLM "Software\Classes\.omap" "" + StrCmp $R0 "OpenOrienteering.Map" 0 +2 + DeleteRegKey HKLM "Software\Classes\.omap" + + ReadRegStr $R0 HKLM "Software\Classes\.xmap" "" + StrCmp $R0 "OpenOrienteering.Map" 0 +2 + DeleteRegKey HKLM "Software\Classes\.xmap" + + DeleteRegValue HKLM "Software\Classes\.ocd\OpenWithProgIDs" "OpenOrienteering.Map" + ReadRegStr $R0 HKLM "Software\Classes\.ocd" "" + StrCmp $R0 "OpenOrienteering.Map" 0 +2 + DeleteRegKey HKLM "Software\Classes\.ocd" + + ; The application + DeleteRegKey HKLM "Software\Classes\OpenOrienteering.Map" + + System::Call 'Shell32::SHChangeNotify(i ${SHCNE_ASSOCCHANGED}, i ${SHCNF_IDLIST}, p0, p0)' +FunctionEnd + diff --git a/resources.qrc b/resources.qrc new file mode 100644 index 0000000..cf574a9 --- /dev/null +++ b/resources.qrc @@ -0,0 +1,131 @@ + + + images/about.png + images/arrow-down.png + images/arrow-left.png + images/arrow-right.png + images/arrow-thin-upleft.png + images/arrow-thin-downright.png + images/arrow-up.png + images/close.png + images/colors.png + images/compass.png + images/control.png + images/copy.png + images/copy-coords.png + images/cursor-crosshair.png + images/cursor-cut.png + images/cursor-delete.png + images/cursor-draw-circle.png + images/cursor-draw-path.png + images/cursor-draw-point.png + images/cursor-draw-rectangle.png + images/cursor-draw-text.png + images/cursor-fill.png + images/cursor-georeferencing-add.png + images/cursor-georeferencing-move.png + images/cursor-hollow.png + images/cursor-invisible.png + images/cursor-paint-on-template.png + images/cursor-rotate.png + images/cursor-scale.png + images/cut.png + images/delete.png + images/draw-circle.png + images/draw-freehand.png + images/draw-path.png + images/draw-point.png + images/draw-point-gps.png + images/draw-rectangle.png + images/draw-text.png + images/georeferencing.png + images/gps-distance-rings.png + images/gps-temporary-point.png + images/gps-temporary-path.png + images/gps-temporary-clear.png + images/grid.png + images/group.png + images/help.png + images/magnifying-glass.png + images/map-parts.png + images/mapper.png + images/minus.png + images/move.png + images/new.png + images/open-orienteering.png + images/open.png + images/paint-on-template-settings.png + images/paste.png + images/pencil.png + images/plus.png + images/point-handles.png + images/point-handles-2x.png + images/point-handles-4x.png + images/print.png + images/print-mode-vector.png + images/print-mode-raster.png + images/print-mode-separations.png + images/redo.png + images/rotate-map.png + images/save.png + images/settings.png + images/symbols.png + images/symbol_point_explanation.png + images/tag-selector.png + images/templates.png + images/text-align-left.png + images/text-align-hcenter.png + images/text-align-right.png + images/text-align-top.png + images/text-align-vcenter.png + images/text-align-baseline.png + images/text-align-bottom.png + images/three-dots.png + images/title.png + images/tool-boolean-difference.png + images/tool-boolean-intersection.png + images/tool-boolean-union.png + images/tool-boolean-xor.png + images/tool-boolean-merge-holes.png + images/tool-connect-paths.png + images/tool-convert-to-curves.png + images/tool-cut.png + images/tool-cut-hole.png + images/tool-cutout-physical.png + images/tool-cutout-physical-inner.png + images/tool-distribute-points.png + images/tool-duplicate.png + images/tool-edit.png + images/tool-edit-line.png + images/tool-fill.png + images/tool-fill-border.png + images/tool-gps-display.png + images/tool-measure.png + images/tool-rotate.png + images/tool-rotate-pattern.png + images/tool-scale.png + images/tool-simplify-path.png + images/tool-switch-dashes.png + images/tool-switch-symbol.png + images/tool-touch-cursor.png + images/undo.png + images/view-show-all.png + images/view-zoom-in.png + images/view-zoom-out.png + images/window-new.png + images/mapper-icon/Mapper-128.png + help/tip-of-the-day/tips_en.txt + + + help/tip-of-the-day/tips_de.txt + + + help/tip-of-the-day/tips_fr.txt + + + help/tip-of-the-day/tips_ru.txt + + + help/tip-of-the-day/tips_uk.txt + + diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt new file mode 100644 index 0000000..23e0907 --- /dev/null +++ b/src/CMakeLists.txt @@ -0,0 +1,484 @@ +# +# Copyright 2012-2014 Thomas Schöps +# Copyright 2012-2016 Kai Pastor +# +# This file is part of OpenOrienteering. +# +# OpenOrienteering is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# OpenOrienteering is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with OpenOrienteering. If not, see . + +find_package(Qt5Core 5.2 REQUIRED) +find_package(Qt5Widgets REQUIRED) +find_package(Qt5Xml REQUIRED) +find_package(Qt5Network) +find_package(Qt5PrintSupport) + +if(Mapper_PACKAGE_QT AND UNIX AND NOT APPLE AND NOT Mapper_DEVELOPMENT_BUILD) + set(MAPPER_USE_QT_CONF_QRC 1) +endif() + +configure_file(mapper_config.h.in "${CMAKE_CURRENT_BINARY_DIR}/mapper_config.h.tmp") +execute_process( + COMMAND "${CMAKE_COMMAND}" -E copy_if_different mapper_config.h.tmp mapper_config.h + WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}" +) +include_directories("${CMAKE_CURRENT_BINARY_DIR}") +include_directories(AFTER "../3rd-party/qbezier/src") # Always, last + +set(Mapper_Common_SRCS + core/autosave.cpp + core/crs_template.cpp + core/crs_template_implementation.cpp + core/georeferencing.cpp + core/latlon.cpp + core/map_color.cpp + core/map_coord.cpp + core/map_grid.cpp + core/map_printer.cpp + core/map_view.cpp + core/path_coord.cpp + core/storage_location.cpp + core/virtual_path.cpp + core/virtual_coord_vector.cpp + + global.cpp + util.cpp + util_task_dialog.cpp + util_translation.cpp + mapper_resource.cpp + undo.cpp + undo_manager.cpp + matrix.cpp + transformation.cpp + + settings.cpp + + map.cpp + map_part.cpp + map_part_undo.cpp + map_widget.cpp + touch_cursor.cpp + map_editor.cpp + map_editor_activity.cpp + object_undo.cpp + map_dialog_new.cpp + map_dialog_scale.cpp + map_dialog_rotate.cpp + + color_dock_widget.cpp + + symbol.cpp + symbol_dialog_replace.cpp + symbol_setting_dialog.cpp + symbol_properties_widget.cpp + symbol_point_editor.cpp + symbol_point.cpp + symbol_line.cpp + symbol_area.cpp + symbol_text.cpp + symbol_combined.cpp + renderable.cpp + renderable_implementation.cpp + object.cpp + object_query.cpp + object_text.cpp + + template.cpp + template_image.cpp + template_track.cpp + template_map.cpp + template_dialog_reopen.cpp + template_position_dock_widget.cpp + template_adjust.cpp + template_tool_move.cpp + template_tool_paint.cpp + + tool.cpp + tool_base.cpp + tool_helpers.cpp + tool_pan.cpp + tool_edit.cpp + tool_edit_point.cpp + tool_edit_line.cpp + tool_distribute_points.cpp + tool_draw_line_and_area.cpp + tool_draw_point.cpp + tool_draw_point_gps.cpp + tool_draw_path.cpp + tool_draw_circle.cpp + tool_draw_rectangle.cpp + tool_draw_freehand.cpp + tool_draw_text.cpp + tool_cut.cpp + tool_cut_hole.cpp + tool_cutout.cpp + tool_rotate.cpp + tool_rotate_pattern.cpp + tool_scale.cpp + tool_boolean.cpp + tool_fill.cpp + + gps_track.cpp + gps_display.cpp + gps_temporary_markers.cpp + gps_track_recorder.cpp + dxfparser.cpp + + compass.cpp + + file_format.cpp + file_format_registry.cpp + file_import_export.cpp + file_format_native.cpp + file_format_ocad8.cpp + file_format_xml.cpp + + fileformats/ocd_file_export.cpp + fileformats/ocd_file_format.cpp + fileformats/ocd_file_import.cpp + fileformats/ocd_types.cpp + + gui/about_dialog.cpp + gui/autosave_dialog.cpp + gui/color_dialog.cpp + gui/georeferencing_dialog.cpp + gui/home_screen_controller.cpp + gui/main_window.cpp + gui/main_window_controller.cpp + gui/configure_grid_dialog.cpp + gui/modifier_key.cpp + gui/point_handles.cpp + gui/print_progress_dialog.cpp + gui/print_tool.cpp + gui/print_widget.cpp + gui/select_crs_dialog.cpp + gui/settings_dialog.cpp + gui/text_browser_dialog.cpp + + gui/widgets/action_grid_bar.cpp + gui/widgets/color_dropdown.cpp + gui/widgets/compass_display.cpp + gui/widgets/crs_param_widgets.cpp + gui/widgets/crs_selector.cpp + gui/widgets/editor_settings_page.cpp + gui/widgets/general_settings_page.cpp + gui/widgets/home_screen_widget.cpp + gui/widgets/key_button_bar.cpp + gui/widgets/mapper_proxystyle.cpp + gui/widgets/measure_widget.cpp + gui/widgets/pie_menu.cpp + gui/widgets/segmented_button_layout.cpp + gui/widgets/settings_page.cpp + gui/widgets/symbol_dropdown.cpp + gui/widgets/symbol_render_widget.cpp + gui/widgets/symbol_tooltip.cpp + gui/widgets/symbol_widget.cpp + gui/widgets/tag_select_widget.cpp + gui/widgets/tags_widget.cpp + gui/widgets/template_list_widget.cpp + gui/widgets/text_alignment_widget.cpp + + util/encoding.cpp + util/item_delegates.cpp + util/overriding_shortcut.cpp + util/recording_translator.cpp + util/scoped_signals_blocker.cpp + util/xml_stream_util.cpp +) + +set(Mapper_Common_MOC_INPUT + color_dock_widget.h + compass.h + file_format_ocad8_p.h + file_format_xml_p.h + file_import_export.h + gps_display.h + gps_temporary_markers.h + gps_track_recorder.h + map.h + map_dialog_new.h + map_dialog_scale.h + map_dialog_rotate.h + map_editor.h + map_editor_p.h + map_editor_activity.h + object_undo.h + map_widget.h + settings.h + symbol_area.h + symbol_combined.h + symbol_dialog_replace.h + symbol_line.h + symbol_point.h + symbol_point_editor.h + symbol_properties_widget.h + symbol_setting_dialog.h + symbol_text.h + template.h + template_adjust.h + template_dialog_reopen.h + template_track.h + template_image.h + template_map.h + template_position_dock_widget.h + template_tool_move.h + template_tool_paint.h + tool.h + tool_base.h + tool_cut.h + tool_cut_hole.h + tool_cutout.h + tool_distribute_points.h + tool_draw_circle.h + tool_draw_freehand.h + tool_draw_line_and_area.h + tool_draw_path.h + tool_draw_point.h + tool_draw_point_gps.h + tool_draw_rectangle.h + tool_draw_text.h + tool_edit.h + tool_edit_point.h + tool_edit_line.h + tool_fill.h + tool_helpers.h + tool_pan.h + tool_rotate.h + tool_rotate_pattern.h + tool_scale.h + undo_manager.h + util_task_dialog.h + + core/autosave_p.h + core/georeferencing.h + core/map_printer.h + core/map_view.h + + fileformats/ocd_file_export.h + fileformats/ocd_file_import.h + + gui/about_dialog.h + gui/autosave_dialog.h + gui/color_dialog.h + gui/configure_grid_dialog.h + gui/georeferencing_dialog.h + gui/home_screen_controller.h + gui/main_window.h + gui/main_window_controller.h + gui/print_progress_dialog.h + gui/print_tool.h + gui/print_widget.h + gui/select_crs_dialog.h + gui/settings_dialog.h + gui/text_browser_dialog.h + + gui/widgets/action_grid_bar.h + gui/widgets/color_dropdown.h + gui/widgets/compass_display.h + gui/widgets/crs_param_widgets.h + gui/widgets/crs_selector.h + gui/widgets/editor_settings_page.h + gui/widgets/general_settings_page.h + gui/widgets/home_screen_widget.h + gui/widgets/key_button_bar.h + gui/widgets/mapper_proxystyle.h + gui/widgets/measure_widget.h + gui/widgets/pie_menu.h + gui/widgets/segmented_button_layout.h + gui/widgets/settings_page.h + gui/widgets/symbol_dropdown.h + gui/widgets/symbol_render_widget.h + gui/widgets/symbol_tooltip.h + gui/widgets/symbol_widget.h + gui/widgets/tag_select_widget.h + gui/widgets/tags_widget.h + gui/widgets/template_list_widget.h + gui/widgets/text_alignment_widget.h + + util/item_delegates.h + util/overriding_shortcut.h + util/recording_translator.h +) + +# Extra header to show in the IDE, but not be written to src.pro +set(Mapper_Common_HEADERS + core/crs_template.h + core/crs_template_implementation.h + core/image_transparency_fixup.h + core/latlon.h + core/map_coord.h + core/map_grid.h + core/path_coord.h + core/virtual_path.cpp + core/virtual_coord_vector.h + + fileformats/ocd_file_format.h + fileformats/ocd_types.h + fileformats/ocd_types_v8.h + fileformats/ocd_types_v9.h + fileformats/ocd_types_v10.h + fileformats/ocd_types_v11.h + fileformats/ocd_types_v12.h + + gui/point_handles.h + + util/backports.h + util/memory.h + util/scoped_signals_blocker.h + + map_part.h + map_part_undo.h + object_operations.h + renderable.h + renderable_implementation.h + symbol.h + undo.h + util_gui.h +) + +qt5_wrap_cpp(Mapper_Common_MOC ${Mapper_Common_MOC_INPUT} TARGET Mapper_Common) + +# Resources (from project root) + +if(MAPPER_USE_QT_CONF_QRC) + set(Mapper_RESOURCES ${Mapper_RESOURCES} ${PROJECT_BINARY_DIR}/3rd-party/qt5/qt.conf.qrc) +endif() +set(Mapper_RESOURCES ${Mapper_RESOURCES} ${PROJECT_SOURCE_DIR}/resources.qrc) +qt5_add_resources(Mapper_RESOURCES_RCC ${Mapper_RESOURCES} OPTIONS -no-compress) + + +# Mapper common: static library of full runtime +# (To be used by Mapper executable and by system tests.) + +add_library(Mapper_Common STATIC + ${Mapper_Common_SRCS} + ${Mapper_Common_MOC} + ${Mapper_Common_MOC_INPUT} # for IDE + ${Mapper_Common_HEADERS} # for IDE + ${Mapper_RESOURCES_RCC} +) +add_dependencies(Mapper_Common + Mapper_prerequisites +) +target_link_libraries(Mapper_Common + libocad + Polyclipping::Polyclipping + printsupport + PROJ4::proj + Qt5::Widgets + Qt5::Xml +) +if(Qt5Network_FOUND) + target_link_libraries(Mapper_Common + Qt5::Network + ) +endif() +if(Qt5PrintSupport_FOUND) + target_link_libraries(Mapper_Common + Qt5::PrintSupport + ) +endif() +if(TARGET mapper-gdal) + target_link_libraries(Mapper_Common mapper-gdal) +endif() +target_compile_definitions(Mapper_Common PRIVATE + QT_NO_CAST_FROM_ASCII + QT_NO_CAST_TO_ASCII + QT_USE_QSTRINGBUILDER +) + +qt5_translations_sources( + SOURCES ${Mapper_Common_SRCS} ${Mapper_COMMON_MOC_INPUT} +) + + +# Mapper executable + +set(Mapper_SRCS + main.cpp +) + +if(WIN32) + enable_language(RC) + if(MINGW) + # Cf. http://public.kitware.com/Bug/view.php?id=14865 + if(CMAKE_RC_COMPILER MATCHES "windres\$" AND CMAKE_RC_COMPILE_OBJECT MATCHES "/fo") + include(Platform/${CMAKE_SYSTEM_NAME}-windres) + endif() + endif() + configure_file(mingw/resources.rc.in ${CMAKE_CURRENT_BINARY_DIR}/resources.rc @ONLY) + configure_file(${PROJECT_SOURCE_DIR}/images/mapper-icon/Mapper.ico ${CMAKE_CURRENT_BINARY_DIR}/Mapper.ico COPYONLY) + list(APPEND Mapper_SRCS ${CMAKE_CURRENT_BINARY_DIR}/resources.rc) +endif() + +add_executable(Mapper + WIN32 + MACOSX_BUNDLE + ${Mapper_SRCS} +) + +if(TARGET QtSingleApplication) + target_link_libraries(Mapper QtSingleApplication) +endif() + +target_link_libraries(Mapper + Mapper_Common + doc-licensing +) +target_compile_definitions(Mapper PRIVATE + QT_NO_CAST_FROM_ASCII + QT_NO_CAST_TO_ASCII + QT_USE_QSTRINGBUILDER +) + +install(TARGETS Mapper + RUNTIME DESTINATION "${MAPPER_RUNTIME_DESTINATION}" + BUNDLE DESTINATION "${MAPPER_RUNTIME_DESTINATION}" +) + +if(Mapper_BUILD_QT) + write_qt_conf() +elseif(EXISTS "${CMAKE_CURRENT_BINARY_DIR}/qt.conf") + file(REMOVE "${CMAKE_CURRENT_BINARY_DIR}/qt.conf") +endif() + + +# Workaround Qt private include dir issue +# Cf. https://bugreports.qt.io/browse/QTBUG-37417 + +if(WIN32) + set(PRIVATE_MODULES Core Gui PrintSupport) +else() + set(PRIVATE_MODULES) +endif() +foreach(module ${PRIVATE_MODULES}) + set(qt_module Qt${module}) + set(qt5_module Qt5${module}) + if("${${qt5_module}_PRIVATE_INCLUDE_DIRS}" STREQUAL "") + foreach(base_dir ${${qt5_module}_INCLUDE_DIRS}) + if("${base_dir}" MATCHES "/${qt_module}\$") + list(APPEND ${qt5_module}_PRIVATE_INCLUDE_DIRS "${base_dir}/${${qt5_module}_VERSION}/${qt_module}") + endif() + endforeach() + endif() + target_include_directories(Mapper_Common PRIVATE ${${qt5_module}_PRIVATE_INCLUDE_DIRS}) +endforeach() + + +# qmake configuration + +set(MAPPER_PRO_GENERATOR "Generated in CMakeLists.txt from src.pro.in") +string(REPLACE ";" " \\\n " MAPPER_PRO_HEADERS "${Mapper_Common_MOC_INPUT};${Mapper_Common_HEADERS}") +string(REPLACE ";" " \\\n " MAPPER_PRO_SOURCES "${Mapper_Common_SRCS}") +configure_file(src.pro.in src.pro.tmp @ONLY) +execute_process(COMMAND "${CMAKE_COMMAND}" -E copy_if_different "${CMAKE_CURRENT_BINARY_DIR}/src.pro.tmp" "${CMAKE_CURRENT_SOURCE_DIR}/src.pro") diff --git a/src/color_dock_widget.cpp b/src/color_dock_widget.cpp new file mode 100644 index 0000000..708fb53 --- /dev/null +++ b/src/color_dock_widget.cpp @@ -0,0 +1,456 @@ +/* + * Copyright 2012, 2013 Thomas Schöps + * Copyright 2012-2015 Kai Pastor + * + * This file is part of OpenOrienteering. + * + * OpenOrienteering is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenOrienteering is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenOrienteering. If not, see . + */ + + +#include "color_dock_widget.h" + +#include +#include +#include +#include +#include +#include +#include + +#include "core/map_color.h" +#include "map.h" +#include "util.h" +#include "util_gui.h" +#include "util/item_delegates.h" +#include "gui/color_dialog.h" +#include "gui/main_window.h" +#include "gui/widgets/segmented_button_layout.h" + +ColorWidget::ColorWidget(Map* map, MainWindow* window, QWidget* parent) +: QWidget(parent), + map(map), + window(window) +{ + react_to_changes = true; + + setWhatsThis(Util::makeWhatThis("color_dock_widget.html")); + + // Color table + color_table = new QTableWidget(map->getNumColors(), 7); + color_table->setEditTriggers(QAbstractItemView::SelectedClicked | QAbstractItemView::AnyKeyPressed); + color_table->setSelectionMode(QAbstractItemView::SingleSelection); + color_table->setSelectionBehavior(QAbstractItemView::SelectRows); + color_table->verticalHeader()->setVisible(false); + color_table->setHorizontalHeaderLabels(QStringList() << + QString{} << tr("Name") << tr("Spot color") << tr("CMYK") << tr("RGB") << tr("K.o.") << tr("Opacity") ); + color_table->setItemDelegateForColumn(0, new ColorItemDelegate(this)); + color_table->setItemDelegateForColumn(6, new PercentageDelegate(this)); + color_table->setColumnHidden(6, true); + + QMenu* new_button_menu = new QMenu(this); + (void) new_button_menu->addAction(tr("New"), this, SLOT(newColor())); + duplicate_action = new_button_menu->addAction(tr("Duplicate"), this, SLOT(duplicateColor())); + duplicate_action->setIcon(QIcon(QString::fromLatin1(":/images/tool-duplicate.png"))); + + // Buttons + QToolButton* new_button = newToolButton(QIcon(QString::fromLatin1(":/images/plus.png")), tr("New")); + new_button->setPopupMode(QToolButton::DelayedPopup); // or MenuButtonPopup + new_button->setMenu(new_button_menu); + delete_button = newToolButton(QIcon(QString::fromLatin1(":/images/minus.png")), tr("Delete")); + + SegmentedButtonLayout* add_remove_layout = new SegmentedButtonLayout(); + add_remove_layout->addWidget(new_button); + add_remove_layout->addWidget(delete_button); + + move_up_button = newToolButton(QIcon(QString::fromLatin1(":/images/arrow-up.png")), tr("Move Up")); + move_up_button->setAutoRepeat(true); + move_down_button = newToolButton(QIcon(QString::fromLatin1(":/images/arrow-down.png")), tr("Move Down")); + move_down_button->setAutoRepeat(true); + + SegmentedButtonLayout* up_down_layout = new SegmentedButtonLayout(); + up_down_layout->addWidget(move_up_button); + up_down_layout->addWidget(move_down_button); + + // TODO: In Mapper >= 0.6, switch to ColorWidget (or generic) translation context. + edit_button = newToolButton(QIcon(QString::fromLatin1(":/images/settings.png")), QApplication::translate("MapEditorController", "&Edit").remove(QLatin1Char('&'))); + edit_button->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); + + QToolButton* help_button = newToolButton(QIcon(QString::fromLatin1(":/images/help.png")), tr("Help")); + help_button->setAutoRaise(true); + + // The buttons row layout + QBoxLayout* buttons_group_layout = new QHBoxLayout(); + buttons_group_layout->addLayout(add_remove_layout); + buttons_group_layout->addLayout(up_down_layout); + buttons_group_layout->addWidget(edit_button); + buttons_group_layout->addWidget(new QLabel(QString::fromLatin1(" ")), 1); + buttons_group_layout->addWidget(help_button); + + // The layout of all components below the table + QBoxLayout* bottom_layout = new QVBoxLayout(); + QStyleOption style_option(QStyleOption::Version, QStyleOption::SO_DockWidget); + bottom_layout->setContentsMargins( + style()->pixelMetric(QStyle::PM_LayoutLeftMargin, &style_option) / 2, + 0, // Covered by the main layout's spacing. + style()->pixelMetric(QStyle::PM_LayoutRightMargin, &style_option) / 2, + style()->pixelMetric(QStyle::PM_LayoutBottomMargin, &style_option) / 2 + ); + bottom_layout->addLayout(buttons_group_layout); + bottom_layout->addWidget(new QLabel(tr("Double-click a color value to open a dialog."))); + + // The main layout + QBoxLayout* layout = new QVBoxLayout(); + layout->setContentsMargins(QMargins()); + layout->addWidget(color_table, 1); + layout->addLayout(bottom_layout); + setLayout(layout); + + for (int i = 0; i < map->getNumColors(); ++i) + addRow(i); + + QHeaderView* header_view = color_table->horizontalHeader(); + header_view->setSectionResizeMode(QHeaderView::Interactive); + header_view->resizeSections(QHeaderView::ResizeToContents); + header_view->setSectionResizeMode(0, QHeaderView::Fixed); // Color + header_view->resizeSection(0, 32); + header_view->setSectionResizeMode(1, QHeaderView::Stretch); // Name + header_view->setSectionResizeMode(1, QHeaderView::Interactive); // Spot colors + header_view->setSectionResizeMode(5, QHeaderView::Fixed); // Knockout + header_view->resizeSection(5, 32); + header_view->setSectionsClickable(false); + + currentCellChange(color_table->currentRow(), 0, 0, 0); // enable / disable move color buttons + + // Connections + connect(color_table, SIGNAL(cellChanged(int,int)), this, SLOT(cellChange(int,int))); + connect(color_table, SIGNAL(currentCellChanged(int,int,int,int)), this, SLOT(currentCellChange(int,int,int,int))); + connect(color_table, SIGNAL(cellDoubleClicked(int,int)), this, SLOT(editCurrentColor())); + + connect(new_button, SIGNAL(clicked(bool)), this, SLOT(newColor())); + connect(delete_button, SIGNAL(clicked(bool)), this, SLOT(deleteColor())); + connect(move_up_button, SIGNAL(clicked(bool)), this, SLOT(moveColorUp())); + connect(move_down_button, SIGNAL(clicked(bool)), this, SLOT(moveColorDown())); + connect(edit_button, SIGNAL(clicked(bool)), this, SLOT(editCurrentColor())); + connect(help_button, SIGNAL(clicked(bool)), this, SLOT(showHelp())); + + connect(map, SIGNAL(colorAdded(int, const MapColor*)), this, SLOT(colorAdded(int, const MapColor*))); + connect(map, SIGNAL(colorChanged(int, const MapColor*)), this, SLOT(colorChanged(int, const MapColor*))); + connect(map, SIGNAL(colorDeleted(int, const MapColor*)), this, SLOT(colorDeleted(int, const MapColor*))); +} + +ColorWidget::~ColorWidget() +{ +} + +QToolButton* ColorWidget::newToolButton(const QIcon& icon, const QString& text) +{ + QToolButton* button = new QToolButton(); + button->setToolButtonStyle(Qt::ToolButtonFollowStyle); + button->setToolTip(text); + button->setIcon(icon); + button->setText(text); + button->setWhatsThis(whatsThis()); + return button; +} + +void ColorWidget::newColor() +{ + int row = color_table->currentRow(); + if (row < 0) + row = color_table->rowCount(); + map->addColor(new MapColor(), row); + + map->updateAllObjects(); + + editCurrentColor(); +} + +void ColorWidget::deleteColor() +{ + int row = color_table->currentRow(); + Q_ASSERT(row >= 0); + if (row < 0) return; // In release mode + + // Show a warning if the color is used + if (map->isColorUsedByASymbol(map->getColor(row))) + { + if (QMessageBox::warning(this, tr("Confirmation"), tr("The map contains symbols with this color. Deleting it will remove the color from these objects! Do you really want to do that?"), QMessageBox::Yes | QMessageBox::No) == QMessageBox::No) + return; + } + + map->deleteColor(row); + + map->setColorsDirty(); + map->updateAllObjects(); +} + +void ColorWidget::duplicateColor() +{ + int row = color_table->currentRow(); + Q_ASSERT(row >= 0); + if (row < 0) return; // In release mode + + MapColor* new_color = new MapColor(*map->getColor(row)); + new_color->setName(new_color->getName() + tr(" (Duplicate)")); + map->addColor(new_color, row); + + map->updateAllObjects(); + + editCurrentColor(); +} + +void ColorWidget::moveColorUp() +{ + int row = color_table->currentRow(); + Q_ASSERT(row >= 1); + if (row < 1) return; // In release mode + + MapColor* above_color = map->getMapColor(row - 1); + MapColor* cur_color = map->getMapColor(row); + map->setColor(cur_color, row - 1); + map->setColor(above_color, row); + updateRow(row - 1); + updateRow(row); + + color_table->setCurrentCell(row - 1, color_table->currentColumn()); + + map->setColorsDirty(); + map->updateAllObjects(); +} + +void ColorWidget::moveColorDown() +{ + int row = color_table->currentRow(); + Q_ASSERT(row < color_table->rowCount() - 1); + if (row >= color_table->rowCount() - 1) return; // In release mode + + MapColor* below_color = map->getMapColor(row + 1); + MapColor* cur_color = map->getMapColor(row); + map->setColor(cur_color, row + 1); + map->setColor(below_color, row); + updateRow(row + 1); + updateRow(row); + + color_table->setCurrentCell(row + 1, color_table->currentColumn()); + + map->setColorsDirty(); + map->updateAllObjects(); +} + +// slot +void ColorWidget::editCurrentColor() +{ + int row = color_table->currentRow(); + if (row >= 0) + { + MapColor* color = map->getMapColor(row); + ColorDialog dialog(*map, *color, this); + dialog.setWindowModality(Qt::WindowModal); + int result = dialog.exec(); + if (result == QDialog::Accepted) + { + *color = dialog.getColor(); + map->setColor(color, row); // trigger colorChanged signal + map->setColorsDirty(); + map->updateAllObjects(); + } + } +} + +void ColorWidget::showHelp() const +{ + Util::showHelp(window, "color_dock_widget.html"); +} + +void ColorWidget::cellChange(int row, int column) +{ + if (!react_to_changes) + return; + + react_to_changes = false; + + MapColor* color = map->getMapColor(row); + QString text = color_table->item(row, column)->text().trimmed(); + + if (column == 1) + { + color->setName(text); + react_to_changes = true; + } + else if (column == 6) // Opacity + { + auto opacity = color_table->item(row, column)->data(Qt::DisplayRole).toFloat(); + if (!qFuzzyCompare(1.0f+opacity, 1.0f+color->getOpacity())) + { + color->setOpacity(qBound(0.0f, opacity, 1.0f)); + updateRow(row); + } + react_to_changes = true; + } + else + { + react_to_changes = true; + return; + } + + map->setColor(color, row); // trigger colorChanged signal + map->setColorsDirty(); + map->updateAllObjects(); +} + +void ColorWidget::currentCellChange(int current_row, int current_column, int previous_row, int previous_column) +{ + Q_UNUSED(current_column); + Q_UNUSED(previous_row); + Q_UNUSED(previous_column); + if (!react_to_changes) + return; + + bool valid_row = (current_row >= 0); + delete_button->setEnabled(valid_row); + duplicate_action->setEnabled(valid_row); + move_up_button->setEnabled(valid_row && current_row >= 1); + move_down_button->setEnabled(valid_row && current_row < color_table->rowCount() - 1); + edit_button->setEnabled(valid_row); +} + +void ColorWidget::colorAdded(int index, const MapColor* color) +{ + Q_UNUSED(color); + color_table->insertRow(index); + addRow(index); + if (index < color_table->rowCount() - 1) + { + updateRow(index + 1); + } + color_table->setCurrentCell(index, 1); +} + +void ColorWidget::colorChanged(int index, const MapColor* color) +{ + Q_UNUSED(color); + updateRow(index); +} + +void ColorWidget::colorDeleted(int index, const MapColor* color) +{ + Q_UNUSED(color); + color_table->removeRow(index); + currentCellChange(color_table->currentRow(), color_table->currentColumn(), -1, -1); +} + +void ColorWidget::addRow(int row) +{ + react_to_changes = false; + + QTableWidgetItem* item; + for (int col = 0; col < color_table->columnCount(); ++col) + { + item = new QTableWidgetItem(); + item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); + // TODO: replace "define" with "edit" + item->setToolTip(tr("Double click to define the color")); + color_table->setItem(row, col, item); + } + + // Name + item = color_table->item(row, 1); + item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsEditable); + item->setToolTip(tr("Click to select the name and click again to edit.")); + + // Opacity + item = color_table->item(row, 6); + item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsEditable); + + react_to_changes = true; + + updateRow(row); +} + +void ColorWidget::updateRow(int row) +{ + react_to_changes = false; + + const MapColor* color = map->getColor(row); + auto color_with_opacity = colorWithOpacity(*color); + + // Color preview + QTableWidgetItem* item = color_table->item(row, 0); + item->setBackground(color_with_opacity); + + // Name + item = color_table->item(row, 1); + item->setText(color->getName()); + + // Spot color + item = color_table->item(row, 2); + item->setText(color->getSpotColorName()); + switch (color->getSpotColorMethod()) + { + case MapColor::SpotColor: + item->setData(Qt::DecorationRole, color_with_opacity); + break; + default: + item->setData(Qt::DecorationRole, QColor(Qt::transparent)); + } + + // CMYK + item = color_table->item(row, 3); + item->setToolTip(tr("Double click to define the color")); + const MapColorCmyk& cmyk = color->getCmyk(); + QLocale l; + item->setText(QString::fromLatin1("%1/%2/%3/%4").arg( + l.toString(100*cmyk.c, 'g', 3), l.toString(100*cmyk.m, 'g', 3), + l.toString(100*cmyk.y, 'g', 3), l.toString(100*cmyk.k, 'g', 3))); + switch (color->getCmykColorMethod()) + { + case MapColor::SpotColor: + case MapColor::RgbColor: + item->setForeground(palette().color(QPalette::Disabled, QPalette::Text)); + item->setData(Qt::DecorationRole, QColor(Qt::transparent)); + break; + default: + item->setForeground(palette().color(QPalette::Active, QPalette::Text)); + item->setData(Qt::DecorationRole, colorWithOpacity(color->getCmyk(), color->getOpacity())); + } + + // RGB + item = color_table->item(row, 4); + item->setText(QColor(color->getRgb()).name()); + item->setToolTip(item->text()); + switch (color->getRgbColorMethod()) + { + case MapColor::SpotColor: + case MapColor::CmykColor: + item->setForeground(palette().color(QPalette::Disabled, QPalette::Text)); + item->setData(Qt::DecorationRole, QColor(Qt::transparent)); + break; + default: + item->setForeground(palette().color(QPalette::Active, QPalette::Text)); + item->setData(Qt::DecorationRole, colorWithOpacity(color->getRgb(), color->getOpacity())); + } + + // Knockout + item = color_table->item(row, 5); + item->setCheckState(color->getKnockout() ? Qt::Checked : Qt::Unchecked); + item->setForeground(palette().color(QPalette::Disabled, QPalette::Text)); + + // Opacity + item = color_table->item(row, 6); + item->setData(Qt::DisplayRole, color->getOpacity()); + + react_to_changes = true; +} + diff --git a/src/color_dock_widget.h b/src/color_dock_widget.h new file mode 100644 index 0000000..d41ea9a --- /dev/null +++ b/src/color_dock_widget.h @@ -0,0 +1,91 @@ +/* + * Copyright 2012, 2013 Thomas Schöps + * Copyright 2012, 2013, 2014 Kai Pastor + * + * This file is part of OpenOrienteering. + * + * OpenOrienteering is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenOrienteering is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenOrienteering. If not, see . + */ + + +#ifndef _OPENORIENTEERING_COLOR_DOCK_WIDGET_H_ +#define _OPENORIENTEERING_COLOR_DOCK_WIDGET_H_ + +#include + +class QAction; +class QTableWidget; +class QToolButton; + +class ColorDropDown; +class MainWindow; +class Map; +class MapColor; +class PaletteColor; + +/** + * A widget showing the list of map colors and some edit buttons at the bottom. + * Enables to define new colors and edit or delete existing colors. + * This widget is used inside a dock widget. + */ +class ColorWidget : public QWidget +{ +Q_OBJECT +public: + /** Creates a new ColorWidget for a given map and MainWindow. */ + ColorWidget(Map* map, MainWindow* window, QWidget* parent = NULL); + + /** Destroys the ColorWidget. */ + virtual ~ColorWidget(); + +protected slots: + void newColor(); + void deleteColor(); + void duplicateColor(); + void moveColorUp(); + void moveColorDown(); + void editCurrentColor(); + void showHelp() const; + + void cellChange(int row, int column); + void currentCellChange(int current_row, int current_column, int previous_row, int previous_column); + + void colorAdded(int index, const MapColor* color); + void colorChanged(int index, const MapColor* color); + void colorDeleted(int index, const MapColor* color); + +protected: + QToolButton* newToolButton(const QIcon& icon, const QString& text); + +private: + void addRow(int row); + void updateRow(int row); + + // Color list + QTableWidget* color_table; + + QAction* duplicate_action; + + // Buttons + QToolButton* delete_button; + QToolButton* move_up_button; + QToolButton* move_down_button; + QToolButton* edit_button; + + Map* const map; + MainWindow* const window; + bool react_to_changes; +}; + +#endif diff --git a/src/compass.cpp b/src/compass.cpp new file mode 100644 index 0000000..f158112 --- /dev/null +++ b/src/compass.cpp @@ -0,0 +1,589 @@ +/* + * Copyright 2014 Thomas Schöps, Kai Pastor + * + * This file is part of OpenOrienteering. + * + * OpenOrienteering is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenOrienteering is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenOrienteering. If not, see . + */ + +#include "compass.h" + +#include +#include +#include +#include + + +namespace SensorHelpers +{ + void matrixMultiplication(float* A, float* B, float* result) + { + result[0] = A[0] * B[0] + A[1] * B[3] + A[2] * B[6]; + result[1] = A[0] * B[1] + A[1] * B[4] + A[2] * B[7]; + result[2] = A[0] * B[2] + A[1] * B[5] + A[2] * B[8]; + + result[3] = A[3] * B[0] + A[4] * B[3] + A[5] * B[6]; + result[4] = A[3] * B[1] + A[4] * B[4] + A[5] * B[7]; + result[5] = A[3] * B[2] + A[4] * B[5] + A[5] * B[8]; + + result[6] = A[6] * B[0] + A[7] * B[3] + A[8] * B[6]; + result[7] = A[6] * B[1] + A[7] * B[4] + A[8] * B[7]; + result[8] = A[6] * B[2] + A[7] * B[5] + A[8] * B[8]; + } + + /** + * Ported from android.hardware.SensorManager.getOrientation(). + * + * Computes the device's orientation based on the rotation matrix. + *

When it returns, the array values is filled with the result: + *

+ *

+ */ + void getOrientation(float* R, float* values) + { + /* + * / R[ 0] R[ 1] R[ 2] \ + * | R[ 3] R[ 4] R[ 5] | + * \ R[ 6] R[ 7] R[ 8] / + */ + values[0] = (float)atan2(R[1], R[4]); + values[1] = (float)asin(-R[7]); + values[2] = (float)atan2(-R[6], R[8]); + } + + /** From http://www.thousand-thoughts.com/2012/03/android-sensor-fusion-tutorial/2/ + * Should be optimized ... */ + void getRotationMatrixFromOrientation(float* orientation, float* result) + { + float xM[9]; + float yM[9]; + float zM[9]; + + float sinX = (float)qSin(orientation[1]); + float cosX = (float)qCos(orientation[1]); + float sinY = (float)qSin(orientation[2]); + float cosY = (float)qCos(orientation[2]); + float sinZ = (float)qSin(orientation[0]); + float cosZ = (float)qCos(orientation[0]); + + // rotation about x-axis (pitch) + xM[0] = 1.0f; xM[1] = 0.0f; xM[2] = 0.0f; + xM[3] = 0.0f; xM[4] = cosX; xM[5] = sinX; + xM[6] = 0.0f; xM[7] = -sinX; xM[8] = cosX; + + // rotation about y-axis (roll) + yM[0] = cosY; yM[1] = 0.0f; yM[2] = sinY; + yM[3] = 0.0f; yM[4] = 1.0f; yM[5] = 0.0f; + yM[6] = -sinY; yM[7] = 0.0f; yM[8] = cosY; + + // rotation about z-axis (azimuth) + zM[0] = cosZ; zM[1] = sinZ; zM[2] = 0.0f; + zM[3] = -sinZ; zM[4] = cosZ; zM[5] = 0.0f; + zM[6] = 0.0f; zM[7] = 0.0f; zM[8] = 1.0f; + + // rotation order is y, x, z (roll, pitch, azimuth) + float temp[9]; + matrixMultiplication(xM, yM, temp); + matrixMultiplication(zM, temp, result); + } + + /** + * Ported from android.hardware.SensorManager.getRotationMatrix(). + * + * Computes the inclination matrix I as well as the rotation + * matrix R transforming a vector from the + * device coordinate system to the world's coordinate system [...] + */ + bool getRotationMatrix(float* R, float* gravity, float* geomagnetic) + { + float Ax = gravity[0]; + float Ay = gravity[1]; + float Az = gravity[2]; + // Change relative to Android version: scale values from teslas to microteslas + const float to_micro = 1000*1000; + const float Ex = to_micro * geomagnetic[0]; + const float Ey = to_micro * geomagnetic[1]; + const float Ez = to_micro * geomagnetic[2]; + + float Hx = Ey*Az - Ez*Ay; + float Hy = Ez*Ax - Ex*Az; + float Hz = Ex*Ay - Ey*Ax; + const float normH = (float)sqrt(Hx*Hx + Hy*Hy + Hz*Hz); + if (normH < 0.1f) { + // device is close to free fall (or in space?), or close to + // magnetic north pole. Typical values are > 100. + return false; + } + const float invH = 1.0f / normH; + Hx *= invH; + Hy *= invH; + Hz *= invH; + const float invA = 1.0f / (float)sqrt(Ax*Ax + Ay*Ay + Az*Az); + Ax *= invA; + Ay *= invA; + Az *= invA; + const float Mx = Ay*Hz - Az*Hy; + const float My = Az*Hx - Ax*Hz; + const float Mz = Ax*Hy - Ay*Hx; + + R[0] = Hx; R[1] = Hy; R[2] = Hz; + R[3] = Mx; R[4] = My; R[5] = Mz; + R[6] = Ax; R[7] = Ay; R[8] = Az; + +// if (I != null) { +// // compute the inclination matrix by projecting the geomagnetic +// // vector onto the Z (gravity) and X (horizontal component +// // of geomagnetic vector) axes. +// const float invE = 1.0f / (float)std::sqrt(Ex*Ex + Ey*Ey + Ez*Ez); +// const float c = (Ex*Mx + Ey*My + Ez*Mz) * invE; +// const float s = (Ex*Ax + Ey*Ay + Ez*Az) * invE; +// I[0] = 1; I[1] = 0; I[2] = 0; +// I[3] = 0; I[4] = c; I[5] = s; +// I[6] = 0; I[7] =-s; I[8] = c; +// } + return true; + } + + /** + * Ported from android.hardware.SensorManager.getRotationMatrixFromVector(). + * + * Helper function to convert a rotation vector to a rotation matrix. + */ + void getRotationMatrixFromVector(float* R, float* rotationVector) + { + float q0; + float q1 = rotationVector[0]; + float q2 = rotationVector[1]; + float q3 = rotationVector[2]; + +// if (rotationVector.length == 4) { + q0 = rotationVector[3]; +// } else { +// q0 = 1 - q1*q1 - q2*q2 - q3*q3; +// q0 = (q0 > 0) ? (float)std::sqrt(q0) : 0; +// } + + float sq_q1 = 2 * q1 * q1; + float sq_q2 = 2 * q2 * q2; + float sq_q3 = 2 * q3 * q3; + float q1_q2 = 2 * q1 * q2; + float q3_q0 = 2 * q3 * q0; + float q1_q3 = 2 * q1 * q3; + float q2_q0 = 2 * q2 * q0; + float q2_q3 = 2 * q2 * q3; + float q1_q0 = 2 * q1 * q0; + + R[0] = 1 - sq_q2 - sq_q3; + R[1] = q1_q2 - q3_q0; + R[2] = q1_q3 + q2_q0; + + R[3] = q1_q2 + q3_q0; + R[4] = 1 - sq_q1 - sq_q3; + R[5] = q2_q3 - q1_q0; + + R[6] = q1_q3 - q2_q0; + R[7] = q2_q3 + q1_q0; + R[8] = 1 - sq_q1 - sq_q2; + } +} + + +#ifdef QT_SENSORS_LIB +#include +#include +#include +#include +#include +#include + +#ifdef Q_OS_ANDROID +#include +#endif + +class CompassPrivate : public QGyroscopeFilter +{ +public: + CompassPrivate(Compass* compass) + : thread(this) + , compass(compass) + , enabled(false) + , latest_azimuth(-1) + { + // Try to filter out non-gravity sources of acceleration + accelerometer.setAccelerationMode(QAccelerometer::Gravity); + + // Try to filter out local magnetic interference + magnetometer.setReturnGeoValues(true); + + // Check if a gyroscope is available + gyro_available = ! QSensor::sensorsForType(QGyroscope::type).empty(); + if (gyro_available) + gyroscope.addFilter(this); + + thread.start(); + } + + ~CompassPrivate() + { + thread.keep_running = false; + thread.condition.wakeAll(); + thread.wait(); + } + + void enable(bool enabled) + { + if (enabled) + { + last_gyro_timestamp = 0; + gyro_orientation_initialized = false; + + accelerometer.start(); + magnetometer.start(); + gyroscope.start(); + + thread.wait_mutex.lock(); + this->enabled = true; + thread.condition.wakeAll(); + thread.wait_mutex.unlock(); + } + else + { + this->enabled = false; + gyroscope.stop(); + magnetometer.stop(); + accelerometer.stop(); + } + } + + float getLatestAzimuth() + { + return latest_azimuth; + } + + /** Called on new gyro readings */ + virtual bool filter(QGyroscopeReading* reading) + { + if (! gyro_orientation_initialized) + return false; + + if (last_gyro_timestamp > 0) + { + // Calculate rotation matrix from gyro reading according to Android developer documentation + const float EPSILON = 1e-9f; + + const float microseconds_to_seconds = 1.0f / (1000*1000); + const float dt = (reading->timestamp() - last_gyro_timestamp) * microseconds_to_seconds; + // Axis of the rotation sample, not normalized yet. + const float deg_to_rad = M_PI / 180.0f; + float axisX = deg_to_rad * reading->x(); + float axisY = deg_to_rad * reading->y(); + float axisZ = deg_to_rad * reading->z(); + + // Calculate the angular speed of the sample + float omegaMagnitude = sqrt(axisX*axisX + axisY*axisY + axisZ*axisZ); + + // Normalize the rotation vector if it's big enough to get the axis + if (omegaMagnitude > EPSILON) { + axisX /= omegaMagnitude; + axisY /= omegaMagnitude; + axisZ /= omegaMagnitude; + } + + // Integrate around this axis with the angular speed by the timestep + // in order to get a delta rotation from this sample over the timestep + // We will convert this axis-angle representation of the delta rotation + // into a quaternion before turning it into the rotation matrix. + float thetaOverTwo = omegaMagnitude * dt / 2.0f; + float sinThetaOverTwo = qSin(thetaOverTwo); + float cosThetaOverTwo = qCos(thetaOverTwo); + float deltaRotationVector[4]; + deltaRotationVector[0] = sinThetaOverTwo * axisX; + deltaRotationVector[1] = sinThetaOverTwo * axisY; + deltaRotationVector[2] = sinThetaOverTwo * axisZ; + deltaRotationVector[3] = cosThetaOverTwo; + + float R[9]; + SensorHelpers::getRotationMatrixFromVector(R, deltaRotationVector); + + float temp[9]; + gyro_mutex.lock(); + SensorHelpers::matrixMultiplication(gyro_rotation_matrix, R, temp); + memcpy(gyro_rotation_matrix, temp, 9 * sizeof(float)); + SensorHelpers::getOrientation(gyro_rotation_matrix, gyro_orientation); + gyro_mutex.unlock(); + } + + last_gyro_timestamp = reading->timestamp(); + return true; + } + +private: + class SensorThread : public QThread + { + // no Q_OBJECT as it is not required here and was problematic in .cpp + //Q_OBJECT + public: + SensorThread(CompassPrivate* p) + : keep_running(true) + , p(p) + { + } + + float fuseOrientationCoefficient(float gyro, float acc_mag) + { + const float FILTER_COEFFICIENT = 0.98f; + const float ONE_MINUS_COEFF = 1.0f - FILTER_COEFFICIENT; + + float result; + // Correctly handle wrap-around + if (gyro < -0.5 * M_PI && acc_mag > 0.0) { + result = (float) (FILTER_COEFFICIENT * (gyro + 2.0 * M_PI) + ONE_MINUS_COEFF * acc_mag); + result -= (result > M_PI) ? 2.0 * M_PI : 0; + } + else if (acc_mag < -0.5 * M_PI && gyro > 0.0) { + result = (float) (FILTER_COEFFICIENT * gyro + ONE_MINUS_COEFF * (acc_mag + 2.0 * M_PI)); + result -= (result > M_PI)? 2.0 * M_PI : 0; + } + else { + result = FILTER_COEFFICIENT * gyro + ONE_MINUS_COEFF * acc_mag; + } + return result; + } + + void filter() + { + if (p->accelerometer.reading() == NULL || + p->magnetometer.reading() == NULL) + return; + + // Make copies of the sensor readings (and hope that the reading thread + // does not overwrite parts of them while they are being copied) + float acceleration[3] = { + (float) p->accelerometer.reading()->x(), + (float) p->accelerometer.reading()->y(), + (float) p->accelerometer.reading()->z() + }; + float geomagnetic[3] = { + (float) p->magnetometer.reading()->x(), + (float) p->magnetometer.reading()->y(), + (float) p->magnetometer.reading()->z() + }; + + // Calculate orientation from accelerometer and magnetometer (acc_mag_orientation) + float R[9]; + bool ok = SensorHelpers::getRotationMatrix(R, acceleration, geomagnetic); + if (!ok) + return; + + float acc_mag_orientation[3]; + SensorHelpers::getOrientation(R, acc_mag_orientation); + + // If gyro not initialized yet (or we do not have a gyro): + // use acc_mag_orientation (and initialize gyro if present) + float azimuth; + if (! p->gyro_available || ! p->gyro_orientation_initialized) + { + if (p->gyro_available) + { + memcpy(p->gyro_orientation, acc_mag_orientation, 3 * sizeof(float)); + SensorHelpers::getRotationMatrixFromOrientation(p->gyro_orientation, p->gyro_rotation_matrix); + p->gyro_orientation_initialized = true; + } + + azimuth = acc_mag_orientation[0]; + } + else + { + // Filter acc_mag_orientation and gyro_orientation to fused_orientation + p->gyro_mutex.lock(); + float fused_orientation[3]; + fused_orientation[0] = fuseOrientationCoefficient(p->gyro_orientation[0], acc_mag_orientation[0]); + fused_orientation[1] = fuseOrientationCoefficient(p->gyro_orientation[1], acc_mag_orientation[1]); + fused_orientation[2] = fuseOrientationCoefficient(p->gyro_orientation[2], acc_mag_orientation[2]); + + // Write back fused_orientation to gyro_orientation + SensorHelpers::getRotationMatrixFromOrientation(fused_orientation, p->gyro_rotation_matrix); + memcpy(p->gyro_orientation, fused_orientation, 3 * sizeof(float)); + p->gyro_mutex.unlock(); + + azimuth = fused_orientation[0]; + } + + p->latest_azimuth = 180 * azimuth / M_PI; +#ifdef Q_OS_ANDROID + // Adjust for display rotation + jint orientation = QAndroidJniObject::callStaticMethod( + "org/openorienteering/mapper/MapperActivity", + "getDisplayRotation"); + switch (orientation) + { + case 1: + p->latest_azimuth = (p->latest_azimuth < 90) ? (p->latest_azimuth + 90) : (p->latest_azimuth - 90); + break; + case 2: + p->latest_azimuth = (p->latest_azimuth < 180) ? (p->latest_azimuth + 180) : (p->latest_azimuth - 180); + break; + case 3: + p->latest_azimuth = (p->latest_azimuth < 270) ? (p->latest_azimuth + 270) : (p->latest_azimuth - 270); + break; + default: + ;// nothing + } +#endif + + // Send update to receivers + p->compass->emitAzimuthChanged(p->latest_azimuth); + } + + void run() + { + // Wait until sensors are initialized + QThread::msleep(1000); + + while (keep_running) + { + if (! p->enabled) + { + wait_mutex.lock(); + if (! p->enabled) + condition.wait(&wait_mutex); + wait_mutex.unlock(); + + // May do initializations after (re-)enabling here + } + + filter(); + + QThread::msleep(30); + } + } + + QMutex wait_mutex; + QWaitCondition condition; + bool keep_running; + CompassPrivate* p; + }; + + QAccelerometer accelerometer; + QMagnetometer magnetometer; + QGyroscope gyroscope; + bool gyro_available; + float gyro_orientation[3]; + float gyro_rotation_matrix[9]; + quint64 last_gyro_timestamp; + bool gyro_orientation_initialized; + QMutex gyro_mutex; + + SensorThread thread; + Compass* compass; + + bool enabled; + float latest_azimuth; +}; +#endif + + +Compass::Compass(): QObject() +{ + reference_counter = 0; +#ifdef QT_SENSORS_LIB + p = new CompassPrivate(this); +#else + p = NULL; +#endif +} + +Compass::~Compass() +{ +#ifdef QT_SENSORS_LIB + delete p; +#endif +} + +Compass& Compass::getInstance() +{ + static Compass theOneAndOnly; + return theOneAndOnly; +} + +void Compass::startUsage() +{ + ++ reference_counter; +#ifdef QT_SENSORS_LIB + if (reference_counter == 1) + p->enable(true); +#endif +} + +void Compass::stopUsage() +{ + -- reference_counter; +#ifdef QT_SENSORS_LIB + if (reference_counter == 0) + p->enable(false); +#endif +} + +float Compass::getCurrentAzimuth() +{ +#ifdef QT_SENSORS_LIB + return p->getLatestAzimuth(); +#elif MAPPER_DEVELOPMENT_BUILD + // DEBUG: rotate around ... + QTime now = QTime::currentTime(); + return 360 * (now.msecsSinceStartOfDay() % (10 * 1000)) / (float)(10 * 1000); +#else + return 0.0f; +#endif +} + +void Compass::connectToAzimuthChanges(const QObject* receiver, const char* slot) +{ +#ifdef QT_SENSORS_LIB + connect(this, SIGNAL(azimuthChanged(float)), receiver, slot, Qt::QueuedConnection); +#else + Q_UNUSED(receiver); + Q_UNUSED(slot); +#endif +} + +void Compass::disconnectFromAzimuthChanges(const QObject* receiver) +{ +#ifdef QT_SENSORS_LIB + this->disconnect(receiver); +#else + Q_UNUSED(receiver); +#endif +} + +void Compass::connectNotify(const QMetaMethod& signal) +{ + if (signal == QMetaMethod::fromSignal(&Compass::azimuthChanged)) + startUsage(); +} + +void Compass::disconnectNotify(const QMetaMethod& signal) +{ + if (signal == QMetaMethod::fromSignal(&Compass::azimuthChanged)) + stopUsage(); +} + +void Compass::emitAzimuthChanged(float value) +{ + emit azimuthChanged(value); +} diff --git a/src/compass.h b/src/compass.h new file mode 100644 index 0000000..5650685 --- /dev/null +++ b/src/compass.h @@ -0,0 +1,77 @@ +/* + * Copyright 2014 Thomas Schöps + * + * This file is part of OpenOrienteering. + * + * OpenOrienteering is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenOrienteering is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenOrienteering. If not, see . + */ + + +#ifndef _OPENORIENTEERING_COMPASS_H_ +#define _OPENORIENTEERING_COMPASS_H_ + +#include + +class CompassPrivate; + + +/** Provides access to the device's compass. Singleton class. */ +class Compass : public QObject +{ +Q_OBJECT +friend class CompassPrivate; +public: + ~Compass(); + + /** Singleton accessor method. Constructs the object on first use. */ + static Compass& getInstance(); + + /** Adds a reference. If this is the first one, initializes the compass. */ + void startUsage(); + + /** Dereferences compass usage. */ + void stopUsage(); + + /** Returns the most recent azimuth value + * (in degrees clockwise from north; updated approx. every 30 milliseconds). */ + float getCurrentAzimuth(); + + /** Connects to the azimuthChanged(float azimuth_degrees) signal. This ensures to use a queued + * connection, which is important because the data provider runs on another + * thread. Updates are delivered approx. every 30 milliseconds. */ + void connectToAzimuthChanges(const QObject* receiver, const char* slot); + + /** Disconnects the given receiver from azimuth changes. */ + void disconnectFromAzimuthChanges(const QObject* receiver); + +signals: + /** Emitted regularly with the current azimuth value (in degrees). + * Preferably use connectToAzimuthChanges() to connect to this signal. */ + void azimuthChanged(float azimuth); + +protected: + void connectNotify(const QMetaMethod& signal) override; + + void disconnectNotify(const QMetaMethod& signal) override; + +private: + Compass(); + + void emitAzimuthChanged(float value); + + int reference_counter; + CompassPrivate* p; +}; + +#endif diff --git a/src/core/autosave.cpp b/src/core/autosave.cpp new file mode 100644 index 0000000..0a20303 --- /dev/null +++ b/src/core/autosave.cpp @@ -0,0 +1,133 @@ +/* + * Copyright 2014 Kai Pastor + * + * This file is part of OpenOrienteering. + * + * OpenOrienteering is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenOrienteering is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenOrienteering. If not, see . + */ + +#include "autosave.h" +#include "autosave_p.h" + +#include "../settings.h" + +AutosavePrivate::AutosavePrivate(Autosave& document) +: document(document) +, autosave_needed(false) +{ + autosave_timer = new QTimer(this); + autosave_timer->setSingleShot(true); + connect(autosave_timer, SIGNAL(timeout()), this, SLOT(autosave())); + connect(&Settings::getInstance(), SIGNAL(settingsChanged()), this, SLOT(settingsChanged())); + settingsChanged(); +} + +AutosavePrivate::~AutosavePrivate() +{ + // nothing, not inlined +} + +void AutosavePrivate::settingsChanged() +{ + // Normally, the autosave interval can be stored as an integer. + // It is loaded as a double here to allow for faster unit testing. + autosave_interval = Settings::getInstance().getSetting(Settings::General_AutosaveInterval).toDouble() * 60000; + if (autosave_interval < 1000) + { + // stop autosave + autosave_interval = 0; + autosave_timer->stop(); + } + else if (autosave_needed && !autosave_timer->isActive()) + { + // start autosave + autosave_timer->setInterval(autosave_interval); + autosave_timer->start(); + } +} + +bool AutosavePrivate::autosaveNeeded() +{ + return autosave_needed; +} + +void AutosavePrivate::setAutosaveNeeded(bool needed) +{ + autosave_needed = needed; + if (autosave_interval) + { + // autosaving enabled + if (autosave_needed && !autosave_timer->isActive()) + { + autosave_timer->setInterval(autosave_interval); + autosave_timer->start(); + } + else if (!autosave_needed && autosave_timer->isActive()) + { + autosave_timer->stop(); + } + } +} + +void AutosavePrivate::autosave() +{ + Autosave::AutosaveResult result = document.autosave(); + if (autosave_interval) + { + switch (result) + { + case Autosave::TemporaryFailure: + autosave_timer->setInterval(5000); + autosave_timer->start(); + break; + case Autosave::Success: + case Autosave::PermanentFailure: + autosave_timer->setInterval(autosave_interval); + autosave_timer->start(); + break; + default: + Q_ASSERT(false && "Return value of Autosave() is not a valid Autosave::AutosaveResult."); + } + } +} + + + +// ### Autosave ### + +Autosave::Autosave() +: autosave_controller(new AutosavePrivate(*this)) +{ + // Nothing, not inlined +} + +Autosave::~Autosave() +{ + // Nothing, not inlined +} + +QString Autosave::autosavePath(const QString &path) const +{ + return path + QLatin1String(".autosave"); +} + +void Autosave::setAutosaveNeeded(bool needed) +{ + autosave_controller->setAutosaveNeeded(needed); +} + +bool Autosave::autosaveNeeded() const +{ + return autosave_controller->autosaveNeeded(); +} diff --git a/src/core/autosave.h b/src/core/autosave.h new file mode 100644 index 0000000..f67ccb7 --- /dev/null +++ b/src/core/autosave.h @@ -0,0 +1,84 @@ +/* + * Copyright 2014 Kai Pastor + * + * This file is part of OpenOrienteering. + * + * OpenOrienteering is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenOrienteering is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenOrienteering. If not, see . + */ + +#ifndef _OPENORIENTEERING_AUTOSAVE_H +#define _OPENORIENTEERING_AUTOSAVE_H + +#include + +class AutosavePrivate; + +/** + * @brief Class Autosave implements autosaving behaviour. + * + * Autosaving means that data which has been modified is automatically saved + * after some period of time if no regular saving (typically triggered by the + * user) happens before. + * + * Classes which wish to implement autosaving may inherit from this class. + * Inheriting classes must implement autosave(). Furthermore, they must call + * setAutosaveNeeded() when changes need to be taken care of by Autosave, or + * when normal saving has terminated the need to perform autosaving. + * + * Autosaving, as implemented by autosave(), may succeed, fail temporary (e.g. + * during editing), or fail permanent (e.g. for lack of disk space). + * On success or permanent failure, autosave() will be called again after the + * regular autosaving period. + * On temporary failure, autosave() will be called again after five seconds. + * + * The autosave period (in minutes) is taken from the setting + * Settings::General_AutosaveInterval. + */ +class Autosave +{ +public: + /** @brief Possible results of autosave attempts. */ + enum AutosaveResult + { + Success, ///< Autosaving succeeded. + PermanentFailure, ///< Autosaving failed for some persistent reason. + TemporaryFailure ///< Autosaving failed for some transient reason and shall be retried soon. + }; + + /** @brief Returns the autosave file path for the given path. */ + virtual QString autosavePath(const QString &path) const; + + /** @brief Performs an autosave, if possible. */ + virtual AutosaveResult autosave() = 0; + + /** @brief Informs Autosave whether autosaving is needed or not. */ + void setAutosaveNeeded(bool); + + /** @brief Returns true if autosave is known to be needed. */ + bool autosaveNeeded() const; + +protected: + /** @brief Initializes the autosave feature. */ + Autosave(); + + /** @brief Destructs the autosave feature. */ + ~Autosave(); + +private: + friend class AutosavePrivate; + + QScopedPointer autosave_controller; +}; + +#endif diff --git a/src/core/autosave_p.h b/src/core/autosave_p.h new file mode 100644 index 0000000..a06ad6f --- /dev/null +++ b/src/core/autosave_p.h @@ -0,0 +1,63 @@ +/* + * Copyright 2014 Kai Pastor + * + * This file is part of OpenOrienteering. + * + * OpenOrienteering is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenOrienteering is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenOrienteering. If not, see . + */ + +#ifndef _OPENORIENTEERING_AUTOSAVE_P_H +#define _OPENORIENTEERING_AUTOSAVE_P_H + +#include +#include + +#include "autosave.h" + +/** + * @brief AutosavePrivate is a helper class of Autosave. + * + * AutosavePrivate implements most of Autosave's behaviour. + * Autosave is meant to be used through inheritance. + * Due to the implemenation of QObject and moc, only the first inherited class + * may be derived from QObject. That is why Autosave itself is not derived from + * QObject, but rather uses this helper class. + */ +class AutosavePrivate : public QObject +{ +Q_OBJECT +public: + AutosavePrivate(Autosave& document); + + virtual ~AutosavePrivate(); + + bool autosaveNeeded(); + + void setAutosaveNeeded(bool); + +public slots: + void autosave(); + + void settingsChanged(); + +private: + Q_DISABLE_COPY(AutosavePrivate) + + Autosave& document; + QTimer* autosave_timer; + bool autosave_needed; + int autosave_interval; +}; + +#endif diff --git a/src/core/crs_template.cpp b/src/core/crs_template.cpp new file mode 100644 index 0000000..2299fb2 --- /dev/null +++ b/src/core/crs_template.cpp @@ -0,0 +1,123 @@ +/* + * Copyright 2013, 2014 Thomas Schöps + * Copyright 2014, 2015 Kai Pastor + * + * This file is part of OpenOrienteering. + * + * OpenOrienteering is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenOrienteering is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenOrienteering. If not, see . + */ + + +#include "crs_template.h" + + +// From crs_template_implementation.h/.cpp +namespace CRSTemplates +{ + CRSTemplateRegistry::TemplateList defaultList(); +} + + + +// ### CRSTemplateParameter ### + +CRSTemplateParameter::CRSTemplateParameter(const QString& key, const QString& description) + : param_id(key) + , param_name(description) +{ + // nothing +} + +CRSTemplateParameter::~CRSTemplateParameter() +{ + // nothing, not inlined +} + +std::vector CRSTemplateParameter::specValues(const QString& edit_value) const +{ + return { edit_value }; +} + + + +// ### CRSTemplate ### + +CRSTemplate::CRSTemplate( + const QString& id, + const QString& name, + const QString& coordinates_name, + const QString& spec_template, + ParameterList&& parameters) + : template_id(id) + , template_name(name) + , coordinates_name(coordinates_name) + , spec_template(spec_template) + , params(std::move(parameters)) +{ + // nothing +} + +CRSTemplate::~CRSTemplate() +{ + for (auto&& param : params) + delete param; +} + +QString CRSTemplate::coordinatesName(const std::vector& values) const +{ + Q_ASSERT(params.size() == values.size() + || values.empty()); + + auto name = coordinates_name; + + auto value = begin(values); + auto last_value = end(values); + for (auto key = begin(params), last = end(params); + key != last && value != last_value; + ++key, ++value) + { + name.replace(QLatin1Char('@') + (*key)->id() + QLatin1Char('@'), *value); + } + + return name; +} + + + +// ### CRSTemplateRegistry ### + +CRSTemplateRegistry::CRSTemplateRegistry() +{ + static auto shared_list = CRSTemplates::defaultList(); + this->templates = &shared_list; +} + +const CRSTemplate* CRSTemplateRegistry::find(const QString& id) const +{ + const CRSTemplate* ret = nullptr; + for (auto&& temp : *templates) + { + if (temp->id() == id) { + ret = temp.get(); + break; + } + + } + return ret; +} + +void CRSTemplateRegistry::add(std::unique_ptr temp) +{ + templates->push_back(std::move(temp)); +} diff --git a/src/core/crs_template.h b/src/core/crs_template.h new file mode 100644 index 0000000..88511ad --- /dev/null +++ b/src/core/crs_template.h @@ -0,0 +1,304 @@ +/* + * Copyright 2013, 2014 Thomas Schöps + * Copyright 2014, 2015 Kai Pastor + * + * This file is part of OpenOrienteering. + * + * OpenOrienteering is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenOrienteering is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenOrienteering. If not, see . + */ + + +#ifndef _OPENORIENTEERING_CRS_TEMPLATE_H_ +#define _OPENORIENTEERING_CRS_TEMPLATE_H_ + +#include +#include + +#include + +class QObject; +class QWidget; + +class Georeferencing; + +/** + * Abstract base class for users of CRS parameter widgets. + */ +class CRSParameterWidgetObserver +{ +public: + /** + * Informs the observer about a change in a CRS parameter widget. + */ + virtual void crsParameterEdited() = 0; + + /** + * Returns the current georeferencing. + * + * CRS parameter widgets may use this georeferencing for calculating values. + */ + virtual const Georeferencing& georeferencing() const = 0; +}; + + + +/** + * Abstract base class for parameters in CRSTemplates. + */ +class CRSTemplateParameter +{ +public: + using WidgetObserver = CRSParameterWidgetObserver; + + /** + * Constructs a new parameter with the given key and description. + */ + CRSTemplateParameter(const QString& id, const QString& name); + + /** + * Destructor. + */ + virtual ~CRSTemplateParameter(); + + /** + * Returns the parameter's permanent unique ID. + */ + QString id() const; + + /** + * Returns the parameter's display name. + */ + QString name() const; + + /** + * Creates a widget which can be used to edit the value. + * + * The widget should be simple in the sense that it can be used as a field + * in a QFormLayout, together with the parameter's label. + */ + virtual QWidget* createEditor(WidgetObserver& widget_observer) const = 0; + + /** + * Return a list of actual specification parameters values from a value in + * storage format. + * + * The default implementation returns a vector which contains just the + * single edit_value. + */ + virtual std::vector specValues(const QString& edit_value) const; + + /** + * Return the widget's value(s) in form of a single string. + * + * This string can be stored and used for restoring the widget. + * + * \see CRSTemplateParameter::setValue + */ + virtual QString value(const QWidget* edit_widget) const = 0; + + /** + * Sets the widget to a stored value. + * + * \see CRSTemplateParameter::value + */ + virtual void setValue(QWidget* edit_widget, const QString& value) = 0; + +private: + const QString param_id; + const QString param_name; +}; + + + +/** + * A template for a coordinate reference system specification (CRS) string. + * + * A CRSTemplate may contain one or more parameters described by the + * CRSTemplateParameter class. For each parameter, spec_template must contain a + * number of free parameters for QString::arg(), e.g. "%1" for the first parameter. + */ +class CRSTemplate +{ +public: + using Parameter = CRSTemplateParameter; + + using ParameterList = std::vector; + + /** + * Creates a new CRS template. + * + * The id must be unique and different from "Local". + * The template takes ownership of the parameters in the list. + * + * The coordinates_name may contain placeholders written @id@ which refer + * to the parameter with the given ID. They can be replaced with actual + * parameter values when calling coordinatesName(). + */ + CRSTemplate( + const QString& template_id, + const QString& template_name, + const QString& coordinates_name, + const QString& spec_template, + ParameterList&& parameters + ); + + // Copying of parameters is not implemented here. + CRSTemplate(const CRSTemplate&) = delete; + + /** + * Destructor. + * + * This deletes the parameters. + */ + ~CRSTemplate(); + + // Copying of parameters is not implemented here. + CRSTemplate& operator=(const CRSTemplate&) = delete; + + + /** + * Returns the unique ID of this template. + */ + QString id() const; + + /** + * Returns the display name of this template. + */ + QString name() const; + + /** + * Returns the display name for the coordinates of this template, + * e.g. "UTM coordinates". + * + * The values list must be either of the same size as the templates list + * parameters, or empty. The given parameter values are substituted for the + * respective @id@ placeholders in the coordinates_name which was passed to + * the constructor. + */ + QString coordinatesName(const std::vector& values = {}) const; + + /** + * Returns the specification string template in Proj.4 format. + */ + QString specificationTemplate() const; + + /** + * Returns the parameters. + */ + const ParameterList& parameters() const; + + +private: + const QString template_id; + const QString template_name; + const QString coordinates_name; + const QString spec_template; + const ParameterList params; +}; + + + +/** + * A directory of known CRS templates. + * + * All instances of this class provide access to the same list. + */ +class CRSTemplateRegistry +{ +public: + using TemplateList = std::vector< std::unique_ptr >; + + /** + * Creates an object for accessing the CRS template directory. + */ + CRSTemplateRegistry(); + + /** + * Returns the list of registered CRS templates. + */ + const TemplateList& list() const; + + /** + * Finds the registered CRS template with the given id, + * or returns nullptr if the given id does not exist. + */ + const CRSTemplate* find(const QString& id) const; + + /** + * Registers a CRS template. + * + * Note that the directory and thus the template outlives the + * CRSTemplateRegistry object. + */ + void add(std::unique_ptr temp); + +private: + TemplateList* templates; +}; + + + +//### CRSTemplateParameter inline code ### + +inline +QString CRSTemplateParameter::id() const +{ + return param_id; +} + +inline +QString CRSTemplateParameter::name() const +{ + return param_name; +} + + + +//### CRSTemplate inline code ### + +inline +QString CRSTemplate::id() const +{ + return template_id; +} + +inline +QString CRSTemplate::name() const +{ + return template_name; +} + +inline +QString CRSTemplate::specificationTemplate() const +{ + return spec_template; +} + +inline +const CRSTemplate::ParameterList& CRSTemplate::parameters() const +{ + return params; +} + + + +//### CRSTemplateRegistry inline code ### + +inline +const CRSTemplateRegistry::TemplateList& CRSTemplateRegistry::list() const +{ + return *templates; +} + +#endif diff --git a/src/core/crs_template_implementation.cpp b/src/core/crs_template_implementation.cpp new file mode 100644 index 0000000..4cd1931 --- /dev/null +++ b/src/core/crs_template_implementation.cpp @@ -0,0 +1,286 @@ +/* + * Copyright 2013, 2014 Thomas Schöps + * Copyright 2014, 2015 Kai Pastor + * + * This file is part of OpenOrienteering. + * + * OpenOrienteering is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenOrienteering is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenOrienteering. If not, see . + */ + + +#include "crs_template_implementation.h" + +#include +#include +#include +#include + +#include "georeferencing.h" +#include "../gui/widgets/crs_param_widgets.h" +#include "../gui/georeferencing_dialog.h" +#include "../util_gui.h" +#include "../util/memory.h" +#include "../util/scoped_signals_blocker.h" + + +namespace CRSTemplates +{ + +CRSTemplateRegistry::TemplateList defaultList() +{ + CRSTemplateRegistry::TemplateList templates; + templates.reserve(5); + + // UTM + auto temp = make_unique( + QString::fromLatin1("UTM"), + Georeferencing::tr("UTM", "UTM coordinate reference system"), + Georeferencing::tr("UTM coordinates"), + QString::fromLatin1("+proj=utm +datum=WGS84 +zone=%1"), + CRSTemplate::ParameterList { + new UTMZoneParameter(QString::fromLatin1("zone"), Georeferencing::tr("UTM Zone (number north/south)")) + } ); + templates.push_back(std::move(temp)); + + // Gauss-Krueger + temp = make_unique( + QString::fromLatin1("Gauss-Krueger, datum: Potsdam"), + Georeferencing::tr("Gauss-Krueger, datum: Potsdam", "Gauss-Krueger coordinate reference system"), + Georeferencing::tr("Gauss-Krueger coordinates"), + QString::fromLatin1("+proj=tmerc +lat_0=0 +lon_0=%1 +k=1.000000 +x_0=%2 +y_0=0 +ellps=bessel +datum=potsdam +units=m +no_defs"), + CRSTemplate::ParameterList { + new IntRangeParameter(QString::fromLatin1("zone"), Georeferencing::tr("Zone number (1 to 119)", "Zone number for Gauss-Krueger coordinates"), + 1, 119, { {3, 0}, {1000000, 500000} }) + } ); + templates.push_back(std::move(temp)); + + // EPSG + temp = make_unique( + QString::fromLatin1("EPSG"), + Georeferencing::tr("by EPSG code", "as in: The CRS is specified by EPSG code"), + //: Don't translate @code@. It is placeholder. + Georeferencing::tr("EPSG @code@ coordinates"), + QString::fromLatin1("+init=epsg:%1"), + CRSTemplate::ParameterList { + new IntRangeParameter(QString::fromLatin1("code"), Georeferencing::tr("EPSG code"), 1000, 99999) + } ); + templates.push_back(std::move(temp)); + + // Custom + temp = make_unique( + QString::fromLatin1("PROJ.4"), // Don't change this ID. + Georeferencing::tr("Custom PROJ.4", "PROJ.4 specification"), + Georeferencing::tr("Local coordinates"), + QString::fromLatin1("%1"), + CRSTemplate::ParameterList { + new FullSpecParameter(QString::fromLatin1("spec"), Georeferencing::tr("Specification", "PROJ.4 specification")) + } ); + templates.push_back(std::move(temp)); + + return templates; +} + + + +// ### TextParameter ### + +TextParameter::TextParameter(const QString& key, const QString& name) + : CRSTemplateParameter(key, name) +{ + // nothing +} + +QWidget* TextParameter::createEditor(WidgetObserver& observer) const +{ + auto widget = new TextParameter::Editor(); + QObject::connect(widget, &TextParameter::Editor::textChanged, [&observer](){ observer.crsParameterEdited(); }); + return widget; +} + +QString TextParameter::value(const QWidget* edit_widget) const +{ + QString value; + auto field = qobject_cast(edit_widget); + if (field) + value = field->text(); + return value; +} + +void TextParameter::setValue(QWidget* edit_widget, const QString& value) +{ + auto field = qobject_cast(edit_widget); + if (field) + field->setText(value); +} + + + +// ### FullSpecParameter ### + +FullSpecParameter::FullSpecParameter(const QString& key, const QString& name) + : TextParameter(key, name) +{ + // nothing +} + +QWidget* FullSpecParameter::createEditor(WidgetObserver& observer) const +{ + auto widget = qobject_cast(TextParameter::createEditor(observer)); + Q_ASSERT(widget); + if (widget) + { + const QSignalBlocker block(widget); + widget->setText(observer.georeferencing().getProjectedCRSSpec()); + } + return widget; +} + +void FullSpecParameter::setValue(QWidget* edit_widget, const QString& value) +{ + // Don't accidently clear this field. + if (!value.isEmpty()) + TextParameter::setValue(edit_widget, value); +} + + + +// ### UTMZoneParameter ### + +UTMZoneParameter::UTMZoneParameter(const QString& key, const QString& name) + : CRSTemplateParameter(key, name) +{ + // nothing +} + +UTMZoneParameter::~UTMZoneParameter() +{ + // nothing +} + +QWidget* UTMZoneParameter::createEditor(WidgetObserver& observer) const +{ + auto widget = new UTMZoneEdit(observer, nullptr); + QObject::connect(widget, &UTMZoneEdit::textEdited, [&observer](){ observer.crsParameterEdited(); }); + return widget; +} + +std::vector UTMZoneParameter::specValues(const QString& edit_value) const +{ + auto zone = QString { edit_value }; + zone.remove(QLatin1String(" N")); + zone.replace(QLatin1String(" S"), QLatin1String(" +south")); + return { zone }; +} + +QString UTMZoneParameter::value(const QWidget* edit_widget) const +{ + QString value; + if (auto text_edit = qobject_cast(edit_widget)) + value = text_edit->text(); + return value; +} + +void UTMZoneParameter::setValue(QWidget* edit_widget, const QString& value) +{ + // Don't accidently clear this field. + auto text_edit = qobject_cast(edit_widget); + if (text_edit && !value.isEmpty()) + text_edit->setText(value); +} + +QVariant UTMZoneParameter::calculateUTMZone(const LatLon lat_lon) +{ + QVariant ret; + + const double lat = lat_lon.latitude(); + if (fabs(lat) < 84.0) + { + const double lon = lat_lon.longitude(); + int zone_no = int(floor(lon) + 180) / 6 % 60 + 1; + if (zone_no == 31 && lon >= 3.0 && lat >= 56.0 && lat < 64.0) + zone_no = 32; // South Norway + else if (lat >= 72.0 && lon >= 3.0 && lon <= 39.0) + zone_no = 2 * (int(floor(lon) + 3.0) / 12) + 31; // Svalbard + QString zone = QString::number(zone_no); + if (zone_no < 10) + zone.prepend(QLatin1Char('0')); + zone.append((lat >= 0.0) ? QLatin1String(" N") : QLatin1String(" S")); + ret = zone; + } + + return ret; +} + + + +// ### IntRangeParameter ### + +IntRangeParameter::IntRangeParameter(const QString& key, const QString& name, int min_value, int max_value) + : IntRangeParameter(key, name, min_value, max_value, { {1, 0} }) +{ + // nothing +} + +IntRangeParameter::IntRangeParameter(const QString& key, const QString& name, int min_value, int max_value, OutputList&& outputs) + : CRSTemplateParameter(key, name) + , min_value(min_value) + , max_value(max_value) + , outputs(std::move(outputs)) +{ + // nothing +} + +IntRangeParameter::~IntRangeParameter() +{ + // nothing +} + +QWidget* IntRangeParameter::createEditor(WidgetObserver& observer) const +{ + using TakingIntArgument = void (QSpinBox::*)(int); + auto widget = Util::SpinBox::create(min_value, max_value); + QObject::connect(widget, (TakingIntArgument) &QSpinBox::valueChanged, [&observer](){ observer.crsParameterEdited(); }); + return widget; +} + +std::vector IntRangeParameter::specValues(const QString& edit_value) const +{ + auto chosen_value = edit_value.toInt(); + + std::vector spec_values; + spec_values.reserve(outputs.size()); + for (auto&& factor_and_bias : outputs) + { + spec_values.push_back(QString::number(factor_and_bias.first * chosen_value + factor_and_bias.second)); + } + return spec_values; +} + +QString IntRangeParameter::value(const QWidget* edit_widget) const +{ + QString value; + if (auto spin_box = qobject_cast(edit_widget)) + value = spin_box->cleanText(); + return value; +} + +void IntRangeParameter::setValue(QWidget* edit_widget, const QString& value) +{ + if (auto spin_box = qobject_cast(edit_widget)) + spin_box->setValue(value.toInt()); +} + + + +} // namespace CRSTemplates diff --git a/src/core/crs_template_implementation.h b/src/core/crs_template_implementation.h new file mode 100644 index 0000000..4891fb5 --- /dev/null +++ b/src/core/crs_template_implementation.h @@ -0,0 +1,127 @@ +/* + * Copyright 2013, 2014 Thomas Schöps + * Copyright 2014, 2015 Kai Pastor + * + * This file is part of OpenOrienteering. + * + * OpenOrienteering is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenOrienteering is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenOrienteering. If not, see . + */ + + +#ifndef _OPENORIENTEERING_CRS_TEMPLATE_IMPLEMENTATION_H_ +#define _OPENORIENTEERING_CRS_TEMPLATE_IMPLEMENTATION_H_ + +#include "crs_template.h" + +#include + +class QLineEdit; +class QVariant; +class QWidget; + +class LatLon; + + +/** + * This namespace collects CRS template implementations + */ +namespace CRSTemplates +{ + +/** + * Creates and returns a list of known CRS Templates. + */ +CRSTemplateRegistry::TemplateList defaultList(); + + + +/** + * CRSTemplate parameter specifying a text parameter. + */ +class TextParameter : public CRSTemplateParameter +{ +public: + TextParameter(const QString& id, const QString& name); + QWidget* createEditor(WidgetObserver& observer) const override; + QString value(const QWidget* edit_widget) const override; + void setValue(QWidget* edit_widget, const QString& value) override; + +protected: + /// The type of editor widget returned from createEditor. + using Editor = QLineEdit; +}; + + + +/** + * CRSTemplate parameter giving a full specification. + */ +class FullSpecParameter : public TextParameter +{ +public: + FullSpecParameter(const QString& id, const QString& name); + QWidget* createEditor(WidgetObserver& observer) const override; + void setValue(QWidget* edit_widget, const QString& value) override; +}; + + + +/** + * CRSTemplate parameter specifying a UTM zone. + */ +class UTMZoneParameter : public CRSTemplateParameter +{ +public: + UTMZoneParameter(const QString& id, const QString& name); + ~UTMZoneParameter(); + QWidget* createEditor(WidgetObserver& observer) const override; + std::vector specValues(const QString& edit_value) const override; + QString value(const QWidget* edit_widget) const override; + void setValue(QWidget* edit_widget, const QString& value) override; + + /** + * Determines the UTM zone from the given latitude and longitude. + * + * Returns a null value on error. + */ + static QVariant calculateUTMZone(const LatLon lat_lon); +}; + + + +/** + * CRSTemplate integer parameter, with values from an integer range. + */ +class IntRangeParameter : public CRSTemplateParameter +{ +public: + using OutputList = std::vector< std::pair >; + + IntRangeParameter(const QString& id, const QString& name, int min_value, int max_value); + IntRangeParameter(const QString& id, const QString& name, int min_value, int max_value, OutputList&& outputs); + ~IntRangeParameter(); + QWidget* createEditor(WidgetObserver& observer) const override; + std::vector specValues(const QString& edit_value) const override; + QString value(const QWidget* edit_widget) const override; + void setValue(QWidget* edit_widget, const QString& value) override; + +private: + const int min_value; + const int max_value; + const OutputList outputs; +}; + +} // namespace CRSTemplates + +#endif diff --git a/src/core/georeferencing.cpp b/src/core/georeferencing.cpp new file mode 100644 index 0000000..b5f333f --- /dev/null +++ b/src/core/georeferencing.cpp @@ -0,0 +1,872 @@ +/* + * Copyright 2012-2016 Kai Pastor + * + * This file is part of OpenOrienteering. + * + * OpenOrienteering is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenOrienteering is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenOrienteering. If not, see . + */ + + +#include "georeferencing.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "crs_template.h" +#include "../file_format.h" +#include "../file_format_xml.h" +#include "../mapper_resource.h" +#include "../util_gui.h" +#include "../util/xml_stream_util.h" +#include "../util/scoped_signals_blocker.h" + + +// ### A namespace which collects various string constants of type QLatin1String. ### + +namespace literal +{ + static const QLatin1String georeferencing("georeferencing"); + + static const QLatin1String scale("scale"); + static const QLatin1String grid_scale_factor{"grid_scale_factor"}; + static const QLatin1String declination("declination"); + static const QLatin1String grivation("grivation"); + + static const QLatin1String ref_point("ref_point"); + static const QLatin1String ref_point_deg("ref_point_deg"); + static const QLatin1String projected_crs("projected_crs"); + static const QLatin1String geographic_crs("geographic_crs"); + static const QLatin1String spec("spec"); + static const QLatin1String parameter("parameter"); + + static const QLatin1String x("x"); + static const QLatin1String y("y"); + + static const QLatin1String id("id"); + static const QLatin1String language("language"); + + static const QLatin1String lat("lat"); + static const QLatin1String lon("lon"); + + static const QLatin1String proj_4("PROJ.4"); + static const QLatin1String geographic_coordinates("Geographic coordinates"); +} + +namespace +{ + /** Helper for PROJ.4 initialization. + * + * To be used as static object in the right place. + */ + class ProjSetup + { + public: + ProjSetup() + { + QVarLengthArray buffer; + QVarLengthArray data; + for (auto&& location : MapperResource::getLocations(MapperResource::PROJ_DATA)) + { + buffer.append(location.toLocal8Bit()); + data.append(buffer.back().data()); + } + pj_set_searchpath(data.size(), data.data()); + +#if defined(Q_OS_ANDROID) + // Register file finder function needed by Proj.4 + registerProjFileHelper(); +#endif + } + }; + + /** Helper for PROJ.4 initialization. + * + * This helper adds "+no_defs" if it is not already part of the + * specification. It also takes care of resetting the pj errno. + */ + projPJ pj_init_plus_no_defs(const QString& spec) + { + auto spec_latin1 = spec.toLatin1(); + if (!spec_latin1.contains("+no_defs")) + spec_latin1.append(" +no_defs"); + + *pj_get_errno_ref() = 0; + return pj_init_plus(spec_latin1); + } + + + /** + * List of substitutions for specifications which are known to be broken in Proj.4. + */ + std::vector< std::pair > spec_substitutions { + // #542, S-JTSK (Greenwich) / Krovak East North + { QString::fromLatin1("+init=epsg:5514"), + QString::fromLatin1("+proj=krovak +lat_0=49.5 +lon_0=24.83333333333333 +alpha=30.28813972222222 +k=0.9999 +x_0=0 +y_0=0 " + "+ellps=bessel +towgs84=542.5,89.2,456.9,5.517,2.275,5.516,6.96 +pm=greenwich +units=m +no_defs") }, + }; +} + + +//### Georeferencing ### + +const QString Georeferencing::geographic_crs_spec(QString::fromLatin1("+proj=latlong +datum=WGS84")); + +Georeferencing::Georeferencing() +: state(Local), + scale_denominator(1), + grid_scale_factor{1.0}, + declination(0.0), + grivation(0.0), + grivation_error(0.0), + map_ref_point(0, 0), + projected_ref_point(0, 0) +{ + static ProjSetup run_once; + + updateTransformation(); + + projected_crs_id = QString::fromLatin1("Local"); + projected_crs = NULL; + geographic_crs = pj_init_plus_no_defs(geographic_crs_spec); + Q_ASSERT(geographic_crs != NULL); +} + +Georeferencing::Georeferencing(const Georeferencing& other) +: QObject(), + state(other.state), + scale_denominator(other.scale_denominator), + grid_scale_factor{other.grid_scale_factor}, + declination(other.declination), + grivation(other.grivation), + grivation_error(other.grivation_error), + map_ref_point(other.map_ref_point), + projected_ref_point(other.projected_ref_point), + projected_crs_id(other.projected_crs_id), + projected_crs_spec(other.projected_crs_spec), + projected_crs_parameters(other.projected_crs_parameters), + geographic_ref_point(other.geographic_ref_point) +{ + updateTransformation(); + + geographic_crs = pj_init_plus_no_defs(geographic_crs_spec); + Q_ASSERT(geographic_crs != NULL); + projected_crs = pj_init_plus_no_defs(projected_crs_spec); +} + +Georeferencing::~Georeferencing() +{ + if (projected_crs != NULL) + pj_free(projected_crs); + if (geographic_crs != NULL) + pj_free(geographic_crs); +} + +Georeferencing& Georeferencing::operator=(const Georeferencing& other) +{ + state = other.state; + scale_denominator = other.scale_denominator; + grid_scale_factor = other.grid_scale_factor; + declination = other.declination; + grivation = other.grivation; + grivation_error = other.grivation_error; + map_ref_point = other.map_ref_point; + projected_ref_point = other.projected_ref_point; + from_projected = other.from_projected; + to_projected = other.to_projected; + projected_ref_point = other.projected_ref_point; + projected_crs_id = other.projected_crs_id; + projected_crs_spec = other.projected_crs_spec; + projected_crs_parameters = other.projected_crs_parameters; + geographic_ref_point = other.geographic_ref_point; + + if (projected_crs != NULL) + pj_free(projected_crs); + projected_crs = pj_init_plus_no_defs(projected_crs_spec); + + emit stateChanged(); + emit transformationChanged(); + emit declinationChanged(); + emit projectionChanged(); + + return *this; +} + +void Georeferencing::load(QXmlStreamReader& xml, bool load_scale_only) +{ + Q_ASSERT(xml.name() == literal::georeferencing); + + { + // Reset to default values + const QSignalBlocker block(this); + *this = Georeferencing(); + } + + XmlElementReader georef_element(xml); + scale_denominator = georef_element.attribute(literal::scale); + if (scale_denominator <= 0) + throw FileFormatException(tr("Map scale specification invalid or missing.")); + + if (georef_element.hasAttribute(literal::grid_scale_factor)) + { + grid_scale_factor = roundScaleFactor(georef_element.attribute(literal::grid_scale_factor)); + if (grid_scale_factor <= 0.0) + throw FileFormatException(tr("Invalid grid scale factor: %1").arg(QString::number(grid_scale_factor))); + } + + state = Local; + if (load_scale_only) + { + xml.skipCurrentElement(); + } + else + { + if (georef_element.hasAttribute(literal::declination)) + declination = roundDeclination(georef_element.attribute(literal::declination)); + if (georef_element.hasAttribute(literal::grivation)) + { + grivation = roundDeclination(georef_element.attribute(literal::grivation)); + grivation_error = georef_element.attribute(literal::grivation) - grivation; + } + + while (xml.readNextStartElement()) + { + if (xml.name() == literal::ref_point) + { + XmlElementReader ref_point_element(xml); + map_ref_point.setX(ref_point_element.attribute(literal::x)); + map_ref_point.setY(ref_point_element.attribute(literal::y)); + } + else if (xml.name() == literal::projected_crs) + { + XmlElementReader crs_element(xml); + projected_crs_id = crs_element.attribute(literal::id); + while (xml.readNextStartElement()) + { + XmlElementReader current_element(xml); + if (xml.name() == literal::spec) + { + const QString language = current_element.attribute(literal::language); + if (language != literal::proj_4) + throw FileFormatException(tr("Unknown CRS specification language: %1").arg(language)); + projected_crs_spec = xml.readElementText(); + } + else if (xml.name() == literal::parameter) + { + projected_crs_parameters.push_back(xml.readElementText()); + } + else if (xml.name() == literal::ref_point) + { + projected_ref_point.setX(current_element.attribute(literal::x)); + projected_ref_point.setY(current_element.attribute(literal::y)); + } + else // unknown + { + ; // nothing + } + } + } + else if (xml.name() == literal::geographic_crs) + { + while (xml.readNextStartElement()) + { + XmlElementReader current_element(xml); + if (xml.name() == literal::spec) + { + const QString language = current_element.attribute(literal::language); + if (language != literal::proj_4) + throw FileFormatException(tr("Unknown CRS specification language: %1").arg(language)); + QString geographic_crs_spec = xml.readElementText(); + if (Georeferencing::geographic_crs_spec != geographic_crs_spec) + throw FileFormatException(tr("Unsupported geographic CRS specification: %1").arg(geographic_crs_spec)); + } + else if (xml.name() == literal::ref_point) + { + // Legacy, latitude/longitude in radiant + double latitude = current_element.attribute(literal::lat); + double longitude = current_element.attribute(literal::lon); + geographic_ref_point = LatLon::fromRadiant(latitude, longitude); + } + else if (xml.name() == literal::ref_point_deg) + { + // Legacy, latitude/longitude in degrees + double latitude = current_element.attribute(literal::lat); + double longitude = current_element.attribute(literal::lon); + geographic_ref_point = LatLon(latitude, longitude); + } + else // unknown + { + ; // nothing + } + } + } + else // unknown + { + ; // nothing + } + } + } + + emit stateChanged(); + updateTransformation(); + emit declinationChanged(); + if (!projected_crs_spec.isEmpty()) + { + if (projected_crs != NULL) + pj_free(projected_crs); + projected_crs = pj_init_plus_no_defs(projected_crs_spec); + if (0 == *pj_get_errno_ref()) + { + state = Normal; + emit stateChanged(); + } + } + emit projectionChanged(); +} + +void Georeferencing::save(QXmlStreamWriter& xml) const +{ + XmlElementWriter georef_element(xml, literal::georeferencing); + georef_element.writeAttribute(literal::scale, scale_denominator); + if (grid_scale_factor != 1.0) + georef_element.writeAttribute(literal::grid_scale_factor, grid_scale_factor, scaleFactorPrecision()); + if (!qIsNull(declination)) + georef_element.writeAttribute(literal::declination, declination, declinationPrecision()); + if (!qIsNull(grivation)) + georef_element.writeAttribute(literal::grivation, grivation, declinationPrecision()); + + if (!qIsNull(map_ref_point.lengthSquared())) + { + XmlElementWriter ref_point_element(xml, literal::ref_point); + ref_point_element.writeAttribute(literal::x, map_ref_point.x()); + ref_point_element.writeAttribute(literal::y, map_ref_point.y()); + } + + { + XmlElementWriter crs_element(xml, literal::projected_crs); + if (!projected_crs_id.isEmpty()) + crs_element.writeAttribute(literal::id, projected_crs_id); + + if (!projected_crs_spec.isEmpty()) + { + XmlElementWriter spec_element(xml, literal::spec); + spec_element.writeAttribute(literal::language, literal::proj_4); + xml.writeCharacters(projected_crs_spec); + } + + if (!projected_crs_parameters.empty()) + { + for (size_t i = 0; i < projected_crs_parameters.size(); ++i) + { + XmlElementWriter parameter_element(xml, literal::parameter); + xml.writeCharacters(projected_crs_parameters[i]); + Q_UNUSED(parameter_element); // Suppress compiler warnings + } + } + + if (!qIsNull(projected_ref_point.manhattanLength())) + { + XmlElementWriter ref_point_element(xml, literal::ref_point); + ref_point_element.writeAttribute(literal::x, projected_ref_point.x(), 6); + ref_point_element.writeAttribute(literal::y, projected_ref_point.y(), 6); + } + } + + if (state == Normal) + { + XmlElementWriter crs_element(xml, literal::geographic_crs); + crs_element.writeAttribute(literal::id, literal::geographic_coordinates); + { + XmlElementWriter spec_element(xml, literal::spec); + spec_element.writeAttribute(literal::language, literal::proj_4); + xml.writeCharacters(geographic_crs_spec); + } + if (XMLFileFormat::active_version < 6) + { + // Legacy compatibility + XmlElementWriter ref_point_element(xml, literal::ref_point); + ref_point_element.writeAttribute(literal::lat, degToRad(geographic_ref_point.latitude()), 10); + ref_point_element.writeAttribute(literal::lon, degToRad(geographic_ref_point.longitude()), 10); + } + { + XmlElementWriter ref_point_element(xml, literal::ref_point_deg); + ref_point_element.writeAttribute(literal::lat, geographic_ref_point.latitude(), 8); + ref_point_element.writeAttribute(literal::lon, geographic_ref_point.longitude(), 8); + } + } +} + + +void Georeferencing::setState(Georeferencing::State value) +{ + if (state != value) + { + state = value; + updateTransformation(); + + if (state != Normal) + setProjectedCRS(QString::fromLatin1("Local")); + + emit stateChanged(); + } +} + +void Georeferencing::setScaleDenominator(int value) +{ + Q_ASSERT(value > 0); + if (scale_denominator != (unsigned int)value) + { + scale_denominator = value; + updateTransformation(); + } +} + +void Georeferencing::setGridScaleFactor(double value) +{ + Q_ASSERT(value > 0); + if (grid_scale_factor != value) + { + grid_scale_factor = value; + updateTransformation(); + } +} + +void Georeferencing::setDeclination(double value) +{ + double declination = roundDeclination(value); + double grivation = declination - getConvergence(); + setDeclinationAndGrivation(declination, grivation); +} + +void Georeferencing::setGrivation(double value) +{ + double grivation = roundDeclination(value); + double declination = grivation + getConvergence(); + setDeclinationAndGrivation(declination, grivation); +} + +void Georeferencing::setDeclinationAndGrivation(double declination, double grivation) +{ + bool declination_change = declination != this->declination; + if (declination_change || grivation != this->grivation) + { + this->declination = declination; + this->grivation = grivation; + this->grivation_error = 0.0; + updateTransformation(); + + if (declination_change) + emit declinationChanged(); + } +} + +void Georeferencing::setMapRefPoint(MapCoord point) +{ + if (map_ref_point != point) + { + map_ref_point = point; + updateTransformation(); + } +} + +void Georeferencing::setProjectedRefPoint(QPointF point, bool update_grivation) +{ + if (projected_ref_point != point || state == Normal) + { + projected_ref_point = point; + bool ok; + LatLon new_geo_ref_point; + + switch (state) + { + default: + Q_ASSERT(false && "Undefined georeferencing state"); + // fall through + case Local: + break; + case Normal: + new_geo_ref_point = toGeographicCoords(point, &ok); + if (ok && new_geo_ref_point != geographic_ref_point) + { + geographic_ref_point = new_geo_ref_point; + if (update_grivation) + updateGrivation(); + emit projectionChanged(); + } + } + updateTransformation(); + } +} + +QString Georeferencing::getProjectedCRSName() const +{ + QString name = tr("Local"); + if (auto temp = CRSTemplateRegistry().find(projected_crs_id)) + name = temp->name(); + + return name; +} + +QString Georeferencing::getProjectedCoordinatesName() const +{ + QString name = tr("Local coordinates"); + if (auto temp = CRSTemplateRegistry().find(projected_crs_id)) + name = temp->coordinatesName(projected_crs_parameters); + + return name; +} + +double Georeferencing::getConvergence() const +{ + if (state != Normal || !isValid()) + return 0.0; + + // Second point on the same meridian + const double delta_phi = 360.0 / 40000.0; // roughly 1 km + double other_latitude = geographic_ref_point.latitude(); + other_latitude += (other_latitude < 0.0) ? delta_phi : -delta_phi; + const double same_longitude = geographic_ref_point.longitude(); + QPointF projected_other = toProjectedCoords(LatLon(other_latitude, same_longitude)); + + double denominator = projected_other.y() - projected_ref_point.y(); + if (fabs(denominator) < 0.00000000001) + return 0.0; + + return roundDeclination(RAD_TO_DEG * atan((projected_ref_point.x() - projected_other.x()) / denominator)); +} + +void Georeferencing::setGeographicRefPoint(LatLon lat_lon, bool update_grivation) +{ + bool geo_ref_point_changed = geographic_ref_point != lat_lon; + if (geo_ref_point_changed || state == Normal) + { + geographic_ref_point = lat_lon; + if (state != Normal) + setState(Normal); + + bool ok; + QPointF new_projected_ref = toProjectedCoords(lat_lon, &ok); + if (ok && new_projected_ref != projected_ref_point) + { + projected_ref_point = new_projected_ref; + if (update_grivation) + updateGrivation(); + updateTransformation(); + emit projectionChanged(); + } + else if (geo_ref_point_changed) + { + emit projectionChanged(); + } + } +} + +void Georeferencing::updateTransformation() +{ + QTransform transform; + transform.translate(projected_ref_point.x(), projected_ref_point.y()); + transform.rotate(-grivation); + + double scale = grid_scale_factor * scale_denominator / 1000.0; // to meters + transform.scale(scale, -scale); + transform.translate(-map_ref_point.x(), -map_ref_point.y()); + + if (to_projected != transform) + { + to_projected = transform; + from_projected = transform.inverted(); + emit transformationChanged(); + } +} + +void Georeferencing::updateGrivation() +{ + setDeclination(declination); +} + +void Georeferencing::initDeclination() +{ + setGrivation(grivation); +} + +void Georeferencing::setTransformationDirectly(const QTransform& transform) +{ + if (transform != to_projected) + { + to_projected = transform; + from_projected = to_projected.inverted(); + emit transformationChanged(); + } +} + +bool Georeferencing::setProjectedCRS(const QString& id, QString spec, std::vector params) +{ + // Default return value if no change is neccessary + bool ok = (state == Normal || projected_crs_spec.isEmpty()); + + for (const auto& substitution : spec_substitutions) + { + if (substitution.first == spec) + { + spec = substitution.second; + break; + } + } + + // Changes in params shall already be recorded in spec + if (projected_crs_id != id + || projected_crs_spec != spec + || projected_crs_parameters.size() != params.size() + || !std::equal(begin(params), end(params), begin(projected_crs_parameters)) + || (!ok && !spec.isEmpty()) ) + { + if (projected_crs != NULL) + pj_free(projected_crs); + + projected_crs_id = id; + projected_crs_spec = spec; + if (projected_crs_spec.isEmpty()) + { + projected_crs_parameters.clear(); + projected_crs = NULL; + ok = (state != Normal); + } + else + { + projected_crs_parameters.swap(params); // params was passed by value! + projected_crs = pj_init_plus_no_defs(projected_crs_spec); + ok = (0 == *pj_get_errno_ref()); + if (ok && state != Normal) + setState(Normal); + } + + emit projectionChanged(); + } + + return ok; +} + +QPointF Georeferencing::toProjectedCoords(const MapCoord& map_coords) const +{ + return to_projected.map(QPointF(map_coords)); +} + +QPointF Georeferencing::toProjectedCoords(const MapCoordF& map_coords) const +{ + return to_projected.map(map_coords); +} + +MapCoord Georeferencing::toMapCoords(const QPointF& projected_coords) const +{ + return MapCoord(from_projected.map(projected_coords)); +} + +MapCoordF Georeferencing::toMapCoordF(const QPointF& projected_coords) const +{ + return MapCoordF(from_projected.map(projected_coords)); +} + +LatLon Georeferencing::toGeographicCoords(const MapCoordF& map_coords, bool* ok) const +{ + return toGeographicCoords(toProjectedCoords(map_coords), ok); +} + +LatLon Georeferencing::toGeographicCoords(const QPointF& projected_coords, bool* ok) const +{ + if (ok != NULL) + *ok = false; + + double easting = projected_coords.x(), northing = projected_coords.y(); + if (projected_crs && geographic_crs) { + int ret = pj_transform(projected_crs, geographic_crs, 1, 1, &easting, &northing, NULL); + if (ok != NULL) + *ok = (ret == 0); + } + return LatLon::fromRadiant(northing, easting); +} + +QPointF Georeferencing::toProjectedCoords(const LatLon& lat_lon, bool* ok) const +{ + if (ok != NULL) + *ok = false; + + double easting = degToRad(lat_lon.longitude()), northing = degToRad(lat_lon.latitude()); + if (projected_crs && geographic_crs) { + int ret = pj_transform(geographic_crs, projected_crs, 1, 1, &easting, &northing, NULL); + if (ok != NULL) + *ok = (ret == 0); + } + return QPointF(easting, northing); +} + +MapCoord Georeferencing::toMapCoords(const LatLon& lat_lon, bool* ok) const +{ + return toMapCoords(toProjectedCoords(lat_lon, ok)); +} + +MapCoordF Georeferencing::toMapCoordF(const LatLon& lat_lon, bool* ok) const +{ + return toMapCoordF(toProjectedCoords(lat_lon, ok)); +} + +MapCoordF Georeferencing::toMapCoordF(const Georeferencing* other, const MapCoordF& map_coords, bool* ok) const +{ + if (other == NULL) + { + if (ok) + *ok = true; + return map_coords; + } + else if (isLocal() || other->isLocal()) + { + if (ok) + *ok = true; + return toMapCoordF(other->toProjectedCoords(map_coords)); + } + else + { + if (ok != NULL) + *ok = false; + + QPointF projected_coords = other->toProjectedCoords(map_coords); + double easting = projected_coords.x(), northing = projected_coords.y(); + if (projected_crs && other->projected_crs) { + // Direct transformation: + //int ret = pj_transform(other->projected_crs, projected_crs, 1, 1, &easting, &northing, NULL); + // Use geographic coordinates as intermediate step to enforce + // that coordinates are assumed to have WGS84 datum if datum is specified in only one CRS spec: + int ret = pj_transform(other->projected_crs, geographic_crs, 1, 1, &easting, &northing, NULL); + ret |= pj_transform(geographic_crs, projected_crs, 1, 1, &easting, &northing, NULL); + + if (ret != 0) + { + if (ok != NULL) + *ok = false; + return MapCoordF(easting, northing); + } + if (ok != NULL) + *ok = true; + } + return toMapCoordF(QPointF(easting, northing)); + } +} + +QString Georeferencing::getErrorText() const +{ + int err_no = *pj_get_errno_ref(); + return (err_no == 0) ? QString() : QString::fromLatin1(pj_strerrno(err_no)); +} + +double Georeferencing::radToDeg(double val) +{ + return RAD_TO_DEG * val; +} + +double Georeferencing::degToRad(double val) +{ + return DEG_TO_RAD * val; +} + +QString Georeferencing::degToDMS(double val) +{ + qint64 tmp = val * 360000; + int csec = tmp % 6000; + tmp = tmp / 6000; + int min = tmp % 60; + int deg = tmp / 60; + QString ret = QString::fromUtf8("%1°%2'%3\"").arg(deg).arg(min).arg(QLocale().toString(csec/100.0,'f',2)); + return ret; +} + +QDebug operator<<(QDebug dbg, const Georeferencing &georef) +{ + dbg.nospace() + << "Georeferencing(1:" << georef.scale_denominator + << " " << georef.grid_scale_factor + << " " << georef.declination + << " " << georef.grivation + << "deg, " << georef.projected_crs_id + << " (" << georef.projected_crs_spec + << ") " << QString::number(georef.projected_ref_point.x(), 'f', 8) << "," << QString::number(georef.projected_ref_point.y(), 'f', 8); + if (georef.isLocal()) + dbg.nospace() << ", local)"; + else + dbg.nospace() << ", geographic)"; + + return dbg.space(); +} + +#if defined(Q_OS_ANDROID) + +QScopedPointer temp_dir; // removed upon destruction +QByteArray c_string; // buffer for const char* + +extern "C" +{ + /** + * @brief Provides required files for Proj.4 library. + * + * This C function implements the interface required by pj_set_finder(). + * + * This functions checks if the requested file name is available in a + * temporary directory. If not, it tries to copy the file from the proj + * subfolder of the assets folder to this temporary directory. + * + * If the file exists in the temporary folder (or copying was successful) + * this function returns the full path of this file as a C string. + * This string becomes invalid the next time this function is called. + * Otherwise it returns NULL. + */ + const char* projFileHelperAndroid(const char *name) + { + if (temp_dir->isValid()) + { + QString path = QDir(temp_dir->path()).filePath(QString::fromUtf8(name)); + QFile file(path); + if (file.exists() || QFile::copy(QLatin1String("assets:/proj/") + QLatin1String(name), path)) + { + c_string = path.toLocal8Bit(); + return c_string.constData(); + } + } + qDebug() << "Could not projection data file" << name; + return NULL; + } + + void registerProjFileHelper() + { + // QTemporaryDir must not be constructed before QApplication + temp_dir.reset(new QTemporaryDir()); + if (temp_dir->isValid()) + { + pj_set_finder(&projFileHelperAndroid); + } + else + { + qDebug() << "Could not create a temporary directory for projection data."; + } + } +} + +#endif diff --git a/src/core/georeferencing.h b/src/core/georeferencing.h new file mode 100644 index 0000000..4071ea7 --- /dev/null +++ b/src/core/georeferencing.h @@ -0,0 +1,670 @@ +/* + * Copyright 2012-2016 Kai Pastor + * + * This file is part of OpenOrienteering. + * + * OpenOrienteering is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenOrienteering is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenOrienteering. If not, see . + */ + + +#ifndef OPENORIENTEERING_GEOREFERENCING_H +#define OPENORIENTEERING_GEOREFERENCING_H + +#include +#include +#include + +#include "latlon.h" +#include "../core/map_coord.h" +#include "../file_format.h" + +class QDebug; +class QXmlStreamReader; +class QXmlStreamWriter; + +typedef void* projPJ; + + + +#if defined(Q_OS_ANDROID) + +/** + * Registers a file finder function needed by Proj.4 on Android. + */ +extern "C" void registerProjFileHelper(); + +#endif + + + +/** + * A Georeferencing defines a mapping between "map coordinates" (as measured on + * paper) and coordinates in the real world. It provides functions for + * converting coordinates from one coordinate system to another. + * + * Conversions between map coordinates and "projected coordinates" (flat metric + * coordinates in a projected coordinate reference system) are made as affine + * transformation based on the map scale (principal scale), grid scale factor, + * the grivation and a defined reference point. + * + * Conversions between projected coordinates and geographic coordinates (here: + * latitude/longitude for the WGS84 datum) are made based on a specification + * of the coordinate reference system of the projected coordinates. The actual + * geographic transformation is done by the PROJ.4 library for geographic + * projections. + * + * If no (valid) specification is given, the projected coordinates are regarded + * as local coordinates. Local coordinates cannot be converted to other + * geographic coordinate systems. The georeferencing is "local". + * + * Conversions between "map coordinates" and "geographic coordinates" use the + * projected coordinates as intermediate step. + */ +class Georeferencing : public QObject +{ +Q_OBJECT + +friend class NativeFileImport; +friend QDebug operator<<(QDebug dbg, const Georeferencing& georef); + +public: + /// Georeferencing state + enum State + { + /// Only conversions between map and local projected coordinates are possible. + Local = 1, + + /// All coordinate conversions are possible (if there is no error in the + /// crs specification). + Normal = 2 + }; + + + /** + * @brief Returns the precision of the grid scale factor. + * + * The precision is given in number of decimal places, + * i.e. digits after the decimal point. + */ + static constexpr unsigned int scaleFactorPrecision(); + + /** + * @brief Rounds according to the defined precision of the grid scale factor. + * + * @see scaleFactorPrecision(); + */ + static double roundScaleFactor(double value); + + + /** + * @brief Returns the precision of declination/grivation/convergence. + * + * The precision is given in number of decimal places, + * i.e. digits after the decimal point. + * + * All values set as declination or grivation will be rounded to this precisison. + */ + static constexpr unsigned int declinationPrecision(); + + /** + * @brief Rounds according to the defined precision of declination/grivation/convergence. + * + * @see declinationPrecision(); + */ + static double roundDeclination(double); + + + /** + * Constructs a scale-only georeferencing. + */ + Georeferencing(); + + /** + * Constructs a georeferencing which is a copy of an existing georeferencing. + * + * Note: Since QObjects may not be copied, this is better understood as + * creating a new object with the same settings. + */ + Georeferencing(const Georeferencing& georeferencing); + + /** + * Cleans up memory allocated by the georeferencing + */ + ~Georeferencing(); + + + /** + * Saves the georeferencing to an XML stream. + */ + void save(QXmlStreamWriter& xml) const; + + /** + * Creates a georeferencing from an XML stream. + */ + void load(QXmlStreamReader& xml, bool load_scale_only); + + + /** + * Assigns the properties of another Georeferencing to this one. + * + * Having this method in a QObject is in contradiction to Qt conventions. + * But we really need to assign properties from one object to another, + * where each object maintains its own identity. + */ + Georeferencing& operator=(const Georeferencing& other); + + + /** + * Returns if the georeferencing settings are valid. + * + * This means that coordinates can be converted between map and projected + * coordinates. isLocal() can be checked to determine if a conversion + * to geographic coordinates is also possible. + */ + bool isValid() const; + + /** + * Returns true if this georeferencing is local. + * + * A georeferencing is local if no (valid) coordinate system specification + * is given for the projected coordinates. A local georeferencing cannot + * convert coordinates from and to geographic coordinate systems. + */ + bool isLocal() const; + + + /** + * Returns the georeferencing state. + */ + State getState() const; + + /** + * Sets the georeferencing state. + * + * This is only neccessary to decrease the state to Local, as otherwise it + * will be automatically changed when setting the respective values. + */ + void setState(State value); + + + /** + * Returns the principal scale denominator. + * + * The principal scale - or representative fraction - is the ratio between + * units on the printed map and units on ground. + */ + unsigned int getScaleDenominator() const; + + /** + * Sets the principal scale denominator. + */ + void setScaleDenominator(int value); + + + /** + * Returns the grid scale factor. + * + * The grid scale factor is the ratio between a length in the grid and the + * length on the earth model. It is applied as a factor to ground distances + * to get grid plane distances. + * + * Mapper doesn't explicitly deal with any other factors (elevation factor, + * unit of measurement). Technically, this property can be used as a + * combined factor. + */ + double getGridScaleFactor() const; + + /** + * Sets the grid scale factor. + * + * \see getGridScaleFactor() + */ + void setGridScaleFactor(double value); + + + /** + * Returns the magnetic declination (in degrees). + * + * @see setDeclination() + */ + double getDeclination() const; + + /** + * Sets the magnetic declination (in degrees). + * + * Magnetic declination is the angle between magnetic north and true north. + * In the context of OpenOrienteering Mapper, it is the angle between the + * y axis of map coordinates and the latitude axis of geographic + * coordinates. + * + * This will also affect the grivation value and the transformations. + */ + void setDeclination(double declination); + + + /** + * Returns the grivation. + * + * @see setGrivation() + */ + double getGrivation() const; + + /** + * Returns the deviation of the grivation from the one given in pre-0.6 files. + * + * Only valid immediately after loading a georeferencing from a file. + * Returns 0.0 in any other context. + * + * Files from Mapper versions before 0.6 may have used any number of decimal + * places for grivation. Since version 0.6, grivation is rounded to the + * number of decimal places defined by declinationPrecision(). When this + * rounding takes place (i.e. only when opening a file which has not been + * saved by 0.6 or later), the difference between the original value and the + * rounded value is temporarily provided by this function. This value can be + * used to for correcting dependent data. Any changes to declination or + * grivation will invalidate this value. + * + * @see getGrivation() + * @see declinationPrecision() + */ + double getGrivationError() const; + + /** + * Sets the grivation (in degrees). + * + * Grivation is the angle between magnetic north and grid north. + * In the context of OpenOrienteering Mapper, it is the angle between the y + * axes of map coordinates and projected coordinates. + * + * This will also affect the declination value and the transformations. + */ + void setGrivation(double grivation); + + + /** + * Returns the map coordinates of the reference point. + */ + MapCoord getMapRefPoint() const; + + /** + * Defines the map coordinates of the reference point. + * + * This will not update the map and geographic coordinates of the reference point. + */ + void setMapRefPoint(MapCoord point); + + + /** + * Returns the projected coordinates of the reference point. + */ + QPointF getProjectedRefPoint() const; + + /** + * Defines the projected coordinates of the reference point. + * + * This may trigger changes of the geographic coordinates of the reference + * point, the convergence, the grivation and the transformations. + */ + void setProjectedRefPoint(QPointF point, bool update_grivation = true); + + + /** + * Returns the unique id of the projected CRS. + */ + QString getProjectedCRSId() const; + + /** + * Returns the name of the coordinate reference system (CRS) of the + * projected coordinates. + */ + QString getProjectedCRSName() const; + + /** + * Returns the name of the projected coordinates. + */ + QString getProjectedCoordinatesName() const; + + /** + * Returns the array of projected crs parameter values. + */ + const std::vector& getProjectedCRSParameters() const; + + /** + * Returns the specification of the coordinate reference system (CRS) of the + * projected coordinates + * @return a PROJ.4 specification of the CRS + */ + QString getProjectedCRSSpec() const { return projected_crs_spec; } + + /** + * Sets the coordinate reference system (CRS) of the projected coordinates. + * + * This will not touch any of the reference points, the declination, the + * grivation. It is up to the user to decide how to reestablish a valid + * configuration of geographic reference point, projected reference point, + * declination and grivation. + * + * @param id an identifier + * @param spec the PROJ.4 specification of the CRS + * @param params parameter values (ignore for empty spec) + * @return true if the specification is valid or empty, false otherwise + */ + bool setProjectedCRS(const QString& id, QString spec = QString{}, std::vector< QString > params = std::vector()); + + /** + * Calculates the meridian convergence at the reference point. + * + * The meridian convergence is the angle between grid north and true north. + * + * @return zero for a local georeferencing, or a calculated approximation + */ + double getConvergence() const; + + + /** + * Returns the geographic coordinates of the reference point. + */ + LatLon getGeographicRefPoint() const; + + /** + * Defines the geographic coordinates of the reference point. + * + * This may trigger changes of the projected coordinates of the reference + * point, the convergence, the grivation and the transformations. + */ + void setGeographicRefPoint(LatLon lat_lon, bool update_grivation = true); + + + /** + * Transforms map (paper) coordinates to projected coordinates. + */ + QPointF toProjectedCoords(const MapCoord& map_coords) const; + + /** + * Transforms map (paper) coordinates to projected coordinates. + */ + QPointF toProjectedCoords(const MapCoordF& map_coords) const; + + /** + * Transforms projected coordinates to map (paper) coordinates. + */ + MapCoord toMapCoords(const QPointF& projected_coords) const; + + /** + * Transforms projected coordinates to map (paper) coordinates. + */ + MapCoordF toMapCoordF(const QPointF& projected_coords) const; + + + /** + * Transforms map (paper) coordinates to geographic coordinates (lat/lon). + */ + LatLon toGeographicCoords(const MapCoordF& map_coords, bool* ok = 0) const; + + /** + * Transforms CRS coordinates to geographic coordinates (lat/lon). + */ + LatLon toGeographicCoords(const QPointF& projected_coords, bool* ok = 0) const; + + /** + * Transforms geographic coordinates (lat/lon) to CRS coordinates. + */ + QPointF toProjectedCoords(const LatLon& lat_lon, bool* ok = 0) const; + + /** + * Transforms geographic coordinates (lat/lon) to map coordinates. + */ + MapCoord toMapCoords(const LatLon& lat_lon, bool* ok = NULL) const; + + /** + * Transforms geographic coordinates (lat/lon) to map coordinates. + */ + MapCoordF toMapCoordF(const LatLon& lat_lon, bool* ok = NULL) const; + + + /** + * Transforms map coordinates from the other georeferencing to + * map coordinates of this georeferencing, if possible. + */ + MapCoordF toMapCoordF(const Georeferencing* other, const MapCoordF& map_coords, bool* ok = NULL) const; + + + /** + * Returns the current error text. + */ + QString getErrorText() const; + + /** + * Converts a value from radians to degrees. + */ + static double radToDeg(double val); + + /** + * Converts a value from degrees to radians. + */ + static double degToRad(double val); + + /** + * Converts a value from degrees to a D°M'S" string. + */ + static QString degToDMS(double val); + + + /** + * Updates the transformation parameters between map coordinates and + * projected coordinates from the current projected reference point + * coordinates, the grivation and the scale. + */ + void updateTransformation(); + + /** + * Updates the grivation. + * + * The new value is calculated from the declination and the convergence. + * For a local georeferencing, the convergence is zero, and grivation + * is set to the same value as declination. + */ + void updateGrivation(); + + /** + * Initializes the declination. + * + * The new value is calculated from the grivation and the convergence. + * For a local georeferencing, the convergence is zero, and declination + * is set to the same value as grivation. + */ + void initDeclination(); + + /** + * Sets the transformation matrix from map coordinates to projected + * coordinates directly. + */ + void setTransformationDirectly(const QTransform& transform); + + +signals: + /** + * Indicates a change of the state property. + */ + void stateChanged(); + + /** + * Indicates a change to the transformation rules between map coordinates + * and projected coordinates. + */ + void transformationChanged(); + + /** + * Indicates a change to the projection rules between geographic coordinates + * and projected coordinates. + */ + void projectionChanged(); + + /** + * Indicates a change of the declination. + * + * The declination has no direct influence on projection or transformation. + * That's why there is an independent signal. + */ + void declinationChanged(); + + +private: + void setDeclinationAndGrivation(double declination, double grivation); + + State state; + + unsigned int scale_denominator; + double grid_scale_factor; + double declination; + double grivation; + double grivation_error; + MapCoord map_ref_point; + + QPointF projected_ref_point; + + QTransform from_projected; + QTransform to_projected; + + /// Projected CRS id, used for lookup in the CRS registry. + /// If the spec is directly entered as string, the id is empty. + QString projected_crs_id; + QString projected_crs_spec; + std::vector< QString > projected_crs_parameters; + projPJ projected_crs; + + LatLon geographic_ref_point; + + projPJ geographic_crs; + + static const QString geographic_crs_spec; +}; + +/** + * Dumps a Georeferencing to the debug output. + * + * Note that this requires a *reference*, not a pointer. + */ +QDebug operator<<(QDebug dbg, const Georeferencing &georef); + + + +//### Georeferencing inline code ### + +inline +constexpr unsigned int Georeferencing::scaleFactorPrecision() +{ + return 6u; +} + +inline +double Georeferencing::roundScaleFactor(double value) +{ + // This must match the implementation in scaleFactorPrecision(). + return floor(value*1000000.0+0.5)/1000000.0; +} + +inline +constexpr unsigned int Georeferencing::declinationPrecision() +{ + // This must match the implementation in declinationRound(). + return 2u; +} + +inline +double Georeferencing::roundDeclination(double value) +{ + // This must match the implementation in declinationPrecision(). + return floor(value*100.0+0.5)/100.0; +} + +inline +bool Georeferencing::isValid() const +{ + return state == Local || projected_crs != NULL; +} + +inline +bool Georeferencing::isLocal() const +{ + return state == Local; +} + +inline +Georeferencing::State Georeferencing::getState() const +{ + return state; +} + +inline +unsigned int Georeferencing::getScaleDenominator() const +{ + return scale_denominator; +} + +inline +double Georeferencing::getGridScaleFactor() const +{ + return grid_scale_factor; +} + +inline +double Georeferencing::getDeclination() const +{ + return declination; +} + +inline +double Georeferencing::getGrivation() const +{ + return grivation; +} + +inline +double Georeferencing::getGrivationError() const +{ + return grivation_error; +} + +inline +MapCoord Georeferencing::getMapRefPoint() const +{ + return map_ref_point; +} + +inline +QPointF Georeferencing::getProjectedRefPoint() const +{ + return projected_ref_point; +} + +inline +QString Georeferencing::getProjectedCRSId() const +{ + return projected_crs_id; +} + +inline +const std::vector& Georeferencing::getProjectedCRSParameters() const +{ + return projected_crs_parameters; +} + +inline +LatLon Georeferencing::getGeographicRefPoint() const +{ + return geographic_ref_point; +} + +#endif diff --git a/src/core/image_transparency_fixup.h b/src/core/image_transparency_fixup.h new file mode 100644 index 0000000..3c91980 --- /dev/null +++ b/src/core/image_transparency_fixup.h @@ -0,0 +1,89 @@ +/* + * Copyright 2012, 2013 Kai Pastor + * + * This file is part of OpenOrienteering. + * + * OpenOrienteering is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenOrienteering is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenOrienteering. If not, see . + */ + +#ifndef _OPENORIENTEERING_IMAGE_TRANSPARENCY_FIXUP_H_ +#define _OPENORIENTEERING_IMAGE_TRANSPARENCY_FIXUP_H_ + +#include + +/** + * ImageTransparencyFixup repairs a particular issue with composing + * transparent pixels. + * + * QPainter::CompositionMode_Multiply and QPainter::CompositionMode_Darken + * on a QImage of Format_ARGB32_Premultiplied calculate the resulting alpha + * channel in a very efficient but not accurate way. A particular case is the + * composition of two fully transparent pixels which should in theory give a + * fully transparent pixel. Qt yields an alpha value of 1 (in 0..255) instead. + * The error accumulates with further compositions. + * + * This class may be used as a functor on a particular image, providing a + * comfortable way to fix the described case after each composition. + * + * Synopsis: + * + * QImage image(100, 100, QImage::Format_ARGB32_Premultiplied); + * ImageTransparencyFixup fixup(&image); + * QPainter p(&image); + * p.setCompositionMode(QPainter::CompositionMode_Multiply); + * p.drawImage(another_image); + * p.end(); + * fixup(); + */ +class ImageTransparencyFixup +{ +public: + /** + * Create a fixup functor for the given image. + * + * The image must be of QImage::Format_ARGB32_Premultiplied. + * It may be null. + */ + inline ImageTransparencyFixup(QImage* image) + : dest(0), dest_end(0) + { + // NOTE: Here we may add a check for a setting which disables the + // fixup (for better application performance) + if (image != NULL) + { + dest = (QRgb*)image->bits(); + dest_end = dest + image->byteCount() / sizeof(QRgb); + } + } + + /** + * Checks all pixels of the image for the known wrong result of composing + * fully transparent pixels, and replaces them with a fully transparent + * pixel. + */ + inline void operator()() const + { + for (QRgb* px = dest; px < dest_end; px++) + { + if (*px == 0x01000000) /* qRgba(0, 0, 0, 1) */ + *px = 0x00000000; /* qRgba(0, 0, 0, 0) */ + } + } + +protected: + QRgb* dest; + QRgb* dest_end; +}; + +#endif \ No newline at end of file diff --git a/src/core/latlon.cpp b/src/core/latlon.cpp new file mode 100644 index 0000000..cd434ac --- /dev/null +++ b/src/core/latlon.cpp @@ -0,0 +1,32 @@ +/* + * Copyright 2012, 2013, 2014 Kai Pastor + * + * This file is part of OpenOrienteering. + * + * OpenOrienteering is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenOrienteering is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenOrienteering. If not, see . + */ + +#include "latlon.h" + +#include + +#include "georeferencing.h" + +QDebug operator<<(QDebug dbg, const LatLon& lat_lon) +{ + dbg.space() + << "LatLon" + << lat_lon.latitude() << lat_lon.longitude(); + return dbg.space(); +} diff --git a/src/core/latlon.h b/src/core/latlon.h new file mode 100644 index 0000000..7639292 --- /dev/null +++ b/src/core/latlon.h @@ -0,0 +1,136 @@ +/* + * Copyright 2012, 2013, 2014 Kai Pastor + * + * This file is part of OpenOrienteering. + * + * OpenOrienteering is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenOrienteering is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenOrienteering. If not, see . + */ + + +#ifndef _OPENORIENTEERING_LATLON_H_ +#define _OPENORIENTEERING_LATLON_H_ + +#include + +QT_BEGIN_NAMESPACE +class QDebug; +QT_END_NAMESPACE + + +/** + * @brief Specifies geographic location by latitude and longitude. + * + * Latitude is a geographic coordinate that specifies the north-south + * position (φ, phi). + * + * Longitude is a geographic coordinate that specifies the east-west + * position (λ, lambda). + * + * LatLon is meant to be similar to QGeoCoordinate (part of Qt since 5.2). + * This Qt class might eventually replace LatLon. QGeoCoordinate has altitude + * as an additional property which is rarely used in Mapper at the moment. + * + * @see QGeoCoordinate (http://qt-project.org/doc/qt-5/qgeocoordinate.html) + */ +class LatLon +{ +private: + double latitude_value; + double longitude_value; + friend QDebug operator<<(QDebug dbg, const LatLon& lat_lon); + +public: + /** + * Constructs a new LatLon for the latitude and longitude given in degrees. + */ + LatLon(double latitude = 0.0, double longitude = 0.0); + + /** + * Returns a new LatLon for the latitude and longitude given in radiant. + */ + static LatLon fromRadiant(double latitude, double longitude); + + /** + * Returns the latitude value in degrees. + */ + double latitude() const; + + /** + * Returns the longitude value in degrees. + */ + double longitude() const; + + /** + * Returns true if this object has exactly the same latitude and longitude + * like another. FP precision issues are not taken into account. + */ + bool operator==(const LatLon& rhs) const; + + /** + * Returns true if this object has not exactly the same latitude and longitude + * like another. FP precision issues are not taken into account. + */ + bool operator!=(const LatLon& rhs) const; +}; + +/** + * Dumps a LatLon to the debug output. + * + * Note that this requires a *reference*, not a pointer. + */ +QDebug operator<<(QDebug dbg, const LatLon &lat_lon); + + + +//### LatLon inline code ### + +inline +LatLon::LatLon(double latitude, double longitude) +: latitude_value(latitude) +, longitude_value(longitude) +{ + ; // nothing +} + +inline +LatLon LatLon::fromRadiant(double latitude, double longitude) +{ + return LatLon(latitude * 180.0 / M_PI, longitude * 180.0 / M_PI); +} + +inline +double LatLon::latitude() const +{ + return latitude_value; +} + +inline +double LatLon::longitude() const +{ + return longitude_value; +} + +inline +bool LatLon::operator==(const LatLon& rhs) const +{ + return (this->latitude_value == rhs.latitude_value) && (this->longitude_value == rhs.longitude_value); +} + +inline +bool LatLon::operator!=(const LatLon& rhs) const +{ + return !(*this == rhs); +} + +#endif diff --git a/src/core/map_color.cpp b/src/core/map_color.cpp new file mode 100644 index 0000000..738b724 --- /dev/null +++ b/src/core/map_color.cpp @@ -0,0 +1,381 @@ +/* + * Copyright 2012, 2013 Thomas Schöps + * Copyright 2015 Kai Pastor + * + * This file is part of OpenOrienteering. + * + * OpenOrienteering is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenOrienteering is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenOrienteering. If not, see . + */ + + +#include "map_color.h" + +#include + + +MapColor::MapColor() +: name(QCoreApplication::translate("Map", "New color")), + priority(Undefined), + opacity(1.0f), + q_color(Qt::black), + spot_color_method(MapColor::UndefinedMethod), + cmyk_color_method(MapColor::CustomColor), + rgb_color_method(MapColor::CmykColor), + flags(0), + spot_color_name() +{ + Q_ASSERT(isBlack()); +} + +MapColor::MapColor(int priority) +: name(QCoreApplication::translate("Map", "New color")), + priority(priority), + opacity(1.0f), + q_color(Qt::black), + spot_color_method(MapColor::UndefinedMethod), + cmyk_color_method(MapColor::CustomColor), + rgb_color_method(MapColor::CmykColor), + flags(0), + spot_color_name() +{ + Q_ASSERT(isBlack()); + + switch (priority) + { + case CoveringWhite: + setCmyk(QColor(Qt::white)); + Q_ASSERT(isWhite()); + opacity = 1000.0f; // HACK: (almost) always opaque, even if multiplied by opacity factors + break; + case CoveringRed: + setRgb(QColor(Qt::red)); + setCmykFromRgb(); + opacity = 1000.0f; // HACK: (almost) always opaque, even if multiplied by opacity factors + break; + case Undefined: + setCmyk(QColor(Qt::darkGray)); + break; + case Registration: + Q_ASSERT(isBlack()); + name = QCoreApplication::translate("MapColor", "Registration black (all printed colors)"); + break; + default: + ; // no change + } +} + +MapColor::MapColor(const QString& name, int priority) +: name(name), + priority(priority), + opacity(1.0), + q_color(Qt::black), + spot_color_method(MapColor::UndefinedMethod), + cmyk_color_method(MapColor::CustomColor), + rgb_color_method(MapColor::CmykColor), + flags(0), + spot_color_name() +{ + Q_ASSERT(isBlack()); +} + + +MapColor* MapColor::duplicate() const +{ + MapColor* copy = new MapColor(name, priority); + copy->cmyk = cmyk; + copy->rgb = rgb; + copy->opacity = opacity; + copy->q_color = q_color; + copy->spot_color_method = spot_color_method; + copy->cmyk_color_method = cmyk_color_method; + copy->rgb_color_method = rgb_color_method; + copy->flags = flags; + copy->spot_color_name = spot_color_name; + copy->components = components; + return copy; +} + +bool MapColor::isBlack() const +{ + Q_ASSERT(rgb.isBlack() == cmyk.isBlack()); + return rgb.isBlack(); +} + +bool MapColor::isWhite() const +{ + Q_ASSERT(rgb.isWhite() == cmyk.isWhite()); + return rgb.isWhite(); +} + + +bool operator==(const SpotColorComponents &lhs, const SpotColorComponents& rhs) +{ + if (lhs.size() != rhs.size()) + return false; + + // Not efficient, but correct. + SpotColorComponents::const_iterator rhs_it, rhs_end = rhs.end(); + for (SpotColorComponents::const_iterator lhs_it = lhs.begin(), lhs_end = lhs.end(); lhs_it != lhs_end; ++lhs_it) + { + for (rhs_it = rhs.begin(); rhs_it != rhs_end; ++rhs_it) + { + if (*lhs_it->spot_color != *rhs_it->spot_color) + continue; + if (qAbs(lhs_it->factor - rhs_it->factor) < 1e-03) + break; + } + if (rhs_it == rhs_end) + return false; // No match for *lhs_it + } + return true; +} + +bool MapColor::componentsEqual(const MapColor& other, bool compare_priority) const +{ + const SpotColorComponents& lhs(components); + const SpotColorComponents& rhs(other.components); + if (lhs.size() != rhs.size()) + return false; + + // Not efficient, but correct. + SpotColorComponents::const_iterator rhs_it, rhs_end = rhs.end(); + for (SpotColorComponents::const_iterator lhs_it = lhs.begin(), lhs_end = lhs.end(); lhs_it != lhs_end; ++lhs_it) + { + for (rhs_it = rhs.begin(); rhs_it != rhs_end; ++rhs_it) + { + if (!lhs_it->spot_color->equals(*rhs_it->spot_color, compare_priority)) + continue; + if (qAbs(lhs_it->factor - rhs_it->factor) < 1e-03) + break; + } + if (rhs_it == rhs_end) + return false; // No match for *lhs_it + } + return true; +} + +bool MapColor::equals(const MapColor& other, bool compare_priority) const +{ + return (!compare_priority || (priority == other.priority)) && + (name.compare(other.name, Qt::CaseInsensitive) == 0) && + (spot_color_method == other.spot_color_method) && + (cmyk_color_method == other.cmyk_color_method) && + (rgb_color_method == other.rgb_color_method) && + (flags == other.flags) && + (cmyk_color_method != CustomColor || cmyk == other.cmyk) && + (rgb_color_method != CustomColor || rgb == other.rgb) && + ( spot_color_method == UndefinedMethod || + (spot_color_method == SpotColor && spot_color_name.compare(other.spot_color_name, Qt::CaseInsensitive) == 0) || + (spot_color_method == CustomColor && componentsEqual(other, compare_priority)) ) && + (qAbs(opacity - other.opacity) < 1e-03); +} + + +void MapColor::setSpotColorName(const QString& spot_color_name) +{ + spot_color_method = MapColor::SpotColor; + this->spot_color_name = spot_color_name; + components.clear(); + updateCalculatedColors(); +} + +void MapColor::setSpotColorComposition(const SpotColorComponents& components) +{ + this->components = components; + if (components.empty()) + spot_color_method = UndefinedMethod; + else + spot_color_method = CustomColor; + + removeSpotColorComponent(this); + updateCompositionName(); + updateCalculatedColors(); +} + +bool MapColor::removeSpotColorComponent(const MapColor* color) +{ + auto size_before = components.size(); + auto match = [this, color](const SpotColorComponent& scc) { return scc.spot_color == color; }; + components.erase(std::remove_if(begin(components), end(components), match), end(components)); + bool changed = components.size() != size_before; + if (changed) + { + if (components.empty()) + spot_color_method = UndefinedMethod; + + updateCompositionName(); + updateCalculatedColors(); + } + return changed; +} + +void MapColor::setKnockout(bool flag) +{ + if (spot_color_method != MapColor::UndefinedMethod) + { + if (flag) + { + if (!getKnockout()) + flags += MapColor::Knockout; + } + else if (getKnockout()) + flags -= MapColor::Knockout; + + Q_ASSERT(getKnockout() == flag); + } +} + +bool MapColor::getKnockout() const +{ + return (flags & MapColor::Knockout) > 0; +} + + +void MapColor::setCmyk(const MapColorCmyk& new_cmyk) +{ + cmyk_color_method = MapColor::CustomColor; + cmyk = new_cmyk; + updateCalculatedColors(); +} + +void MapColor::setCmykFromSpotColors() +{ + if (spot_color_method == MapColor::CustomColor) + { + cmyk_color_method = MapColor::SpotColor; + updateCalculatedColors(); + } +} + +void MapColor::setCmykFromRgb() +{ + if (rgb_color_method == MapColor::CmykColor) + rgb_color_method = MapColor::CustomColor; + + cmyk_color_method = MapColor::RgbColor; + updateCalculatedColors(); +} + + +void MapColor::setRgb(const MapColorRgb& new_rgb) +{ + rgb_color_method = MapColor::CustomColor; + rgb = new_rgb; + updateCalculatedColors(); +} + +void MapColor::setRgbFromSpotColors() +{ + if (spot_color_method == MapColor::CustomColor) + { + rgb_color_method = MapColor::SpotColor; + updateCalculatedColors(); + } +} + +void MapColor::setRgbFromCmyk() +{ + if (cmyk_color_method == MapColor::RgbColor) + cmyk_color_method = MapColor::CustomColor; + + rgb_color_method = MapColor::CmykColor; + updateCalculatedColors(); +} + +void MapColor::updateCompositionName() +{ + if (spot_color_method != MapColor::SpotColor) + { + spot_color_name.clear(); + for (auto& component : components) + { + if (!spot_color_name.isEmpty()) + spot_color_name += QLatin1String(", "); + spot_color_name += component.spot_color->getSpotColorName() + QLatin1Char(' ') + + QString::number(component.factor * 100) /* % */; + } + } +} + +void MapColor::updateCalculatedColors() +{ + Q_ASSERT(components.size() == 0 || spot_color_method == CustomColor); + Q_ASSERT(components.size() > 0 || spot_color_method != CustomColor); + Q_ASSERT(!((cmyk_color_method == RgbColor) && (rgb_color_method == CmykColor))); + + if (spot_color_method != CustomColor) + { + // No composition, thus cannot determine CMYK or RGB from spot colors. + if (cmyk_color_method == MapColor::SpotColor) + cmyk_color_method = MapColor::CustomColor; + + if (rgb_color_method == MapColor::SpotColor) + rgb_color_method = MapColor::CustomColor; + } + else + { + if (cmyk_color_method == MapColor::SpotColor) + cmyk = cmykFromSpotColors(); + + if (rgb_color_method == MapColor::SpotColor) + rgb = rgbFromSpotColors(); + } + + if (cmyk_color_method == MapColor::RgbColor) + cmyk = MapColorCmyk(rgb); + + if (rgb_color_method == MapColor::CmykColor) + rgb = MapColorRgb(cmyk); + + if (cmyk_color_method != RgbColor) + q_color = cmyk; + else + q_color = rgb; + + Q_ASSERT(components.size() > 0 || cmyk_color_method != MapColor::SpotColor); + Q_ASSERT(components.size() > 0 || rgb_color_method != MapColor::SpotColor); +} + +MapColorCmyk MapColor::cmykFromSpotColors() const +{ + Q_ASSERT(components.size() > 0); + + MapColorCmyk cmyk(Qt::white); + Q_ASSERT(cmyk.isWhite()); + for (auto&& component : components) + { + const MapColorCmyk& other = component.spot_color->cmyk; + cmyk.c = cmyk.c + component.factor * other.c * (1.0f - cmyk.c); + cmyk.m = cmyk.m + component.factor * other.m * (1.0f - cmyk.m); + cmyk.y = cmyk.y + component.factor * other.y * (1.0f - cmyk.y); + cmyk.k = cmyk.k + component.factor * other.k * (1.0f - cmyk.k); + } + return cmyk; +} + +MapColorRgb MapColor::rgbFromSpotColors() const +{ + Q_ASSERT(components.size() > 0); + + MapColorRgb rgb = QColor(Qt::white); + Q_ASSERT(rgb.isWhite()); + for (auto&& component : components) + { + const MapColorRgb& other = component.spot_color->rgb; + rgb.r = rgb.r - component.factor * (1.0f - other.r) * rgb.r; + rgb.g = rgb.g - component.factor * (1.0f - other.g) * rgb.g; + rgb.b = rgb.b - component.factor * (1.0f - other.b) * rgb.b; + } + return rgb; +} diff --git a/src/core/map_color.h b/src/core/map_color.h new file mode 100644 index 0000000..3d011c5 --- /dev/null +++ b/src/core/map_color.h @@ -0,0 +1,884 @@ +/* + * Copyright 2012, 2013 Thomas Schöps, Kai Pastor + * + * This file is part of OpenOrienteering. + * + * OpenOrienteering is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenOrienteering is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenOrienteering. If not, see . + */ + + +#ifndef _OPENORIENTEERING_MAP_COLOR_H_ +#define _OPENORIENTEERING_MAP_COLOR_H_ + +#include + +#include +#include +#include +#include +#include + +class Map; +class MapColor; + +/** + * The MapColorCmyk class provides a datatype for storing and transfering + * opaque CMYK colors. + * + * Components (c, m, y, k) are floats in the range [0.0; 1.0]. + */ +struct MapColorCmyk +{ + /** The cyan component. */ + float c; + /** The magenta component. */ + float m; + /** The yellow component. */ + float y; + /** The black component (aka key). */ + float k; + + /** Constructs a black color. */ + MapColorCmyk(); + + /** Constructs a color with the given components. */ + MapColorCmyk(float c, float m, float y, float k); + + /** Constructs a copy of the given CMYK color. */ + MapColorCmyk(const MapColorCmyk& other); + + /** Constructs a CMYK color of the given QColor. Used for type conversions. */ + MapColorCmyk(const QColor& other); + + /** Assigns another color's value to this color. */ + void operator=(const MapColorCmyk& other); + + /** Converts this color to a QColor. */ + operator QColor() const; + + /** Returns true if this color is black. */ + bool isBlack() const; + + /** Returns true if this color is white. */ + bool isWhite() const; +}; + +/** Returns true iff the MapColorCmyk are equal in all components. */ +bool operator==(const MapColorCmyk& lhs, const MapColorCmyk& rhs); + +/** Returns true iff the MapColorCmyk differ in at least one components. */ +bool operator!=(const MapColorCmyk& lhs, const MapColorCmyk& rhs); + + +/** + * The MapColorRgb class provides a datatype for storing and transfering + * opaque RGB colors. + * + * Components (r, g, b) are floats in the range [0.0; 1.0]. + */ +struct MapColorRgb +{ + /** The red component. */ + float r; + /** The green component. */ + float g; + /** The blue component. */ + float b; + + /** Constructs a black color. */ + MapColorRgb(); + + /** Constructs a color with the given components. */ + MapColorRgb(float r, float g, float b); + + /** Constructs a copy of the given RGB color. */ + MapColorRgb(const MapColorRgb& other); + + /** Constructs a RGB color of the given QColor. Used for type conversions. */ + MapColorRgb(const QColor& other); + + /** Assigns another color's value to this color. */ + void operator=(const MapColorRgb& other); + + /** Converts this color to a QColor. */ + operator QColor() const; + + /** Returns true if this color is black. */ + bool isBlack() const; + + /** Returns true if this color is white. */ + bool isWhite() const; +}; + +/** Returns true if both MapColorRgb are equal in all components. */ +bool operator==(const MapColorRgb& lhs, const MapColorRgb& rhs); + +/** Returns true iff the MapColorRgb differ in at least one components. */ +bool operator!=(const MapColorRgb& lhs, const MapColorRgb& rhs); + + +/** + * The SpotColorComponent datatype describes the use of a spot color in a + * screen or overprint to create another color. + */ +struct SpotColorComponent +{ + /** A map color which is a spot color. */ + const MapColor* spot_color; + + /** The factor describes the halftoning (screen). + * It is a value in the range [0.0; 1.0]. */ + float factor; + + /** Constructs a component with an undefined spot color and halftoning. */ + SpotColorComponent(); + + /** Constructs a component for the given spot color and halftoning. */ + SpotColorComponent(const MapColor* spot_color, float factor); + + /** Returns true iff the spot color is defined. */ + bool isValid() const; +}; + + +/** + * The SpotColorComponents type is a STL container that stores all + * SpotColorComponent elements which make up a particular map color. + */ +typedef std::vector SpotColorComponents; + +/** + * Returns true if for each element in lhs, there is an element of equal color + * and factor in rhs. */ +bool operator==(const SpotColorComponents &lhs, const SpotColorComponents& rhs); + + +/** + * The MapColor class provides colors which may be used by symbols (and + * objects). Apart from the mere color, it specifies how to output the color + * to different type of devices and optionally how the color was composed + * from other colors. + */ +class MapColor +{ +public: + /** + * SpecialProperties provides identifiers for (pseudo-)colors serving + * particular purposes in the program. + */ + enum SpecialPriorities + { + CoveringRed = -1005, ///< Foreground color for tool helper lines + CoveringWhite = -1000, ///< Background color for tool helper lines + Registration = -900, ///< Registration Black: all printed colors + Undefined = -500, ///< Color for objects with undefined symbol + Reserved = -1 ///< Never drawn + }; + + /** + * ColorMethod provides identifiers for methods on how to determine a + * particular realization of a color. + */ + enum ColorMethod + { + UndefinedMethod = 0, + CustomColor = 1, + SpotColor = 2, + CmykColor = 4, + RgbColor = 8, + Knockout = 16 + }; + + /** Constructs a black CMYK map color of undefined priority.*/ + MapColor(); + + /** Constructs a black CMYK map color with the given priority. */ + MapColor(int priority); + + /** Constructs a black CMYK map color with the given name and priority. */ + MapColor(const QString& name, int priority); + + /** Returns a copy of the color. */ + MapColor* duplicate() const; + + + /** Returns a QColor representation (reference) of the map color. + * + * This color is based on the CMYK color unless the CMYK color method is + * RGB: In that case, the returned value is based on the RGB color. + */ + operator const QColor&() const; + + /** Converts the current RGB values to a QRgb. */ + operator QRgb() const; + + + /** Returns the color's name for the mapping context. */ + const QString& getName() const; + + /** Sets the color's name for the mapping context. */ + void setName(const QString& name); + + /** Returns the color's priority. */ + int getPriority() const; + + /** + * Sets the color's priority. + * Normally you don't want to call this directly. + */ + void setPriority(int priority); + + /** @deprecated Returns the color's opacity. */ + float getOpacity() const; + + /** @deprecated Sets the color's opacity. */ + void setOpacity(float opacity); + + + /** + * Returns how the spot color is to be created. + * + * Returns UndefinedMethod, SpotColor (for a full tone single color + * referenced by name), or CustomColor (for a color created from named + * colors using halftoning (screens) and overprint. + */ + ColorMethod getSpotColorMethod() const; + + /** + * Returns the name for the single spot color or a label for the spot color + * composition which realizes this map color. + * Returns an empty string for an UndefinedMethod. + */ + const QString& getSpotColorName() const; + + /** + * Sets the name of a single spot color which realizes this map color, + * and sets the spot color method to SpotColor. + */ + void setSpotColorName(const QString& spot_color_id); + + /** + * Sets the given components (i.e. screens and/or overprint) for the color, + * and sets the spot color method to CustomColor. + */ + void setSpotColorComposition(const SpotColorComponents& components); + + /** + * Returns the components of the spot color realization of this color. + * Returns an empty list if the spot color method is not CustomColor. + */ + const SpotColorComponents& getComponents() const; + + /** + * Removes a component color. + * + * Returns true if components were removed. + * Returns false if the color was not part of the composition before. + */ + bool removeSpotColorComponent(const MapColor* color); + + /** + * Sets the value of knockout flag for spot color printing. + * + * The color must have a spot color definition, or no change will be done. + */ + void setKnockout(bool flag); + + /** + * Returns the value of the knockout flag. + */ + bool getKnockout() const; + + + /** + * Returns how the CMYK color value is determined. + * + * Returns CustomColor (for custom CMYK values, e.g. for named spot colors), + * SpotColor (for values determined from evaluation the spot color composition), + * or RgbColor (for values directly derived from the current RGB values). + */ + ColorMethod getCmykColorMethod() const; + + /** Returns the map color's CMYK values. */ + const MapColorCmyk& getCmyk() const; + + /** Sets the CMYK values, and sets the CMYK color method to CustomColor. */ + void setCmyk(const MapColorCmyk& cmyk); + + /** + * Determines the CMYK values from the spot color composition, + * and sets the CMYK color method to SpotColor. + * + * The spot color method must be CustomColor. + * If the spot color composition is empty, the spot color method is + * changed to CustomColor, and the CMYK color method is changed to + * CustomColor. + */ + void setCmykFromSpotColors(); + + /** + * Determines the CMYK from the current RGB value, + * and sets the CMYK color method to RgbColor. + * + * If the RGB color method is CmykColor, it is changed to CustomColor. + */ + void setCmykFromRgb(); + + + /** + * Returns how the RGB color value is determined. + * + * Returns CustomColor (for custom RGB values), + * SpotColor (for values determined from evaluation the spot color composition), + * or CmykColor (for values directly derived from the current CMYK value). + */ + ColorMethod getRgbColorMethod() const; + + /** Returns the map color's RGB values. */ + const MapColorRgb& getRgb() const; + + /** Sets the RGB values, and sets the RGB color method to CustomColor. */ + void setRgb(const MapColorRgb& rgb); + + /** + * Determines the RGB values from the spot color composition, + * and sets the RGB color method to SpotColor. + * + * The spot color method must be CustomColor. + * If the spot color composition is empty, the spot color method is + * changed to CustomColor, and the RGB color method is changed to + * CustomColor. + */ + void setRgbFromSpotColors(); + + /** + * Determines the RGB from the current CMYK value, + * and sets the RGB color method to CmykColor. + * + * If the CMYK color method is RgbColor, it is changed to CustomColor. + */ + void setRgbFromCmyk(); + + + /** Returns true if this color is black. */ + bool isBlack() const; + + /** Returns true if this color is white. */ + bool isWhite() const; + + + /** Compares this color and another. */ + bool equals(const MapColor& other, bool compare_priority) const; + + /** Compares two colors given by pointers. + * Returns true if the colors are equal or if both pointers are NULL. */ + static bool equal(const MapColor* color, const MapColor* other); + + /** Returns true if this color's priority is less than the other's. */ + bool comparePriority(const MapColor& other) const; + + /** Compares this color's components and another. */ + bool componentsEqual(const MapColor& other, bool compare_priority) const; + +protected: + /** + * Determines the composition name from the components. + * + * Does nothing it the spot color method is not CustomColor. + */ + void updateCompositionName(); + + /** + * Updates all calculated color values. + * + * If the spot color method is different from CustomColor, resets CMYK and + * RGB methods from SpotColor tp CustomColor. + */ + void updateCalculatedColors(); + + /** + * Returns a CMYK color determined from the cmyk color of the spot color + * components. + */ + MapColorCmyk cmykFromSpotColors() const; + + /** + * Returns a RGB color determined from the cmyk color of the spot color + * components. + */ + MapColorRgb rgbFromSpotColors() const; + + + QString name; + int priority; + + MapColorCmyk cmyk; + MapColorRgb rgb; + float opacity; + + QColor q_color; + + char spot_color_method; + char cmyk_color_method; + char rgb_color_method; + char flags; + + QString spot_color_name; + SpotColorComponents components; +}; + +// Allow explicit use of MapColor pointers in QVariant +Q_DECLARE_METATYPE(const MapColor*) + +/** Returns true if both MapColor are equal in all components. */ +bool operator==(const MapColor& lhs, const MapColor& rhs); + +/** Returns true iff the MapColor differ in at least one components. */ +bool operator!=(const MapColor& lhs, const MapColor& rhs); + + +/** + * MapColorMap provides a mapping from one map color to another. + * + * In addition to explicitly user-defined key-value pairs of colors, it will + * (in const contexts) map colors with reserved priorities to themselves, + * assuming that there is only a single static instance of these colors. + */ +class MapColorMap +{ +public: + /** Constructs a new MapColorMap. */ + MapColorMap(); + + /** Returns the size, i.e. the number of user-defined key-value pairs. */ + int size() const; + + /** Clears the user-defined key-value pairs. */ + void clear(); + + /** Returns true if there is a user-defined value for the key color */ + bool contains(const MapColor* key) const; + + /** Returns the mapped value for the key color. + * + * Returns the user-defined value for the key color if it is defined. + * Otherwise, if the key color's priority is from the RESERVED domain, + * returns key. Otherwise returns NULL. + */ + const MapColor* value(const MapColor* key) const; + + /** Returns the mapped value for the key color. Same as value(). + * + * Returns the user-defined value for the key color if it is defined. + * Otherwise, if the key color's priority is from the RESERVED domain, + * returns key. Otherwise returns NULL. + */ + const MapColor* operator[](const MapColor* key) const; + + /** Returns a reference to pointer to the mapped value for the key color. + * If a user-defined mapped value does not exist yet, a default- + * constructed mapped value is created first. + */ + const MapColor* & operator[](const MapColor* key); + +private: + /** The low-level mapping. */ + QHash mapping; +}; + + +/** + * Constructs a QColor with the alpha given by opacity from the prototype c. + * + * A QColor object must be constructible from c. + */ +template +QColor colorWithOpacity(T c, float opacity); + +/** + * Constructs a QColor with opacity from the given MapColor. + */ +QColor colorWithOpacity(const MapColor& c); + + + +// ### MapColorCmyk inline code ### + +inline +MapColorCmyk::MapColorCmyk() + : c(0.0f), m(0.0f), y(0.0f), k(1.0f) +{ + Q_ASSERT(isBlack()); +} + +inline +MapColorCmyk::MapColorCmyk(float c, float m, float y, float k) + : c(c), m(m), y(y), k(k) +{ + // Nothing +} + +inline +MapColorCmyk::MapColorCmyk(const MapColorCmyk& other) + : c(other.c), m(other.m), y(other.y), k(other.k) +{ + // Nothing +} + +inline +MapColorCmyk::MapColorCmyk(const QColor& other) + : c(other.cyanF()), m(other.magentaF()), y(other.yellowF()), k(other.blackF()) +{ + // Nothing +} + +inline +void MapColorCmyk::operator=(const MapColorCmyk& other) +{ + c = other.c; + m = other.m; + y = other.y; + k = other.k; +} + +inline +MapColorCmyk::operator QColor() const +{ + return QColor::fromCmykF(c, m, y, k); +} + +inline +bool MapColorCmyk::isBlack() const +{ + return (1.0 == k) || (1.0 == c && 1.0 == m && 1.0 == y); +} + +inline +bool MapColorCmyk::isWhite() const +{ + return (0.0 == c && 0.0 == m && 0.0 == y && 0.0 == k); +} + +inline +bool operator==(const MapColorCmyk& lhs, const MapColorCmyk& rhs) +{ + // The maximum difference of two floating point member values + // which are regarded as *equal*. + static const float epsilon = 0.0005f; + return ( qAbs(lhs.c - rhs.c) <= epsilon && + qAbs(lhs.m - rhs.m) <= epsilon && + qAbs(lhs.y - rhs.y) <= epsilon && + qAbs(lhs.k - rhs.k) <= epsilon ); +} + +inline +bool operator!=(const MapColorCmyk& lhs, const MapColorCmyk& rhs) +{ + return !(lhs == rhs); +} + + +// ### MapColorRgb inline code ### + +inline +MapColorRgb::MapColorRgb() + : r(0.0f), g(0.0f), b(0.0f) +{ + Q_ASSERT(isBlack()); +} + +inline +MapColorRgb::MapColorRgb(float r, float g, float b) + : r(r), g(g), b(b) +{ + // Nothing +} + +inline +MapColorRgb::MapColorRgb(const MapColorRgb& other) + : r(other.r), g(other.g), b(other.b) +{ + // Nothing +} + +inline +MapColorRgb::MapColorRgb(const QColor& other) + : r(other.redF()), g(other.greenF()), b(other.blueF()) +{ + // Nothing +} + +inline +void MapColorRgb::operator=(const MapColorRgb& other) +{ + r = other.r; + g = other.g; + b = other.b; +} + +inline +MapColorRgb::operator QColor() const +{ + return QColor::fromRgbF(r, g, b); +} + +inline +bool MapColorRgb::isBlack() const +{ + return (0.0 == r && 0.0 == g && 0.0 == b); +} + +inline +bool MapColorRgb::isWhite() const +{ + return (1.0 == r && 1.0 == g && 1.0 == b); +} + +inline +bool operator==(const MapColorRgb& lhs, const MapColorRgb& rhs) +{ + // The maximum difference of two floating point member values + // which are regarded as *equal*. + static const float epsilon = 0.0005f; + return ( qAbs(lhs.r - rhs.r) <= epsilon && + qAbs(lhs.g - rhs.g) <= epsilon && + qAbs(lhs.b - rhs.b) <= epsilon ); +} + +inline +bool operator!=(const MapColorRgb& lhs, const MapColorRgb& rhs) +{ + return !(lhs == rhs); +} + + +// ### SpotColorComponent inline code ### + +inline +SpotColorComponent::SpotColorComponent() + : spot_color(NULL), + factor(0.0f) +{ + // Nothing +} + +inline +SpotColorComponent::SpotColorComponent(const MapColor* spot_color, float factor) + : spot_color(spot_color), + factor(factor) +{ + // Nothing +} + +inline +bool SpotColorComponent::isValid() const +{ + return spot_color != NULL; +} + + +// ### MapColor inline code ### + +inline +MapColor::operator const QColor&() const +{ + return q_color; +} + +inline +MapColor::operator QRgb() const +{ + return qRgba(qFloor(255.9 * rgb.r), qFloor(255.9 * rgb.g), qFloor(255.9 * rgb.b), qFloor(255.9 * opacity)); +} + +inline +const QString& MapColor::getName() const +{ + return name; +} + +inline +void MapColor::setName(const QString& name) +{ + this->name = name; +} + +inline +int MapColor::getPriority() const +{ + return priority; +} + +inline +void MapColor::setPriority(int priority) +{ + this->priority = priority; +} + +inline +float MapColor::getOpacity() const +{ + return opacity; +} + +inline +void MapColor::setOpacity(float opacity) +{ + this->opacity = opacity; +} + +inline +MapColor::ColorMethod MapColor::getSpotColorMethod() const +{ + return (ColorMethod)spot_color_method; +} + +inline +const QString& MapColor::getSpotColorName() const +{ + return spot_color_name; +} + +inline +const SpotColorComponents& MapColor::getComponents() const +{ + return components; +} + +inline +MapColor::ColorMethod MapColor::getCmykColorMethod() const +{ + return (ColorMethod)cmyk_color_method; +} + +inline +const MapColorCmyk& MapColor::getCmyk() const +{ + return cmyk; +} + +inline +MapColor::ColorMethod MapColor::getRgbColorMethod() const +{ + return (ColorMethod)rgb_color_method; +} + +inline +const MapColorRgb& MapColor::getRgb() const +{ + return rgb; +} + +inline +bool MapColor::comparePriority(const MapColor& other) const +{ + return priority < other.priority; +} + +inline +bool MapColor::equal(const MapColor* color, const MapColor* other) +{ + if (color == other) + return true; + else if (color && other) + return color->equals(*other, false); + else + return false; +} + +inline +bool operator==(const MapColor& lhs, const MapColor& rhs) +{ + return lhs.equals(rhs, true); +} + +inline +bool operator!=(const MapColor& lhs, const MapColor& rhs) +{ + return !lhs.equals(rhs, true); +} + + +// ### MapColorMap inline code ### + +inline +MapColorMap::MapColorMap() + : mapping() +{ + // Nothing. +} + +inline +int MapColorMap::size() const +{ + return mapping.size(); +} + +inline +void MapColorMap::clear() +{ + mapping.clear(); +} + +inline +bool MapColorMap::contains(const MapColor* key) const +{ + return mapping.contains(key); +} + +inline +const MapColor* MapColorMap::value(const MapColor* key) const +{ + if (mapping.contains(key)) + { + return mapping.value(key); + } + else if (key != NULL && key->getPriority() < 0) + { + return key; + } + else + { + return NULL; + } +} + +inline +const MapColor* MapColorMap::operator[](const MapColor* key) const +{ + return value(key); +} + +inline +const MapColor* & MapColorMap::operator[](const MapColor* key) +{ + return mapping[key]; +} + +template +QColor colorWithOpacity(T c, float opacity) +{ + auto color = static_cast(c); + color.setAlphaF(opacity); + return color; +} + +inline +QColor colorWithOpacity(const MapColor& c) +{ + return colorWithOpacity(static_cast(c), c.getOpacity()); +} + + +#endif diff --git a/src/core/map_coord.cpp b/src/core/map_coord.cpp new file mode 100644 index 0000000..7ba1113 --- /dev/null +++ b/src/core/map_coord.cpp @@ -0,0 +1,449 @@ +/* + * Copyright 2012, 2013 Thomas Schöps + * Copyright 2014, 2015 Kai Pastor + * + * This file is part of OpenOrienteering. + * + * OpenOrienteering is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenOrienteering is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenOrienteering. If not, see . + */ + +#include "map_coord.h" + +#include + +#include +#include +#include +#include + +#include "../util/xml_stream_util.h" + + +static_assert(sizeof(qint32) <= sizeof(int), + "MapCoord::setX/Y uses qRound() returning int, xp/yp is of type qint32"); + +static_assert(!MapCoord::BoundsOffset().check_for_offset, + "Default-constructed BoundsOffset must have check_for_offset == false."); +static_assert(MapCoord::BoundsOffset().x == 0, + "Default-constructed BoundsOffset must have x == 0."); +static_assert(MapCoord::BoundsOffset().y == 0, + "Default-constructed BoundsOffset must have y == 0."); +static_assert(MapCoord::BoundsOffset().isZero(), + "Default-constructed BoundsOffset must be null."); + +static_assert(std::is_nothrow_move_constructible::value, "MapCoord must be nothrow move constructible."); +static_assert(std::is_nothrow_move_assignable::value, "MapCoord must be nothrow move assignable."); + +static_assert(MapCoordF(1.0, 1.0) == QPointF(1.0, 1.0), + "MapCoordF and QPointF constructors must use the same unit of measurement"); +static_assert(MapCoord(1, 1) == MapCoord(MapCoordF(1.0, 1.0)), + "MapCoord and MapCoordF constructors must use the same unit of measurement"); +static_assert(MapCoord(1.0, 1.0) == MapCoord(QPointF(1.0, 1.0)), + "MapCoord and QPointF constructors must use the same unit of measurement"); +static_assert(MapCoord(1, 1) == MapCoord::fromNative(1000, 1000), + "MapCoord::fromRaw must use the native unit of measurement"); + +static_assert(MapCoord(1, 1) + MapCoord (2, -1) == MapCoord(3, 0), + "MapCoord has component-wise operator+"); +static_assert(MapCoord(1, 1) - MapCoord (2, -1) == MapCoord(-1, 2), + "MapCoord has component-wise operator-"); +static_assert(MapCoord(1, 1) * 2.1 == MapCoord(2.1, 2.1), + "MapCoord has component-wise operator*(coord, factor)"); +static_assert(0.5 * MapCoord(1, 1) == MapCoord(0.5, 0.5), + "MapCoord has component-wise operator*(factor, coord)"); +static_assert(MapCoord(1, 1) / 4 == MapCoord(0.25, 0.25), + "MapCoord has component-wise operator/(coord, divisor"); +static_assert(-MapCoord(-2, 1) == MapCoord(2, -1), + "MapCoord has unary operator-()"); + +static_assert(!MapCoord(0.0, 0.0).isCurveStart(), + "MapCoord::isCurveStart() must return false by default."); +static_assert(MapCoord(0.0, 0.0, MapCoord::CurveStart).isCurveStart(), + "MapCoord::CurveStart must result in MapCoord::isCurveStart() returning true."); + +static_assert(!MapCoord(0.0, 0.0).isClosePoint(), + "MapCoord::isClosePoint() must return false by default."); +static_assert(MapCoord(0.0, 0.0, MapCoord::ClosePoint).isClosePoint(), + "MapCoord::ClosePoint must result in MapCoord::isClosePoint() returning true."); + +static_assert(!MapCoord(0.0, 0.0).isHolePoint(), + "MapCoord::isHolePoint() must return false by default."); +static_assert(MapCoord(0.0, 0.0, MapCoord::HolePoint).isHolePoint(), + "MapCoord::HolePoint must result in MapCoord::isHolePoint() returning true."); + +static_assert(!MapCoord(0.0, 0.0).isDashPoint(), + "MapCoord::isDashPoint() must return false by default."); +static_assert(MapCoord(0.0, 0.0, MapCoord::DashPoint).isDashPoint(), + "MapCoord::DashPoint must result in MapCoord::isDashPoint() returning true."); + +static_assert(!MapCoord(0.0, 0.0).isGapPoint(), + "MapCoord::isGapPoint() must return false by default."); +static_assert(MapCoord(0.0, 0.0, MapCoord::GapPoint).isGapPoint(), + "MapCoord::GapPoint must result in MapCoord::isGapPoint() returning true."); + +static_assert(MapCoord(-1.0, 2.0).x() == -1, + "MapCoord::x() must return original value (w/o flags)"); +static_assert(MapCoord(-1.0, 2.0, 255).x() == -1.0, + "MapCoord::x() must return original value (with flags)"); + +static_assert(MapCoord::fromNative(-1, 2).nativeX() == -1, + "MapCoord::nativeX() must return original value (w/o flags)"); +static_assert(MapCoord::fromNative(-1, 2, 255).nativeX() == -1, + "MapCoord::nativeX() must return original value (with flags)"); + +#ifndef MAPPER_NO_QREAL_CHECK +// Check that QPointF/MapCoorF will actually use double. +static_assert(std::is_same::value, "qreal is not double. This could work but was not tested."); +#endif + +static_assert(std::is_nothrow_move_constructible::value, "MapCoord must be nothrow move constructible."); +static_assert(std::is_nothrow_move_assignable::value, "MapCoord must be nothrow move assignable."); + +static_assert(QLineF(QPointF(0,0), -MapCoordF(1,0).perpRight()) == QLineF(QPointF(0,0), QPointF(1,0)).normalVector(), + "MapCoordF::perpRight() must return a vector in opposite direction of QLineF::normalVector()."); +static_assert(QLineF(QPointF(0,0), MapCoordF(1,0).normalVector()) == QLineF(QPointF(0,0), QPointF(1,0)).normalVector(), + "MapCoordF::normalVector() must behave like QLineF::normalVector()."); + + + +namespace literal +{ + static const QLatin1String x("x"); + static const QLatin1String y("y"); + static const QLatin1String flags("flags"); +} + + + +namespace +{ + +// Acceptable coord bounds on import, derived from printing UI bounds +constexpr qint64 min_coord = -50000000; +constexpr qint64 max_coord = +50000000; + +MapCoord::BoundsOffset bounds_offset; + +inline +void applyBoundsOffset(qint64& x64, qint64& y64) +{ + x64 -= bounds_offset.x; + y64 -= bounds_offset.y; +} + +inline +void handleBoundsOffset(qint64& x64, qint64& y64) +{ + if (bounds_offset.check_for_offset) + { + bounds_offset.check_for_offset = false; + if (x64 < min_coord || x64 > max_coord) + { + bounds_offset.x = x64; + x64 = 0; + } + if (y64 < min_coord || y64 > max_coord) + { + bounds_offset.y = y64; + y64 = 0; + } + } + else + { + applyBoundsOffset(x64, y64); + } +} + +inline +void ensureBoundsForQint32(qint64 x64, qint64 y64) +{ + if ( x64 < std::numeric_limits::min() + || x64 > std::numeric_limits::max() + || y64 < std::numeric_limits::min() + || y64 > std::numeric_limits::max() ) + { + throw std::range_error(QT_TRANSLATE_NOOP("MapCoord", "Coordinates are out-of-bounds.")); + } +} + +} // namespace + + + +MapCoord::BoundsOffset& MapCoord::boundsOffset() +{ + return bounds_offset; +} + +bool MapCoord::isRegular() const +{ + return (xp > 2 * min_coord + && xp < 2 * max_coord + && yp > 2 * min_coord + && yp < 2 * max_coord ); +} + +MapCoord MapCoord::fromNative64(qint64 x64, qint64 y64) +{ + // We only need to check the storage bounds here because + // this is the technical invariant. + // Printing bounds will be checked during map loading ATM. + ensureBoundsForQint32(x64, y64); + return MapCoord{ static_cast(x64), static_cast(y64), Flags() }; +} + +MapCoord MapCoord::fromNative64withOffset(qint64 x64, qint64 y64) +{ + applyBoundsOffset(x64, y64); + ensureBoundsForQint32(x64, y64); + return MapCoord { static_cast(x64), static_cast(y64), Flags() }; +} + +void MapCoord::save(QXmlStreamWriter& xml) const +{ + XmlElementWriter element(xml, XmlStreamLiteral::coord); + element.writeAttribute(literal::x, xp); + element.writeAttribute(literal::y, yp); + if (fp) + { + element.writeAttribute(literal::flags, Flags::Int(fp)); + } +} + +MapCoord MapCoord::load(QXmlStreamReader& xml) +{ + XmlElementReader element(xml); + auto x64 = element.attribute(literal::x); + auto y64 = element.attribute(literal::y); + auto flags = element.attribute(literal::flags); + + handleBoundsOffset(x64, y64); + ensureBoundsForQint32(x64, y64); + return MapCoord { static_cast(x64), static_cast(y64), flags }; +} + +MapCoord MapCoord::load(qreal x, qreal y, int flags) +{ + auto x64 = qRound64(x * 1000); + auto y64 = qRound64(y * 1000); + + handleBoundsOffset(x64, y64); + ensureBoundsForQint32(x64, y64); + return MapCoord { static_cast(x64), static_cast(y64), flags }; +} + +#ifndef NO_NATIVE_FILE_FORMAT + +MapCoord::MapCoord(const LegacyMapCoord& coord) + : xp{ decltype(xp)(coord.x >> 4) } + , yp{ decltype(yp)(coord.y >> 4) } + , fp{ Flags::Int((coord.x & 0xf) | ((coord.y & 0xf) << 4)) } +{ + //nothing +} + +#endif + +QString MapCoord::toString() const +{ + /* The buffer size must allow for + * 1x ';': 1 + * 2x '-': 2 + * 2x ' ': 2 + * 2x the decimal digits for values up to 0..2^31: + * 20 + * 1x the decimal digits for 0..2^8-1: + * 3 + * Total: 28 */ + constexpr std::size_t buf_size = 1+2+2+20+3; + static const QChar encoded[10] = { + QLatin1Char{'0'}, QLatin1Char{'1'}, + QLatin1Char{'2'}, QLatin1Char{'3'}, + QLatin1Char{'4'}, QLatin1Char{'5'}, + QLatin1Char{'6'}, QLatin1Char{'7'}, + QLatin1Char{'8'}, QLatin1Char{'9'} + }; + QChar buffer[buf_size]; + + // For efficiency, we construct the string from the back. + std::size_t j = buf_size - 1; + buffer[j] = QLatin1Char{';'}; + --j; + + int flags = fp; + if (flags > 0) + { + do + { + buffer[j] = encoded[flags % 10]; + flags = flags / 10; + --j; + } + while (flags != 0); + + buffer[j] = QChar::Space; + --j; + } + + qint64 tmp = yp; + static_assert(sizeof(decltype(tmp)) > sizeof(decltype(MapCoord::yp)), + "decltype(tmp) must be large enough to hold" + "-std::numeric_limits::min()" ); + QChar sign { QChar::Null }; + if (tmp < 0) + { + sign = QLatin1Char{'-'}; + tmp = -tmp; + } + do + { + buffer[j] = encoded[tmp % 10]; + tmp = tmp / 10; + --j; + } + while (tmp != 0); + if (!sign.isNull()) + { + buffer[j] = sign; + --j; + sign = QChar::Null; + } + + buffer[j] = QChar::Space; + --j; + + static_assert(sizeof(decltype(tmp)) > sizeof(decltype(MapCoord::xp)), + "decltype(tmp) must be large enough to hold" + "-std::numeric_limits::min()" ); + tmp = xp; + if (tmp < 0) + { + sign = QLatin1Char{'-'}; + tmp = -tmp; + } + do + { + buffer[j] = encoded[tmp % 10]; + tmp = tmp / 10; + --j; + } + while (tmp != 0); + if (!sign.isNull()) + { + buffer[j] = sign; + --j; + } + + ++j; + Q_ASSERT(j < buf_size); + j = qMin(j, buf_size); + return QString(buffer+j, buf_size-j); +} + +MapCoord::MapCoord(QStringRef& text) +: MapCoord{} +{ + const int len = text.length(); + if (Q_UNLIKELY(len < 2)) + throw std::invalid_argument("Premature end of data"); + + auto data = text.constData(); + int i = 0; + + qint64 x64 = data[0].unicode(); + if (x64 == '-') + { + x64 = '0' - data[1].unicode(); + for (i = 2; i != len; ++i) + { + auto c = data[i].unicode(); + if (c < '0' || c > '9') + break; + else + x64 = 10*x64 + '0' - c; + } + } + else if (x64 >= '0' && x64 <= '9') + { + x64 -= '0'; + for (i = 1; i != len; ++i) + { + auto c = data[i].unicode(); + if (c < '0' || c > '9') + break; + else + x64 = 10*x64 + c - '0'; + } + } + + ++i; + if (Q_UNLIKELY(i+1 >= len)) + throw std::invalid_argument("Premature end of data"); + + qint64 y64 = data[i].unicode(); + if (y64 == '-') + { + ++i; + y64 = '0' - data[i].unicode(); + for (++i; i != len; ++i) + { + auto c = data[i].unicode(); + if (c < '0' || c > '9') + break; + else + y64 = 10*y64 + '0' - c; + } + } + else if (y64 >= '0' && y64 <= '9') + { + y64 -= '0'; + for (++i; i != len; ++i) + { + auto c = data[i].unicode(); + if (c < '0' || c > '9') + break; + else + y64 = 10*y64 + c - '0'; + } + } + + handleBoundsOffset(x64, y64); + ensureBoundsForQint32(x64, y64); + xp = static_cast(x64); + yp = static_cast(y64); + + if (i < len && data[i] == QChar::Space) + { + ++i; + if (Q_UNLIKELY(i == len)) + throw std::invalid_argument("Premature end of data"); + + // there are no negative flags + fp = Flags(data[i].unicode() - '0'); + for (++i; i < len; ++i) + { + auto c = data[i].unicode(); + if (c < '0' || c > '9') + break; + else + fp = Flags(10*int(fp) + c - '0'); + } + } + + if (Q_UNLIKELY(i >= len || data[i] != QLatin1Char{';'})) + throw std::invalid_argument("Invalid data"); + + ++i; + text = text.mid(i, len-i); +} diff --git a/src/core/map_coord.h b/src/core/map_coord.h new file mode 100644 index 0000000..ee816cb --- /dev/null +++ b/src/core/map_coord.h @@ -0,0 +1,1124 @@ +/* + * Copyright 2012, 2013 Thomas Schöps + * Copyright 2013-2015 Kai Pastor + * + * This file is part of OpenOrienteering. + * + * OpenOrienteering is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenOrienteering is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenOrienteering. If not, see . + */ + + +#ifndef _OPENORIENTEERING_MAP_COORD_H_ +#define _OPENORIENTEERING_MAP_COORD_H_ + +#include +#include + +#include +#include +#include + +class QString; +class QTextStream; +class QXmlStreamReader; +class QXmlStreamWriter; + +#ifndef NO_NATIVE_FILE_FORMAT + +/** + * The legacy MapCoord structure, only used for legacy native file format. + * + * @deprecated + */ +struct LegacyMapCoord +{ + qint64 x; + qint64 y; +}; + +#endif + + + +/** + * Coordinates of a point in a map, with optional flags. + * + * This coordinate uses what we call native map coordinates. + * One unit in native map coordinates is 1/1000th of a millimeter on the map paper. + * + * The possible flags are: + * + *

    + *
  • isCurveStart(): If set, this point is the first one in a sequence of + * four points which define a cubic bezier curve.
  • + *
  • isHolePoint(): If set, this point marks the end of a distinct path. + * Only area objects may have more than one path. The first path can be + * understood as outline, while the remaining paths can be seen as holes in + * the area, subject to the filling rule. + *
  • isDashPoint(): This flag marks special points in the path. + * The effect depends on the type of symbol. + *
  • isClosePoint(): If this flag is set for the last point of a path, + * this path is treated as closed. The point's coordinates must be equal to + * the first point's coordinates in this path.
  • + *
  • isGapPoint(): This flag is used to indicate the begin and the end + * of gaps in a path. This only used internally at the moment (for dealing + * with dashed lines.) + *
+ * + * These coordinates are implemented as 32 bit integers, + * the flags are store separately. + */ +class MapCoord +{ + Q_DECLARE_TR_FUNCTIONS(MapCoord) + +public: + /** + * These flags provide extra information on each coordinate in a path. + * + * Don't change the values, they are used in import/export. + */ + enum Flag + { + CurveStart = 1 << 0, + ClosePoint = 1 << 1, + GapPoint = 1 << 2, + //unused 1 << 3, + HolePoint = 1 << 4, + DashPoint = 1 << 5, + //... + }; + Q_DECLARE_FLAGS(Flags, Flag) + + /** + * Offset and flag for importing and moving out-of-bounds MapCoords. + * + * Since reducing MapCoord bits from 60 (64 minus flags) to 32, we need to + * deal with old files possibly having out-of-bounds coordinates. + * + * In addition, we need to deal with files suffering from out-of-print range + * coordinates (issue #513). In the print dialog, the printable area is up + * to 1000 m of paper [!] wide and high. The top left point is allowed to be + * up 1000 m away from the origin in each direction. Every point to be + * printed (from the UI) must be within this area. + * + * The idea for correcting maps during loading (where we may hit the + * out-of-bounds coordinates for the first time) is to look at the first + * point in the map (the georeferencing reference point or the coordinates + * of the first object). If this point is more than 500 m of paper [!] from + * the origin, it is moved to the origin, and the same offset is applied to + * all other coordinates. After that adjustment, anything up to 1000 m of + * paper away from the first point will be in the printable area. + * + * The current implementation uses a global variable and thus can handle + * only one file at the same time. However, the global variables is + * initially configured to a neutral value. Any code activating the tracking + * of out-of-bounds coordinates it responsible to rollback this neutral + * configuration when finished. + * + * Since symbol definitions are stored in MapCoords, too, extra care needs + * to be taken not to adjust coordinates of the symbols' elements. + * + * \see XMLFileImporter::import + */ + struct BoundsOffset + { + qint64 x = 0; + qint64 y = 0; + bool check_for_offset = false; + + /** Returns true if both x and y are equal to zero. */ + constexpr bool isZero() const; + + /** Resets x and y to zero, and sets check_for_offset. */ + void reset(bool check_for_offset); + }; + +private: + /** Benchmark */ + friend class CoordXmlTest; + + qint32 xp; + qint32 yp; + Flags fp; + +public: + /** Returns the global bounds offset. + * + * It is returned as a non-const reference, so that it can be used in + * QScopedValueRollack. + */ + static BoundsOffset& boundsOffset(); + + + /** Creates a MapCoord with position at the origin and without any flags set. */ + constexpr MapCoord() noexcept; + + /** Copy constructor. */ + constexpr MapCoord(const MapCoord&) noexcept = default; + +#ifndef NO_NATIVE_FILE_FORMAT + + /** Creates a MapCoord from the legacy structure. + * + * @deprecated + */ + MapCoord(const LegacyMapCoord& coord); + +#endif + + /** Creates a MapCoord from a position given in millimeters on the map. + * + * This is a convenience constructor for efficient construction of a point + * at the origin i.e. MapCoord(0, 0), or for simple vectors i.e. + * MapCoord(1, 0). Intentionally, there is no public version with flags - + * you need to use other argument types than int if the compiler complains + * about ambiguity. + */ + constexpr MapCoord(int x, int y); + +private: + /** Creates a MapCoord from native map coordinates. + * + * This is exposed via fromNative() - you must be explicit when you want to + * use native units. + */ + constexpr MapCoord(qint32 x, qint32 y, int flags); + +public: + /** Creates a MapCoord from a position given in millimeters on the map. */ + constexpr MapCoord(qreal x, qreal y); + + /** Creates a MapCoord with the given flags from a position given in millimeters on the map. */ + constexpr MapCoord(qreal x, qreal y, int flags); + + /** Creates a MapCoord with the position taken from a QPointF. */ + explicit constexpr MapCoord(QPointF point); + + /** Creates a MapCoord with the given flags and with the position taken from a QPointF. */ + constexpr MapCoord(QPointF point, int flags); + + + /** Creates a MapCoord from native map coordinates. */ + static constexpr MapCoord fromNative(qint32 x, qint32 y); + + /** Creates a MapCoord from native map coordinates. */ + static constexpr MapCoord fromNative(qint32 x, qint32 y, int flags); + + /** It is illegal to call MapCoord::fromNative with qint64 arguments. + * + * Use fromNative64 instead. That method tests the values against the bounds of qint32. + */ + static MapCoord fromNative(qint64 x, qint64 y) = delete; + + /** Creates a MapCoord from native map coordinates. + * + * The coordinates are expected to be in the bounds of qint32. + * + * \todo Raise (and handle exceptions) when out of bounds. + */ + static MapCoord fromNative64(qint64 x, qint64 y); + + /** Creates a MapCoord from native map coordinates. + * + * This will apply the BoundsOffset() and throw a std::range_error if the + * adjusted coordinates are out of bounds for qint32. + * It does not modify BoundsOffset()! + */ + static MapCoord fromNative64withOffset(qint64 x, qint64 y); + + + /** Assignment operator */ + MapCoord& operator= (const MapCoord& other) = default; + + + /** Returns the coord's x position in millimeters on the map. */ + constexpr qreal x() const; + + /** Returns the coord's y position in millimeters on the map. */ + constexpr qreal y() const; + + /** Sets the coord's x position to a value in millimeters on the map. */ + inline void setX(qreal x); + + /** Sets the coord's y position to a value in millimeters on the map. */ + inline void setY(qreal y); + + + /** Returns the coord's x position in native map coords. */ + constexpr qint32 nativeX() const; + + /** Returns the coord's y position in native map coords. */ + constexpr qint32 nativeY() const; + + /** Sets the coord's x position to a value in native map coords. */ + inline void setNativeX(qint32 new_x); + + /** Sets the coord's y position to a value in native map coords. */ + inline void setNativeY(qint32 new_y); + + + /** Returns the coord's flags separately, merged into the lowest 8 bits of an int. */ + constexpr int flags() const; + + /** Sets the flags as retrieved by flags(). */ + void setFlags(int flags); + + + /** + * Returns true iff the coordinates are within "regular" bounds. + */ + bool isRegular() const; + + + /** + * Returns the length of this coord, seen as a vector from the origin + * to the given coordinate, in millimeters on the map. + */ + qreal length() const; + + /** + * Returns the squared length of this coord, seen as a vector from the origin + * to the given coordinate, in millimeters on the map. Faster than length(). + */ + constexpr qreal lengthSquared() const; + + /** + * Returns the distance from this coord to the other + * in millimeters on the map. + */ + qreal distanceTo(const MapCoord& other) const; + + /** + * Returns the squared distance from this coord to the other + * in millimeters on the map. Faster than lengthTo(). + */ + constexpr qreal distanceSquaredTo(const MapCoord& other) const; + + + /** + * Returns if this coord's position is equal to that of the other one. + */ + constexpr bool isPositionEqualTo(const MapCoord& other) const; + + + /** Is this point the first point of a cubic bezier curve segment? */ + constexpr bool isCurveStart() const; + + /** Sets the curve start flag. */ + void setCurveStart(bool value); + + /** + * Is this the last point of a closed path, which is at the same position + * as the first point? This is set in addition to isHolePoint(). + */ + constexpr bool isClosePoint() const; + + /** Sets the close point flag. */ + void setClosePoint(bool value); + + + /** Is this the start of a hole for a line? */ + constexpr bool isHolePoint() const; + + /** Sets the hole point flag. */ + void setHolePoint(bool value); + + + /** Is this coordinate a special dash point? */ + constexpr bool isDashPoint() const; + + /** Sets the dash point flag. */ + void setDashPoint(bool value); + + + /** Is this coordinate a gap point? */ + constexpr bool isGapPoint() const; + + /** Sets the gap point flag. */ + void setGapPoint(bool value); + + + /** Additive inverse. */ + constexpr MapCoord operator-() const; + + /** Component-wise addition. */ + MapCoord& operator+= (const MapCoord& rhs_vector); + + /** Component-wise addition of this and a MapCoordF/QPointF. */ + MapCoord& operator+= (const QPointF& rhs_vector); + + /** Component-wise subtraction. */ + MapCoord& operator-= (const MapCoord& rhs_vector); + + /** Component-wise subtraction of this and a MapCoordF/QPointF. */ + MapCoord& operator-= (const QPointF& rhs_vector); + + /** Multiply with scalar factor. */ + MapCoord& operator*= (qreal factor); + + /** Divide by scalar factor. */ + MapCoord& operator/= (qreal scalar); + + + /** Converts the coord's position to a QPointF. */ + constexpr explicit operator QPointF() const; + + + /** + * Writes raw coordinates and flags to a string. + */ + QString toString() const; + + /** + * Constructs the MapCoord from the beginning of text, and moves the + * reference to behind the this coordinates data. + * + * This is the counterpiece to toString(). It will throw a + * std::invalid_argument if the (beginning of) text does not + * contain valid data. + * + * This constructor will initialize the boundsOffset() if neccessary. + * Otherwise it will apply the BoundsOffset() and throw a std::range_error + * if the adjusted coordinates are out of bounds for qint32. + */ + MapCoord(QStringRef& text); + + + /** Saves the MapCoord in xml format to the stream. */ + void save(QXmlStreamWriter& xml) const; + + /** Loads the MapCoord in xml format from the stream. + * + * This will initialize the boundsOffset() if neccessary. Otherwise it will + * apply the BoundsOffset() and throw a std::range_error if the adjusted + * coordinates are out of bounds for qint32. + */ + static MapCoord load(QXmlStreamReader& xml); + + /** Creates a MapCoord from map coordinates in millimeters, with offset handling. + * + * This will initialize the boundsOffset() if neccessary. Otherwise it will + * apply the BoundsOffset() and throw a std::range_error if the adjusted + * coordinates are out of bounds for qint32. + */ + static MapCoord load(qreal x, qreal y, int flags); + + + friend constexpr bool operator==(const MapCoord& lhs, const MapCoord& rhs); + friend constexpr MapCoord operator+(const MapCoord& lhs, const MapCoord& rhs); + friend constexpr MapCoord operator+(const MapCoord& lhs, const QPointF& rhs); + friend constexpr MapCoord operator-(const MapCoord& lhs, const MapCoord& rhs); + friend constexpr MapCoord operator-(const MapCoord& lhs, const QPointF& rhs); + friend constexpr MapCoord operator*(const MapCoord& lhs, qreal factor); + friend constexpr MapCoord operator*(qreal factor, const MapCoord& rhs); + friend constexpr MapCoord operator/(const MapCoord& lhs, qreal divisor); +}; + +/** Compare MapCoord for equality. */ +constexpr bool operator==(const MapCoord& lhs, const MapCoord& rhs); + +/** Compare MapCoord for inequality. */ +constexpr bool operator!=(const MapCoord& lhs, const MapCoord& rhs); + + +/** Component-wise addition of MapCoord. */ +constexpr MapCoord operator+(const MapCoord& lhs, const MapCoord& rhs); + +/** Component-wise addition of MapCoord and MapCoordF/QPointF. */ +constexpr MapCoord operator+(const MapCoord& lhs, const QPointF& rhs); + +/** Component-wise subtraction of MapCoord. */ +constexpr MapCoord operator-(const MapCoord& lhs, const MapCoord& rhs); + +/** Component-wise subtraction of MapCoord and MapCoordF/QPointF. */ +constexpr MapCoord operator-(const MapCoord& lhs, const QPointF& rhs); + +/** Multiply MapCoord with scalar factor. */ +constexpr MapCoord operator*(const MapCoord& lhs, qreal factor); + +/** Multiply MapCoord with scalar factor. */ +constexpr MapCoord operator*(qreal factor, const MapCoord& rhs); + +/** Divide MapCoord by scalar factor. */ +constexpr MapCoord operator/(const MapCoord& lhs, qreal divisor); + + + +/** + * Map coordinates stored as floating point numbers. + * + * The unit is millimeters on the map paper. + * + * This type was initially meant as intermediate format for rendering but + * is currently used in a wide range of functions related to editing. + * In contrast to MapCoord, MapCoordF does not store flags. + * + * The type is based on QPointF and provides additional methods for using it to + * represent 2D vectors. (Some of the methods do have counterparts in QLineF + * rather than QPointF.) Similar to QPointF, many operators return const values, + * although one might argue that it is no longer good practice in C++11. + */ +class MapCoordF : public QPointF +{ +public: + + /** Creates a MapCoordF with both values set to zero. */ + constexpr MapCoordF(); + + /** Creates a MapCoordF with the given position in map coordinates. */ + constexpr MapCoordF(qreal x, qreal y); + + /** Creates a MapCoordF from a MapCoord, dropping its flags. */ + explicit constexpr MapCoordF(MapCoord coord); + + /** Copy constructor. */ + constexpr MapCoordF(const MapCoordF&) = default; + + /** Copy constructor for QPointF prototypes. */ + explicit constexpr MapCoordF(const QPointF& point); + + + /** Returns a vector with the given length and angle. */ + static const MapCoordF fromPolar(qreal length, qreal angle); + + + /** Assignment operator. */ + MapCoordF& operator= (const QPointF& point); + + + /** + * Returns the length of the vector. + * + * The value returned the from this function is the MapCoords distance to + * the origin of the coordinate system. + */ + qreal length() const; + + /** + * Returns the square of the length of the vector. + * + * This is a slightly faster alternative to MapCoordF::length() which + * preserves comparability. + */ + constexpr qreal lengthSquared() const; + + /** + * Returns the distance of the coordinate to another coordinate. + */ + qreal distanceTo(const MapCoordF& to) const; + + /** + * Returns the square of the distance of this coordinate to another coordinate. + * + * This is a silghtly faster alternative to MapCoordF::distanceTo() which + * preserves comparability. + */ + constexpr qreal distanceSquaredTo(const MapCoordF& to) const; + + /** + * Changes the length of the vector. + * + * The MapCoordF is interpreted as a vector and adjusted to a vector of the + * same direction but having the given lenght. + * It does nothing if the vector is very close to (0, 0). + */ + void setLength(qreal new_length); + + /** + * Normalizes the length of the vector. + * + * The MapCoordF is interpreted as a vector and adjusted to a vector of the + * same direction but length 1 (i.e. unit vector). + */ + void normalize(); + + + /** + * Returns the angle of the vector relative to the vector (1, 0). + * + * The returned value is in radians, in the range range [-PI; +PI]. + * MapCoordF { 0, 1 }.getAngle() returns +PI/2, + * MapCoordF { 0, -1 }.getAngle() returns -PI/2. + */ + qreal angle() const; + + /** + * Rotates the vector. + * + * The argument is to be given in radians. + * Positive arguments result in a counter-clockwise rotation. + */ + void rotate(qreal angle); + + /** + * Returns a vector which is the result of rotating this vector. + * + * The argument is to be given in radians. + * Positive arguments result in a counter-clockwise rotation. + */ + const MapCoordF rotated(qreal angle) const; + + /** + * Returns a vector with the same length that is perpendicular to this vector. + * + * Note that in contrast to normalVector(), this function returns a + * perpendicular vector pointing to the right. + * + * \todo Replace with normalVector(), similar to QLineF API. + */ + constexpr const MapCoordF perpRight() const; + + /** + * Returns a vector with the same length that is perpendicular to this vector. + * + * \see QLineF::normalVector() + */ + constexpr const MapCoordF normalVector() const; + + + /** Additive inverse */ + constexpr const MapCoordF operator-() const; + + /** Component-wise addition */ + MapCoordF& operator+= (const MapCoordF& rhs); + + /** Component-wise subtraction */ + MapCoordF& operator-= (const MapCoordF& rhs); + + /** Multiply with a scalar */ + MapCoordF& operator*= (qreal factor); + + /** Divide by a scalar */ + MapCoordF& operator/= (qreal divisor); + + using QPointF::dotProduct; +}; + +constexpr const MapCoordF operator+(const MapCoordF& lhs, const MapCoordF& rhs); + +constexpr const MapCoordF operator-(const MapCoordF& lhs, const MapCoordF& rhs); + +constexpr const MapCoordF operator*(const MapCoordF& lhs, qreal factor); +constexpr const MapCoordF operator*(qreal factor, const MapCoordF& rhs); + +constexpr const MapCoordF operator/(const MapCoordF& lhs, qreal divisor); + + + +typedef std::vector MapCoordVector; +typedef std::vector MapCoordVectorF; + + + +// ### MapCoord inline code ### + +Q_DECLARE_OPERATORS_FOR_FLAGS(MapCoord::Flags) + + +constexpr bool MapCoord::BoundsOffset::isZero() const +{ + return x==0 && y==0; +} + +inline +void MapCoord::BoundsOffset::reset(bool check_for_offset) +{ + this->check_for_offset = check_for_offset; + x = 0; + y = 0; +} + + +constexpr MapCoord::MapCoord() noexcept + : xp{ 0 } + , yp{ 0 } + , fp{ 0 } +{ + // nothing else +} + +constexpr MapCoord::MapCoord(int x, int y) + : xp{ x*1000 } + , yp{ y*1000 } + , fp{ 0 } +{ + // nothing else +} + +constexpr MapCoord::MapCoord(qint32 x, qint32 y, int flags) + : xp{ x } + , yp{ y } + , fp{ flags } +{ + // nothing else +} + +constexpr MapCoord::MapCoord(qreal x, qreal y) + : xp{ qRound(x*1000) } + , yp{ qRound(y*1000) } + , fp{ 0 } +{ + // nothing else +} + +constexpr MapCoord::MapCoord(qreal x, qreal y, int flags) + : xp{ qRound(x*1000) } + , yp{ qRound(y*1000) } + , fp{ flags } +{ + // nothing else +} + +constexpr MapCoord::MapCoord(QPointF point) + : MapCoord { point.x(), point.y() } +{ + // nothing else +} + +constexpr MapCoord::MapCoord(QPointF point, int flags) + : MapCoord { point.x(), point.y(), flags } +{ + // nothing else +} + +constexpr MapCoord MapCoord::fromNative(qint32 x, qint32 y) +{ + return MapCoord{ x, y, Flags() }; +} + +constexpr MapCoord MapCoord::fromNative(qint32 x, qint32 y, int flags) +{ + return MapCoord{ x, y, flags }; +} + +constexpr qreal MapCoord::x() const +{ + return nativeX() / 1000.0; +} + +constexpr qreal MapCoord::y() const +{ + return nativeY() / 1000.0; +} + +inline +void MapCoord::setX(qreal x) +{ + this->xp = qRound(x * 1000); +} + +inline +void MapCoord::setY(qreal y) +{ + this->yp = qRound(y * 1000); +} + +constexpr qint32 MapCoord::nativeX() const +{ + return xp; +} + +constexpr qint32 MapCoord::nativeY() const +{ + return yp; +} + +inline +void MapCoord::setNativeX(qint32 new_x) +{ + xp = new_x; +} + +inline +void MapCoord::setNativeY(qint32 new_y) +{ + yp = new_y; +} + +constexpr int MapCoord::flags() const +{ + return fp; +} + +inline +void MapCoord::setFlags(int flags) +{ + fp = Flags(flags); +} + + +inline +qreal MapCoord::length() const +{ + return sqrt(lengthSquared()); +} + +constexpr qreal MapCoord::lengthSquared() const +{ + return x()*x() + y()*y(); +} + +inline +qreal MapCoord::distanceTo(const MapCoord& other) const +{ + return sqrt(distanceSquaredTo(other)); +} + +constexpr qreal MapCoord::distanceSquaredTo(const MapCoord& other) const +{ + return (*this - other).lengthSquared(); +} + +constexpr bool MapCoord::isPositionEqualTo(const MapCoord& other) const +{ + return (xp == other.xp) && (yp == other.yp); +} + +constexpr bool MapCoord::isCurveStart() const { + return fp.testFlag(CurveStart); +} + +inline +void MapCoord::setCurveStart(bool value) +{ + if (fp.testFlag(CurveStart) != value) + fp ^= CurveStart; +} + +constexpr bool MapCoord::isClosePoint() const +{ + return fp.testFlag(ClosePoint); +} + +inline +void MapCoord::setClosePoint(bool value) +{ + if (fp.testFlag(ClosePoint) != value) + fp ^= ClosePoint; +} + +constexpr bool MapCoord::isHolePoint() const +{ + return fp.testFlag(HolePoint); +} + +inline +void MapCoord::setHolePoint(bool value) +{ + if (fp.testFlag(HolePoint) != value) + fp ^= HolePoint; +} + +constexpr bool MapCoord::isDashPoint() const +{ + return fp.testFlag(DashPoint); +} + +inline +void MapCoord::setDashPoint(bool value) +{ + if (fp.testFlag(DashPoint) != value) + fp ^= DashPoint; +} + +constexpr bool MapCoord::isGapPoint() const +{ + return fp.testFlag(GapPoint); +} + +inline +void MapCoord::setGapPoint(bool value) +{ + if (fp.testFlag(GapPoint) != value) + fp ^= GapPoint; +} + + +constexpr MapCoord MapCoord::operator-() const +{ + return MapCoord { -xp, -yp, fp }; +} + +inline +MapCoord& MapCoord::operator+=(const MapCoord& rhs_vector) +{ + xp += rhs_vector.xp; + yp += rhs_vector.yp; + return *this; +} + +inline +MapCoord& MapCoord::operator+=(const QPointF& rhs_vector) +{ + *this += MapCoord{ rhs_vector }; + return *this; +} + +inline +MapCoord& MapCoord::operator-=(const MapCoord& rhs_vector) +{ + xp -= rhs_vector.xp; + yp -= rhs_vector.yp; + return *this; +} + +inline +MapCoord& MapCoord::operator-=(const QPointF& rhs_vector) +{ + *this -= MapCoord{ rhs_vector }; + return *this; +} + +inline +MapCoord& MapCoord::operator*=(qreal factor) +{ + xp *= factor; + yp *= factor; + return *this; +} + +inline +MapCoord& MapCoord::operator/=(qreal divisor) +{ + xp /= divisor; + yp /= divisor; + return *this; +} + +constexpr MapCoord::operator QPointF() const +{ + return QPointF(x(), y()); +} + + + +constexpr bool operator==(const MapCoord& lhs, const MapCoord& rhs) +{ + return (lhs.xp == rhs.xp) && (lhs.yp == rhs.yp) && (lhs.fp == rhs.fp); +} + + +constexpr bool operator!=(const MapCoord& lhs, const MapCoord& rhs) +{ + return !(lhs == rhs); +} + + +constexpr MapCoord operator+(const MapCoord& lhs, const MapCoord& rhs) +{ + return MapCoord::fromNative(lhs.xp + rhs.xp, lhs.yp + rhs.yp); +} + +constexpr MapCoord operator+(const MapCoord& lhs, const QPointF& rhs) +{ + return lhs + MapCoord{ rhs }; +} + +constexpr MapCoord operator-(const MapCoord& lhs, const MapCoord& rhs) +{ + return MapCoord::fromNative(lhs.xp - rhs.xp, lhs.yp - rhs.yp); +} + +constexpr MapCoord operator-(const MapCoord& lhs, const QPointF& rhs) +{ + return lhs - MapCoord{ rhs }; +} + +constexpr MapCoord operator*(const MapCoord& lhs, double factor) +{ + return MapCoord::fromNative(qRound(lhs.xp * factor), qRound(lhs.yp * factor)); +} + +constexpr MapCoord operator*(double factor, const MapCoord& rhs) +{ + return MapCoord::fromNative(qRound(factor * rhs.xp), qRound(factor * rhs.yp)); +} + +constexpr MapCoord operator/(const MapCoord& lhs, double divisor) +{ + return MapCoord::fromNative(qRound(lhs.xp / divisor), qRound(lhs.yp / divisor)); +} + + + +// ### MapCoordF inline code ### + +constexpr MapCoordF::MapCoordF() + : QPointF {} +{ + // Nothing else +} + +constexpr MapCoordF::MapCoordF(qreal x, qreal y) + : QPointF { x, y } +{ + // Nothing else +} + +constexpr MapCoordF::MapCoordF(MapCoord coord) + : QPointF { coord.x(), coord.y() } +{ + // Nothing else +} + +constexpr MapCoordF::MapCoordF(const QPointF& point) + : QPointF { point } +{ + // Nothing else +} + +// static +inline +const MapCoordF MapCoordF::fromPolar(qreal length, qreal angle) +{ + return MapCoordF(cos(angle) * length, sin(angle) * length); +} + +inline +MapCoordF& MapCoordF::operator=(const QPointF& point) +{ + return static_cast(*static_cast(this) = point); +} + +inline +qreal MapCoordF::length() const +{ + return sqrt(lengthSquared()); +} + +constexpr qreal MapCoordF::lengthSquared() const +{ + return x()*x() + y()*y(); +} + +inline +qreal MapCoordF::distanceTo(const MapCoordF& to) const +{ + return sqrt(distanceSquaredTo(to)); +} + +constexpr qreal MapCoordF::distanceSquaredTo(const MapCoordF& to) const +{ + return (to - *this).lengthSquared(); +} + +inline +void MapCoordF::setLength(qreal new_length) +{ + auto length_squared = lengthSquared(); + if (length_squared > 1e-16) + { + auto factor = new_length / sqrt(length_squared); + rx() *= factor; + ry() *= factor; + } +} + +inline +void MapCoordF::normalize() +{ + setLength(1.0); +} + +inline +qreal MapCoordF::angle() const +{ + return atan2(y(), x()); +} + +inline +void MapCoordF::rotate(qreal angle) +{ + angle += this->angle(); + auto len = length(); + rx() = cos(angle) * len; + ry() = sin(angle) * len; +} + +inline +const MapCoordF MapCoordF::rotated(qreal angle) const +{ + return MapCoordF::fromPolar(length(), angle + this->angle()); +} + +constexpr const MapCoordF MapCoordF::perpRight() const +{ + return MapCoordF { -y(), x() }; +} + +constexpr const MapCoordF MapCoordF::normalVector() const +{ + return MapCoordF { y(), -x() }; +} + +constexpr const MapCoordF MapCoordF::operator-() const +{ + return static_cast(-static_cast(*this)); +} + +inline +MapCoordF& MapCoordF::operator+=(const MapCoordF& rhs) +{ + return static_cast(static_cast(*this) += rhs); +} + +inline +MapCoordF& MapCoordF::operator-=(const MapCoordF& rhs) +{ + return static_cast(static_cast(*this) -= rhs); +} + +inline +MapCoordF& MapCoordF::operator*=(qreal factor) +{ + return static_cast(static_cast(*this) *= factor); +} + +inline +MapCoordF& MapCoordF::operator/=(qreal divisor) +{ + return static_cast(static_cast(*this) /= divisor); +} + + + +constexpr const MapCoordF operator+(const MapCoordF& lhs, const MapCoordF& rhs) +{ + return static_cast(static_cast(lhs) + static_cast(rhs)); +} + +constexpr const MapCoordF operator-(const MapCoordF& lhs, const MapCoordF& rhs) +{ + return static_cast(static_cast(lhs) - static_cast(rhs)); +} + +constexpr const MapCoordF operator*(const MapCoordF& lhs, qreal factor) +{ + return static_cast(static_cast(lhs) * factor); +} + +constexpr const MapCoordF operator*(qreal factor, const MapCoordF& rhs) +{ + return static_cast(factor * static_cast(rhs)); +} + +constexpr const MapCoordF operator/(const MapCoordF& lhs, qreal divisor) +{ + return static_cast(static_cast(lhs) / divisor); +} + + + +#endif diff --git a/src/core/map_grid.cpp b/src/core/map_grid.cpp new file mode 100644 index 0000000..3d0bf44 --- /dev/null +++ b/src/core/map_grid.cpp @@ -0,0 +1,219 @@ +/* + * Copyright 2012, 2013 Thomas Schöps + * Copyright 2014, 2015 Kai Pastor + * + * This file is part of OpenOrienteering. + * + * OpenOrienteering is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenOrienteering is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenOrienteering. If not, see . + */ + + +#include "map_grid.h" + +#include + +#include +#include +#include +#include + +#include "georeferencing.h" +#include "../map.h" +#include "../core/map_coord.h" +#include "../util.h" +#include "../util/xml_stream_util.h" + +struct ProcessLine +{ + QPainter* painter; + void processLine(QPointF a, QPointF b); +}; + +void ProcessLine::processLine(QPointF a, QPointF b) +{ + painter->drawLine(a, b); +} + +// ### MapGrid ### + +MapGrid::MapGrid() +{ + snapping_enabled = true; + color = qRgba(100, 100, 100, 128); + display = AllLines; + + alignment = MagneticNorth; + additional_rotation = 0; + + unit = MetersInTerrain; + horz_spacing = 500; + vert_spacing = 500; + horz_offset = 0; + vert_offset = 0; +} + +#ifndef NO_NATIVE_FILE_FORMAT + +const MapGrid& MapGrid::load(QIODevice* file, int version) +{ + Q_UNUSED(version); + file->read((char*)&snapping_enabled, sizeof(bool)); + file->read((char*)&color, sizeof(QRgb)); + int temp; + file->read((char*)&temp, sizeof(int)); + display = (DisplayMode)temp; + file->read((char*)&temp, sizeof(int)); + alignment = (Alignment)temp; + file->read((char*)&additional_rotation, sizeof(double)); + file->read((char*)&temp, sizeof(int)); + unit = (Unit)temp; + file->read((char*)&horz_spacing, sizeof(double)); + file->read((char*)&vert_spacing, sizeof(double)); + file->read((char*)&horz_offset, sizeof(double)); + file->read((char*)&vert_offset, sizeof(double)); + + return *this; +} + +#endif + +void MapGrid::save(QXmlStreamWriter& xml) const +{ + XmlElementWriter element{xml, QLatin1String("grid")}; + element.writeAttribute(QLatin1String("color"), QColor(color).name()); + element.writeAttribute(QLatin1String("display"), display); + element.writeAttribute(QLatin1String("alignment"), alignment); + element.writeAttribute(QLatin1String("additional_rotation"), additional_rotation); + element.writeAttribute(QLatin1String("unit"), unit); + element.writeAttribute(QLatin1String("h_spacing"), horz_spacing); + element.writeAttribute(QLatin1String("v_spacing"), vert_spacing); + element.writeAttribute(QLatin1String("h_offset"), horz_offset); + element.writeAttribute(QLatin1String("v_offset"), vert_offset); + element.writeAttribute(QLatin1String("snapping_enabled"), snapping_enabled); +} + +const MapGrid& MapGrid::load(QXmlStreamReader& xml) +{ + Q_ASSERT(xml.name() == QLatin1String("grid")); + + XmlElementReader element(xml); + QXmlStreamAttributes attributes = xml.attributes(); + color = QColor(element.attribute(QLatin1String("color"))).rgba(); + display = MapGrid::DisplayMode(element.attribute(QLatin1String("display"))); + alignment = MapGrid::Alignment(element.attribute(QLatin1String("alignment"))); + additional_rotation = element.attribute(QLatin1String("additional_rotation")); + unit = MapGrid::Unit(element.attribute(QLatin1String("unit"))); + horz_spacing = element.attribute(QLatin1String("h_spacing")); + vert_spacing = element.attribute(QLatin1String("v_spacing")); + horz_offset = element.attribute(QLatin1String("h_offset")); + vert_offset = element.attribute(QLatin1String("v_offset")); + snapping_enabled = element.attribute(QLatin1String("snapping_enabled")); + + return *this; +} + +void MapGrid::draw(QPainter* painter, QRectF bounding_box, Map* map, bool on_screen) const +{ + double final_horz_spacing, final_vert_spacing; + double final_horz_offset, final_vert_offset; + double final_rotation; + calculateFinalParameters(final_horz_spacing, final_vert_spacing, final_horz_offset, final_vert_offset, final_rotation, map); + + QPen pen(color); + if (on_screen) + { + // zero-width cosmetic pen (effectively one pixel) + pen.setWidth(0); + pen.setCosmetic(true); + } + else + { + // 0.1 mm wide non-cosmetic pen + pen.setWidthF(0.1f); + } + painter->setPen(pen); + painter->setBrush(Qt::NoBrush); + painter->setOpacity(qAlpha(color) / 255.0); + + ProcessLine process_line; + process_line.painter = painter; + + if (display == AllLines) + Util::gridOperation(bounding_box, final_horz_spacing, final_vert_spacing, final_horz_offset, final_vert_offset, final_rotation, process_line); + else if (display == HorizontalLines) + Util::hatchingOperation(bounding_box, final_vert_spacing, final_vert_offset, final_rotation + M_PI / 2, process_line); + else // if (display == VeritcalLines) + Util::hatchingOperation(bounding_box, final_horz_spacing, final_horz_offset, final_rotation, process_line); +} + +void MapGrid::calculateFinalParameters(double& final_horz_spacing, double& final_vert_spacing, double& final_horz_offset, double& final_vert_offset, double& final_rotation, Map* map) const +{ + double factor = ((unit == MetersInTerrain) ? (1000.0 / map->getScaleDenominator()) : 1); + final_horz_spacing = factor * horz_spacing; + final_vert_spacing = factor * vert_spacing; + final_horz_offset = factor * horz_offset; + final_vert_offset = factor * vert_offset; + final_rotation = additional_rotation + M_PI / 2; + + const Georeferencing& georeferencing = map->getGeoreferencing(); + if (alignment == GridNorth) + { + final_rotation += georeferencing.getGrivation() * M_PI / 180; + + // Shift origin to projected coordinates origin + double prev_horz_offset = MapCoordF::dotProduct(MapCoordF(0, -1).rotated(final_rotation), MapCoordF(georeferencing.getMapRefPoint().x(), -1 * georeferencing.getMapRefPoint().y())); + double target_horz_offset = MapCoordF::dotProduct(MapCoordF(0, -1).rotated(additional_rotation + M_PI / 2), MapCoordF(georeferencing.getProjectedRefPoint().x(), georeferencing.getProjectedRefPoint().y())); + final_horz_offset -= factor * target_horz_offset - prev_horz_offset; + + double prev_vert_offset = MapCoordF::dotProduct(MapCoordF(1, 0).rotated(final_rotation), MapCoordF(georeferencing.getMapRefPoint().x(), -1 * georeferencing.getMapRefPoint().y())); + double target_vert_offset = MapCoordF::dotProduct(MapCoordF(1, 0).rotated(additional_rotation + M_PI / 2), MapCoordF(georeferencing.getProjectedRefPoint().x(), georeferencing.getProjectedRefPoint().y())); + final_vert_offset += factor * target_vert_offset - prev_vert_offset; + } + else if (alignment == TrueNorth) + final_rotation += georeferencing.getDeclination() * M_PI / 180; +} + +MapCoordF MapGrid::getClosestPointOnGrid(MapCoordF position, Map* map) const +{ + double final_horz_spacing, final_vert_spacing; + double final_horz_offset, final_vert_offset; + double final_rotation; + calculateFinalParameters(final_horz_spacing, final_vert_spacing, final_horz_offset, final_vert_offset, final_rotation, map); + + position.rotate(final_rotation - M_PI / 2); + return MapCoordF(qRound((position.x() - final_horz_offset) / final_horz_spacing) * final_horz_spacing + final_horz_offset, + qRound((position.y() - final_vert_offset) / final_vert_spacing) * final_vert_spacing + final_vert_offset).rotated(-1 * (final_rotation - M_PI / 2)); +} + + + +bool operator==(const MapGrid& lhs, const MapGrid& rhs) +{ + return + lhs.snapping_enabled == rhs.snapping_enabled && + lhs.color == rhs.color && + lhs.display == rhs.display && + lhs.alignment == rhs.alignment && + lhs.additional_rotation == rhs.additional_rotation && + lhs.unit == rhs.unit && + lhs.horz_spacing == rhs.horz_spacing && + lhs.vert_spacing == rhs.vert_spacing && + lhs.horz_offset == rhs.horz_offset && + lhs.vert_offset == rhs.vert_offset; +} + +bool operator!=(const MapGrid& lhs, const MapGrid& rhs) +{ + return !(lhs == rhs); +} diff --git a/src/core/map_grid.h b/src/core/map_grid.h new file mode 100644 index 0000000..953551b --- /dev/null +++ b/src/core/map_grid.h @@ -0,0 +1,167 @@ +/* + * Copyright 2012, 2013 Thomas Schöps + * Copyright 2014 Kai Pastor + * + * This file is part of OpenOrienteering. + * + * OpenOrienteering is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenOrienteering is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenOrienteering. If not, see . + */ + + +#ifndef _OPENORIENTEERING_MAP_GRID_H_ +#define _OPENORIENTEERING_MAP_GRID_H_ + +#include + +QT_BEGIN_NAMESPACE +class QIODevice; +class QPainter; +class QRectF; +class QXmlStreamReader; +class QXmlStreamWriter; +QT_END_NAMESPACE + +class Map; +class MapCoordF; + + +/** + * Class for displaying a grid on a map. + * + * Each map has an instance of this class which can be retrieved with map->getGrid(). + * The grid's visibility is defined per MapView. + */ +class MapGrid +{ +public: + /** Options for aligning the grid with different north concepts. */ + enum Alignment + { + MagneticNorth = 0, + GridNorth = 1, + TrueNorth = 2 + }; + + /** Different units for specifying the grid interval. */ + enum Unit + { + MillimetersOnMap = 0, + MetersInTerrain = 1 + }; + + /** Different display modes for map grids. */ + enum DisplayMode + { + AllLines = 0, + HorizontalLines = 1, + VerticalLines = 2 + }; + + /** Creates a new map grid with default settings. */ + MapGrid(); + + /** Loads the grid in the old "native" format from the given file. */ + const MapGrid& load(QIODevice* file, int version); + + /** Saves the grid in xml format to the given stream. */ + void save(QXmlStreamWriter& xml) const; + + /** Loads the grid in xml format from the given stream. */ + const MapGrid& load(QXmlStreamReader& xml); + + /** + * Draws the map grid. + * + * @param painter The QPainter used for drawing. + * @param bounding_box Bounding box of the area to draw the grid for, in + * map coordinates. + * @param map Map to draw the grid for. + * @param on_screen If true, uses a cosmetic pen (one pixel wide), + * otherwise uses a 0.1 mm wide pen. + */ + void draw(QPainter* painter, QRectF bounding_box, Map* map, bool on_screen) const; + + /** + * Calculates the "final" parameters with the following properties: + * - spacings and offsets are in millimeters on the map + * - rotation is relative to the vector (1, 0) and counterclockwise + */ + void calculateFinalParameters( + double& final_horz_spacing, double& final_vert_spacing, + double& final_horz_offset, double& final_vert_offset, + double& final_rotation, Map* map + ) const; + + /** Returns the grid point which is closest to the given position. */ + MapCoordF getClosestPointOnGrid(MapCoordF position, Map* map) const; + + // Getters / Setters + + inline bool isSnappingEnabled() const {return snapping_enabled;} + inline void setSnappingEnabled(bool enable) {snapping_enabled = enable;} + inline QRgb getColor() const {return color;} + inline void setColor(QRgb color) {this->color = color;} + + inline DisplayMode getDisplayMode() const {return display;} + inline void setDisplayMode(DisplayMode mode) {display = mode;} + + inline Alignment getAlignment() const {return alignment;} + inline void setAlignment(Alignment alignment) {this->alignment = alignment;} + inline double getAdditionalRotation() const {return additional_rotation;} + inline void setAdditionalRotation(double rotation) {additional_rotation = rotation;} + + inline Unit getUnit() const {return unit;} + inline void setUnit(Unit unit) {this->unit = unit;} + inline double getHorizontalSpacing() const {return horz_spacing;} + inline void setHorizontalSpacing(double spacing) {horz_spacing = spacing;} + inline double getVerticalSpacing() const {return vert_spacing;} + inline void setVerticalSpacing(double spacing) {vert_spacing = spacing;} + inline double getHorizontalOffset() const {return horz_offset;} + inline void setHorizontalOffset(double offset) {horz_offset = offset;} + inline double getVerticalOffset() const {return vert_offset;} + inline void setVerticalOffset(double offset) {vert_offset = offset;} + +private: + bool snapping_enabled; + QRgb color; + DisplayMode display; + + Alignment alignment; + double additional_rotation; + + Unit unit; + double horz_spacing; + double vert_spacing; + double horz_offset; + double vert_offset; + + friend bool operator==(const MapGrid& lhs, const MapGrid& rhs); +}; + +/** + * Compares two map grid objects. + * + * @return true if the objects are equal, false otherwise + */ +bool operator==(const MapGrid& lhs, const MapGrid& rhs); + +/** + * Compares two map grid objects for inequality. + * + * @return true if the objects are not equal, false otherwise + */ +bool operator!=(const MapGrid& lhs, const MapGrid& rhs); + + +#endif diff --git a/src/core/map_printer.cpp b/src/core/map_printer.cpp new file mode 100644 index 0000000..6068c5c --- /dev/null +++ b/src/core/map_printer.cpp @@ -0,0 +1,1285 @@ +/* + * Copyright 2012, 2013 Thomas Schöps + * Copyright 2012-2016 Kai Pastor + * + * This file is part of OpenOrienteering. + * + * OpenOrienteering is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenOrienteering is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenOrienteering. If not, see . + */ + + +#include "map_printer.h" + +#include + +#include +#include +#include +#include +#include +#include +#include + + +#if defined(QT_PRINTSUPPORT_LIB) +# include +# include +# if defined(Q_OS_WIN) +# include +# endif +#endif + +#include "../core/georeferencing.h" +#include "../core/map_color.h" +#include "../core/map_view.h" +#include "../map.h" +#include "../renderable.h" +#include "../settings.h" +#include "../template.h" +#include "../util.h" +#include "../util/xml_stream_util.h" + + +// ### A namespace which collects various string constants of type QLatin1String. ### + +namespace literal +{ + static const QLatin1String scale("scale"); + static const QLatin1String resolution("resolution"); + static const QLatin1String templates_visible("templates_visible"); + static const QLatin1String grid_visible("grid_visible"); + static const QLatin1String simulate_overprinting("simulate_overprinting"); + static const QLatin1String mode("mode"); + static const QLatin1String vector("vector"); + static const QLatin1String raster("raster"); + static const QLatin1String separations("separations"); + static const QLatin1String color_mode("color_mode"); + static const QLatin1String default_color_mode("default"); + static const QLatin1String device_cmyk("DeviceCMYK"); + static const QLatin1String page_format("page_format"); + static const QLatin1String paper_size("paper_size"); + static const QLatin1String orientation("orientation"); + static const QLatin1String portrait("portrait"); + static const QLatin1String landscape("landscape"); + static const QLatin1String h_overlap("h_overlap"); + static const QLatin1String v_overlap("v_overlap"); + static const QLatin1String dimensions("dimensions"); + static const QLatin1String page_rect("page_rect"); + static const QLatin1String print_area("print_area"); + static const QLatin1String center_area("center_area"); + static const QLatin1String single_page("single_page"); +} + + + +// #### MapPrinterPageFormat ### + +MapPrinterPageFormat::MapPrinterPageFormat(QSizeF page_rect_size, qreal margin, qreal overlap) + : +#ifdef QT_PRINTSUPPORT_LIB + paper_size(QPrinter::Custom) +#else + paper_size(-1) +#endif + , orientation(Portrait) + , page_rect(QRectF(QPointF(margin, margin), page_rect_size)) + , paper_dimensions(page_rect.size() + 2.0* QSizeF(margin, margin)) + , h_overlap(overlap) + , v_overlap(overlap) +{ + // nothing +} + +#ifdef QT_PRINTSUPPORT_LIB + +MapPrinterPageFormat::MapPrinterPageFormat(const QPrinter& printer, qreal overlap) + : paper_size(printer.paperSize()) + , orientation((printer.orientation() == QPrinter::Portrait) ? MapPrinterPageFormat::Portrait : MapPrinterPageFormat::Landscape) + , page_rect(printer.pageRect(QPrinter::Millimeter)) + , paper_dimensions(printer.paperSize(QPrinter::Millimeter)) + , h_overlap(overlap) + , v_overlap(overlap) +{ + // nothing +} + +#endif + +MapPrinterPageFormat MapPrinterPageFormat::fromDefaultPrinter() +{ +#ifdef QT_PRINTSUPPORT_LIB + QPrinter default_printer; + return MapPrinterPageFormat(default_printer); +#else + return MapPrinterPageFormat(); +#endif +} + +bool operator==(const MapPrinterPageFormat& lhs, const MapPrinterPageFormat& rhs) +{ + return lhs.paper_size == rhs.paper_size && + lhs.orientation == rhs.orientation && + fabs(lhs.h_overlap - rhs.h_overlap) < 0.05 && + fabs(lhs.v_overlap - rhs.v_overlap) < 0.05 && + fabs(lhs.page_rect.top() - rhs.page_rect.top()) < 0.05 && + fabs(lhs.page_rect.left() - rhs.page_rect.left()) < 0.05 && + fabs(lhs.page_rect.right() - rhs.page_rect.right()) < 0.05 && + fabs(lhs.page_rect.bottom() - rhs.page_rect.bottom()) < 0.05 && + fabs(lhs.paper_dimensions.width() - rhs.paper_dimensions.width()) < 0.05 && + fabs(lhs.paper_dimensions.height() - rhs.paper_dimensions.height()) < 0.05; +} + +// ### MapPrinterOptions ### + +MapPrinterOptions::MapPrinterOptions(unsigned int scale, int resolution, MapPrinterMode mode) + : scale(scale), + resolution(resolution), + mode(mode), + color_mode(DefaultColorMode), + show_templates(false), + show_grid(false), + simulate_overprinting(false) +{ + // nothing +} + + + +// ### MapPrinterConfig ### + +MapPrinterConfig::MapPrinterConfig(const Map& map) + : printer_name(QString::fromLatin1("DEFAULT")), + print_area(map.calculateExtent()), + page_format(MapPrinterPageFormat::fromDefaultPrinter()), + options(map.getScaleDenominator()), + center_print_area(false), + single_page_print_area(false) +{ + if (print_area.isEmpty()) + print_area = page_format.page_rect; +} + +MapPrinterConfig::MapPrinterConfig(const Map& map, QXmlStreamReader& xml) + : printer_name(QString::fromLatin1("DEFAULT")), + print_area(0.0, 0.0, 100.0, 100.0), // Avoid expensive calculation before loading. + page_format(), + options(map.getScaleDenominator()), + center_print_area(false), + single_page_print_area(false) +{ + XmlElementReader printer_config_element(xml); + + options.scale = printer_config_element.attribute(literal::scale); + options.resolution = printer_config_element.attribute(literal::resolution); + options.show_templates = printer_config_element.attribute(literal::templates_visible); + options.show_grid = printer_config_element.attribute(literal::grid_visible); + options.simulate_overprinting = printer_config_element.attribute(literal::simulate_overprinting); + QStringRef mode = printer_config_element.attribute(literal::mode); + if (!mode.isEmpty()) + { + if (mode == literal::vector) + options.mode = MapPrinterOptions::Vector; + else if (mode == literal::raster) + options.mode = MapPrinterOptions::Raster; + else if (mode == literal::separations) + options.mode = MapPrinterOptions::Separations; + else + qDebug() << "Unsupported map printing mode:" << mode; + } + QStringRef color_mode = printer_config_element.attribute(literal::color_mode); + if (!color_mode.isEmpty()) + { + if (color_mode == literal::default_color_mode) + options.color_mode = MapPrinterOptions::DefaultColorMode; + else if (color_mode == literal::device_cmyk) + options.color_mode = MapPrinterOptions::DeviceCmyk; + else + qDebug() << "Unsupported map color mode:" << color_mode; + } + + while (xml.readNextStartElement()) + { + if (xml.name() == literal::page_format) + { + XmlElementReader page_format_element(xml); + QString value; + +#ifdef QT_PRINTSUPPORT_LIB + value = page_format_element.attribute(literal::paper_size); + const QHash< int, const char* >& paper_size_names = MapPrinter::paperSizeNames(); + for (int i = 0; i < paper_size_names.count(); ++i) + { + if (value == QLatin1String(paper_size_names[i])) + page_format.paper_size = i; + } +#endif + + value = page_format_element.attribute(literal::orientation); + page_format.orientation = + (value == literal::portrait) ? MapPrinterPageFormat::Portrait : MapPrinterPageFormat::Landscape; + if (page_format_element.hasAttribute(literal::h_overlap)) + page_format.h_overlap = page_format_element.attribute(literal::h_overlap); + if (page_format_element.hasAttribute(literal::v_overlap)) + page_format.v_overlap = page_format_element.attribute(literal::v_overlap); + + while (xml.readNextStartElement()) + { + if (xml.name() == literal::dimensions) + { + XmlElementReader(xml).read(page_format.paper_dimensions); + } + else if (xml.name() == literal::page_rect) + { + XmlElementReader(xml).read(page_format.page_rect); + } + else + xml.skipCurrentElement(); + } + } + else if (xml.name() == literal::print_area) + { + XmlElementReader print_area_element(xml); + print_area_element.read(print_area); + center_print_area = print_area_element.attribute(literal::center_area); + single_page_print_area= print_area_element.attribute(literal::single_page); + } + else + xml.skipCurrentElement(); + } + + // Sanity checks + if (options.scale <= 0) + options.scale = map.getScaleDenominator(); + if (options.resolution <= 0) + options.resolution = 600; +} + +void MapPrinterConfig::save(QXmlStreamWriter& xml, const QLatin1String& element_name) const +{ + XmlElementWriter printer_config_element(xml, element_name); + + printer_config_element.writeAttribute(literal::scale, options.scale); + printer_config_element.writeAttribute(literal::resolution, options.resolution); + printer_config_element.writeAttribute(literal::templates_visible, options.show_templates); + printer_config_element.writeAttribute(literal::grid_visible, options.show_grid); + printer_config_element.writeAttribute(literal::simulate_overprinting, options.simulate_overprinting); + switch (options.mode) + { + case MapPrinterOptions::Vector: + printer_config_element.writeAttribute(literal::mode, literal::vector); + break; + case MapPrinterOptions::Raster: + printer_config_element.writeAttribute(literal::mode, literal::raster); + break; + case MapPrinterOptions::Separations: + printer_config_element.writeAttribute(literal::mode, literal::separations); + break; + default: + // Do not fail on saving + qDebug() << "Unsupported map printing mode:" << options.mode; + } + + switch (options.color_mode) + { + case MapPrinterOptions::DefaultColorMode: + // No need to write an attribute for default mode. + // printer_config_element.writeAttribute(literal::color_mode, literal::default_color_mode); + break; + case MapPrinterOptions::DeviceCmyk: + printer_config_element.writeAttribute(literal::color_mode, literal::device_cmyk); + break; + default: + // Do not fail on saving + qDebug() << "Unsupported map color mode:" << options.color_mode; + } + + { + XmlElementWriter page_format_element(xml, literal::page_format); +#ifdef QT_PRINTSUPPORT_LIB + page_format_element.writeAttribute(literal::paper_size, + MapPrinter::paperSizeNames()[page_format.paper_size]); +#endif + page_format_element.writeAttribute(literal::orientation, + (page_format.orientation == MapPrinterPageFormat::Portrait) ? literal::portrait : literal::landscape ); + page_format_element.writeAttribute(literal::h_overlap, page_format.h_overlap, 2); + page_format_element.writeAttribute(literal::v_overlap, page_format.v_overlap, 2); + { + XmlElementWriter(xml, literal::dimensions).write(page_format.paper_dimensions, 3); + } + { + XmlElementWriter(xml, literal::page_rect).write(page_format.page_rect, 3); + } + } + { + XmlElementWriter print_area_element(xml, literal::print_area); + print_area_element.write(print_area, 3); + print_area_element.writeAttribute(literal::center_area, center_print_area); + print_area_element.writeAttribute(literal::single_page, single_page_print_area); + } +} + + + +#ifdef QT_PRINTSUPPORT_LIB + +// ### MapPrinter ### +const QPrinterInfo* MapPrinter::pdfTarget() +{ + static QPrinterInfo pdf_target; // TODO: set name and features? + return &pdf_target; +} + +const QPrinterInfo* MapPrinter::imageTarget() +{ + static QPrinterInfo image_target; // TODO: set name and features? + return &image_target; +} + +const QHash< int, const char* >& MapPrinter::paperSizeNames() +{ + static QHash< int, const char* > names; + if (names.empty()) + { + names[QPrinter::A0] = "A0"; + names[QPrinter::A1] = "A1"; + names[QPrinter::A2] = "A2"; + names[QPrinter::A3] = "A3"; + names[QPrinter::A4] = "A4"; + names[QPrinter::A5] = "A5"; + names[QPrinter::A6] = "A6"; + names[QPrinter::A7] = "A7"; + names[QPrinter::A8] = "A8"; + names[QPrinter::A9] = "A9"; + names[QPrinter::B0] = "B0"; + names[QPrinter::B1] = "B1"; + names[QPrinter::B2] = "B2"; + names[QPrinter::B3] = "B3"; + names[QPrinter::B4] = "B4"; + names[QPrinter::B5] = "B5"; + names[QPrinter::B6] = "B6"; + names[QPrinter::B7] = "B7"; + names[QPrinter::B8] = "B8"; + names[QPrinter::B9] = "B9"; + names[QPrinter::B10] = "B10"; + names[QPrinter::C5E] = "C5E"; + names[QPrinter::DLE] = "DLE"; + names[QPrinter::Executive] = "Executive"; + names[QPrinter::Folio] = "Folio"; + names[QPrinter::Ledger] = "Ledger"; + names[QPrinter::Legal] = "Legal"; + names[QPrinter::Letter] = "Letter"; + names[QPrinter::Tabloid] = "Tabloid"; + names[QPrinter::Comm10E] = "US Common #10 Envelope"; + names[QPrinter::Custom] = "Custom"; + } + return names; +} + + +MapPrinter::MapPrinter(Map& map, const MapView* view, QObject* parent) +: QObject(parent), + MapPrinterConfig(map.printerConfig()), + map(map), + view(view), + target(nullptr) +{ + scale_adjustment = map.getScaleDenominator() / qreal(options.scale); + updatePaperDimensions(); + connect(&map.getGeoreferencing(), &Georeferencing::transformationChanged, this, &MapPrinter::mapScaleChanged); +} + +MapPrinter::~MapPrinter() +{ + // Do not remove. +} + +void MapPrinter::saveConfig() const +{ + map.setPrinterConfig(*this); +} + +// slot +void MapPrinter::setTarget(const QPrinterInfo* new_target) +{ + if (new_target != target) + { + const QPrinterInfo* old_target = target; + if (!new_target) + target = new_target; + else if (new_target == pdfTarget()) + target = new_target; + else if (new_target == imageTarget()) + target = new_target; + else + { + // We don't own this target, so we need to make a copy. + target_copy = *new_target; + target = &target_copy; + } + + if (old_target == imageTarget() || new_target == imageTarget()) + { + // No page margins. Will emit pageFormatChanged( ). + setCustomPaperSize(page_format.page_rect.size()); + } + else if (page_format.paper_size != QPrinter::Custom) + { + updatePaperDimensions(); + emit pageFormatChanged(page_format); + } + + emit targetChanged(target); + } +} + +std::unique_ptr MapPrinter::makePrinter() const +{ + std::unique_ptr printer; + if (!target) + { + printer.reset(new QPrinter(QPrinter::HighResolution)); + } + else if (isPrinter()) + { + printer.reset(new QPrinter(*target, QPrinter::HighResolution)); + } + else if (options.color_mode == MapPrinterOptions::DeviceCmyk) + { + printer.reset(new AdvancedPdfPrinter(*target, QPrinter::HighResolution)); + } + else + { + printer.reset(new QPrinter(*target, QPrinter::HighResolution)); + printer->setOutputFormat(QPrinter::PdfFormat); + } + + if (!printer->isValid()) + { + printer.reset(); + return printer; + } + + // Color can only be changed in (native) properties dialogs. This is the default. + printer->setColorMode(separationsModeSelected() ? QPrinter::GrayScale : QPrinter::Color); + if (printer->outputFormat() == QPrinter::NativeFormat) + { + PlatformPrinterProperties::restore(printer.get(), native_data); + } + + printer->setDocName(tr("- Map -")); + printer->setFullPage(true); + if (page_format.paper_size == QPrinter::Custom) + { + printer->setPaperSize(page_format.paper_dimensions, QPrinter::Millimeter); + printer->setOrientation(QPrinter::Portrait); + } + else + { + printer->setPaperSize(QPrinter::PaperSize(page_format.paper_size)); + printer->setOrientation((page_format.orientation == MapPrinterPageFormat::Portrait) ? QPrinter::Portrait : QPrinter::Landscape); + } + printer->setResolution(options.resolution); + + if (page_format.paper_size == QPrinter::Custom || !isPrinter()) + { + printer->setPageMargins(0.0, 0.0, 0.0, 0.0, QPrinter::Millimeter); + } + + return printer; +} + +bool MapPrinter::isPrinter() const +{ + bool is_printer = target + && target != imageTarget() + && target != pdfTarget(); + return is_printer; +} + +// slot +void MapPrinter::setPrintArea(const QRectF& area) +{ + if (print_area != area && area.left() < area.right() && area.top() < area.bottom()) + { + print_area = area; + + if (target == imageTarget() && print_area.size() != page_format.paper_dimensions) + setCustomPaperSize(print_area.size() * scale_adjustment); + + updatePageBreaks(); + + emit printAreaChanged(print_area); + } +} + +// slot +void MapPrinter::setPaperSize(const int size) +{ + if (page_format.paper_size != size) + { + if (size == QPrinter::Custom) + { + setCustomPaperSize(page_format.paper_dimensions); + } + else + { + if ( page_format.paper_size == QPrinter::Custom && + page_format.paper_dimensions.width() > page_format.paper_dimensions.height() ) + { + // After QPrinter::Custom, determine orientation from actual dimensions. + page_format.orientation = MapPrinterPageFormat::Landscape; + } + page_format.paper_size = size; + updatePaperDimensions(); + } + emit pageFormatChanged(page_format); + } +} + +// slot +void MapPrinter::setCustomPaperSize(const QSizeF dimensions) +{ + if ((page_format.paper_size != QPrinter::Custom || + page_format.paper_dimensions != dimensions) && + ! dimensions.isEmpty()) + { + page_format.paper_size = QPrinter::Custom; + page_format.orientation = MapPrinterPageFormat::Portrait; + page_format.paper_dimensions = dimensions; + updatePaperDimensions(); + emit pageFormatChanged(page_format); + } +} + +// slot +void MapPrinter::setPageOrientation(const MapPrinterPageFormat::Orientation orientation) +{ + if (page_format.paper_size == QPrinter::Custom) + { + // do nothing + emit pageFormatChanged(page_format); + } + else if (page_format.orientation != orientation) + { + page_format.orientation = orientation; + page_format.paper_dimensions.transpose(); + updatePaperDimensions(); + updatePageBreaks(); + emit pageFormatChanged(page_format); + } +} + +// slot +void MapPrinter::setOverlap(qreal h_overlap, qreal v_overlap) +{ + if (page_format.h_overlap != h_overlap || page_format.v_overlap != v_overlap) + { + page_format.h_overlap = qMax(qreal(0), qMin(h_overlap, page_format.page_rect.width())); + page_format.v_overlap = qMax(qreal(0), qMin(v_overlap, page_format.page_rect.height())); + updatePageBreaks(); + emit pageFormatChanged(page_format); + } +} + +void MapPrinter::updatePaperDimensions() +{ + if (target == imageTarget() && page_format.paper_size == QPrinter::Custom) + { + // No margins, no need to query QPrinter. + page_format.page_rect = QRectF(QPointF(0.0, 0.0), page_format.paper_dimensions); + page_format.h_overlap = qMax(qreal(0), qMin(page_format.h_overlap, page_format.page_rect.width())); + page_format.v_overlap = qMax(qreal(0), qMin(page_format.v_overlap, page_format.page_rect.height())); + updatePageBreaks(); + return; + } + + QPrinter* printer = target ? new QPrinter(*target, QPrinter::HighResolution) + : new QPrinter(QPrinter::HighResolution); + if (!printer->isValid() || target == imageTarget() || target == pdfTarget()) + printer->setOutputFormat(QPrinter::PdfFormat); + + if (page_format.paper_size == QPrinter::Custom) + { + printer->setPaperSize(page_format.paper_dimensions, QPrinter::Millimeter); + page_format.orientation = (printer->orientation() == QPrinter::Portrait) ? MapPrinterPageFormat::Portrait : MapPrinterPageFormat::Landscape; + } + else + { + printer->setPaperSize(QPrinter::PaperSize(page_format.paper_size)); + printer->setOrientation((page_format.orientation == MapPrinterPageFormat::Portrait) ? QPrinter::Portrait : QPrinter::Landscape); + } + + page_format.page_rect = printer->paperRect(QPrinter::Millimeter); + page_format.paper_dimensions = page_format.page_rect.size(); + + if ( target != imageTarget() && target != pdfTarget() && + page_format.paper_size != QPrinter::Custom ) + { + qreal left, top, right, bottom; + printer->getPageMargins(&left, &top, &right, &bottom, QPrinter::Millimeter); + page_format.page_rect.adjust(left, top, -right, -bottom); + } + page_format.h_overlap = qMax(qreal(0), qMin(page_format.h_overlap, page_format.page_rect.width())); + page_format.v_overlap = qMax(qreal(0), qMin(page_format.v_overlap, page_format.page_rect.height())); + + delete printer; + updatePageBreaks(); +} + +// slot +void MapPrinter::setResolution(int dpi) +{ + if (dpi > 0 && options.resolution != dpi) + { + options.resolution = dpi; + emit optionsChanged(options); + } +} + +// slot +void MapPrinter::setScale(const unsigned int value) +{ + if (options.scale != value) + { + Q_ASSERT(value > 0); + options.scale = value; + scale_adjustment = map.getScaleDenominator() / qreal(value); + updatePageBreaks(); + emit optionsChanged(options); + } +} + +// slot +void MapPrinter::setMode(const MapPrinterOptions::MapPrinterMode mode) +{ + if (options.mode != mode) + { + options.mode = mode; + emit optionsChanged(options); + } +} + +// slot +void MapPrinter::setPrintTemplates(const bool visible) +{ + if (options.show_templates != visible) + { + options.show_templates = visible; + emit optionsChanged(options); + } +} + +// slot +void MapPrinter::setPrintGrid(const bool visible) +{ + if (options.show_grid != visible) + { + options.show_grid = visible; + emit optionsChanged(options); + } +} + +// slot +void MapPrinter::setSimulateOverprinting(bool enabled) +{ + if (enabled && !map.hasSpotColors()) + { + options.simulate_overprinting = false; + emit optionsChanged(options); + } + else if (options.simulate_overprinting != enabled) + { + options.simulate_overprinting = enabled; + emit optionsChanged(options); + } +} + +void MapPrinter::setColorMode(MapPrinterOptions::ColorMode color_mode) +{ + if (options.color_mode != color_mode) + { + options.color_mode = color_mode; + emit optionsChanged(options); + } +} + +bool MapPrinter::isOutputEmpty() const +{ + return ( + (map.getNumObjects() == 0 || (view && !view->effectiveMapVisibility().visible)) && + (!options.show_templates || map.getNumTemplates() == 0) && + !options.show_grid + ); +} + +void MapPrinter::updatePageBreaks() +{ + Q_ASSERT(print_area.left() <= print_area.right()); + Q_ASSERT(print_area.top() <= print_area.bottom()); + + // This whole implementation needs to deal with FP precision issues + + h_page_pos.clear(); + qreal h_pos = print_area.left(); + h_page_pos.push_back(h_pos); + const qreal h_overlap = page_format.h_overlap / scale_adjustment; + const qreal page_width = page_format.page_rect.width() / scale_adjustment - h_overlap; + + const qreal right_bound = print_area.right() - h_overlap - 0.05; + if (page_width >= 0.01) + { + for (h_pos += page_width; h_pos < right_bound; h_pos += page_width) + h_page_pos.push_back(h_pos); + + // Center the print area on the pages total area. + // Don't pre-calculate this offset to avoid FP precision problems + const qreal h_offset = 0.5 * (h_pos + h_overlap - print_area.right()); + for (auto& pos : h_page_pos) + pos -= h_offset; + } + + v_page_pos.clear(); + qreal v_pos = print_area.top(); + v_page_pos.push_back(v_pos); + const qreal v_overlap = page_format.v_overlap / scale_adjustment; + const qreal page_height = page_format.page_rect.height() / scale_adjustment - v_overlap; + const qreal bottom_bound = print_area.bottom() - v_overlap - 0.05; + if (page_height >= 0.01) + { + for (v_pos += page_height; v_pos < bottom_bound; v_pos += page_height) + v_page_pos.push_back(v_pos); + + // Don't pre-calculate offset to avoid FP precision problems + const qreal v_offset = 0.5 * (v_pos + v_overlap - print_area.bottom()); + for (auto& pos : v_page_pos) + pos -= v_offset; + } +} + +void MapPrinter::mapScaleChanged() +{ + auto value = qreal(map.getScaleDenominator()) / options.scale; + if (!qFuzzyCompare(scale_adjustment, value)) + { + scale_adjustment = value; + updatePageBreaks(); + emit optionsChanged(options); + } +} + +void MapPrinter::takePrinterSettings(const QPrinter* printer) +{ + MapPrinterPageFormat f(*printer); + if (target == pdfTarget() || target == imageTarget()) + { + f.page_rect = QRectF(QPointF(0.0, 0.0), f.paper_dimensions); + } + + if (f != page_format) + { + page_format.paper_size = f.paper_size; + page_format.orientation = f.orientation; + page_format.paper_dimensions = f.paper_dimensions; + page_format.page_rect = f.page_rect; + updatePageBreaks(); + emit pageFormatChanged(page_format); + } + + setResolution(printer->resolution()); + + if (printer && printer->outputFormat() == QPrinter::NativeFormat) + { + PlatformPrinterProperties::save(printer, native_data); + } +} + +// local +void drawBuffer(QPainter* device_painter, const QImage* page_buffer, qreal pixel2units) +{ + Q_ASSERT(page_buffer); + + device_painter->save(); + +#if defined(Q_OS_MAC) + // Workaround for miss-scaled image export output + int logical_dpi = device_painter->device()->logicalDpiX(); + if (logical_dpi != 0) + { + int physical_dpi = device_painter->device()->physicalDpiX(); + if (physical_dpi != 0 && logical_dpi != physical_dpi) + { + qreal s = (qreal)logical_dpi / (qreal)physical_dpi; + //qreal s = physical_dpi / logical_dpi; + device_painter->scale(s, s); + } + } +#endif + + device_painter->scale(pixel2units, pixel2units); + device_painter->setRenderHint(QPainter::SmoothPixmapTransform, false); + device_painter->drawImage(0, 0, *page_buffer); + device_painter->restore(); +} + +void MapPrinter::drawPage(QPainter* device_painter, float units_per_inch, const QRectF& page_extent, bool white_background, QImage* page_buffer) const +{ + device_painter->save(); + + device_painter->setRenderHint(QPainter::Antialiasing); + device_painter->setRenderHint(QPainter::SmoothPixmapTransform); + + QPainter* painter = device_painter; + + // Logical units per mm + qreal units_per_mm = units_per_inch / 25.4; + // Image pixels per mm + qreal pixel_per_mm = options.resolution / 25.4; + // Scaling from pixels to logical units + qreal pixel2units = units_per_inch / options.resolution; + // The current painter's resolution + qreal scale = units_per_mm; + + /* + * Analyse need for page buffer + * + * Painting raster images with opacity is not supported on print devices. + * This can only be solved by merging the images before sending them to + * the printer. For the map itself, this may result in loss of sharpness + * and increase in data volume. + * + * In vector mode, a page buffer (raster image) is used to collect background + * templates and raster foreground templates. After this buffer is sent to + * to the printer, map, grid, and + * non-raster foreground templates are drawn on top of it. + * + * In raster mode, all map features are drawn to in regular order to + * temporary images first. + * + * When the target is an image, use the temporary image to enforce the given + * resolution. + */ + bool use_buffer_for_map = (options.mode == MapPrinterOptions::Raster || target == imageTarget()); + bool use_buffer_for_background = use_buffer_for_map && options.show_templates; + bool use_buffer_for_foreground = use_buffer_for_map && options.show_templates; + if (view && options.show_templates) + { + if (!use_buffer_for_background) + { + for (int i = 0; i < map.getFirstFrontTemplate() && !use_buffer_for_background; ++i) + { + if (map.getTemplate(i)->isRasterGraphics()) + { + auto visibility = view->getTemplateVisibility(map.getTemplate(i)); + use_buffer_for_background = visibility.visible && visibility.opacity < 1.0f; + } + } + } + if (!use_buffer_for_foreground) + { + for (int i = map.getFirstFrontTemplate(); i < map.getNumTemplates() && !use_buffer_for_foreground; ++i) + { + if (map.getTemplate(i)->isRasterGraphics()) + { + auto visibility = view->getTemplateVisibility(map.getTemplate(i)); + use_buffer_for_foreground = visibility.visible && visibility.opacity < 1.0f; + } + } + } + } + + // Prepare buffer if required + bool use_page_buffer = use_buffer_for_map || + use_buffer_for_background || + use_buffer_for_foreground; + QImage scoped_buffer; + if (use_page_buffer && !page_buffer) + { + scale = pixel_per_mm; + int w = qCeil(page_format.paper_dimensions.width() * scale); + int h = qCeil(page_format.paper_dimensions.height() * scale); +#if defined (Q_OS_MAC) + if (device_painter->device()->physicalDpiX() == 0) + { + // Possible Qt bug, since according to QPaintDevice documentation, + // "if the physicalDpiX() doesn't equal the logicalDpiX(), + // the corresponding QPaintEngine must handle the resolution mapping" + // which doesn't seem to happen here. + qreal corr = device_painter->device()->logicalDpiX() / 72.0; + w = qCeil(page_format.paper_dimensions.width() * scale * corr); + h = qCeil(page_format.paper_dimensions.height() * scale * corr); + } +#endif + + scoped_buffer = QImage(w, h, QImage::Format_RGB32); + if (scoped_buffer.isNull()) + { + // Allocation failed + device_painter->restore(); + device_painter->end(); // Signal error + return; + } + + page_buffer = &scoped_buffer; + painter = new QPainter(page_buffer); + painter->setRenderHints(device_painter->renderHints()); + } + + /* + * Prepare the common background + */ + if (use_page_buffer) + { + page_buffer->fill(QColor(Qt::white)); + } + else if (white_background) + { + painter->fillRect(QRect(0, 0, painter->device()->width(), painter->device()->height()), Qt::white); + } + + /* + * One-time setup of transformation and clipping + */ + // Translate for top left page margin + painter->scale(scale, scale); + painter->translate(page_format.page_rect.left(), page_format.page_rect.top()); + + // Convert native map scale to print scale + if (scale_adjustment != 1.0) + { + scale *= scale_adjustment; + painter->scale(scale_adjustment, scale_adjustment); + } + + // Translate and clip for margins and print area + painter->translate(-page_extent.left(), -page_extent.top()); + + QTransform transform = painter->transform(); + + QRectF page_region_used(page_extent.intersected(print_area)); + painter->setClipRect(page_region_used, Qt::ReplaceClip); + + /* + * Draw templates in the background + */ + if (options.show_templates) + { + map.drawTemplates(painter, page_region_used, 0, map.getFirstFrontTemplate() - 1, view, false); + if (vectorModeSelected() && use_buffer_for_foreground) + { + for (int i = map.getFirstFrontTemplate(); i < map.getNumTemplates(); ++i) + { + if (map.getTemplate(i)->isRasterGraphics()) + map.drawTemplates(painter, page_region_used, i, i, view, false); + } + } + } + + if (use_buffer_for_background && !use_buffer_for_map) + { + // Flush the buffer, reset painter + delete painter; + drawBuffer(device_painter, page_buffer, pixel2units); + + painter = device_painter; + painter->setTransform(transform); + painter->setClipRect(page_region_used, Qt::ReplaceClip); + } + + /* + * Draw the map + */ + if (!view || view->effectiveMapVisibility().visible) + { + QImage map_buffer; + QPainter* map_painter = painter; + if (use_buffer_for_map) + { + // Draw map into a temporary buffer first which is printed with the map's opacity later. + // This prevents artifacts with overlapping objects. + if (painter == device_painter) + { + map_buffer = *page_buffer; // Use existing buffer + } + else + { + map_buffer = QImage(page_buffer->size(), QImage::Format_ARGB32_Premultiplied); + } + map_buffer.fill(QColor(Qt::transparent)); + + map_painter = new QPainter(&map_buffer); + map_painter->setRenderHints(painter->renderHints()); + map_painter->setTransform(painter->transform()); + } + + RenderConfig config = { map, page_region_used, scale, RenderConfig::NoOptions, 1.0 }; + + if (rasterModeSelected() && options.simulate_overprinting) + { + map.drawOverprintingSimulation(map_painter, config); + } + else + { + if (vectorModeSelected() && view) + config.opacity = view->effectiveMapVisibility().opacity; + + map.draw(map_painter, config); + } + + if (map_painter != painter) + { + // Flush the buffer + delete map_painter; + map_painter = nullptr; + + // Print buffer with map opacity + painter->save(); + painter->resetTransform(); + if (view) + painter->setOpacity(view->effectiveMapVisibility().opacity); + painter->setRenderHint(QPainter::SmoothPixmapTransform, false); + painter->drawImage(0, 0, map_buffer); + painter->restore(); + } + } + + /* + * Draw the grid + */ + if (options.show_grid) + map.drawGrid(painter, print_area, false); // Maybe replace by page_region_used? + + /* + * Draw the foreground templates + */ + if (options.show_templates) + { + if (vectorModeSelected() && use_buffer_for_foreground) + { + for (int i = map.getFirstFrontTemplate(); i < map.getNumTemplates(); ++i) + { + if (!map.getTemplate(i)->isRasterGraphics()) + map.drawTemplates(painter, page_region_used, i, i, view, false); + } + } + else + { + if (use_buffer_for_foreground && !use_buffer_for_map) + { + page_buffer->fill(QColor(Qt::transparent)); + painter = new QPainter(page_buffer); + painter->setRenderHints(device_painter->renderHints()); + painter->setTransform(transform); + painter->setClipRect(page_region_used, Qt::ReplaceClip); + } + map.drawTemplates(painter, page_region_used, map.getFirstFrontTemplate(), map.getNumTemplates() - 1, view, false); + } + } + + /* + * Cleanup: If a temporary buffer has been used, paint it on the device painter + */ + if (painter != device_painter) + { + delete painter; + painter = nullptr; + device_painter->resetTransform(); + drawBuffer(device_painter, page_buffer, pixel2units); + } + device_painter->restore(); +} + +void MapPrinter::drawSeparationPages(QPrinter* printer, QPainter* device_painter, float dpi, const QRectF& page_extent) const +{ + Q_ASSERT(printer->colorMode() == QPrinter::GrayScale); + + device_painter->save(); + + device_painter->setRenderHint(QPainter::Antialiasing); + + // Translate for top left page margin + qreal scale = dpi / 25.4; // Dots per mm + device_painter->scale(scale, scale); + device_painter->translate(page_format.page_rect.left(), page_format.page_rect.top()); + + // Convert native map scale to print scale + if (scale_adjustment != 1.0) + { + scale *= scale_adjustment; + device_painter->scale(scale_adjustment, scale_adjustment); + } + + // Translate and clip for margins and print area + device_painter->translate(-page_extent.left(), -page_extent.top()); + device_painter->setClipRect(page_extent.intersected(print_area), Qt::ReplaceClip); + + bool need_new_page = false; + for (int i = map.getNumColors() - 1; i >= 0; --i) + { + const MapColor* color = map.getColor(i); + if (color->getSpotColorMethod() == MapColor::SpotColor) + { + if (need_new_page) + { + printer->newPage(); + } + + RenderConfig config = { map, page_extent, scale, RenderConfig::NoOptions, 1.0 }; + map.drawColorSeparation(device_painter, config, color); + need_new_page = true; + } + } + + device_painter->restore(); +} + +bool MapPrinter::printMap(QPrinter* printer) +{ + // Printer settings may have been changed by preview or application. + // We need to use them for printing. + printer->setFullPage(true); + takePrinterSettings(printer); + + QSizeF extent_size = page_format.page_rect.size() / scale_adjustment; + QPainter painter(printer); + + auto resolution = float(options.resolution); + +#if defined(Q_OS_WIN) + // Workaround for Wine + if (printer->resolution() == 0) + { + return false; + } + + if (printer->paintEngine()->type() == QPaintEngine::Windows) + { + /* QWin32PrintEngine will (have to) do rounding when passing coordinates + * to GDI, using the device's reported logical resolution. + * We establish an MM_ISOTROPIC transformation from a higher resolution + * to avoid the loss of precision due to this rounding. + */ + + QWin32PrintEngine* engine = static_cast(printer->printEngine()); + HDC dc = engine->getDC(); + + // The high resolution in units per millimeter + const int hires_ppmm = 1000; + + // The paper dimensions in high resolution units + const int hires_width = qRound(page_format.page_rect.width() * hires_ppmm); + const int hires_height = qRound(page_format.page_rect.height() * hires_ppmm); + + // The physical paper dimensions in device units + const int phys_width = GetDeviceCaps(dc, PHYSICALWIDTH); + const int phys_height = GetDeviceCaps(dc, PHYSICALHEIGHT); + + // The physical printing offset in device units + const int phys_off_x = GetDeviceCaps(dc, PHYSICALOFFSETX); + const int phys_off_y = GetDeviceCaps(dc, PHYSICALOFFSETY); + // (Needed to work around an unexpected offset, maybe related to QTBUG-5363) + + if (phys_width > 0) + { + // Establish the transformation + SetMapMode (dc, MM_ISOTROPIC); + SetWindowExtEx(dc, hires_width, hires_height, nullptr); + SetViewportExtEx(dc, phys_width, phys_height, nullptr); + SetViewportOrgEx(dc, -phys_off_x, -phys_off_y, nullptr); + resolution *= ((double)hires_width / phys_width); + } + } + else if (printer->paintEngine()->type() == QPaintEngine::Picture) + { + // Preview: work around for offset, maybe related to QTBUG-5363 + painter.translate( + -page_format.page_rect.left()*resolution / 25.4, + -page_format.page_rect.top()*resolution / 25.4 ); + } +#endif + + cancel_print_map = false; + int step = 0; + auto num_steps = v_page_pos.size() * h_page_pos.size(); + const QString message_template( (options.mode == MapPrinterOptions::Separations) ? + tr("Processing separations of page %1...") : + tr("Processing page %1...") ); + auto message = message_template.arg(1); + emit printProgress(0, message); + + bool need_new_page = false; + for (auto vpos : v_page_pos) + { + if (!painter.isActive()) + { + break; + } + + for (auto hpos : h_page_pos) + { + if (!painter.isActive()) + { + break; + } + + ++step; + auto progress = qMin(99, qMax(1, int((100 * static_cast(step) - 50) / num_steps))); + emit printProgress(progress, message_template.arg(step)); + + if (cancel_print_map) /* during printProgress handling */ + { + painter.end(); + break; + } + + if (need_new_page) + { + printer->newPage(); + } + + QRectF page_extent = QRectF(QPointF(hpos, vpos), extent_size); + if (separationsModeSelected()) + { + drawSeparationPages(printer, &painter, resolution, page_extent); + } + else + { + drawPage(&painter, resolution, page_extent, false); + } + + need_new_page = true; + } + } + + if (cancel_print_map) + { + emit printProgress(100, tr("Canceled")); + } + else if (!painter.isActive()) + { + emit printProgress(100, tr("Error")); + return false; + } + else + { + emit printProgress(100, tr("Finished")); + } + return true; +} + +void MapPrinter::cancelPrintMap() +{ + cancel_print_map = true; +} + +#endif // QT_PRINTSUPPORT_LIB diff --git a/src/core/map_printer.h b/src/core/map_printer.h new file mode 100644 index 0000000..1d5face --- /dev/null +++ b/src/core/map_printer.h @@ -0,0 +1,543 @@ +/* + * Copyright 2012, 2013 Thomas Schöps + * Copyright 2012-2016 Kai Pastor + * + * This file is part of OpenOrienteering. + * + * OpenOrienteering is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenOrienteering is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenOrienteering. If not, see . + */ + + +#ifndef _OPENORIENTEERING_MAP_PRINTER_H_ +#define _OPENORIENTEERING_MAP_PRINTER_H_ + +#include +#include + +#include +#include +#include +#include + +#ifdef QT_PRINTSUPPORT_LIB +#include +#endif + +QT_BEGIN_NAMESPACE +class QImage; +class QXmlStreamReader; +class QXmlStreamWriter; +QT_END_NAMESPACE + +class Map; +class MapView; + +/** The MapPrinterPageFormat is a complete description of page properties. */ +class MapPrinterPageFormat +{ +public: + /** Copy of QPrinter::Orientation because QPrinter is not available for Android */ + enum Orientation { Portrait, Landscape }; + + /** Constructs a new page format. + * + * The format is initialized as a custom page format with a page rectangle + * of the given size, surrounded by the given margin (in mm). */ + MapPrinterPageFormat(QSizeF page_rect_size = QSizeF(100.0, 100.0), qreal margin = 5.0, qreal overlap = 5.0); + +#ifdef QT_PRINTSUPPORT_LIB + /** Constructs a new page format, initialized from the given printer's settings. */ + MapPrinterPageFormat(const QPrinter& printer, qreal overlap = 5.0); +#endif + + /** Returns a page format initialized from the default printer's settings. + * + * When building without Qt Print Support, returns a default constructed + * page format. */ + static MapPrinterPageFormat fromDefaultPrinter(); + + /** The nominal paper size (of type QPrinter::PaperSize) */ + int paper_size; + + /** The orientation of the paper. */ + Orientation orientation; + + /** The printable page rectangle in mm. */ + QRectF page_rect; + + /** The total dimensions of the page in mm. */ + QSizeF paper_dimensions; + + /** The horizontal overlap in mm of pages when the output covers muliple pages. */ + qreal h_overlap; + + /** The vertival overlap in mm of pages when the output covers muliple pages. */ + qreal v_overlap; +}; + +/** Returns true iff the MapPrinterPageFormat values are equal. */ +bool operator==(const MapPrinterPageFormat& lhs, const MapPrinterPageFormat& rhs); + +/** Returns true iff the MapPrinterPageFormat values are not equal. */ +bool operator!=(const MapPrinterPageFormat& lhs, const MapPrinterPageFormat& rhs); + + + +/** MapPrinterOptions control how the map is rendered. */ +class MapPrinterOptions +{ +public: + /** Basic modes of printing. */ + enum MapPrinterMode + { + Vector, ///< Print in vector graphics mode + Raster, ///< Print in raster graphics mode + Separations ///< Print spot color separations (b/w vector) + }; + + /** Color modes. + * + * At the moment, only PDF supports a different mode than the default. + */ + enum ColorMode + { + DefaultColorMode, ///< Use the target engine's default color mode. + DeviceCmyk ///< Use device-dependent CMYK for vector data. + }; + + /** Constructs new printer options. + * + * The scale, the mode and the resolution are initialized to the given + * values, all boolean properties are initialized to false. + */ + MapPrinterOptions(unsigned int scale, int resolution = 600, MapPrinterMode mode = Vector); + + /** The scale to be used for printing. */ + unsigned int scale; + + /** The nominal resolution to be used. */ + int resolution; + + /** The mode of printing. + * + * Note that other printing options may be available only in particular modes. + */ + MapPrinterMode mode; + + /** The color mode. */ + ColorMode color_mode; + + /** Controls if templates get printed. + * + * Not available in MapPrinterOptions::Separations mode. + */ + bool show_templates; + + /** Controls if the configured grid is printed. + * + * Not available in MapPrinterOptions::Separations mode. + */ + bool show_grid; + + /** Controls if the desktop printing is to simulate spot color printing. + * + * Only available in MapPrinterOptions::Raster mode. + */ + bool simulate_overprinting; +}; + + + +/** MapPrintParameters contains all options that control printing + * and provides methods for saving and loading. */ +class MapPrinterConfig +{ +public: + /** Constructs a default config for the given map. */ + MapPrinterConfig(const Map& map); + + /** Constructs a config and loads the map print parameters from an XML stream. */ + MapPrinterConfig(const Map& map, QXmlStreamReader& xml); + + /** Saves the map print parameters to an XML stream. */ + void save(QXmlStreamWriter& xml, const QLatin1String& element_name) const; + + /** The name of the printer. */ + QString printer_name; + + /** The print area. */ + QRectF print_area; + + /** The page format. */ + MapPrinterPageFormat page_format; + + /** Printing options. */ + MapPrinterOptions options; + + /** A flag which indicates to the UI whether to maintain a centered + * print area when the size of the map or the page changes. */ + bool center_print_area; + + /** A flag which indicates to the UI whether to adjust the print area size + * to the current page size. */ + bool single_page_print_area; + + /** Platform-dependent data. */ + std::shared_ptr native_data; +}; + + + +#ifdef QT_PRINTSUPPORT_LIB + +/** MapPrinter provides an interface to print a map (to a printer or file). + * It may render a page on any QPaintDevice, such as an QImage. */ +class MapPrinter : public QObject, protected MapPrinterConfig +{ +Q_OBJECT +public: + /** Returns a QPrinterInfo pointer which signals printing to a PDF file. */ + static const QPrinterInfo* pdfTarget(); + + /** Returns a QPrinterInfo pointer which signals printing to a raster file. */ + static const QPrinterInfo* imageTarget(); + + /** Returns a reference to a hash which maps paper sizes to names as C strings. + * These strings are not translated. */ + static const QHash< int, const char* >& paperSizeNames(); + + /** Constructs a new MapPrinter for the given map and (optional) view. */ + MapPrinter(Map& map, const MapView* view, QObject* parent = nullptr); + + /** Destructor. */ + virtual ~MapPrinter(); + + /** Returns the configured target printer in terms of QPrinterInfo. */ + const QPrinterInfo* getTarget() const; + + /** Returns true if a real printer is configured. */ + bool isPrinter() const; + + /** Returns the page format specification. */ + const MapPrinterPageFormat& getPageFormat() const; + + /** Returns the map area to be printed. */ + const QRectF& getPrintArea() const; + + /** Returns the rendering options. */ + const MapPrinterOptions& getOptions() const; + + /** Returns true if the current print area and rendering options will + * result in empty pages. (The grid is not considered.) */ + bool isOutputEmpty() const; + + /** Returns the quotient of map scale denominator and print scale denominator. */ + qreal getScaleAdjustment() const; + + /** Returns the paper size which is required by the current print area and scale. */ + QSizeF getPrintAreaPaperSize() const; + + /** Returns the print area size which is possible with the current page rect size. */ + QSizeF getPageRectPrintAreaSize() const; + + /** Returns a list of horizontal page positions on the map. */ + const std::vector< qreal >& horizontalPagePositions() const; + + /** Returns a list of vertical page positions on the map. */ + const std::vector< qreal >& verticalPagePositions() const; + + /** Creates a printer configured according to the current settings. */ + std::unique_ptr makePrinter() const; + + /** Takes the settings from the given printer, + * and generates signals for changing properties. */ + void takePrinterSettings(const QPrinter* printer); + + /** Prints the map to the given printer. + * + * This will first update this object's properties from the printer's properties. + * + * @return true on success, false on error. */ + bool printMap(QPrinter* printer); + + /** Draws a single page to the painter. + * + * In case of an error, the painter will be inactive when returning from + * this function. + * + * When the actual paint device is a QImage, pass it as page_buffer. + * This helps to determine the exact dimensions and to avoid the allocation + * of another buffer. + * Otherwise, drawPage() may allocate a buffer with this map printer's + * resolution and size. Parameter units_per_inch has no influence on this + * buffer but refers to the logical coordinates of device_painter. */ + void drawPage(QPainter* device_painter, float units_per_inch, const QRectF& page_extent, bool white_background, QImage* page_buffer = nullptr) const; + + /** Draws the separations as distinct pages to the printer. */ + void drawSeparationPages(QPrinter* printer, QPainter* device_painter, float dpi, const QRectF& page_extent) const; + + /** Returns the current configuration. */ + const MapPrinterConfig& config() const; + +public slots: + /** Sets the target QPrinterInfo. + * Ownership is not taken over! Target may even be nullptr. */ + void setTarget(const QPrinterInfo* new_target); + + /** Sets the map area which is to be printed. */ + void setPrintArea(const QRectF& area); + + /** Sets the QPrinter::PaperSize to be used. */ + void setPaperSize(const int size); + + /** Sets a custom paper size with the given dimensions. */ + void setCustomPaperSize(const QSizeF dimensions); + + /** Sets the page orientation. */ + void setPageOrientation(const MapPrinterPageFormat::Orientation orientation); + + /** Sets the overlapping of the pages at the margins. */ + void setOverlap(qreal h_overlap, qreal v_overlap); + + /** Sets the desired printing resolution in dpi. + * The actual resolution will be set by the printer. + * + * Does nothing if dpi is 0 or less. + */ + void setResolution(int dpi); + + /** Sets the denominator of the map scale for printing. */ + void setScale(const unsigned int value); + + /** Sets the printing mode. */ + void setMode(const MapPrinterOptions::MapPrinterMode mode); + + /** Controls whether to print templates. + * If a MapView is given when enabling template printing, + * it will determine the visibility of map and templates. */ + void setPrintTemplates(const bool visible); + + /** Controls whether to print the map grid. */ + void setPrintGrid(const bool visible); + + /** Controls whether to print in overprinting simulation mode. */ + void setSimulateOverprinting(bool enabled); + + /** Controls the color mode. */ + void setColorMode(MapPrinterOptions::ColorMode color_mode); + + /** Saves the print parameter (to the map). */ + void saveConfig() const; + + /** Cancels a running printMap(), if possible. + * This can only be used during handlers of the printMapProgress() signal. */ + void cancelPrintMap(); + +signals: + /** Indicates a new target printer. */ + void targetChanged(const QPrinterInfo* target) const; + + /** Indicates a change in the map area. */ + void printAreaChanged(const QRectF& area) const; + + /** Indicates a change in the page format. */ + void pageFormatChanged(const MapPrinterPageFormat& format) const; + + /** Indicates a change in the rendering options. */ + void optionsChanged(const MapPrinterOptions& options) const; + + /** Emitted during printMap() to indicate progress. You can expect this + * signal to be emitted at the start of the print process (value = 1), + * after each page printed, and at the end of the process (value = 100). + * + * @param value Reflects the progress in the range from 1 (just started) + * to 100 (finished). + * @param status A verbal representation of what printMap() is doing. */ + void printProgress(int value, QString status) const; + +protected: + /** Returns true if vector mode is set. */ + bool vectorModeSelected() const; + + /** Returns true if raster mode is set. */ + bool rasterModeSelected() const; + + /** Returns true if separations mode is set. */ + bool separationsModeSelected() const; + + /** Updates the paper dimensions from paper format and orientation. */ + void updatePaperDimensions(); + + /** Updates the page breaks from map area and page format. */ + void updatePageBreaks(); + + /** Updates the scale adjustment and page breaks. */ + void mapScaleChanged(); + + Map& map; + const MapView* view; + const QPrinterInfo* target; + QPrinterInfo target_copy; + qreal scale_adjustment; + std::vector h_page_pos; + std::vector v_page_pos; + bool cancel_print_map; +}; + +#endif + + + +//### MapPrinterPageFormat inline code ### + +inline +bool operator!=(const MapPrinterPageFormat& lhs, const MapPrinterPageFormat& rhs) +{ + return !(lhs == rhs); +} + + + +//### MapPrinterOptions inline code ### + +/** Returns true iff the MapPrinterOptions values are equal. */ +inline +bool operator==(const MapPrinterOptions& lhs, const MapPrinterOptions& rhs) +{ + return lhs.mode == rhs.mode + && lhs.color_mode == rhs.color_mode + && lhs.resolution == rhs.resolution + && lhs.scale == rhs.scale + && lhs.show_templates == rhs.show_templates + && lhs.show_grid == rhs.show_grid + && lhs.simulate_overprinting == rhs.simulate_overprinting; +} + +/** Returns true iff the MapPrinterOptions values are not equal. */ +inline +bool operator!=(const MapPrinterOptions& lhs, const MapPrinterOptions& rhs) +{ + return !(lhs == rhs); +} + + + +// ### MapPrinterConfig ### + +/** Returns true iff the MapPrinterConfig values are equal. */ +inline +bool operator==(const MapPrinterConfig& lhs, const MapPrinterConfig& rhs) +{ + return lhs.printer_name == rhs.printer_name + && lhs.print_area == rhs.print_area + && lhs.page_format == rhs.page_format + && lhs.options == rhs.options + && lhs.center_print_area == rhs.center_print_area + && lhs.single_page_print_area == rhs.single_page_print_area; +} + +/** Returns true iff the MapPrinterConfig values are not equal. */ +inline +bool operator!=(const MapPrinterConfig& lhs, const MapPrinterConfig& rhs) +{ + return !(lhs == rhs); +} + + + +// ### MapPrinter inline code ### + +#ifdef QT_PRINTSUPPORT_LIB + +inline +const MapPrinterConfig& MapPrinter::config() const +{ + return *this; +} + +inline +const QPrinterInfo* MapPrinter::getTarget() const +{ + return target; +} + +inline +const MapPrinterPageFormat& MapPrinter::getPageFormat() const +{ + return page_format; +} + +inline +const QRectF& MapPrinter::getPrintArea() const +{ + return print_area; +} + +inline +const MapPrinterOptions& MapPrinter::getOptions() const +{ + return options; +} + +inline +qreal MapPrinter::getScaleAdjustment() const +{ + return scale_adjustment; +} + +inline +QSizeF MapPrinter::getPrintAreaPaperSize() const +{ + return getPrintArea().size() * scale_adjustment; +} + +inline +QSizeF MapPrinter::getPageRectPrintAreaSize() const +{ + return page_format.page_rect.size() / scale_adjustment; +} + +inline +const std::vector< qreal >& MapPrinter::horizontalPagePositions() const +{ + return h_page_pos; +} + +inline +const std::vector< qreal >& MapPrinter::verticalPagePositions() const +{ + return v_page_pos; +} + +inline +bool MapPrinter::vectorModeSelected() const +{ + return options.mode == MapPrinterOptions::Vector; +} + +inline +bool MapPrinter::rasterModeSelected() const +{ + return options.mode == MapPrinterOptions::Raster; +} + +inline +bool MapPrinter::separationsModeSelected() const +{ + return options.mode == MapPrinterOptions::Separations; +} + +#endif + +#endif diff --git a/src/core/map_view.cpp b/src/core/map_view.cpp new file mode 100644 index 0000000..07a68c4 --- /dev/null +++ b/src/core/map_view.cpp @@ -0,0 +1,508 @@ +/* + * Copyright 2012, 2013 Thomas Schöps + * Copyright 2014-2016 Kai Pastor + * + * This file is part of OpenOrienteering. + * + * OpenOrienteering is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenOrienteering is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenOrienteering. If not, see . + */ + + +#include "map_view.h" + +#include + +#include "../map.h" +#include "../template.h" +#include "../util.h" +#include "../util/xml_stream_util.h" + + +namespace literal +{ + static const QLatin1String zoom("zoom"); + static const QLatin1String rotation("rotation"); + static const QLatin1String position_x("position_x"); + static const QLatin1String position_y("position_y"); + static const QLatin1String grid("grid"); + static const QLatin1String overprinting_simulation_enabled("overprinting_simulation_enabled"); + static const QLatin1String map("map"); + static const QLatin1String opacity("opacity"); + static const QLatin1String visible("visible"); + static const QLatin1String templates("templates"); + static const QLatin1String hidden("hidden"); + static const QLatin1String ref("ref"); + static const QLatin1String template_string("template"); +} + +const double MapView::zoom_in_limit = 512; +const double MapView::zoom_out_limit = 1 / 16.0; + + +MapView::MapView(QObject* parent, Map* map) +: QObject { parent } +, map { map } +, zoom { 1.0 } +, rotation { 0.0 } +, map_visibility{ 1.0f, true } +, all_templates_hidden{ false } +, grid_visible{ false } +, overprinting_simulation_enabled{ false } +{ + Q_ASSERT(map); + updateTransform(); + connect(map, &Map::templateAdded, this, &MapView::onTemplateAdded); + connect(map, &Map::templateDeleted, this, &MapView::onTemplateDeleted, Qt::QueuedConnection); +} + +MapView::MapView(Map* map) +: MapView { map, map } +{ + // nothing else +} + +MapView::~MapView() +{ + // nothing, not inlined +} + +#ifndef NO_NATIVE_FILE_FORMAT + +void MapView::load(QIODevice* file, int version) +{ + qint64 center_x, center_y; + int unused; + file->read((char*)&zoom, sizeof(double)); + file->read((char*)&rotation, sizeof(double)); + file->read((char*)¢er_x, sizeof(qint64)); + file->read((char*)¢er_y, sizeof(qint64)); + file->read((char*)&unused /*view_x*/, sizeof(int)); + file->read((char*)&unused /*view_y*/, sizeof(int)); + file->read((char*)&pan_offset, sizeof(QPoint)); + + try + { + center_pos = MapCoord::fromNative64withOffset(center_x, center_y); + } + catch (std::range_error) + { + // leave center_pos unchanged + } + + updateTransform(); + + if (version >= 26) + { + file->read((char*)&map_visibility.visible, sizeof(bool)); + file->read((char*)&map_visibility.opacity, sizeof(float)); + } + + int num_template_visibilities; + file->read((char*)&num_template_visibilities, sizeof(int)); + + for (int i = 0; i < num_template_visibilities; ++i) + { + int pos; + file->read((char*)&pos, sizeof(int)); + + TemplateVisibility vis; + file->read((char*)&vis.visible, sizeof(bool)); + file->read((char*)&vis.opacity, sizeof(float)); + setTemplateVisibilityHelper(map->getTemplate(pos), vis); + } + + if (version >= 29) + file->read((char*)&all_templates_hidden, sizeof(bool)); + + if (version >= 24) + file->read((char*)&grid_visible, sizeof(bool)); + + emit viewChanged(CenterChange | ZoomChange | RotationChange); + emit visibilityChanged(MultipleFeatures, true); +} + +#endif + +void MapView::save(QXmlStreamWriter& xml, const QLatin1String& element_name, bool template_details) const +{ + XmlElementWriter mapview_element(xml, element_name); + mapview_element.writeAttribute(literal::zoom, zoom); + mapview_element.writeAttribute(literal::rotation, rotation); + mapview_element.writeAttribute(literal::position_x, center_pos.nativeX()); + mapview_element.writeAttribute(literal::position_y, center_pos.nativeY()); + mapview_element.writeAttribute(literal::grid, grid_visible); + mapview_element.writeAttribute(literal::overprinting_simulation_enabled, overprinting_simulation_enabled); + + { + XmlElementWriter map_element(xml, literal::map); + map_element.writeAttribute(literal::opacity, map_visibility.opacity); + map_element.writeAttribute(literal::visible, map_visibility.visible); + } + + { + XmlElementWriter templates_element(xml, literal::templates); + templates_element.writeAttribute(literal::hidden, all_templates_hidden); + if (template_details) + { + templates_element.writeAttribute(XmlStreamLiteral::count, template_visibilities.size()); + for (auto entry : template_visibilities) + { + XmlElementWriter ref_element(xml, literal::ref); + ref_element.writeAttribute(literal::template_string, map->findTemplateIndex(entry.temp)); + ref_element.writeAttribute(literal::visible, entry.visible); + ref_element.writeAttribute(literal::opacity, entry.opacity); + } + } + } +} + +void MapView::load(QXmlStreamReader& xml) +{ + XmlElementReader mapview_element(xml); + zoom = qMin(mapview_element.attribute(literal::zoom), zoom_in_limit); + if (zoom < zoom_out_limit) + zoom = 1.0; + rotation = mapview_element.attribute(literal::rotation); + + auto center_x = mapview_element.attribute(literal::position_x); + auto center_y = mapview_element.attribute(literal::position_y); + try + { + center_pos = MapCoord::fromNative64withOffset(center_x, center_y); + } + catch (std::range_error) + { + // leave center_pos unchanged + } + updateTransform(); + + grid_visible = mapview_element.attribute(literal::grid); + overprinting_simulation_enabled = mapview_element.attribute(literal::overprinting_simulation_enabled); + + while (xml.readNextStartElement()) + { + if (xml.name() == literal::map) + { + XmlElementReader map_element(xml); + map_visibility.opacity = map_element.attribute(literal::opacity); + if (map_element.hasAttribute(literal::visible)) + map_visibility.visible = map_element.attribute(literal::visible); + else + map_visibility.visible = true; + } + else if (xml.name() == literal::templates) + { + XmlElementReader templates_element(xml); + auto num_template_visibilities = templates_element.attribute(XmlStreamLiteral::count); + template_visibilities.reserve(qBound(20u, num_template_visibilities, 1000u)); + all_templates_hidden = templates_element.attribute(literal::hidden); + + while (xml.readNextStartElement()) + { + if (xml.name() == literal::ref) + { + XmlElementReader ref_element(xml); + int pos = ref_element.attribute(literal::template_string); + if (pos >= 0 && pos < map->getNumTemplates()) + { + TemplateVisibility vis { + qBound(0.0f, ref_element.attribute(literal::opacity), 1.0f), + ref_element.attribute(literal::visible) + }; + setTemplateVisibilityHelper(map->getTemplate(pos), vis); + } + } + else + xml.skipCurrentElement(); + } + } + else + xml.skipCurrentElement(); // unsupported + } + + emit viewChanged(CenterChange | ZoomChange | RotationChange); + emit visibilityChanged(MultipleFeatures, true); +} + +void MapView::updateAllMapWidgets() +{ + emit visibilityChanged(MultipleFeatures, true); +} + +MapCoord MapView::viewToMap(double x, double y) const +{ + return MapCoord(view_to_map.m11() * x + view_to_map.m12() * y + view_to_map.m13(), + view_to_map.m21() * x + view_to_map.m22() * y + view_to_map.m23()); +} + +MapCoordF MapView::viewToMapF(double x, double y) const +{ + return MapCoordF(view_to_map.m11() * x + view_to_map.m12() * y + view_to_map.m13(), + view_to_map.m21() * x + view_to_map.m22() * y + view_to_map.m23()); +} + +QPointF MapView::mapToView(MapCoord coords) const +{ + return QPointF(map_to_view.m11() * coords.x() + map_to_view.m12() * coords.y() + map_to_view.m13(), + map_to_view.m21() * coords.x() + map_to_view.m22() * coords.y() + map_to_view.m23()); +} + +QPointF MapView::mapToView(MapCoordF coords) const +{ + return QPointF(map_to_view.m11() * coords.x() + map_to_view.m12() * coords.y() + map_to_view.m13(), + map_to_view.m21() * coords.x() + map_to_view.m22() * coords.y() + map_to_view.m23()); +} + +qreal MapView::lengthToPixel(qreal length) const +{ + return Util::mmToPixelPhysical(zoom * length / 1000.0); +} + +qreal MapView::pixelToLength(qreal pixel) const +{ + return Util::pixelToMMPhysical(pixel / zoom) * 1000.0; +} + +QRectF MapView::calculateViewedRect(QRectF rect) const +{ + auto top_left = viewToMapF(rect.topLeft()); + auto top_right = viewToMapF(rect.topRight()); + auto bottom_right = viewToMapF(rect.bottomRight()); + auto bottom_left = viewToMapF(rect.bottomLeft()); + + rect = QRectF{ top_left, bottom_right }.normalized(); + rectInclude(rect, top_right); + rectInclude(rect, bottom_left); + rect.adjust(-0.001, -0.001, +0.001, +0.001); + return rect; +} + +QRectF MapView::calculateViewBoundingBox(QRectF rect) const +{ + auto top_left = mapToView(static_cast(rect.topLeft())); + auto top_right = mapToView(static_cast(rect.topRight())); + auto bottom_right = mapToView(static_cast(rect.bottomRight())); + auto bottom_left = mapToView(static_cast(rect.bottomLeft())); + + rect = QRectF{ top_left, bottom_right }.normalized(); + rectInclude(rect, top_right); + rectInclude(rect, bottom_left); + rect.adjust(-1.0, -1.0, +1.0, +1.0); + return rect; +} + +void MapView::setPanOffset(QPoint offset) +{ + if (offset != pan_offset) + { + pan_offset = offset; + emit panOffsetChanged(offset); + } +} + +void MapView::finishPanning(QPoint offset) +{ + setPanOffset({0,0}); + try + { + auto rotated_offset = MapCoord::fromNative64(qRound64(-pixelToLength(offset.x())), + qRound64(-pixelToLength(offset.y())) ); + auto rotated_offset_f = MapCoordF{ rotated_offset }; + rotated_offset_f.rotate(-rotation); + auto move = MapCoord{ rotated_offset_f }; + setCenter(center() + move); + } + catch (std::range_error) + { + // Do nothing + } +} + +void MapView::zoomSteps(double num_steps, QPointF cursor_pos_view) +{ + auto zoom_to = getZoom() * pow(sqrt(2.0), num_steps); + setZoom(zoom_to, cursor_pos_view); +} + +void MapView::zoomSteps(double num_steps) +{ + auto zoom_to = getZoom() * pow(sqrt(2.0), num_steps); + setZoom(zoom_to); +} + +void MapView::setZoom(double value, QPointF center) +{ + auto pos = this->center(); + auto zoom_pos = viewToMap(center); + auto old_zoom = getZoom(); + + setZoom(value); + + if (!qFuzzyCompare(old_zoom, getZoom())) + { + auto zoom_factor = getZoom() / old_zoom ; + setCenter(zoom_pos + (pos - zoom_pos) / zoom_factor); + } +} + +void MapView::setZoom(double value) +{ + zoom = qBound(zoom_out_limit, value, zoom_in_limit); + updateTransform(); + emit viewChanged(ZoomChange); +} + +void MapView::setRotation(double value) +{ + rotation = value; + updateTransform(); + emit viewChanged(RotationChange); +} + +void MapView::setCenter(MapCoord pos) +{ + center_pos = pos; + updateTransform(); + emit viewChanged(CenterChange); +} + +void MapView::updateTransform() +{ + double final_zoom = calculateFinalZoomFactor(); + double final_zoom_cosr = final_zoom * cos(rotation); + double final_zoom_sinr = final_zoom * sin(rotation); + auto center_x = center_pos.x(); + auto center_y = center_pos.y(); + + // Create map_to_view + map_to_view.setMatrix(final_zoom_cosr, -final_zoom_sinr, -final_zoom_cosr * center_x + final_zoom_sinr * center_y, + final_zoom_sinr, final_zoom_cosr, -final_zoom_sinr * center_x - final_zoom_cosr * center_y, + 0, 0, 1); + view_to_map = map_to_view.inverted(); + world_transform = map_to_view.transposed(); +} + + +TemplateVisibility MapView::effectiveMapVisibility() const +{ + if (all_templates_hidden) + return { 1.0f, true }; + else if (map_visibility.opacity < 0.005f) + return { 0.0f, false }; + else + return map_visibility; +} + +void MapView::setMapVisibility(TemplateVisibility vis) +{ + if (map_visibility != vis) + { + map_visibility = vis; + emit visibilityChanged(VisibilityFeature::MapVisible, vis.visible && vis.opacity > 0, nullptr); + } +} + +MapView::TemplateVisibilityVector::const_iterator MapView::findVisibility(const Template* temp) const +{ + return std::find_if(begin(template_visibilities), end(template_visibilities), [temp](const TemplateVisibilityEntry& entry) + { + return entry.temp == temp; + } ); +} + +MapView::TemplateVisibilityVector::iterator MapView::findVisibility(const Template* temp) +{ + return std::find_if(begin(template_visibilities), end(template_visibilities), [temp](const TemplateVisibilityEntry& entry) + { + return entry.temp == temp; + } ); +} + +bool MapView::isTemplateVisible(const Template* temp) const +{ + auto entry = findVisibility(temp); + return entry != end(template_visibilities) + && entry->visible + && entry->opacity > 0; +} + +TemplateVisibility MapView::getTemplateVisibility(const Template* temp) const +{ + auto entry = findVisibility(temp); + if (entry != end(template_visibilities)) + return *entry; + else + return { 1.0f, false }; +} + +void MapView::setTemplateVisibility(const Template* temp, TemplateVisibility vis) +{ + if (setTemplateVisibilityHelper(temp, vis)) + emit visibilityChanged(VisibilityFeature::TemplateVisible, vis.visible && vis.opacity > 0, temp); +} + +bool MapView::setTemplateVisibilityHelper(const Template *temp, TemplateVisibility vis) +{ + auto stored = findVisibility(temp); + if (stored == end(template_visibilities)) + { + template_visibilities.emplace_back(temp, vis); + return true; + } + if (*stored != vis) + { + stored->opacity = vis.opacity; + stored->visible = vis.visible; + return true; + } + return false; +} + +void MapView::onTemplateAdded(int, const Template* temp) +{ + setTemplateVisibility(temp, { 1.0f, true }); +} + +void MapView::onTemplateDeleted(int, const Template* temp) +{ + template_visibilities.erase(findVisibility(temp)); +} + + +void MapView::setAllTemplatesHidden(bool value) +{ + if (all_templates_hidden != value) + { + all_templates_hidden = value; + emit visibilityChanged(VisibilityFeature::AllTemplatesHidden, value); + } +} + +void MapView::setGridVisible(bool visible) +{ + if (grid_visible != visible) + { + grid_visible = visible; + emit visibilityChanged(VisibilityFeature::GridVisible, visible); + } +} + +void MapView::setOverprintingSimulationEnabled(bool enabled) +{ + if (overprinting_simulation_enabled != enabled) + { + overprinting_simulation_enabled = enabled; + emit visibilityChanged(VisibilityFeature::OverprintingEnabled, enabled); + } +} diff --git a/src/core/map_view.h b/src/core/map_view.h new file mode 100644 index 0000000..b2a3cd0 --- /dev/null +++ b/src/core/map_view.h @@ -0,0 +1,519 @@ +/* + * Copyright 2012, 2013 Thomas Schöps + * Copyright 2014-2016 Kai Pastor + * + * This file is part of OpenOrienteering. + * + * OpenOrienteering is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenOrienteering is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenOrienteering. If not, see . + */ + + +#ifndef OPENORIENTEERING_MAP_VIEW_H +#define OPENORIENTEERING_MAP_VIEW_H + +#include + +#include +#include +#include + +#include "../core/map_coord.h" + +class Map; +class Template; +class TemplateVisibility; + +class QXmlStreamReader; +class QXmlStreamWriter; + + +/** + * Contains the visibility information for a template (or the map). + */ +class TemplateVisibility +{ +public: + /** Opacity from 0.0f (invisible) to 1.0f (opaque) */ + float opacity; + + /** Visibility flag */ + bool visible; +}; + +bool operator==(TemplateVisibility lhs, TemplateVisibility rhs); + +bool operator!=(TemplateVisibility lhs, TemplateVisibility rhs); + + +/** + * Stores view position, zoom, rotation and grid / template visibilities + * to define a view onto a map. + * + * These parameters define the view coordinates with origin at the view's center, + * measured in pixels. The class provides methods to convert between view + * coordinates and map coordinates (defined as millimeter on map paper). + */ +class MapView : public QObject +{ + Q_OBJECT + Q_FLAGS(ChangeFlags VisibilityFeature) + +public: + enum ChangeFlag + { + NoChange = 0, + CenterChange = 1, + ZoomChange = 2, + RotationChange = 4, + }; + + Q_DECLARE_FLAGS(ChangeFlags, ChangeFlag) + + enum VisibilityFeature + { + MultipleFeatures = 0, + GridVisible = 1, + OverprintingEnabled = 2, + AllTemplatesHidden = 4, + TemplateVisible = 8, + MapVisible = 16, + }; + + + /** + * Creates a default view looking at the origin. + * + * The parameter map must not be null. + */ + MapView(QObject* parent, Map* map); + + /** Creates a default view looking at the origin. + * + * The map takes ownership of the map view. It must not be null. + */ + MapView(Map* map); + + /** Destroys the map view. */ + ~MapView() override; + + /** Loads the map view in the old "native" format from the file. */ + void load(QIODevice* file, int version); + + /** + * Saves the map view state to an XML stream. + * @param xml The XML output stream. + * @param element_name The name of the element which will be written. + * @param template_details Save template visibilities (default: true) + */ + void save(QXmlStreamWriter& xml, const QLatin1String& element_name, bool template_details = true) const; + + /** Loads the map view state from the current element of an xml stream. */ + void load(QXmlStreamReader& xml); + + /** + * Redraws all map widgets completely. + * + * Note that this calls QWidget::update() which does not cause an immediate + * repaint; instead it schedules a paint event. + * + * Completely repainting widgets can be slow. + * Try to do partial updates instead, if possible. + */ + void updateAllMapWidgets(); + + + /** Converts x, y (with origin at the center of the view) to map coordinates */ + MapCoord viewToMap(double x, double y) const; + + /** Converts the point (with origin at the center of the view) to map coordinates */ + MapCoord viewToMap(QPointF point) const; + + /** Converts x, y (with origin at the center of the view) to map coordinates */ + MapCoordF viewToMapF(double x, double y) const; + + /** Converts the point (with origin at the center of the view) to map coordinates */ + MapCoordF viewToMapF(QPointF point) const; + + + /// Converts map coordinates to view coordinates (with origin at the center of the view) + QPointF mapToView(MapCoord coords) const; + + /// Converts map coordinates to view coordinates (with origin at the center of the view) + QPointF mapToView(MapCoordF coords) const; + + + /** + * Converts a length from native map coordinates to the current length in view pixels. + */ + qreal lengthToPixel(qreal length) const; + + /** + * Converts a length from current view pixels to native map coordinates. + */ + qreal pixelToLength(qreal pixel) const; + + + /** + * Calculates the bounding box of the map coordinates which can be viewed + * using the given view coordinates rect + */ + QRectF calculateViewedRect(QRectF view_rect) const; + + /** + * Calculates the bounding box in view coordinates + * of the given map coordinates rect + */ + QRectF calculateViewBoundingBox(QRectF map_rect) const; + + /** + * Returns a QTransform suitable for QPainter, so objects defined in + * map coordinates will be drawn at their view coordinates. Append a + * viewport transformation to this to get a complete map-to-viewport transformation + * which makes the view center appear at the viewport center. + * + * Note: The transform is to be combined with the painter's existing transform. + */ + const QTransform& worldTransform() const; + + + // Panning + + /** Returns the current pan offset (when dragging the map). */ + QPoint panOffset() const; + + /** Sets the current pan offset while the map is being dragged. */ + void setPanOffset(QPoint offset); + + /** + * Finishes panning the map. + * + * @param offset The final offset, relative to the start of the operation. + */ + void finishPanning(QPoint offset); + + + /** Returns the map this view is defined on. */ + const Map* getMap() const; + + /** Returns the map this view is defined on. */ + Map* getMap(); + + + /** + * Zooms the maps (in steps), preserving the given cursor position. + * + * @param num_steps Number of zoom steps to zoom in. Negative numbers zoom out. + * @param cursor_pos_view The cursor position in view coordinates, must be + * set if preserve_cursor_pos is used. + */ + void zoomSteps(double num_steps, QPointF cursor_pos_view); + + /** + * Zooms the maps (in steps), preserving the center of the view. + * + * @param num_steps Number of zoom steps to zoom in. Negative numbers zoom out. + */ + void zoomSteps(double num_steps); + + /** + * Returns the final zoom factor for use in transformations. + * Depends on the pixel per millimeter of the display. + */ + double calculateFinalZoomFactor() const; + + /** Returns the raw zoom facor, see also calculateFinalZoomFactor(). */ + double getZoom() const; + + /** Sets the zoom factor relative to the given point.*/ + void setZoom(double value, QPointF center); + + /** Sets the zoom factor. */ + void setZoom(double value); + + + /** Returns the view rotation (in radians). */ + double getRotation() const; + + /** Sets the view roation (in radians). */ + void setRotation(double value); + + + /** Returns the position of the view center. */ + MapCoord center() const; + + /** Sets the position of the view center. */ + void setCenter(MapCoord pos); + + + // Map and template visibilities + + /** Returns the effectiv visibility settings of the map drawing. + * + * Other than getMapVisibility, this will always return an (100 %) opaque, + * visible configuration when areAllTemplatesHidden() is true, + * and it return an invisible configuration when the map's opacity is + * below 0.005. + */ + TemplateVisibility effectiveMapVisibility() const; + + /** Returns the visibility settings of the map drawing. */ + TemplateVisibility getMapVisibility() const; + + void setMapVisibility(TemplateVisibility vis); + + /** + * Checks if the template is visible without creating + * a template visibility object if none exists + */ + bool isTemplateVisible(const Template* temp) const; + + /** + * Returns the template visibility. + * + * If the template is unknown, returns default settings. + */ + TemplateVisibility getTemplateVisibility(const Template* temp) const; + + /** + * Sets the template visibility, and emits a change signal. + */ + void setTemplateVisibility(const Template* temp, TemplateVisibility vis); + + + /** Enables or disables hiding all templates in this view */ + void setAllTemplatesHidden(bool value); + + /** + * Returns if the "hide all templates" toggle is active. + * See also setHideAllTemplates(). + */ + bool areAllTemplatesHidden() const; + + + /** Returns if the map grid is visible. */ + bool isGridVisible() const; + + /** Sets the map grid visibility. */ + void setGridVisible(bool visible); + + + /** Returns if overprinting simulation is enabled. */ + bool isOverprintingSimulationEnabled() const; + + /** Enables or disables overprinting simulation. */ + void setOverprintingSimulationEnabled(bool enabled); + + +signals: + /** + * Indicates a change of the viewed area of the map. + * + * @param change The aspects that have chaneged. + */ + void viewChanged(ChangeFlags change); + + /** + * Indicates a change of the pan offset. + */ + void panOffsetChanged(QPoint offset); + + /** + * Indicates a particular change of visibility. + * + * @param feature The map view feature that has changed. + * @param active The features current state of activation. + * @param temp If a the feature is a template, a pointer to this template. + */ + void visibilityChanged(VisibilityFeature feature, bool active, const Template* temp = nullptr); + + +public: + // Static + + /** The global zoom in limit for the zoom factor. */ + static const double zoom_in_limit; + /** The global zoom out limit for the zoom factor. */ + static const double zoom_out_limit; + +protected: + /** + * Sets the template visibility without emitting signals. + */ + bool setTemplateVisibilityHelper(const Template *temp, TemplateVisibility vis); + + /** + * Creates the visibility data when a template is added to the map. + */ + void onTemplateAdded(int pos, const Template* temp); + + /** + * Removes the visibility data when a template is deleted. + */ + void onTemplateDeleted(int pos, const Template* temp); + +private: + Q_DISABLE_COPY(MapView) + + struct TemplateVisibilityEntry : public TemplateVisibility + { + const Template* temp; + TemplateVisibilityEntry() = default; + TemplateVisibilityEntry(const TemplateVisibilityEntry&) = default; + TemplateVisibilityEntry(TemplateVisibilityEntry&&) = default; + TemplateVisibilityEntry& operator=(const TemplateVisibilityEntry&) = default; + TemplateVisibilityEntry& operator=(TemplateVisibilityEntry&&) = default; + TemplateVisibilityEntry(const Template* temp, TemplateVisibility vis) + : TemplateVisibility(vis) + , temp(temp) + {} + }; + typedef std::vector TemplateVisibilityVector; + + + void updateTransform(); // recalculates the x_to_y matrices + + TemplateVisibilityVector::const_iterator findVisibility(const Template* temp) const; + + TemplateVisibilityVector::iterator findVisibility(const Template* temp); + + + Map* map; + + double zoom; // factor + double rotation; // counterclockwise 0 to 2*PI. This is the viewer rotation, so the map is rotated clockwise + MapCoord center_pos;// position of the viewer, positive values move the map to the left; the position is in 1/1000 mm + QPoint pan_offset; // the distance the content of the view was dragged with the mouse, in pixels + + QTransform view_to_map; + QTransform map_to_view; + QTransform world_transform; + + TemplateVisibility map_visibility; + TemplateVisibilityVector template_visibilities; + + bool all_templates_hidden; + bool grid_visible; + bool overprinting_simulation_enabled; +}; + + + +// ### TemplateVisibility inline code ### + +inline +bool operator==(TemplateVisibility lhs, TemplateVisibility rhs) +{ + return lhs.visible == rhs.visible + && qFuzzyCompare(1.0f+rhs.opacity, 1.0f+lhs.opacity); +} + +inline +bool operator!=(TemplateVisibility lhs, TemplateVisibility rhs) +{ + return !(lhs == rhs); +} + + + +// ### MapView inline code ### + +Q_DECLARE_OPERATORS_FOR_FLAGS(MapView::ChangeFlags) + +inline +MapCoord MapView::viewToMap(QPointF point) const +{ + return viewToMap(point.x(), point.y()); +} + +inline +MapCoordF MapView::viewToMapF(QPointF point) const +{ + return viewToMapF(point.x(), point.y()); +} + +inline +const QTransform& MapView::worldTransform() const +{ + return world_transform; +} + +inline +Map* MapView::getMap() +{ + return map; +} + +inline +const Map* MapView::getMap() const +{ + return map; +} + +inline +double MapView::calculateFinalZoomFactor() const +{ + return lengthToPixel(1000.0); +} + +inline +double MapView::getZoom() const +{ + return zoom; +} + +inline +double MapView::getRotation() const +{ + return rotation; +} + +inline +MapCoord MapView::center() const +{ + return center_pos; +} + +inline +QPoint MapView::panOffset() const +{ + return pan_offset; +} + +inline +TemplateVisibility MapView::getMapVisibility() const +{ + return map_visibility; +} + +inline +bool MapView::areAllTemplatesHidden() const +{ + return all_templates_hidden; +} + +inline +bool MapView::isGridVisible() const +{ + return grid_visible; +} + +inline +bool MapView::isOverprintingSimulationEnabled() const +{ + return overprinting_simulation_enabled; +} + + + +#endif diff --git a/src/core/path_coord.cpp b/src/core/path_coord.cpp new file mode 100644 index 0000000..5fe1a81 --- /dev/null +++ b/src/core/path_coord.cpp @@ -0,0 +1,503 @@ +/* + * Copyright 2012, 2013 Thomas Schöps + * Copyright 2012-2016 Kai Pastor + * + * This file is part of OpenOrienteering. + * + * OpenOrienteering is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenOrienteering is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenOrienteering. If not, see . + */ + + +#include "path_coord.h" + +#include "../symbol_line.h" +#include "../util.h" + + + +// ### PathCoord ### + +void PathCoord::splitBezierCurve(MapCoordF c0, MapCoordF c1, MapCoordF c2, MapCoordF c3, float p, MapCoordF& o0, MapCoordF& o1, MapCoordF& o2, MapCoordF& o3, MapCoordF& o4) +{ + if (p >= 1.0) + { + o0 = c1; + o1 = c2; + o2 = c3; + o3 = c3; + o4 = c3; + } + else if (p <= 0.0) + { + o0 = c0; + o1 = c0; + o2 = c0; + o3 = c1; + o4 = c2; + } + else + { + // The output variables may point to the same storage (if unused), so we + // must not access any output identifier after another one was assigned to. + auto c12 = c1 + (c2 - c1) * p; + o0 = c0 + (c1 - c0) * p; + auto tmp_o1 = o0 + (c12 - o0) * p; + o4 = c2 + (c3 - c2) * p; + o3 = c12 + (o4 - c12) * p; + o2 = tmp_o1 + (o3 - tmp_o1) * p; + o1 = tmp_o1; + } +} + + + +// ### SplitPathCoord ### + +MapCoordF SplitPathCoord::tangentVector() const +{ + auto& path_coords = *this->path_coords; + auto& flags = path_coords.flags(); + auto& coords = path_coords.coords(); + auto path_closed = path_coords.isClosed(); + + std::size_t index = path_coord_index; + auto last_index = path_coords.size() - 1; + + /// Check distances, advance to a significant length, handle closed paths. + MapCoordF next = curve_start[0]; + if (pos.distanceSquaredTo(next) >= PathCoord::tangentEpsilonSquared()) + goto next_found; + + if (is_curve_start) + { + next = curve_start[1]; + if (pos.distanceSquaredTo(next) >= PathCoord::tangentEpsilonSquared()) + goto next_found; + } + + // Search along current edge + if (index < last_index && param != 0.0) + { + do + { + ++index; + next = path_coords[index].pos; + if (pos.distanceSquaredTo(next) >= PathCoord::tangentEpsilonSquared()) + goto next_found; + } + while (path_coords[index].param != 0.0); + } + + // Attention, switching from PathCoordVector index to MapCoordVectorF index. + index = path_coords[index].index; + last_index = coords.size() - 1; + + // Search along control points + while (index < last_index) + { + ++index; + next = coords[index]; + if (pos.distanceSquaredTo(next) >= PathCoord::tangentEpsilonSquared()) + goto next_found; + } + + if (path_closed && path_coord_index > 0) + { + index = 0; + last_index = path_coords[path_coord_index].index; + while (index < last_index) + { + ++index; + next = coords[index]; + if (pos.distanceSquaredTo(next) >= PathCoord::tangentEpsilonSquared()) + goto next_found; + } + + if (flags[index].isCurveStart()) + { + next = coords[index+1]; + if (pos.distanceSquaredTo(next) >= PathCoord::tangentEpsilonSquared()) + goto next_found; + } + + // Search along curve + Q_ASSERT(index == path_coords[path_coord_index].index); + + // Attention, switching from MapCoordVectorF index to PathCoordVector index. + auto pc = std::lower_bound(std::begin(path_coords), std::begin(path_coords)+path_coord_index, index, PathCoord::indexLessThanValue); + index = std::distance(std::begin(path_coords), pc); + last_index = path_coord_index; + while (index < last_index) + { + if (pos.distanceSquaredTo(next) >= PathCoord::tangentEpsilonSquared()) + goto next_found; + + ++index; + next = path_coords[index].pos; + } + } + + // No coordinate is distant enough, so reset next. + next = pos; + +next_found: + next -= pos; + next.normalize(); + + + MapCoordF prev = curve_end[1]; + if (pos.distanceSquaredTo(prev) >= PathCoord::tangentEpsilonSquared()) + goto prev_found; + + if (is_curve_end) + { + prev = curve_end[0]; + if (pos.distanceSquaredTo(prev) >= PathCoord::tangentEpsilonSquared()) + goto prev_found; + } + + index = path_coord_index; + + // Search along curve + if (param != 0.0) + { + while (path_coords[index].param != 0.0) + { + --index; + prev = path_coords[index].pos; + if (pos.distanceSquaredTo(prev) >= PathCoord::tangentEpsilonSquared()) + goto prev_found; + } + } + + // Attention, switching from PathCoordVector index to MapCoordVectorF index. + index = path_coords[index].index; + + // Search along control points + while (index > 0) + { + --index; + prev = coords[index]; + if (pos.distanceSquaredTo(prev) >= PathCoord::tangentEpsilonSquared()) + goto prev_found; + } + + last_index = path_coords.size() - 1; + if (path_closed && path_coord_index != last_index) + { + index = path_coords[last_index].index; + last_index = path_coords[path_coord_index].index + (flags[path_coord_index].isCurveStart() ? 3 : 1); + while (index > last_index) + { + --index; + prev = coords[index]; + if (pos.distanceSquaredTo(prev) >= PathCoord::tangentEpsilonSquared()) + goto prev_found; + } + + // Search along curve + Q_ASSERT(index > path_coords[path_coord_index].index); + // Attention, switching from MapCoordVectorF index to PathCoordVector index. + index = std::upper_bound(std::begin(path_coords)+path_coord_index, std::end(path_coords)-1, index, PathCoord::valueLessThanIndex)->index; + last_index = path_coord_index + 1; + while (index > path_coord_index) + { + --index; + prev = path_coords[index].pos; + if (pos.distanceSquaredTo(prev) >= PathCoord::tangentEpsilonSquared()) + goto prev_found; + } + } + prev = pos; + +prev_found: + prev -= pos; + prev.normalize(); + + next -= prev; + return next; +} + +// static +SplitPathCoord SplitPathCoord::begin(const PathCoordVector& path_coords) +{ + Q_ASSERT(!path_coords.empty()); + + auto& flags = path_coords.flags(); + auto& coords = path_coords.coords(); + Q_ASSERT(coords.size() == flags.size()); + + auto first_index = path_coords.front().index; + auto last_index = path_coords.back().index; + Q_ASSERT(last_index > first_index); + + SplitPathCoord split = { coords[first_index], first_index, 0.0f, path_coords.front().clen, &path_coords, 0, false, flags[first_index].isCurveStart(), {}, {} }; + if (flags[last_index].isClosePoint()) + { + split.curve_end[1] = coords[last_index-1]; + if (last_index - first_index > 2 && flags[last_index - 3].isCurveStart()) + { + split.is_curve_end = true; + split.curve_end[0] = coords[last_index-2]; + } + } + else + { + split.curve_end[1] = split.pos; + } + + split.curve_start[0] = coords[first_index+1]; + if (split.is_curve_start) + { + Q_ASSERT(first_index+2 <= last_index); + split.curve_start[1] = coords[first_index+2]; + } + + return split; +} + +// static +SplitPathCoord SplitPathCoord::end(const PathCoordVector& path_coords) +{ + Q_ASSERT(!path_coords.empty()); + + auto& flags = path_coords.flags(); + auto& coords = path_coords.coords(); + Q_ASSERT(coords.size() == flags.size()); + + auto first_index = path_coords.front().index; + auto last_index = path_coords.back().index; + Q_ASSERT(last_index > first_index); + + SplitPathCoord split = { coords[last_index], last_index, 0.0f, path_coords.back().clen, &path_coords, path_coords.size() - 1, false, false, {}, {} }; + if (flags[last_index].isClosePoint()) + { + split.curve_start[0] = coords[first_index+1]; + if (flags[first_index].isCurveStart()) + { + split.is_curve_start = true; + split.curve_start[1] = coords[first_index+2]; + } + } + else + { + split.curve_start[0] = split.pos; + } + + split.curve_end[1] = coords[last_index-1]; + if (last_index - first_index > 2 && flags[last_index-3].isCurveStart()) + { + split.is_curve_end = true; + split.curve_end[0] = coords[last_index-2]; + } + + return split; +} + +// static +SplitPathCoord SplitPathCoord::at( + const PathCoordVector& path_coords, + std::vector::size_type path_coord_index ) +{ + Q_ASSERT(path_coord_index < path_coords.size()); + + auto& flags = path_coords.flags(); + auto& coords = path_coords.coords(); + Q_ASSERT(coords.size() > 1); + Q_ASSERT(coords.size() == flags.size()); + + auto index = path_coords[path_coord_index].index; + SplitPathCoord split = { coords[index], index, path_coords[path_coord_index].param, path_coords[path_coord_index].clen, &path_coords, path_coord_index, false, flags[index].isCurveStart(), {}, {} }; + + if (index+1 < coords.size()) + { + split.curve_start[0] = coords[index+1]; + if (split.is_curve_start && index+2 < coords.size()) + { + split.curve_start[1] = coords[index+2]; + } + else + { + Q_ASSERT(!split.is_curve_start); + } + } + else + { + Q_ASSERT(!split.is_curve_start); + split.curve_start[0] = split.pos; + } + + if (index >= 1) + { + split.curve_end[1] = coords[index-1]; + if (index >= 3 && flags[index-3].isCurveStart()) + { + split.curve_end[0] = coords[index-2]; + split.is_curve_end = true; + } + } + else + { + split.curve_end[1] = split.pos; + } + + return split; +} + +// static +SplitPathCoord SplitPathCoord::at( + length_type length, + const SplitPathCoord& first ) +{ + auto& path_coords = *first.path_coords; + auto& coords = path_coords.coords(); + auto& flags = path_coords.flags(); + + SplitPathCoord split = first; + split.path_coord_index = path_coords.upperBound(length, first.path_coord_index, first.path_coords->size()-1); + if (split.path_coord_index > first.path_coord_index) + { + // New path coordinate, really + split.clen = length; + + const auto& current_coord = path_coords[split.path_coord_index]; + const auto& prev_coord = path_coords[split.path_coord_index-1]; + const auto curve_length = current_coord.clen - prev_coord.clen; + + split.is_curve_end = flags[prev_coord.index].isCurveStart(); + split.is_curve_start = split.is_curve_end; + + auto factor = 1.0f; + if (qFuzzyCompare(1.0f + length, 1.0f + current_coord.clen) || + qFuzzyCompare(1.0f + curve_length, 1.0f)) + { + // Close match at current path coordinate, + // or near-zero curve length. + split.pos = current_coord.pos; + split.clen = current_coord.clen; + split.param = current_coord.param; + } + else + { + // Split between path coordinates. + factor = qBound(0.0f, (length - prev_coord.clen) / curve_length, 1.0f); + auto prev_param = prev_coord.param; + auto current_param = current_coord.param; + if (current_param == 0.0) + current_param = 1.0; + split.param = prev_param + (current_param - prev_param) * factor; + Q_ASSERT(split.param >= 0.0 && split.param <= 1.0); + if (split.param == 1.0) + split.param = 0.0; + } + + if (!split.is_curve_end) + { + // Straight + split.pos = prev_coord.pos + factor * (current_coord.pos - prev_coord.pos); + + if (current_coord.index > path_coords.front().index) + split.curve_end[1] = coords[current_coord.index-1]; + // else + // leave split.curve_end[1] as copied from first. + + split.curve_start[0] = current_coord.pos; + } + else if (split.param == 0.0) + { + // At a node, after a curve + split.pos = current_coord.pos; + + if (prev_coord.index == first.index) + { + // Split in same curve as first + split.curve_end[0] = first.curve_start[0]; + split.curve_end[1] = first.curve_start[1]; + } + else + { + split.curve_end[0] = coords[prev_coord.index+1]; + split.curve_end[1] = coords[prev_coord.index+2]; + } + + // curve_start: handled later + } + else + { + // In curve + Q_ASSERT(split.is_curve_start); + Q_ASSERT(split.is_curve_end); + + auto edge_start = prev_coord.index; + Q_ASSERT(edge_start+3 <= path_coords.back().index); + + if (prev_coord.index == first.index) + { + auto p = (split.param - first.param) / (1.0f - first.param); + Q_ASSERT(p >= 0.0f); + Q_ASSERT(p <= 1.0f); + + PathCoord::splitBezierCurve(first.pos, first.curve_start[0], first.curve_start[1], coords[edge_start+3], + p, + split.curve_end[0], split.curve_end[1], split.pos, split.curve_start[0], split.curve_start[1]); + } + else + { + PathCoord::splitBezierCurve(coords[edge_start], coords[edge_start+1], coords[edge_start+2], coords[edge_start+3], + split.param, + split.curve_end[0], split.curve_end[1], split.pos, split.curve_start[0], split.curve_start[1]); + } + } + + if (split.param == 0.0) + { + // Handle curve_start for non-in-bezier splits. + split.is_curve_start = flags[current_coord.index].isCurveStart(); + if (split.is_curve_start) + { + split.curve_start[0] = coords[current_coord.index+1]; + split.curve_start[1] = coords[current_coord.index+2]; + } + else if (current_coord.index < path_coords.back().index) + { + split.curve_start[0] = coords[current_coord.index+1]; + } + else + { + /// \todo Handle closed paths. + split.curve_start[0] = current_coord.pos; + } + } + else + { + --split.path_coord_index; + } + } + + split.index = path_coords[split.path_coord_index].index; + return split; +} + + +// Not inline or constexpr, because it is meant to be used by function pointer. +bool PathCoord::indexLessThanValue(const PathCoord& coord, size_type value) +{ + return coord.index < value; +} + +// Not inline or constexpr, because it is meant to be used by function pointer. +bool PathCoord::valueLessThanIndex(size_type value, const PathCoord& coord) +{ + return value < coord.index; +} diff --git a/src/core/path_coord.h b/src/core/path_coord.h new file mode 100644 index 0000000..fbbf575 --- /dev/null +++ b/src/core/path_coord.h @@ -0,0 +1,289 @@ +/* + * Copyright 2012, 2013 Thomas Schöps + * Copyright 2012-2015 Kai Pastor + * + * This file is part of OpenOrienteering. + * + * OpenOrienteering is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenOrienteering is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenOrienteering. If not, see . + */ + + +#ifndef OPENORIENTEERING_PATH_COORD_H +#define OPENORIENTEERING_PATH_COORD_H + +#include + +#include "map_coord.h" + +class PathCoordVector; +class SplitPathCoord; + + + +/** + * A PathCoord represents a node in a polygonal approximation of a path. + * + * Complex paths which may consist of straight edges and curves are processed + * into PathCoordVectors, approximating the path with straight edges only. + * + * Apart from a point on this polygonal path, a PathCoord contains additional + * information about that point: + * - the index of the original point where the current edge started, + * - the relative position on this edge, and + * - the length since the start of the path. + */ +class PathCoord +{ + friend class PathCoordVector; + +public: + /** A reaonably sized unsigned integer type for map coord vector sizes and indexes. */ + using size_type = quint32; + + /** A reaonably precise float type for lengths and distances. */ + using length_type = float; + + /** A reaonably precise float type for relative position in the range [0, 1). */ + using param_type = float; + + + /** Position. */ + MapCoordF pos; + + /** MapCoordVector(F) index of the start of the edge which this position belongs to. */ + size_type index; + + /** Relative location of this position on the MapCoordVector edge ([0.0, 1.0)). */ + param_type param; + + /** Cumulative length of the path since the start of the current part. */ + length_type clen; + + + /** Default contructor. */ + constexpr PathCoord(); + + /** Copy constructor. */ + constexpr PathCoord(const PathCoord&) = default; + + /** Move constructor. */ + PathCoord(PathCoord&&) = default; + + /** Explicit construction with all member values. */ + constexpr PathCoord(MapCoordF pos, size_type index, param_type param, length_type clen); + + + /** Assignment operator. */ + PathCoord& operator=(const PathCoord&) = default; + + /** Move assignment operator. */ + PathCoord& operator=(PathCoord&&) = default; + + + /** + * Global position error threshold for approximating bezier curves with straight segments. + * + * @todo Make bezier error configurable + */ + static length_type bezierError(); + + + /** + * Returns true if the PathCoord's index is lower than value. + * + * This function can be used for doing a binary search on a sorted container + * of PathCoords. + * + * @see std::lower_bound + */ + static bool indexLessThanValue(const PathCoord& coord, size_type value); + + /** + * Returns true if the value is lower than the PathCoord's index. + * + * This function can be used for doing a binary search on a sorted container + * of PathCoords. + * + * @see std::upper_bound + */ + static bool valueLessThanIndex(size_type value, const PathCoord& coord); + + + /** + * Splits a cubic bezier curve. + * + * The curve made up by the points c0 ... c3 is split up at the relative + * position p (0..1). The new intermediate points (between c0 and c3) are + * returned in o0 ... o4. + * + * If not all returned values are needed, it is possible to have a subset of + * o0..o4 point to the same memory. + */ + static void splitBezierCurve( + MapCoordF c0, + MapCoordF c1, + MapCoordF c2, + MapCoordF c3, + float p, + MapCoordF& o0, + MapCoordF& o1, + MapCoordF& o2, + MapCoordF& o3, + MapCoordF& o4 + ); + + + /** + * The minimum required (squared) distance of neighboring nodes which are to + * be considered for determining path tangents. + */ + static constexpr qreal tangentEpsilonSquared(); +}; + + + +/** + * An arbitrary position on a path. + * + * A SplitPathCoord supports processing paths in connection with PathCoordVector. + * It can represent an arbitrary position even between the elements of the + * PathCoordVector. Other than PathCoord, it keeps a reference to the + * PathCoordVector. It captures additional state such as adjusted curve parameters. + * + * \see PathCoord + */ +class SplitPathCoord +{ +public: + /** A reaonably precise float type for lengths and distances. */ + using length_type = PathCoord::length_type; + + /** Position. */ + MapCoordF pos; + + /** Index of the cooresponding or preceding map coordinate and flags. */ + PathCoord::size_type index; + + /** Relative location of this position on the MapCoordVector edge ([0.0, 1.0)). */ + float param; + + /** Cumulative length of the path since the start of the current part. */ + length_type clen; + + /** The underlying vector path coordinates. */ + const PathCoordVector* path_coords; + + /** Index of the corresponding or preceding path_coord in a vector. */ + std::vector::size_type path_coord_index; + + /** If true, a bezier edge ends at this split position. */ + bool is_curve_end; + + /** If true, a bezier edge starts at this split position. */ + bool is_curve_start; + + /** If a bezier edge ends here, this will hold the last control points. + * + * Otherwise, curve_end[1] will hold the preceding coordinate, + * or the current coordinate for the start of open paths. + */ + MapCoordF curve_end[2]; + + /** If a bezier edge starts here, this will hold the next control points. + * + * Otherwise, curve_start[0] will hold the next coordinate, + * or the current coordinate for the end of open paths + */ + MapCoordF curve_start[2]; + + + /** + * Returns a vector which is a tangent to the path at this position. + */ + MapCoordF tangentVector() const; + + + /** + * Returns a SplitPathCoord at the begin of the given path. + */ + static SplitPathCoord begin(const PathCoordVector& path_coords); + + /** + * Returns a SplitPathCoord at the end of the given path. + */ + static SplitPathCoord end(const PathCoordVector& path_coords); + + /** + * Returns a SplitPathCoord at the given PathCoordVector index. + */ + static SplitPathCoord at( + const PathCoordVector& path_coords, + std::vector::size_type path_coord_index + ); + + /** + * Returns a SplitPathCoord at the given length. + * + * The search for the position will start at first. + */ + static SplitPathCoord at( + length_type length, + const SplitPathCoord& first + ); + + /** + * Returns a SplitPathCoord at the given length. + */ + static SplitPathCoord at( + const PathCoordVector& path_coords, + length_type length + ); +}; + + + +// ### PathCoord inline code ### + +constexpr PathCoord::PathCoord() + : PathCoord( {}, 0, 0.0, 0.0) +{ + // Nothing else +} + +constexpr PathCoord::PathCoord(MapCoordF pos, size_type index, param_type param, PathCoord::length_type clen) + : pos { pos } + , index { index } + , param { param } + , clen { clen } +{ + // Nothing else +} + +constexpr qreal PathCoord::tangentEpsilonSquared() +{ + return 0.000625; // App. 0.025 mm distance +} + + + +// ### SplitPathCoord inline code ### + +// static +inline +SplitPathCoord SplitPathCoord::at(const PathCoordVector& path_coords, SplitPathCoord::length_type length) +{ + return at(length, begin(path_coords)); +} + +#endif diff --git a/src/core/storage_location.cpp b/src/core/storage_location.cpp new file mode 100644 index 0000000..b9b01a3 --- /dev/null +++ b/src/core/storage_location.cpp @@ -0,0 +1,292 @@ +/* + * Copyright 2016 Kai Pastor + * + * This file is part of OpenOrienteering. + * + * OpenOrienteering is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenOrienteering is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenOrienteering. If not, see . + */ + + +#include "storage_location.h" + +#include +#include + + +#ifdef Q_OS_ANDROID +#include +#include +#include +#include +#include +#include +#include +#include + + +namespace Android { + +/** + * The cache of known locations. + */ +static std::shared_ptr> locations_cache; + +/** + * Tells the media scanner to register the given file or folder. + * + * This is required to make files quickly available for transfer via MTP. + */ +void mediaScannerScanFile(const QString path) +{ + static const auto ACTION_MEDIA_SCANNER_SCAN_FILE = + QAndroidJniObject::getStaticObjectField("android/content/Intent", + "ACTION_MEDIA_SCANNER_SCAN_FILE"); + auto intent = QAndroidJniObject { "android/content/Intent", + "(Ljava/lang/String;)V", + ACTION_MEDIA_SCANNER_SCAN_FILE.object() }; + auto file = QAndroidJniObject { "java/io/File", + "(Ljava/lang/String;)V", + QAndroidJniObject::fromString(path).object() }; + auto uri = QAndroidJniObject::callStaticObjectMethod( + "android/net/Uri", + "fromFile", + "(Ljava/io/File;)Landroid/net/Uri;", + file.object()); + + intent.callObjectMethod("setData", + "(Landroid/net/Uri;)Landroid/content/Intent;", + uri.object()); + auto activity = QtAndroid::androidActivity(); + auto context = activity.callObjectMethod( + "getApplicationContext", + "()Landroid/content/Context;"); + context.callMethod("sendBroadcast", "(Landroid/content/Intent;)V", intent.object()); +} + +/** + * Returns writable application-specific directories on all external storage volumes. + * + * These directories are named "Android/data/PACKAGENAME" and use "synthesized + * permissions", i.e. apps from the package may write to these folders without needing + * explicit permissions. Other apps may read these files. + * + * Files in this location will be deleted when the app is uninstalled. + * + * Requires API level 19. + * + * \see https://developer.android.com/reference/android/content/Context.html#getExternalFilesDirs(java.lang.String) + */ +std::vector getExternalFilesDirs(jstring* type) +{ + auto activity = QtAndroid::androidActivity(); + auto context = activity.callObjectMethod( + "getApplicationContext", + "()Landroid/content/Context;"); + + // Get directories with synthesized permissions on all external storage volumes + auto external_files_dirs = context.callObjectMethod( + "getExternalFilesDirs", + "(Ljava/lang/String;)[Ljava/io/File;", + type); + + QAndroidJniEnvironment jni; + const auto length = jni->GetArrayLength(external_files_dirs.object()); + + std::vector locations; + locations.reserve(std::size_t(length)); + for (auto i = 0; i < length; ++i) + { + auto location_jni = jni->GetObjectArrayElement(external_files_dirs.object(), i); + auto location = QAndroidJniObject{ location_jni }.toString(); + + const auto warning_path = QString(location + QLatin1String("/README.html")); + QFile warning(warning_path); + if (warning.open(QIODevice::WriteOnly | QIODevice::Truncate)) + { + auto android_start = location.indexOf(QLatin1String("/Android/data/")); + warning.write("

\n"); + warning.write(StorageLocation::fileHintTextTemplate(StorageLocation::HintApplication).arg(location.mid(android_start+1)).toUtf8()); + warning.write("\n

"); + warning.close(); + locations.push_back(location); + mediaScannerScanFile(warning_path); + } + } + return locations; +} + +/** + * Constructs a list of OOMapper folders on secondary storage volumes + */ +std::vector getLegacySecondaryStorage(const QString& primary_storage, const std::vector& external_files_dirs) +{ + std::vector result; + result.reserve(external_files_dirs.size()); + for (const auto& dir : external_files_dirs) + { + if (dir.startsWith(primary_storage)) + continue; + + auto index = dir.indexOf(QLatin1String("Android/data/")); + if (index < 0) + continue; + + result.push_back(dir.leftRef(index) + QLatin1String("OOMapper")); + } + return result; +} + +/** + * Constructs the cache of known storage locations. + */ +std::shared_ptr> buildLocationCache() +{ + std::vector locations_normal; + std::vector locations_application; + std::vector locations_readonly; + + // API level 1, single primary external storage + auto primary_storage = QAndroidJniObject::callStaticObjectMethod( + "android/os/Environment", + "getExternalStorageDirectory", + "()Ljava/io/File;", + nullptr).toString(); + + // Easy: "OOMapper" folder on primary external storage. + // Write access depends on the WRITE_EXTERNAL_STORAGE permission, which + // may be revoked by the user since Android 6.0. (Read access depends on the + // READ_EXTERNAL_STORAGE permission only when write access is not given.) + const QFileInfo primary_storage_oomapper { primary_storage + QLatin1String("/OOMapper") }; + if (primary_storage_oomapper.exists()) + { + const auto path = primary_storage_oomapper.filePath(); + if (primary_storage_oomapper.isWritable()) + locations_normal.push_back(path); + else + locations_readonly.push_back(path); + mediaScannerScanFile(path); + } + + // Volatile: Application-specific directories on external storage. + if (QtAndroid::androidSdkVersion() >= 19) + { + // API level 19 + locations_application = Android::getExternalFilesDirs(nullptr); + } + + // Difficult: "OOMapper" folder on secondary external storage. + // Read access, but (normally) no write access. + std::vector secondary_storage_paths; + const auto env = QProcessEnvironment::systemEnvironment(); + auto env_secondary_storage = env.value(QLatin1String("SECONDARY_STORAGE")); + if (!env_secondary_storage.isEmpty()) + { + // Mapper legacy approach, API level < 19 + const auto paths = env_secondary_storage.splitRef(QLatin1Char{';'}); + secondary_storage_paths.reserve(std::size_t(paths.size())); + for (const auto& path : paths) + secondary_storage_paths.emplace_back(path + QLatin1String("/OOMapper")); + } + else if (!locations_application.empty()) + { + // API level 19 + secondary_storage_paths = Android::getLegacySecondaryStorage(primary_storage, locations_application); + } + for (const auto& path : secondary_storage_paths) + { + const QFileInfo secondary_storage { path }; + if (secondary_storage.exists()) + { + if (secondary_storage.isWritable()) + locations_normal.push_back(path); + else + locations_readonly.push_back(path); + mediaScannerScanFile(path); + } + } + + auto locations = std::make_shared>(); + locations->reserve(locations_normal.size() + + locations_application.size() + + locations_readonly.size()); + for (const auto& path : locations_normal) + locations->emplace_back(path, StorageLocation::HintNormal); + for (const auto& path : locations_application) + locations->emplace_back(path, StorageLocation::HintApplication); + for (const auto& path : locations_readonly) + locations->emplace_back(path, StorageLocation::HintReadOnly); + + return locations; +} + +} // namespace + +#endif + + + +// static +std::shared_ptr> StorageLocation::knownLocations() +{ +#ifdef Q_OS_ANDROID + auto locations = Android::locations_cache; + if (!locations) + { + locations = Android::buildLocationCache(); + Android::locations_cache = locations; + } + Q_ASSERT(locations); + return locations; +#else + auto locations = std::make_shared>(); + auto paths = QStandardPaths::standardLocations(QStandardPaths::DocumentsLocation); + locations->reserve(std::size_t(paths.size())); + for (const auto& path : paths) + { + locations->emplace_back(path, HintNormal); + } + return locations; +#endif +} + + +void StorageLocation::refresh() +{ +#ifdef Q_OS_ANDROID + Android::locations_cache.reset(); +#endif +} + + +// static +QString StorageLocation::fileHintTextTemplate(Hint hint) +{ + switch (hint) + { + case HintNormal: + return tr("'%1' is stored in a regular location."); + + case HintApplication: + return tr("'%1' is located in app storage. The files will be removed when uninstalling the app."); + + case HintReadOnly: + return tr("'%1' is not writable. Changes cannot be saved."); + + case HintInvalid: + return tr("'%1' is not a valid storage location."); + } + + Q_UNREACHABLE(); +} + diff --git a/src/core/storage_location.h b/src/core/storage_location.h new file mode 100644 index 0000000..147a23c --- /dev/null +++ b/src/core/storage_location.h @@ -0,0 +1,121 @@ +/* + * Copyright 2016 Kai Pastor + * + * This file is part of OpenOrienteering. + * + * OpenOrienteering is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenOrienteering is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenOrienteering. If not, see . + */ + + +#ifndef OPENORIENTEERING_STORAGE_LOCATION_H +#define OPENORIENTEERING_STORAGE_LOCATION_H + + +#include +#include + +#include +#include + + +// noexcept since Qt 5.5 +constexpr bool qstring_is_nothrow_copy_constructible = std::is_nothrow_copy_constructible::value; +constexpr bool qstring_is_nothrow_move_constructible = std::is_nothrow_move_constructible::value; + + +/** + * Provides information about document storage locations. + */ +class StorageLocation +{ + Q_DECLARE_TR_FUNCTIONS(StorageLocation) + +public: + /** Various hints about locations. */ + enum Hint { + HintNormal, ///< Normal location + HintApplication, ///< Location which might get cleaned unexpectedly + HintReadOnly, ///< Read-only location + HintInvalid ///< Not a valid location at all + }; + + /** Constructs a new location. */ + StorageLocation(const QString& path, Hint hint) noexcept; + + /** Default copy constructor. */ + StorageLocation(const StorageLocation&) noexcept(qstring_is_nothrow_copy_constructible) = default; + + /** Default move constructor. */ + StorageLocation(StorageLocation&&) noexcept(qstring_is_nothrow_move_constructible) = default; + + + /** Returns the path of this location. */ + QString path() const; + + /** Returns the hint for this location. */ + Hint hint() const; + + /** Returns the text representing the hint for this location. */ + QString hintText() const; + + /** Returns a text template for giving the hint for the given path. */ + static QString fileHintTextTemplate(Hint hint); + + + /** + * Returns the known locations for documents. + * + * The returned shared-ptr will always have an object, even if it is an empty list. + */ + static std::shared_ptr> knownLocations(); + + + /** Forces a new scan of locations on the next call to knownLocations(). */ + static void refresh(); + + +private: + const QString m_path; + const Hint m_hint; +}; + + + +inline +StorageLocation::StorageLocation(const QString& path, StorageLocation::Hint hint) noexcept +: m_path { path } +, m_hint { hint } +{ + // nothing else +} + +inline +QString StorageLocation::path() const +{ + return m_path; +} + +inline +StorageLocation::Hint StorageLocation::hint() const +{ + return m_hint; +} + +inline +QString StorageLocation::hintText() const +{ + return fileHintTextTemplate(hint()).arg(path()); +} + +#endif // OPENORIENTEERING_STORAGE_LOCATION_H diff --git a/src/core/virtual_coord_vector.cpp b/src/core/virtual_coord_vector.cpp new file mode 100644 index 0000000..6246221 --- /dev/null +++ b/src/core/virtual_coord_vector.cpp @@ -0,0 +1,36 @@ +/* + * Copyright 2015 Kai Pastor + * + * This file is part of OpenOrienteering. + * + * OpenOrienteering is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenOrienteering is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenOrienteering. If not, see . + */ + +#include "virtual_coord_vector.h" + + + +//### VirtualCoordVector ### + +MapCoordF VirtualCoordVector::fromMapCoordF(size_type index) const +{ + return (*coords)[index]; +} + +MapCoordF VirtualCoordVector::fromMapCoord(size_type index) const +{ + return MapCoordF(flags[index]); +} + + diff --git a/src/core/virtual_coord_vector.h b/src/core/virtual_coord_vector.h new file mode 100644 index 0000000..c2dd3dc --- /dev/null +++ b/src/core/virtual_coord_vector.h @@ -0,0 +1,241 @@ +/* + * Copyright 2015 Kai Pastor + * + * This file is part of OpenOrienteering. + * + * OpenOrienteering is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenOrienteering is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenOrienteering. If not, see . + */ + + +#ifndef OPENORIENTEERING_VIRTUAL_COORD_VECTOR_H +#define OPENORIENTEERING_VIRTUAL_COORD_VECTOR_H + +#include "map_coord.h" + + + +/** + * @brief The VirtualFlagsVector class provides read-only access to a MapCoordVector. + * + * This is an utility class which is used as a public member in VirtualCoordVector. + * Its public API provides read-only STL-style access to a map coordinates vector. + */ +class VirtualFlagsVector +{ + friend class VirtualCoordVector; + +private: + // The pointer to the vector coordinate of coordinates. Never nullptr. + const MapCoordVector* coords; + + // To be used by VirtualCoordVector only + VirtualFlagsVector(const VirtualFlagsVector&) = default; + + // To be used by VirtualCoordVector only + VirtualFlagsVector& operator=(const VirtualFlagsVector&) = default; + +public: + /** + * A reaonably sized unsigned integer type for map coord vector sizes and indexes. + */ + using size_type = quint32; + + /** + * Constructs a new accessor for the given vector of MapCoord. + */ + explicit VirtualFlagsVector(const MapCoordVector& coords); + + + /** + * Returns a direct reference to the underlying coordinates. + */ + const MapCoordVector& data() const; + + + // STL-style API (incomplete) + + bool empty() const; + + size_type size() const; + + MapCoordVector::const_reference operator[](size_type index) const; + + MapCoordVector::const_reference back() const; +}; + + + +/** + * @brief The VirtualCoordVector class provides read-only access to possible distinct coordinates and flags. + * + * Some algorithms in Mapper need to be applied not only to original integer coordinate lists, + * but sometimes also to transformed floating-point coordinates sharing the same flags. + * This class provides uniform access to coordinates and flags in two cases: + * + * (a) Coordinates and flags coming from the same MapCoordVector, and + * + * (b) Coordinates coming from a MapCoordVectorF, and flags from a MapCoordVector. + */ +class VirtualCoordVector +{ +public: + /** + * A reaonably sized unsigned integer type for map coord vector sizes and indexes. + */ + using size_type = VirtualFlagsVector::size_type; + + /** + * An read-only accessor to the flags which provides an operator[](size_type). + */ + // Provides the coordinates in case (a). + VirtualFlagsVector flags; + +private: + // A pointer to the MapCoordVectorF which provides the coordinates in case (b). + const MapCoordVectorF* coords; + + // A pointer to the actual coordinate access implemenation + MapCoordF (VirtualCoordVector::*coords_access)(size_type index) const; + +public: + /** + * Creates another accessor for the data managed by the given prototype. + */ + VirtualCoordVector(const VirtualCoordVector& prototype) = default; + + /** + * Creates an accessor for the flags and coordinates in coords (case a). + */ + explicit VirtualCoordVector(const MapCoordVector& coords); + + /** + * Creates an accessor for the given flags and the coordinates in coords (case b). + */ + explicit VirtualCoordVector(const MapCoordVector& flags, const MapCoordVectorF& coords); + + + /** + * Causes this accessor to serve the same data as rhs. + */ + VirtualCoordVector& operator=(const VirtualCoordVector& rhs) = default; + + + // STL-style API (incomplete, and with some differences, such as returning by value) + + bool empty() const; + + size_type size() const; + + MapCoordF operator[](size_type index) const; + + MapCoordF back() const; + +private: + // Returns a coordinate from coords vector. + MapCoordF fromMapCoordF(size_type index) const; + + // Returns a coordinate from the flags accessors. + MapCoordF fromMapCoord(size_type index) const; +}; + + + +// ### VirtualFlagsVector inline code ### + +inline +VirtualFlagsVector::VirtualFlagsVector(const MapCoordVector& coords) + : coords { &coords } +{ + // nothing else +} + +inline +const MapCoordVector& VirtualFlagsVector::data() const +{ + return *coords; +} + +inline +bool VirtualFlagsVector::empty() const +{ + return coords->empty(); +} + +inline +VirtualFlagsVector::size_type VirtualFlagsVector::size() const +{ + return coords->size(); +} + +inline +MapCoordVector::const_reference VirtualFlagsVector::operator[](size_type index) const +{ + return (*coords)[index]; +} + +inline +MapCoordVector::const_reference VirtualFlagsVector::back() const +{ + return coords->back(); +} + + + +// ### VirtualCoordVector inline code ### + +inline +VirtualCoordVector::VirtualCoordVector(const MapCoordVector& coords) + : flags { coords } + , coords { nullptr } + , coords_access(&VirtualCoordVector::fromMapCoord) +{ + // nothing else +} + +inline +VirtualCoordVector::VirtualCoordVector(const MapCoordVector& flags, const MapCoordVectorF& coords) + : flags { flags } + , coords { &coords } + , coords_access(&VirtualCoordVector::fromMapCoordF) +{ + // nothing else +} + +inline +bool VirtualCoordVector::empty() const +{ + return flags.empty(); +} + +inline +VirtualCoordVector::size_type VirtualCoordVector::size() const +{ + return flags.size(); +} + +inline +MapCoordF VirtualCoordVector::operator[](size_type index) const +{ + return (this->*coords_access)(index); +} + +inline +MapCoordF VirtualCoordVector::back() const +{ + return (this->*coords_access)(size()-1); +} + + + +#endif diff --git a/src/core/virtual_path.cpp b/src/core/virtual_path.cpp new file mode 100644 index 0000000..ca8ee22 --- /dev/null +++ b/src/core/virtual_path.cpp @@ -0,0 +1,838 @@ +/* + * Copyright 2012, 2013 Thomas Schöps + * Copyright 2012-2015 Kai Pastor + * + * This file is part of OpenOrienteering. + * + * OpenOrienteering is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenOrienteering is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenOrienteering. If not, see . + */ + + +#include "virtual_path.h" + +#include "../util.h" + + + +namespace +{ + /** + * Global position error threshold for approximating + * bezier curves with straight segments. + * TODO: make configurable + */ + const PathCoord::length_type bezier_error = 0.005; + + /** + * Global maximum length of generated PathCoord segments for curves. + * + * This ensures that even for flat curves, segments will be generated regularly. + * This is important because while a curve may be flat, the mapping from the + * curve parameter to real position is not linear, which would result in problems. + * This is counteracted by generating many segments. + */ + const PathCoord::length_type bezier_segment_maxlen_squared = 1.0; +} + + + +// ### PathCoord ### + +// static +PathCoord::length_type PathCoord::bezierError() +{ + return bezier_error; +} + + + +// ### PathCoordVector ### + +PathCoordVector::PathCoordVector(const MapCoordVector& coords) + : virtual_coords(coords) +{ + // nothing else +} + +PathCoordVector::PathCoordVector(const MapCoordVector& flags, const MapCoordVectorF& coords) + : virtual_coords(flags, coords) +{ + // nothing else +} + +PathCoordVector::PathCoordVector(const VirtualCoordVector& coords) + : virtual_coords(coords) +{ + // nothing else +} + +VirtualCoordVector::size_type PathCoordVector::update(VirtualCoordVector::size_type part_start) +{ + auto& flags = virtual_coords.flags; + auto part_end = virtual_coords.size() - 1; + if (part_start <= part_end) + { + Q_ASSERT(virtual_coords.size() == flags.size()); + + if (flags[part_start].isHolePoint()) + { + auto pos = virtual_coords[0]; + qWarning("PathCoordVector at %g %g (mm) has an invalid hole at index %d.", + pos.x(), -pos.y(), part_start); + } + + clear(); + if (empty() || (part_start > 0 && flags[part_start-1].isHolePoint())) + { + emplace_back(virtual_coords[part_start], part_start, 0.0, 0.0); + } + + for (auto index = part_start + 1; index <= part_end; ++index) + { + if (flags[index-1].isCurveStart()) + { + Q_ASSERT(index+2 <= part_end); + + // Add curve coordinates + curveToPathCoord(virtual_coords[index-1], virtual_coords[index], virtual_coords[index+1], virtual_coords[index+2], index-1, 0, 1); + index += 2; + } + + // Add end point + const PathCoord& prev = back(); + emplace_back(virtual_coords[index], index, 0.0, prev.clen + prev.pos.distanceTo(virtual_coords[index])); + + Q_ASSERT(back().index == index); + + if (index < part_end && flags[index].isHolePoint()) + { + part_end = index; + } + } + } + return part_end; +} + +bool PathCoordVector::isClosed() const +{ + return virtual_coords.flags[back().index].isClosePoint(); +} + +PathCoordVector::size_type PathCoordVector::findNextDashPoint(PathCoordVector::size_type first) const +{ + // Get behind the current point + auto prev_index = (*this)[first].index; + auto last = size() - 1; + + while (first != last && (*this)[first].index == prev_index) + { + ++first; + } + + // Find a dash point or hole point + while (first != last) + { + const auto& current_flags = virtual_coords.flags[(*this)[first].index]; + if (current_flags.isDashPoint() || current_flags.isHolePoint()) + break; + ++first; + } + + return first; +} + +PathCoord::length_type PathCoordVector::length() const +{ + Q_ASSERT(!empty()); + return back().clen; +} + +double PathCoordVector::calculateArea() const +{ + Q_ASSERT(!empty()); + + auto area = 0.0; + auto end_index = size() - 1; + auto j = end_index; // The last vertex is the 'previous' one to the first + + for (auto i = 0u; i <= end_index; ++i) + { + area += ((*this)[j].pos.x() + (*this)[i].pos.x()) * ((*this)[j].pos.y() - (*this)[i].pos.y()); + j = i; + } + return qAbs(area) / 2; +} + +QRectF PathCoordVector::calculateExtent() const +{ + QRectF extent(0.0, 0.0, -1.0, 0.0); + if (!empty()) + { + auto pc = begin(); + extent = QRectF(pc->pos.x(), pc->pos.y(), 0.0001, 0.0001); + + auto last = end(); + for (++pc; pc != last; ++pc) + { + rectInclude(extent, pc->pos); + } + + Q_ASSERT(extent.isValid()); + } + return extent; +} + +bool PathCoordVector::intersectsBox(QRectF box) const +{ + bool result = false; + if (!empty()) + { + auto last_pos = front().pos; + result = std::any_of(begin()+1, end(), [&box, &last_pos](const PathCoord& pc) + { + auto pos = pc.pos; + auto result = lineIntersectsRect(box, last_pos, pos); /// \todo Implement this here, used nowhere else + last_pos = pos; + return result; + }); + } + return result; +} + +bool PathCoordVector::isPointInside(MapCoordF coord) const +{ + bool inside = false; + if (size() > 2) + { + auto last_pos = back().pos; + for(const auto& path_coord : *this) + { + auto pos = path_coord.pos; + if ( ((pos.y() > coord.y()) != (last_pos.y() > coord.y())) && + (coord.x() < (last_pos.x() - pos.x()) * + (coord.y() - pos.y()) / (last_pos.y() - pos.y()) + pos.x()) ) + { + inside = !inside; + } + last_pos = pos; + } + } + return inside; +} + +void PathCoordVector::curveToPathCoord( + MapCoordF c0, + MapCoordF c1, + MapCoordF c2, + MapCoordF c3, + MapCoordVector::size_type edge_start, + float p0, + float p1 ) +{ + // Common + auto p_half = (p0 + p1) * 0.5; + MapCoordF c12((c1.x() + c2.x()) * 0.5, (c1.y() + c2.y()) * 0.5); + + auto inner_len_sq = c0.distanceSquaredTo(c3); + auto outer_len = [&]() { return c0.distanceTo(c1) + c1.distanceTo(c2) + c2.distanceTo(c3); }; + if (inner_len_sq <= bezier_segment_maxlen_squared && outer_len() - sqrt(inner_len_sq) <= bezier_error) + { + const PathCoord& prev = back(); + emplace_back(c12, edge_start, p_half, prev.clen + float(prev.pos.distanceTo(c12))); + } + else + { + // Split in two + MapCoordF c01((c0.x() + c1.x()) * 0.5f, (c0.y() + c1.y()) * 0.5f); + MapCoordF c23((c2.x() + c3.x()) * 0.5f, (c2.y() + c3.y()) * 0.5f); + MapCoordF c012((c01.x() + c12.x()) * 0.5f, (c01.y() + c12.y()) * 0.5f); + MapCoordF c123((c12.x() + c23.x()) * 0.5f, (c12.y() + c23.y()) * 0.5f); + MapCoordF c0123((c012.x() + c123.x()) * 0.5f, (c012.y() + c123.y()) * 0.5f); + + curveToPathCoord(c0, c01, c012, c0123, edge_start, p0, p_half); + curveToPathCoord(c0123, c123, c23, c3, edge_start, p_half, p1); + } +} + + + +//### VirtualPath ### + +VirtualPath::VirtualPath(const MapCoordVector& coords) + : VirtualPath(coords, 0, coords.size()-1) +{ + // nothing else +} + +VirtualPath::VirtualPath(const MapCoordVector& coords, size_type first, size_type last) + : coords(coords) + , path_coords(coords) + , first_index(first) + , last_index(last) +{ + // nothing else +} + +VirtualPath::VirtualPath(const VirtualCoordVector& coords) + : VirtualPath(coords, 0, coords.size()-1) +{ + // nothing else +} + +VirtualPath::VirtualPath(const VirtualCoordVector& coords, size_type first, size_type last) + : coords(coords) + , path_coords(coords) + , first_index(first) + , last_index(last) +{ + // nothing else +} + +VirtualPath::VirtualPath(const MapCoordVector& flags, const MapCoordVectorF& coords) + : VirtualPath(flags, coords, 0, coords.size()-1) +{ + // nothing else +} + +VirtualPath::VirtualPath(const MapCoordVector& flags, const MapCoordVectorF& coords, size_type first, size_type last) + : coords(flags, coords) + , path_coords(flags, coords) + , first_index(first) + , last_index(last) +{ + // nothing else +} + +VirtualPath::size_type VirtualPath::countRegularNodes() const +{ + size_type num_regular_points = 0; + for (auto i = first_index; i <= last_index; ++i) + { + ++num_regular_points; + if (coords.flags[i].isCurveStart()) + i += 2; + } + + if (num_regular_points && isClosed()) + --num_regular_points; + + return num_regular_points; +} + +bool VirtualPath::isClosed() const +{ + Q_ASSERT(last_index < coords.size()); + Q_ASSERT(last_index >= first_index); + return coords.flags[last_index].isClosePoint(); +} + +PathCoord VirtualPath::findClosestPointTo( + MapCoordF coord, + float& distance_squared, + float distance_bound_squared, + size_type start_index, + size_type end_index ) const +{ + Q_ASSERT(!path_coords.empty()); + + auto result = path_coords.front(); + + // Find upper bound for distance. + for (const auto& path_coord : path_coords) + { + if (path_coord.index > end_index) + break; + if (path_coord.index < start_index) + continue; + + auto to_coord = coord - path_coord.pos; + auto dist_sq = to_coord.lengthSquared(); + if (dist_sq < distance_bound_squared) + { + distance_bound_squared = dist_sq; + result = path_coord; + } + } + + // Check between this coord and the next one. + distance_squared = distance_bound_squared; + auto last = end(path_coords)-1; + for (auto pc = begin(path_coords); pc != last; ++pc) + { + if (pc->index > end_index) + break; + if (pc->index < start_index) + continue; + + auto pos = pc->pos; + auto next_pc = pc+1; + auto next_pos = next_pc->pos; + + auto tangent = next_pos - pos; + tangent.normalize(); + + auto to_coord = coord - pos; + float dist_along_line = MapCoordF::dotProduct(to_coord, tangent); + if (dist_along_line <= 0) + { + if (to_coord.lengthSquared() < distance_squared) + { + distance_squared = to_coord.lengthSquared(); + result = *pc; + } + continue; + } + + float line_length = next_pc->clen - pc->clen; + if (dist_along_line >= line_length) + { + if (coord.distanceSquaredTo(next_pos) < distance_squared) + { + distance_squared = coord.distanceSquaredTo(next_pos); + result = *next_pc; + } + continue; + } + + auto right = tangent.perpRight(); + + float dist_from_line = MapCoordF::dotProduct(right, to_coord); + auto dist_from_line_sq = dist_from_line * dist_from_line; + if (dist_from_line_sq < distance_squared) + { + distance_squared = dist_from_line_sq; + result.clen = pc->clen + dist_along_line; + result.index = pc->index; + auto factor = dist_along_line / line_length; + if (next_pc->index == pc->index) + result.param = pc->param + (next_pc->param - pc->param) * factor; + else + result.param = pc->param + (1.0 - pc->param) * factor; /// \todo verify + + if (coords.flags[result.index].isCurveStart()) + { + MapCoordF unused; + PathCoord::splitBezierCurve(MapCoordF(coords.flags[result.index]), MapCoordF(coords.flags[result.index+1]), + MapCoordF(coords.flags[result.index+2]), MapCoordF(coords.flags[result.index+3]), + result.param, unused, unused, result.pos, unused, unused); + } + else + { + result.pos = pos + (next_pos - pos) * factor; + } + } + } + return result; +} + +VirtualPath::size_type VirtualPath::prevCoordIndex(size_type base_index) const +{ + Q_ASSERT(base_index >= first_index); + + size_type result = first_index; + if (Q_UNLIKELY(base_index > last_index)) + { + result = last_index; + } + else if (base_index > first_index) + { + result = base_index - 1; + for (auto i = 1; i <= 3; ++i) + { + auto alternative = base_index - i; + if (alternative < first_index || alternative > last_index) + break; + + if (coords.flags[alternative].isCurveStart()) + result = alternative; + } + } + + return result; +} + +VirtualPath::size_type VirtualPath::nextCoordIndex(size_type base_index) const +{ + Q_ASSERT(base_index <= last_index); + + size_type result = base_index + 1; + if (Q_UNLIKELY(result > last_index)) + { + result = last_index; + } + + if (Q_UNLIKELY(result <= first_index)) + { + result = first_index; + } + else + { + for (auto i = 0; i < 2; ++i) + { + if (coords.flags[base_index].isCurveStart()) + { + result = base_index + 3; + break; + } + + if (base_index == first_index) + break; + + --base_index; + } + } + + return result; +} + +MapCoordF VirtualPath::calculateTangent(size_type i) const +{ + bool ok_to_coord, ok_to_next; + MapCoordF to_coord = calculateIncomingTangent(i, ok_to_coord); + MapCoordF to_next = calculateOutgoingTangent(i, ok_to_next); + + if (!ok_to_next) + { + to_next = to_coord; + } + else if (ok_to_coord) + { + to_coord.normalize(); + to_next.normalize(); + to_next += to_coord; + } + + return to_next; +} + +std::pair VirtualPath::calculateTangentScaling(size_type i) const +{ + bool ok_to_coord, ok_to_next; + MapCoordF to_coord = calculateIncomingTangent(i, ok_to_coord); + MapCoordF to_next = calculateOutgoingTangent(i, ok_to_next); + + auto scaling = 1.0; + if (!ok_to_next) + { + to_next = to_coord; + } + else if (ok_to_coord) + { + to_coord.normalize(); + to_next.normalize(); + if (to_next == -to_coord) + { + to_next = to_next.perpRight(); + scaling = std::numeric_limits::infinity(); + } + else + { + to_next += to_coord; + to_next.normalize(); + scaling = 1.0/MapCoordF::dotProduct(to_next, to_coord); + } + } + + return std::make_pair(to_next, scaling); +} + +MapCoordF VirtualPath::calculateTangent( + size_type i, + bool backward, + bool& ok) const +{ + if (backward) + return calculateIncomingTangent(i, ok); + else + return calculateOutgoingTangent(i, ok); +} + +MapCoordF VirtualPath::calculateIncomingTangent( + size_type i, + bool& ok) const +{ + ok = true; + MapCoordF tangent; + + for (auto k = i; k > first_index; ) /// \todo Implement unsigned + { + --k; + tangent = coords[i] - coords[k]; + if (tangent.lengthSquared() > PathCoord::tangentEpsilonSquared()) + return tangent; + } + + if (isClosed() && last_index > i+1) + { + // Continue from end + for (auto k = last_index; k > i; --k) + { + tangent = coords[i] - coords[k]; + if (tangent.lengthSquared() > PathCoord::tangentEpsilonSquared()) + return tangent; + } + } + + ok = false; + return tangent; +} + +MapCoordF VirtualPath::calculateOutgoingTangent( + size_type i, + bool& ok) const +{ + ok = true; + MapCoordF tangent; + + for (auto k = i+1; k <= last_index; ++k) + { + tangent = coords[k] - coords[i]; + if (tangent.lengthSquared() > PathCoord::tangentEpsilonSquared()) + return tangent; + } + + if (isClosed()) + { + // Continue from start + for (auto k = first_index; k < i; ++k) + { + tangent = coords[k] - coords[i]; + if (tangent.lengthSquared() > PathCoord::tangentEpsilonSquared()) + return tangent; + } + } + + ok = false; + return tangent; +} + +void VirtualPath::copy( + const SplitPathCoord& first, + const SplitPathCoord& last, + MapCoordVector& out_coords ) const +{ + Q_ASSERT(!empty()); + Q_ASSERT(first.path_coords == &path_coords); + Q_ASSERT(last.path_coords == &path_coords); + + auto& flags = coords.flags; + + // Handle first coordinate and its flags. + if (out_coords.empty() || + out_coords.back().isHolePoint() || + !out_coords.back().isPositionEqualTo(MapCoord(first.pos)) ) + { + out_coords.emplace_back(first.pos); + } + else + { + out_coords.back().setHolePoint(false); + out_coords.back().setClosePoint(false); + } + + if (first.index == last.index) + { + out_coords.back().setCurveStart(last.is_curve_end && last.param != first.param); + } + else + { + out_coords.back().setCurveStart(first.is_curve_start); + + auto stop_index = last.index; + if (last.param == 0.0) + { + stop_index -= last.is_curve_end ? 3 : 1; + } + + auto index = first.index + 1; + if (first.is_curve_start) + { + out_coords.emplace_back(first.curve_start[0]); + out_coords.emplace_back(first.curve_start[1]); + index += 2; + } + + for (; index <= stop_index; ++index) + { + out_coords.emplace_back(coords[index]); + out_coords.back().setFlags(flags[index].flags()); + } + } + + if (out_coords.back().isCurveStart()) + { + Q_ASSERT(last.is_curve_end); + out_coords.emplace_back(last.curve_end[0]); + out_coords.emplace_back(last.curve_end[1]); + } + + out_coords.emplace_back(last.pos); + if (last.param == 0.0) + { + out_coords.back().setHolePoint(flags[last.index].isHolePoint()); + out_coords.back().setClosePoint(flags[last.index].isClosePoint()); + } +} + +void VirtualPath::copy( + const SplitPathCoord& first, + const SplitPathCoord& last, + MapCoordVector& out_flags, + MapCoordVectorF& out_coords) const +{ + Q_ASSERT(!empty()); + Q_ASSERT(first.path_coords == &path_coords); + Q_ASSERT(last.path_coords == &path_coords); + + Q_ASSERT(out_coords.size() == out_flags.size()); + + auto& flags = coords.flags; + + // Handle first coordinate and its flags. + if (out_coords.empty() || + out_flags.back().isHolePoint() || + out_coords.back() != first.pos) + { + out_coords.emplace_back(first.pos); + out_flags.emplace_back(); + } + else + { + out_flags.back().setHolePoint(false); + out_flags.back().setClosePoint(false); + } + + if (first.index == last.index) + { + out_flags.back().setCurveStart(last.is_curve_end && last.param != first.param); + } + else + { + out_flags.back().setCurveStart(first.is_curve_start); + + auto stop_index = last.index; + if (last.param == 0.0) + { + stop_index -= last.is_curve_end ? 3 : 1; + } + + auto index = first.index + 1; + if (first.is_curve_start && index < stop_index) + { + out_flags.emplace_back(); + out_coords.emplace_back(first.curve_start[0]); + out_flags.emplace_back(); + out_coords.emplace_back(first.curve_start[1]); + index += 2; + } + + for (; index <= stop_index; ++index) + { + out_flags.emplace_back(flags[index]); + out_coords.emplace_back(coords[index]); + } + } + + if (out_flags.back().isCurveStart()) + { + Q_ASSERT(last.is_curve_end); + out_flags.emplace_back(); + out_coords.emplace_back(last.curve_end[0]); + out_flags.emplace_back(); + out_coords.emplace_back(last.curve_end[1]); + } + + out_flags.emplace_back(); + out_coords.emplace_back(last.pos); + if (last.param == 0.0) + { + out_flags.back().setHolePoint(flags[last.index].isHolePoint()); + out_flags.back().setClosePoint(flags[last.index].isClosePoint()); + } + + Q_ASSERT(out_coords.size() == out_flags.size()); +} + +// This algorithm must (nearly) match VirtualPath::copy(). +// (It will always copy the length of the starting point, but +// VirtualPath::copy() might skip this point in some cases.) +void VirtualPath::copyLengths( + const SplitPathCoord& first, + const SplitPathCoord& last, + std::vector& out_lengths ) const +{ + Q_ASSERT(!empty()); + Q_ASSERT(first.path_coords == &path_coords); + Q_ASSERT(last.path_coords == &path_coords); + + auto& flags = coords.flags; + + // Handle first coordinate + out_lengths.emplace_back(first.clen); + + bool after_curve_start = false; + + if (first.index == last.index) + { + after_curve_start = last.is_curve_end && last.param != first.param; + } + else + { + after_curve_start = first.is_curve_start; + + auto stop_index = last.index; + if (last.param == 0.0) + { + stop_index -= last.is_curve_end ? 3 : 1; + } + + auto index = first.index + 1; + if (first.is_curve_start && index < stop_index) + { + after_curve_start = false; + out_lengths.emplace_back(first.clen); + out_lengths.emplace_back(first.clen); + index += 2; + } + + auto path_coord_index = first.path_coord_index; + for (; index <= stop_index; ++index) + { + while (path_coords[path_coord_index].index < index) + ++path_coord_index; + + if (path_coords[path_coord_index].index == index) + { + // Normal node + out_lengths.emplace_back(path_coords[path_coord_index].clen); + after_curve_start = flags[index].isCurveStart(); + } + else + { + // Control point + out_lengths.emplace_back(out_lengths.back()); + after_curve_start = false; + } + } + } + + if (after_curve_start) + { + auto length = out_lengths.back(); + out_lengths.emplace_back(length); + out_lengths.emplace_back(length); + } + + out_lengths.push_back(last.clen); +} diff --git a/src/core/virtual_path.h b/src/core/virtual_path.h new file mode 100644 index 0000000..ae48283 --- /dev/null +++ b/src/core/virtual_path.h @@ -0,0 +1,423 @@ +/* + * Copyright 2012, 2013 Thomas Schöps + * Copyright 2012-2015 Kai Pastor + * + * This file is part of OpenOrienteering. + * + * OpenOrienteering is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenOrienteering is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenOrienteering. If not, see . + */ + + +#ifndef OPENORIENTEERING_VIRTUAL_PATH_H +#define OPENORIENTEERING_VIRTUAL_PATH_H + +#include + +#include + +#include "map_coord.h" +#include "path_coord.h" +#include "virtual_coord_vector.h" + + +class SplitPathCoord; + + + +class PathCoordVector : public std::vector +{ +private: + friend class SplitPathCoord; + friend class VirtualPath; + + VirtualCoordVector virtual_coords; + +public: + PathCoordVector(const MapCoordVector& coords); + + PathCoordVector(const MapCoordVector& flags, const MapCoordVectorF& coords); + + PathCoordVector(const VirtualCoordVector& coords); + +private: + PathCoordVector(const PathCoordVector&) = default; + + PathCoordVector(PathCoordVector&&) = default; + + + PathCoordVector& operator=(const PathCoordVector&) = default; + + PathCoordVector& operator=(PathCoordVector&&) = default; + + + const VirtualFlagsVector& flags() const; + + const VirtualCoordVector& coords() const; + + bool isClosed() const; + + +public: + /** + * Updates the path coords from the flags/coords, starting at first. + * + * \return The index after the last element of this part. + */ + VirtualCoordVector::size_type update(VirtualCoordVector::size_type first); + + + /** + * Finds the index of the next dash point after first, or returns size()-1. + * + * \todo Consider return a SplitPathCoord (cf. actual usage). + */ + size_type findNextDashPoint(PathCoordVector::size_type first) const; + + + /** + * Finds the path coordinate index with or just before the given length. + */ + size_type lowerBound( + PathCoord::length_type length, + size_type first, + size_type last + ) const; + + /** + * Finds the path coordinate index with or just after the given length. + */ + size_type upperBound( + PathCoord::length_type length, + size_type first, + size_type last + ) const; + + + /** + * Returns the length of the path. + */ + PathCoord::length_type length() const; + + /** + * Calculates the area of this part. + */ + double calculateArea() const; + + QRectF calculateExtent() const; + + bool intersectsBox(QRectF box) const; + + bool isPointInside(MapCoordF coord) const; + +private: + /** + * Recursive approximation of a bezier curve by polygonal segments. + */ + void curveToPathCoord( + MapCoordF c0, + MapCoordF c1, + MapCoordF c2, + MapCoordF c3, + MapCoordVector::size_type edge_start, + float p0, + float p1 + ); +}; + + + +/** + * A VirtualPath class represents a single path out of a sequence of coords and flags. + * + * It provides a PathCoordVector which is is a polyline approximation of the path + * (i.e. no curves) and provides metadata such as length for each point of the path. + */ +class VirtualPath +{ +public: + /** A reaonably sized unsigned integer type for coord vector sizes and indexes. */ + using size_type = VirtualCoordVector::size_type; + + /** The underlying coordinates and flags. */ + VirtualCoordVector coords; + + /** The derived flattened coordinates and meta data. */ + PathCoordVector path_coords; + + /** Index of first coordinate of this path in the coords. */ + size_type first_index; + + /** Index of the last coordinate of this part in the coords. */ + size_type last_index; + + + explicit VirtualPath(const MapCoordVector& coords); + + VirtualPath(const MapCoordVector& coords, size_type first, size_type last); + + explicit VirtualPath(const VirtualCoordVector& coords); + + VirtualPath(const VirtualCoordVector& coords, size_type first, size_type last); + + VirtualPath(const MapCoordVector& flags, const MapCoordVectorF& coords); + + VirtualPath(const MapCoordVector& flags, const MapCoordVectorF& coords, size_type first, size_type last); + + VirtualPath(const VirtualPath&) = default; + + VirtualPath(VirtualPath&&) = default; + +protected: + VirtualPath& operator=(const VirtualPath&) = default; + + VirtualPath& operator=(VirtualPath&&) = default; + +public: + /** + * Returns true if there are no nodes in this path. + */ + bool empty() const; + + /** + * Returns the number of coordinates in this path. + * + * \see countRegularNodes() + */ + size_type size() const; + + /** + * Calculates the number of regular nodes in this path. + * + * Regular nodes exclude close points and curve handles. + */ + size_type countRegularNodes() const; + + + /** + * Returns true if the path is closed. + * + * For closed paths, the last coordinate is at the same position as the + * first coordinate of the path,and has the "close point" flag set. + * These coords will move together when moved by the user, appearing as + * just one coordinate. + * + * Parts of PathObjects can be closed and opened with PathPart::setClosed() + * or PathPart::connectEnds(). + * + * Objects with area symbols must always be closed. + */ + bool isClosed() const; + + + /** + * Returns the length of the path. + */ + PathCoord::length_type length() const; + + /** + * Calculates the area of this part. + */ + double calculateArea() const; + + QRectF calculateExtent() const; + + bool intersectsBox(QRectF box) const; + + bool isPointInside(MapCoordF coord) const; + + PathCoord findClosestPointTo( + MapCoordF coord, + float& distance_squared, + float distance_bound_squared, + size_type start_index, + size_type end_index) const; + + + /** + * Determines the index of the previous regular coordinate. + * + * Regular coordinates exclude bezier control points and close points. + * + * @param base_index The index of a regular coordinate from which to start. + */ + size_type prevCoordIndex(size_type base_index) const; + + /** + * Determines the index of the next regular coordinate. + * + * Regular coordinates exclude bezier control points and close points. + * + * @param base_index The index of a regular coordinate from which to start. + */ + size_type nextCoordIndex(size_type base_index) const; + + + MapCoordF calculateTangent(size_type i) const; + + std::pair calculateTangentScaling(size_type i) const; + + /** + * Calculates the path tangent at the given MapCoord index. + * + * Takes care of cases where successive points are at equal positions. + * + * @param i Index of the coordinate where to query the tangent. + * @param backward If false, returns the forward tangent, if true, returns + * the backward tangent. Makes a difference at sharp corners. + * @param ok Is set to true if the tangent can be found correctly, false if + * failing to find the tangent. + */ + MapCoordF calculateTangent( + size_type i, + bool backward, + bool& ok + ) const; + + /** + * Similar to calculateTangent(). + */ + MapCoordF calculateIncomingTangent( + size_type i, + bool& ok + ) const; + + /** + * Similar to calculateTangent(). + */ + MapCoordF calculateOutgoingTangent( + size_type i, + bool& ok + ) const; + + + void copy( + const SplitPathCoord& first, + const SplitPathCoord& last, + MapCoordVector& out_coords + ) const; + + void copy( + const SplitPathCoord& first, + const SplitPathCoord& last, + MapCoordVector& out_flags, + MapCoordVectorF& out_coords + ) const; + + + void copyLengths( + const SplitPathCoord& first, + const SplitPathCoord& last, + std::vector& out_lengths + ) const; + +}; + + + +// ### PathCoordVector inline code ### + +inline +const VirtualFlagsVector& PathCoordVector::flags() const +{ + return virtual_coords.flags; +} + +inline +const VirtualCoordVector& PathCoordVector::coords() const +{ + return virtual_coords; +} + +inline +PathCoordVector::size_type PathCoordVector::lowerBound( + PathCoord::length_type length, + PathCoordVector::size_type first, + PathCoordVector::size_type last ) const +{ + auto index = first; + while (index != last) + { + ++index; + if ((*this)[index].clen < length) + { + --index; + break; + } + } + return index; +} + +inline +PathCoordVector::size_type PathCoordVector::upperBound( + PathCoord::length_type length, + PathCoordVector::size_type first, + PathCoordVector::size_type last ) const +{ + auto index = first; + while (index != last && (*this)[index].clen < length) + { + ++index; + } + return index; +} + + + +// ### VirtualPath inline code ### + +inline +bool VirtualPath::empty() const +{ + return last_index+1 == first_index; +} + +inline +VirtualPath::size_type VirtualPath::size() const +{ + return last_index - first_index + 1; +} + +inline +PathCoord::length_type VirtualPath::length() const +{ + return path_coords.length(); +} + +inline +double VirtualPath::calculateArea() const +{ + return path_coords.calculateArea(); +} + +inline +QRectF VirtualPath::calculateExtent() const +{ + return path_coords.calculateExtent(); +} + +inline +bool VirtualPath::intersectsBox(QRectF box) const +{ + return path_coords.intersectsBox(box); +} + +inline +bool VirtualPath::isPointInside(MapCoordF coord) const +{ + return path_coords.isPointInside(coord); +} + + + +#endif diff --git a/src/dxfparser.cpp b/src/dxfparser.cpp new file mode 100644 index 0000000..188677b --- /dev/null +++ b/src/dxfparser.cpp @@ -0,0 +1,600 @@ +/* + * Copyright 2012, 2013 Jan Dalheimer + * + * This file is part of OpenOrienteering. + * + * OpenOrienteering is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenOrienteering is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenOrienteering. If not, see . + */ + +#include "dxfparser.h" + +#include +#include +#include + + +QString DXFParser::parse() +{ + Q_ASSERT(device != NULL); // Programmer's responsibility + + bool must_close_device = false; + if (!device->isOpen()) + { + if (!device->open(QIODevice::ReadOnly)) + { + return QApplication::translate("DXFParser", "Could not open the file."); + } + must_close_device = true; + } + + int code; + QString value; + + QByteArray head(device->peek(16)); + QBuffer buffer(&head); + buffer.open(QIODevice::ReadOnly); + readNextCodeValue(&buffer, code, value); + buffer.close(); + if (code != 0 || value != QLatin1String("SECTION")) + { + // File does not start with DXF section + return QApplication::translate("DXFParser", "The file is not an DXF file."); + } + + paths = QList(); + current_section = NOTHING; + QPointF bottom_right, top_left; + + /* + SECTION + ENTITIES + POLYLINE + SEQEND + ENDSEC + EOF + */ + while (readNextCodeValue(device, code, value)) + { + if (code == 0 && value == QLatin1String("ENDSEC")) + { + current_section = NOTHING; + } + else if (code == 0 && value == QLatin1String("EOF")) + { + current_section = NOTHING; + } + else if (current_section == NOTHING) + { + if (code == 0 && value == QLatin1String("SECTION")) + { + current_section = SECTION; + } + else if (value == QLatin1String("EOF")) + { + break; + } + } + else if (current_section == SECTION) + { + if (code == 2 && value == QLatin1String("ENTITIES")) + { + current_section = ENTITIES; + } + if (code == 2 && value == QLatin1String("HEADER")) + { + current_section = HEADER; + } + } + else if (current_section == ENTITIES) + { + if (code == 0 && value == QLatin1String("LINE")) + parseLine(device, &paths); + else if (code == 0 && value == QLatin1String("POLYLINE")) + { + parsePolyline(device, &paths); + current_section = POLYLINE; + } + else if (code == 0 && value == QLatin1String("LWPOLYLINE")) + parseLwPolyline(device, &paths); + else if (code == 0 && value == QLatin1String("SPLINE")) + parseSpline(device, &paths); + else if (code == 0 && value == QLatin1String("CIRCLE")) + parseCircle(device, &paths); + else if (code == 0 && value == QLatin1String("POINT")) + parsePoint(device, &paths); + else if (code == 0 && value == QLatin1String("TEXT")) + parseText(device, &paths); + else if (code == 0 && value == QLatin1String("ARC")) + parseArc(device, &paths); +#if defined(MAPPER_DEVELOPMENT_BUILD) + else if (code == 0) + qDebug() << "Unknown entity:" << value; +#endif + } + else if (current_section == HEADER) + { + if (code == 9 && value == QLatin1String("$EXTMIN")) + parseExtminmax(device, bottom_right); + else if (code == 9 && value == QLatin1String("$EXTMAX")) + parseExtminmax(device, top_left); + } + else if (current_section == POLYLINE) + { + if (code == 0 && value == QLatin1String("SEQEND")) + { + parseSeqend(device, &paths); + current_section = ENTITIES; + } + else if (code == 0 && value == QLatin1String("VERTEX")) + parseVertex(device, &paths); + } + } + + if (must_close_device) + { + device->close(); + } + + size = QRectF(top_left, bottom_right); + return QString(); +} + +inline +bool DXFParser::atEntityEnd(QIODevice* d) +{ + QByteArray data = d->peek(5); + const int linebreak = data.indexOf('\n'); + if (linebreak > 0) + data.truncate(linebreak); + return data.trimmed() == "0"; +} + +inline +bool DXFParser::readNextCodeValue(QIODevice *device, int &code, QString &value) +{ + code = device->readLine(128).trimmed().toInt(); + value = QString::fromUtf8(device->readLine(256).trimmed()); + return !device->atEnd(); +} + +inline +void DXFParser::parseCommon(int code, const QString& value, DXFPath& path) +{ + if (code == 8) + { + path.layer = value; + } + else if (code == 420) + { + QColor color; + color.setRed(value.left(2).toInt()); + color.setGreen(value.mid(2, 2).toInt()); + color.setBlue(value.right(2).toInt()); + path.color = color; + } + else if (code == 430) + { + path.color.setNamedColor(value); + } + else if (code == 440) + { + path.color.setAlpha(value.toInt()); + } +} + +void DXFParser::parseLine(QIODevice *d, QList *p) +{ + if (in_vertex) + { + vertex_main.coords = vertices; + paths.append(vertex_main); + in_vertex = false; + } + + DXFPath path(LINE); + DXFCoordinate co1; + DXFCoordinate co2; + + int code; + QString value; + while (!atEntityEnd(d) && readNextCodeValue(d, code, value)) + { + if (code == 39) + path.thickness = value.toInt(); + else if (code == 10) + co1.x = value.toDouble(); + else if (code == 20) + co1.y = value.toDouble(); + else if (code == 30 || code == 50) + co1.z = value.toDouble(); + else if (code == 11) + co2.x = value.toDouble(); + else if (code == 21) + co2.y = value.toDouble(); + else if (code == 31) + co2.z = value.toDouble(); + else + parseCommon(code, value, path); + } + + path.coords.append(co1); + path.coords.append(co2); + p->append(path); +} + +void DXFParser::parsePolyline(QIODevice *d, QList *p) +{ + Q_UNUSED(p) + + vertex_main = DXFPath(LINE); + vertices = QList(); + in_vertex = true; + + int code; + QString value; + while (!atEntityEnd(d) && readNextCodeValue(d, code, value)) + { + if (code == 39) + vertex_main.thickness = value.toInt(); + else + parseCommon(code, value, vertex_main); + } +} + +void DXFParser::parseLwPolyline(QIODevice *d, QList *p) +{ + DXFPath path(LINE); + QList coordinates; + DXFCoordinate coord; + bool have_x = false; + bool have_y = false; + + int code; + QString value; + while (!atEntityEnd(d) && readNextCodeValue(d, code, value)) + { + if (code == 39) + path.thickness = value.toInt(); + else if (code == 10) + { + coord.x = value.toDouble(); + have_x = true; + } + else if (code == 20) + { + coord.y = value.toDouble(); + have_y = true; + } + else if (code == 70) + { + path.closed = (value.toInt() & 1) == 1; + } + else + parseCommon(code, value, path); + + if (have_x && have_y) + { + coordinates.append(coord); + have_x = false; + have_y = false; + } + } + path.coords = coordinates; + p->append(path); +} + +void DXFParser::parseSpline(QIODevice* d, QList* p) +{ + DXFPath path(SPLINE); + QList coordinates; + DXFCoordinate coord; + bool have_x = false; + bool have_y = false; + + // TODO: very basic implementation assuming cubic bezier splines. + int code; + QString value; + while (!atEntityEnd(d) && readNextCodeValue(d, code, value)) + { + if (code == 71) + { + if (value != QLatin1String("3")) + { + qWarning() << "DXFParser: Splines of degree" << value << "are not supported!"; + return; + } + } + else if (code == 10) + { + coord.x = value.toDouble(); + have_x = true; + } + else if (code == 20) + { + coord.y = value.toDouble(); + have_y = true; + } + else if (code == 70) + { + path.closed = (value.toInt() & 1) == 1; + } + else + parseCommon(code, value, path); + + if (have_x && have_y) + { + coordinates.append(coord); + have_x = false; + have_y = false; + } + } + path.coords = coordinates; + p->append(path); +} + +void DXFParser::parseCircle(QIODevice *d, QList *p) +{ + if (in_vertex) + { + vertex_main.coords = vertices; + paths.append(vertex_main); + in_vertex = false; + } + + DXFPath path(CIRCLE); + DXFCoordinate co; + + int code; + QString value; + while (!atEntityEnd(d) && readNextCodeValue(d, code, value)) + { + if (code == 39) + path.thickness = value.toInt(); + else if (code == 10) + co.x = value.toDouble(); + else if (code == 20) + co.y = value.toDouble(); + else if (code == 30 || code == 50) + co.z = value.toDouble(); + else if (code == 40) + path.radius = value.toInt(); + else + parseCommon(code, value, path); + } + path.coords.append(co); + p->append(path); +} + +void DXFParser::parsePoint(QIODevice *d, QList *p) +{ + if (in_vertex) + { + vertex_main.coords = vertices; + paths.append(vertex_main); + in_vertex = false; + } + + DXFPath path(POINT); + DXFCoordinate co; + + int code; + QString value; + while (!atEntityEnd(d) && readNextCodeValue(d, code, value)) + { + if (code == 39) + path.thickness = value.toInt(); + else if (code == 10) + co.x = value.toDouble(); + else if (code == 20) + co.y = value.toDouble(); + else if (code == 30) + co.z = value.toDouble(); + else if (code == 50) + path.rotation = value.toDouble(); + else + parseCommon(code, value, path); + } + path.coords.append(co); + p->append(path); +} + +void DXFParser::parseVertex(QIODevice *d, QList *p) +{ + Q_UNUSED(p) + + DXFCoordinate co; + + int code; + QString value; + while (!atEntityEnd(d) && readNextCodeValue(d, code, value)) + { + if (code == 10) + co.x = value.toDouble(); + if (code == 20) + co.y = value.toDouble(); + if (code == 30 || code == 50) + co.z = value.toDouble(); + } + vertices.append(co); +} + +void DXFParser::parseSeqend(QIODevice *d, QList *p) +{ + if (in_vertex) + { + vertex_main.coords = vertices; + p->append(vertex_main); + in_vertex = false; + } + + int code; + QString value; + while (!atEntityEnd(d) && readNextCodeValue(d, code, value)) + { + ; // nothing + } +} + +void DXFParser::parseText(QIODevice *d, QList *p) +{ + if (in_vertex) + { + vertex_main.coords = vertices; + paths.append(vertex_main); + in_vertex = false; + } + + DXFPath path(TEXT); + path.color = Qt::red; + path.text = QString::fromLatin1(""); + DXFCoordinate co; + int alignment = 0; + int valignment = 0; + + int code; + QString value; + while (!atEntityEnd(d) && readNextCodeValue(d, code, value)) + { + if (code == 39) + path.thickness = value.toInt(); + else if (code == 10) + co.x = value.toDouble(); + else if (code == 20) + co.y = value.toDouble(); + else if (code == 30) + co.z = value.toDouble(); + else if (code == 50) + path.rotation = value.toDouble(); + else if (code == 1) + path.text = path.text.insert(path.text.indexOf(QLatin1Char('>'))+1, value); + else if (code == 7) + path.text = path.text.arg(QLatin1String("font-family:") + value + QLatin1String(";%1")); + else if (code == 40) + path.font.setPointSizeF(value.toDouble()); + else if (code == 72) + alignment = value.toInt(); + else if (code == 73) + valignment = value.toInt(); + else + parseCommon(code, value, path); + } + + if (path.color != QColor(127,127,127)) + { + path.text = path.text.arg(QLatin1String("color:") + path.color.name() + QLatin1String(";%1")); + } + if (!path.text.contains(QLatin1String("color"))) + { + path.text = path.text.arg(QString::fromLatin1("color:red")); + } + switch(alignment) + { + case 0: + path.text = path.text.arg(QString::fromLatin1("text-align:left;%1")); + break; + case 1: + path.text = path.text.arg(QString::fromLatin1("text-align:center;%1")); + break; + case 2: + path.text = path.text.arg(QString::fromLatin1("text-align:right;%1")); + break; + } + switch(valignment) + { + case 0: + path.text = path.text.arg(QString::fromLatin1("text-align:baseline;%1")); + break; + case 1: + path.text = path.text.arg(QString::fromLatin1("text-align:bottom;%1")); + break; + case 2: + path.text = path.text.arg(QString::fromLatin1("text-align:middle;%1")); + break; + case 3: + path.text = path.text.arg(QString::fromLatin1("text-align:top;%1")); + } + + path.text = path.text.arg(QString{}); + //qDebug() << path.text; + path.coords.append(co); + p->append(path); +} + +void DXFParser::parseArc(QIODevice *d, QList *p) +{ + if (in_vertex) + { + vertex_main.coords = vertices; + paths.append(vertex_main); + in_vertex = false; + } + + DXFPath path(ARC); + DXFCoordinate co; + + int code; + QString value; + while (!atEntityEnd(d) && readNextCodeValue(d, code, value)) + { + if (code == 39) + path.thickness = value.toInt(); + else if (code == 10) + co.x = value.toDouble(); + else if (code == 20) + co.y = value.toDouble(); + else if (code == 30) + co.z = value.toDouble(); + else if (code == 40) + path.radius = value.toDouble(); + else if (code == 50) + path.start_angle = value.toDouble(); + else if (code == 51) + path.end_angle = value.toDouble(); + else + parseCommon(code, value, path); + } + //qDebug() << "start: " << path.startAngle <<" stop "<< path.endAngle << " radius " << path.radius; + path.coords.append(co); + p->append(path); +} + +void DXFParser::parseExtminmax(QIODevice *d, QPointF &point) +{ + int code; + QString value; + while (!atEntityEnd(d) && readNextCodeValue(d, code, value)) + { + if (code == 10) + point.setX(value.toDouble()); + if (code == 20) + point.setY(value.toDouble()); + } +} + +void DXFParser::parseUnknown(QIODevice *d) +{ + if (in_vertex) + { + vertex_main.coords = vertices; + paths.append(vertex_main); + in_vertex = false; + } + + int code; + QString value; + while (!atEntityEnd(d) && readNextCodeValue(d, code, value)) + { + ; // nothing + } +} diff --git a/src/dxfparser.h b/src/dxfparser.h new file mode 100644 index 0000000..9019cda --- /dev/null +++ b/src/dxfparser.h @@ -0,0 +1,151 @@ +/* + * Copyright 2012, 2013 Jan Dalheimer + * + * This file is part of OpenOrienteering. + * + * OpenOrienteering is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenOrienteering is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenOrienteering. If not, see . + */ + + +#ifndef _OPENORIENTEERING_DXFPARSER_H_ +#define _OPENORIENTEERING_DXFPARSER_H_ + +#include +#include +#include +#include +#include +#include + +struct DXFCoordinate +{ + DXFCoordinate(); + + qreal x; + qreal y; + qreal z; +}; + +enum type_e +{ + CIRCLE, LINE, SPLINE, POINT, TEXT, ARC, UNKNOWN +}; + +/** Path generated by DXFParser. */ +class DXFPath +{ +public: + DXFPath(type_e type); + + QList coords; + QString layer; + QColor color; + qreal thickness; + qreal radius; + type_e type; + qreal rotation; + QFont font; + QString text; + qreal start_angle; + qreal end_angle; + bool closed; +}; + + +/** + * Parses DXF input data into lists of path_t. + * + * TODO: Should be reviewed. + */ +class DXFParser +{ +public: + DXFParser(); + void setData(QIODevice *data) { device = data; in_vertex = false; } + QString parse(); + QList getData() { return paths; } + QRectF getSize() { return size; } + +private: + QIODevice* device; + QList paths; + + QList vertices; + DXFPath vertex_main; + bool in_vertex; + + QRectF size; + + int current_section; + + bool readNextCodeValue(QIODevice* device, int& code, QString& value); + + void parseCommon(int code, const QString& value, DXFPath& path); + + void parseLine(QIODevice *d, QList *p); + void parsePolyline(QIODevice *d, QList *p); + void parseLwPolyline(QIODevice* d, QList *p); + void parseSpline(QIODevice* d, QList *p); + void parseCircle(QIODevice *d, QList *p); + void parsePoint(QIODevice *d, QList *p); + void parseVertex(QIODevice *d, QList *p); + void parseSeqend(QIODevice *d, QList *p); + void parseText(QIODevice *d, QList *p); + void parseArc(QIODevice *d, QList *p); + void parseExtminmax(QIODevice *d, QPointF &p); + void parseUnknown(QIODevice *d); + + bool atEntityEnd(QIODevice *d); + + enum{ + HEADER, ENTITIES, SECTION, NOTHING, POLYLINE + }; +}; + + +// ### Public inline code ### + +inline +DXFCoordinate::DXFCoordinate() + : x(0.0), + y(0.0), + z(0.0) +{ + ; // nothing +} + +inline +DXFPath::DXFPath(type_e type) + : layer(QLatin1Char('1')), + color(127,127,127), + thickness(0), + radius(0), + type(type), + rotation(0.0), + start_angle(0.0), + end_angle(0.0), + closed(false) +{ + ; // nothing +} + +inline +DXFParser::DXFParser() + : device(0), + vertex_main(UNKNOWN) +{ + ; // nothing +} + +#endif diff --git a/src/file_format.cpp b/src/file_format.cpp new file mode 100644 index 0000000..0cec7dd --- /dev/null +++ b/src/file_format.cpp @@ -0,0 +1,88 @@ +/* + * Copyright 2012, 2013 Pete Curtis + * + * This file is part of OpenOrienteering. + * + * OpenOrienteering is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenOrienteering is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenOrienteering. If not, see . + */ + +#include "file_format.h" + +#include + + +// ### FileFormatException ### + +// virtual +FileFormatException::~FileFormatException() noexcept +{ + // Nothing, not inlined +} + +// virtual +const char* FileFormatException::what() const noexcept +{ + return msg_c.constData(); +} + + + +// ### FileFormat ### + +FileFormat::FileFormat(FileFormat::FileType file_type, const char* id, const QString& description, const QString& file_extension, FileFormat::FormatFeatures features) + : file_type(file_type), + format_id(id), + format_description(description), + format_features(features) +{ + Q_ASSERT(file_type != 0); + Q_ASSERT(qstrlen(id) > 0); + Q_ASSERT(!description.isEmpty()); + if (!file_extension.isEmpty()) + addExtension(file_extension); +} + +FileFormat::~FileFormat() +{ + // Nothing +} + +void FileFormat::addExtension(const QString& file_extension) +{ + file_extensions << file_extension; + format_filter = QString::fromLatin1("%1 (*.%2)").arg(format_description, file_extensions.join(QString::fromLatin1(" *."))); +} + +bool FileFormat::understands(const unsigned char *buffer, size_t sz) const +{ + Q_UNUSED(buffer); + Q_UNUSED(sz); + return false; +} + +Importer *FileFormat::createImporter(QIODevice* stream, Map *map, MapView *view) const +{ + Q_UNUSED(stream); + Q_UNUSED(map); + Q_UNUSED(view); + throw FileFormatException(QCoreApplication::translate("Importer", "Format (%1) does not support import").arg(description())); +} + +Exporter *FileFormat::createExporter(QIODevice* stream, Map *map, MapView *view) const +{ + Q_UNUSED(stream); + Q_UNUSED(map); + Q_UNUSED(view); + throw FileFormatException(QCoreApplication::translate("Exporter", "Format (%1) does not support export").arg(description())); +} diff --git a/src/file_format.h b/src/file_format.h new file mode 100644 index 0000000..27c236d --- /dev/null +++ b/src/file_format.h @@ -0,0 +1,321 @@ +/* + * Copyright 2012, 2013 Pete Curtis + * + * This file is part of OpenOrienteering. + * + * OpenOrienteering is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenOrienteering is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenOrienteering. If not, see . + */ + +#ifndef _OPENORIENTEERING_FILE_FORMAT_H +#define _OPENORIENTEERING_FILE_FORMAT_H + +#include + +#include +#include + +class QIODevice; + +class Exporter; +class Importer; +class Map; +class MapView; + +/** An exception type thrown by an importer or exporter if it encounters a fatal error. + */ +class FileFormatException : public std::exception +{ +public: + /** Creates a new exception with the given message + * \param message a text describing the exceptional event that has occurred. + */ + FileFormatException(const QString& message = QString()); + + /** Creates a new exception with the given message + * \param message a text describing the exceptional event that has occurred. + */ + FileFormatException(const char* message); + + /** Copy-constructor (C++ FAQ 17.17). + */ + FileFormatException(const FileFormatException& other) noexcept; + + /** Destroys the exception object. + */ + virtual ~FileFormatException() noexcept; + + /** Returns the message as a QString. + */ + const QString& message() const noexcept; + + /** Returns the message as a C string. + */ + virtual const char* what() const noexcept; + +private: + QString const msg; + QByteArray const msg_c; +}; + + +/** Describes a file format understood by this application. Each file format has an ID + * (an internal, non-translated string); a description (translated); a file extension + * (non-translated); and methods to indicate their support for import or export. Formats + * are installed into a FormatRegistry, and can be looked up in a variety of ways. + * + * A typical FileFormat subclass will look like this: + * + * \code + * class MyCustomFileFormat : public FileFormat { + * public: + * MyCustomFileFormat : FileFormat("custom", ImportExport::tr("Custom file"), "custom", true, true) { + * } + * + * Importer *createImporter(QIODevice* stream, Map *map, MapView *view) const { + * return new CustomImporter(stream, map, view); + * } + * + * Exporter *createExporter(QIODevice* stream, Map *map, MapView *view) const { + * return new CustomExporter(stream, map, view); + * } + * } + * \endcode + */ +class FileFormat +{ +public: + /** File type enumeration. + * + * Each file type shall use a distinct bit so that they may be OR-combined. + * + * Currently the program is only used for mapping, and "Map" is the only + * element. "Course" or "Event" are possible additions. + */ + enum FileType + { + MapFile = 0x01, + OgrFile = 0x02, ///< Geospatial vector data supported by OGR + + AllFiles = MapFile, ///< All types which can be handled by an editor. + + EndOfFileTypes + }; + + /** A type which handles OR-combinations of file types. + */ + Q_DECLARE_FLAGS(FileTypes, FileType) + + /** File format features. + * + * Each feature shall use a distinct bit so that they may be OR-combined. + */ + enum FormatFeatureFlag + { + ImportSupported = 0x01, + ExportSupported = 0x02, + ExportLossy = 0x04, + + EndOfFormatFeatures + }; + + /** A type which handles OR-combinations of format implementation features. + */ + Q_DECLARE_FLAGS(FormatFeatures, FormatFeatureFlag) + + /** Creates a new file format with the given parameters. + * + * Don't use a leading dot on the file extension. + * + */ + FileFormat(FileType file_type, const char* id, const QString& description, const QString& file_extension, FormatFeatures features); + + /** Destroys the file format information. */ + virtual ~FileFormat(); + + /** Registers an alternative file name extension. + * It is used by the filter. + */ + void addExtension(const QString& file_extension); + + /** Returns the type of file. + */ + FileType fileType() const; + + /** Returns the internal ID of the file format. + */ + const char* id() const; + + /** Returns a short human-readable description of the file format. + */ + const QString& description() const; + + /** Returns the primary file name extension used by this file format. + * + * This shall only be used for constructing new file names. Otherwise + * you will probably need to use fileExtensions(). + */ + const QString& primaryExtension() const; + + /** Returns all file name extension supported by this file format. + */ + const QStringList& fileExtensions() const; + + /** Returns the filter that represents this format in file dialogs. + */ + const QString& filter() const; + + /** Returns true if this file format supports importing a map from its associated file type. + */ + bool supportsImport() const; + + /** Returns true if this file format supports exporting a map to its associated file type. + */ + bool supportsExport() const; + + /** Returns true if an exporter for this file format is potentially lossy, i.e., if the exported + * file cannot fully represent all aspects of the internal OO map objects. This flag is used by + * the application to warn the user before saving to a lossy file type. + */ + bool isExportLossy() const; + + /** Returns true if this file format believes it is capable of understanding a file that + * starts with the given byte sequence. "Magic" numbers and version information is commonly + * placed at the beginning of a file, and this method is used by the application to pre-screen + * for a suitable Importer. If there is any doubt about whether the file format can successfully + * process a file, this method should return false. + */ + virtual bool understands(const unsigned char *buffer, size_t sz) const; + + /** Creates an Importer that will read a map file from the given stream into the given map and view. + * The caller can then call doImport() in the returned object to start the import process. The caller + * is responsible for deleting the Importer when it's finished. + * + * If the Importer could not be created, then this method should throw a FormatException. + */ + virtual Importer* createImporter(QIODevice* stream, Map *map, MapView *view) const; + + /** Creates an Exporter that will save the given map and view into the given stream. + * The caller can then call doExport() in the returned object to start the export process. The caller + * is responsible for deleting the Exporter when it's finished. + * + * If the Exporter could not be created, then this method should throw a FormatException. + */ + virtual Exporter *createExporter(QIODevice* stream, Map *map, MapView *view) const; + +private: + FileType file_type; + const char* format_id; + QString format_description; + QStringList file_extensions; + QString format_filter; + FormatFeatures format_features; +}; + + +// ### FileFormatException inline and header code ### + +inline +FileFormatException::FileFormatException(const QString& message) + : msg(message) + , msg_c(message.toLocal8Bit()) +{ + // Nothing +} + +inline +FileFormatException::FileFormatException(const char* message) + : msg(QString::fromLatin1(message)) + , msg_c(message) +{ + // Nothing +} + +inline +FileFormatException::FileFormatException(const FileFormatException& other) noexcept + : msg(other.msg) + , msg_c(other.msg_c) +{ + // Nothing +} + +inline +const QString& FileFormatException::message() const noexcept +{ + return msg; +} + + +// ### FileFormat inline and header code ### + +Q_DECLARE_OPERATORS_FOR_FLAGS(FileFormat::FileTypes) + +Q_DECLARE_OPERATORS_FOR_FLAGS(FileFormat::FormatFeatures) + +inline +FileFormat::FileType FileFormat::fileType() const +{ + return file_type; +} + +inline +const char* FileFormat::id() const +{ + return format_id; +} + +inline +const QString& FileFormat::description() const +{ + return format_description; +} + +inline +const QString& FileFormat::primaryExtension() const +{ + Q_ASSERT(file_extensions.size() > 0); // by constructor + return file_extensions[0]; +} + +inline +const QStringList& FileFormat::fileExtensions() const +{ + return file_extensions; +} + +inline +const QString& FileFormat::filter() const +{ + return format_filter; +} + +inline +bool FileFormat::supportsImport() const +{ + return format_features.testFlag(FileFormat::ImportSupported); +} + +inline +bool FileFormat::supportsExport() const +{ + return format_features.testFlag(FileFormat::ExportSupported); +} + +inline +bool FileFormat::isExportLossy() const +{ + return format_features.testFlag(FileFormat::ExportLossy); +} + + +#endif // _OPENORIENTEERING_FILE_FORMAT_H diff --git a/src/file_format_native.cpp b/src/file_format_native.cpp new file mode 100644 index 0000000..ef64cc9 --- /dev/null +++ b/src/file_format_native.cpp @@ -0,0 +1,424 @@ +/* + * Copyright 2012 Pete Curtis + * Copyright 2012, 2013 Thomas Schöps + * Copyright 2012-2015 Kai Pastor + * + * This file is part of OpenOrienteering. + * + * OpenOrienteering is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenOrienteering is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenOrienteering. If not, see . + */ + +#include "file_format_native.h" + +#include +#include + +#include "core/georeferencing.h" +#include "core/map_color.h" +#include "core/map_grid.h" +#include "core/map_printer.h" +#include "core/map_view.h" +#include "file_import_export.h" +#include "map.h" +#include "symbol.h" +#include "template.h" +#include "template_image.h" +#include "undo_manager.h" +#include "util.h" + + +// ### NativeFileImport declaration ### + +/** An Importer for the native file format. This class delegates to the load() and loadImpl() methods of the + * model objects, but long-term this can be refactored out of the model into this class. + * + * \deprecated + */ +class NativeFileImport : public Importer +{ +public: + /** Creates a new native file importer. + */ + NativeFileImport(QIODevice* stream, Map *map, MapView *view); + + /** Destroys this importer. + */ + ~NativeFileImport(); + +protected: + /** Imports a native file. + */ + void import(bool load_symbols_only); +}; + + +// ### GPSProjectionParameters ### +/** + * Legacy parameters for an ellipsoid and an orthographic projection of + * ellipsoid coordinates to 2D map (template) coordinates. + */ +struct GPSProjectionParameters +{ + double a; // ellipsoidal semi-major axis + double b; // ellipsoidal semi-minor axis + double e_sq; // eccentricity of the ellipsoid (squared) + double center_latitude; // latitude which gives map coordinate zero + double center_longitude; // longitude which gives map coordinate zero + double sin_center_latitude; // sine of center_latitude + double cos_center_latitude; // cosine of center_latitude + double v0; // prime vertical radius of curvature at latitude of origin center_latitude +}; + + + +// ### NativeFileFormat ### + +const int NativeFileFormat::least_supported_file_format_version = 0; +const int NativeFileFormat::current_file_format_version = 30; +const char NativeFileFormat::magic_bytes[4] = {0x4F, 0x4D, 0x41, 0x50}; // "OMAP" + +NativeFileFormat::NativeFileFormat() + : FileFormat(FileFormat::MapFile, "native (deprecated)", ImportExport::tr("OpenOrienteering Mapper").append(QLatin1String(" pre-0.5")), QString::fromLatin1("omap"), + FileFormat::ImportSupported) +{ + // Nothing +} + +bool NativeFileFormat::understands(const unsigned char *buffer, size_t sz) const +{ + // The first four bytes of the file must be 'OMAP'. + return (sz >= 4 && memcmp(buffer, magic_bytes, 4) == 0); +} + +Importer *NativeFileFormat::createImporter(QIODevice* stream, Map* map, MapView* view) const +{ + return new NativeFileImport(stream, map, view); +} + + + +// ### NativeFileImport ### + +NativeFileImport::NativeFileImport(QIODevice* stream, Map *map, MapView *view) : Importer(stream, map, view) +{ +} + +NativeFileImport::~NativeFileImport() +{ +} + +void NativeFileImport::import(bool load_symbols_only) +{ + addWarning(Importer::tr("This file uses an obsolete format. " + "Support for this format is to be removed from this program soon. " + "To be able to open the file in the future, save it again.")); + + MapCoord::boundsOffset().reset(true); + + char buffer[4]; + stream->read(buffer, 4); // read the magic + + int version; + stream->read((char*)&version, sizeof(int)); + if (version < 0) + { + addWarning(Importer::tr("Invalid file format version.")); + } + else if (version < NativeFileFormat::least_supported_file_format_version) + { + throw FileFormatException(Importer::tr("Unsupported old file format version. Please use an older program version to load and update the file.")); + } + else if (version > NativeFileFormat::current_file_format_version) + { + throw FileFormatException(Importer::tr("Unsupported new file format version. Some map features will not be loaded or saved by this version of the program. Consider updating.")); + } + + if (version <= 16) + { + Georeferencing georef; + stream->read((char*)&georef.scale_denominator, sizeof(int)); + + if (version >= 15) + loadString(stream, map->map_notes); + + bool gps_projection_params_set; // obsolete + stream->read((char*)&gps_projection_params_set, sizeof(bool)); + GPSProjectionParameters gps_projection_parameters; // obsolete + stream->read((char*)&gps_projection_parameters, sizeof(GPSProjectionParameters)); + if (gps_projection_params_set) + { + LatLon ref_point = LatLon::fromRadiant(gps_projection_parameters.center_latitude, gps_projection_parameters.center_longitude); + georef.setGeographicRefPoint(ref_point); + } + *map->georeferencing = georef; + } + else if (version >= 17) + { + loadString(stream, map->map_notes); + + Georeferencing georef; + stream->read((char*)&georef.scale_denominator, sizeof(int)); + double value; + if (version >= 18) + { + stream->read((char*)&value, sizeof(double)); + georef.declination = Georeferencing::roundDeclination(value); + } + stream->read((char*)&value, sizeof(double)); + georef.grivation = Georeferencing::roundDeclination(value); + georef.grivation_error = value - georef.grivation; + + double x,y; + stream->read((char*)&x, sizeof(double)); + stream->read((char*)&y, sizeof(double)); + georef.map_ref_point = MapCoord(x,y); + stream->read((char*)&x, sizeof(double)); + stream->read((char*)&y, sizeof(double)); + georef.projected_ref_point = QPointF(x,y); + loadString(stream, georef.projected_crs_id); + loadString(stream, georef.projected_crs_spec); + stream->read((char*)&y, sizeof(double)); + stream->read((char*)&x, sizeof(double)); + georef.geographic_ref_point = LatLon::fromRadiant(y, x); + QString geographic_crs_id, geographic_crs_spec; + loadString(stream, geographic_crs_id); // reserved for geographic crs id + loadString(stream, geographic_crs_spec); // reserved for full geographic crs specification + if (geographic_crs_spec != Georeferencing::geographic_crs_spec) + { + addWarning( + Importer::tr("The geographic coordinate reference system of the map was \"%1\". This CRS is not supported. Using \"%2\"."). + arg(geographic_crs_spec). + arg(Georeferencing::geographic_crs_spec) + ); + } + if (version <= 17) + georef.initDeclination(); + // Correctly set georeferencing state + georef.setProjectedCRS(georef.projected_crs_id, georef.projected_crs_spec); + *map->georeferencing = georef; + } + + if (version >= 24) + map->setGrid(MapGrid().load(stream, version)); + + map->renderable_options = Symbol::RenderNormal; + if (version >= 25) + { + bool area_hatching_enabled, baseline_view_enabled; + stream->read((char*)&area_hatching_enabled, sizeof(bool)); + stream->read((char*)&baseline_view_enabled, sizeof(bool)); + if (area_hatching_enabled) + map->renderable_options |= Symbol::RenderAreasHatched; + if (baseline_view_enabled) + map->renderable_options |= Symbol::RenderBaselines; + } + + if (version >= 6) + { + bool print_params_set; + stream->read((char*)&print_params_set, sizeof(bool)); + if (print_params_set) + { + MapPrinterConfig printer_config(*map); + stream->read((char*)&printer_config.page_format.orientation, sizeof(int)); + stream->read((char*)&printer_config.page_format.paper_size, sizeof(int)); + + float resolution; + stream->read((char*)&resolution, sizeof(float)); + printer_config.options.resolution = qRound(resolution); + stream->read((char*)&printer_config.options.show_templates, sizeof(bool)); + if (version >= 24) + stream->read((char*)&printer_config.options.show_grid, sizeof(bool)); + else + printer_config.options.show_grid = false; + + stream->read((char*)&printer_config.center_print_area, sizeof(bool)); + + float print_area_left, print_area_top, print_area_width, print_area_height; + stream->read((char*)&print_area_left, sizeof(float)); + stream->read((char*)&print_area_top, sizeof(float)); + stream->read((char*)&print_area_width, sizeof(float)); + stream->read((char*)&print_area_height, sizeof(float)); + printer_config.print_area = QRectF(print_area_left, print_area_top, print_area_width, print_area_height); + + if (version >= 26) + { + bool print_different_scale_enabled; + stream->read((char*)&print_different_scale_enabled, sizeof(bool)); + stream->read((char*)&printer_config.options.scale, sizeof(int)); + if (!print_different_scale_enabled) + printer_config.options.scale = map->getScaleDenominator(); + } + map->setPrinterConfig(printer_config); + } + } + + if (version >= 16) + { + stream->read((char*)&map->image_template_use_meters_per_pixel, sizeof(bool)); + stream->read((char*)&map->image_template_meters_per_pixel, sizeof(double)); + stream->read((char*)&map->image_template_dpi, sizeof(double)); + stream->read((char*)&map->image_template_scale, sizeof(double)); + } + + // Load colors + int num_colors; + stream->read((char*)&num_colors, sizeof(int)); + map->color_set->colors.resize(num_colors); + + for (int i = 0; i < num_colors; ++i) + { + int priority; + stream->read((char*)&priority, sizeof(int)); + MapColor* color = new MapColor(priority); + + MapColorCmyk cmyk; + stream->read((char*)&cmyk.c, sizeof(float)); + stream->read((char*)&cmyk.m, sizeof(float)); + stream->read((char*)&cmyk.y, sizeof(float)); + stream->read((char*)&cmyk.k, sizeof(float)); + color->setCmyk(cmyk); + float opacity; + stream->read((char*)&opacity, sizeof(float)); + color->setOpacity(opacity); + + QString name; + loadString(stream, name); + color->setName(name); + + map->color_set->colors[i] = color; + } + + // Load symbols + int num_symbols; + stream->read((char*)&num_symbols, sizeof(int)); + map->symbols.resize(num_symbols); + + for (int i = 0; i < num_symbols; ++i) + { + QScopedValueRollback offset { MapCoord::boundsOffset() }; + MapCoord::boundsOffset().reset(false); + + int symbol_type; + stream->read((char*)&symbol_type, sizeof(int)); + + Symbol* symbol = Symbol::getSymbolForType(static_cast(symbol_type)); + if (!symbol) + { + throw FileFormatException(Importer::tr("Error while loading a symbol with type %2.").arg(symbol_type)); + } + + if (!symbol->load(stream, version, map)) + { + throw FileFormatException(Importer::tr("Error while loading a symbol.")); + } + map->symbols[i] = symbol; + } + + if (!load_symbols_only) + { + // Load templates + stream->read((char*)&map->first_front_template, sizeof(int)); + + int num_templates; + stream->read((char*)&num_templates, sizeof(int)); + map->templates.resize(num_templates); + + for (int i = 0; i < num_templates; ++i) + { + QString path; + loadString(stream, path); + auto temp = Template::templateForFile(path, map); + if (!temp) + temp.reset(new TemplateImage(path, map)); // fallback + + if (version >= 27) + { + loadString(stream, path); + temp->setTemplateRelativePath(path); + } + + temp->loadTemplateConfiguration(stream, version); + + map->templates[i] = temp.release(); + } + + if (version >= 28) + { + int num_closed_templates; + stream->read((char*)&num_closed_templates, sizeof(int)); + map->closed_templates.resize(num_closed_templates); + + for (int i = 0; i < num_closed_templates; ++i) + { + QString path; + loadString(stream, path); + auto temp = Template::templateForFile(path, map); + if (!temp) + temp.reset(new TemplateImage(path, map)); // fallback + + loadString(stream, path); + temp->setTemplateRelativePath(path); + + temp->loadTemplateConfiguration(stream, version); + + map->closed_templates[i] = temp.release(); + } + } + + // Restore widgets and views + if (view) + { + view->load(stream, version); + } + else + { + MapView tmp{ map }; + tmp.load(stream, version); + } + + // Load undo steps + if (version >= 7) + { + if (!map->undoManager().load(stream, version)) + { + throw FileFormatException(Importer::tr("Error while loading undo steps.")); + } + } + + // Load parts + stream->read((char*)&map->current_part_index, sizeof(int)); + + int num_parts; + if (stream->read((char*)&num_parts, sizeof(int)) < (int)sizeof(int)) + { + throw FileFormatException(Importer::tr("Error while reading map part count.")); + } + delete map->parts[0]; + map->parts.resize(num_parts); + + for (int i = 0; i < num_parts; ++i) + { + MapPart* part = new MapPart({}, map); + if (!part->load(stream, version, map)) + { + throw FileFormatException(Importer::tr("Error while loading map part %2.").arg(i+1)); + } + map->parts[i] = part; + } + } + + emit map->currentMapPartIndexChanged(map->current_part_index); + emit map->currentMapPartChanged(map->getPart(map->current_part_index)); +} diff --git a/src/file_format_native.h b/src/file_format_native.h new file mode 100644 index 0000000..1316372 --- /dev/null +++ b/src/file_format_native.h @@ -0,0 +1,69 @@ +/* + * Copyright 2012, 2013 Thomas Schöps, Pete Curtis + * + * This file is part of OpenOrienteering. + * + * OpenOrienteering is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenOrienteering is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenOrienteering. If not, see . + */ + +#ifndef NATIVE_FILE_FORMAT_H +#define NATIVE_FILE_FORMAT_H + +#ifndef NO_NATIVE_FILE_FORMAT + +#include "file_format.h" + +/** Provides a description of the old native file format. + * This is an (architecture-dependent) binary packed format + * with a file extension of "omap", and internal versioning. + * + * \deprecated + */ +class NativeFileFormat : public FileFormat +{ +public: + /** Creates a new file format representing the native type. + */ + NativeFileFormat(); + + /** Returns true if the file starts with the magic byte sequence "OMAP" (0x4f 0x4d 0x41 0x50). + */ + bool understands(const unsigned char *buffer, size_t sz) const; + + /** Creates an importer for this file type. + */ + Importer *createImporter(QIODevice* stream, Map *map, MapView *view) const; + +#ifdef MAPPER_ENABLE_NATIVE_EXPORTER + /** Creates an exporter for this file type. + */ + Exporter *createExporter(QIODevice* stream, Map *map, MapView *view) const; +#endif + + /** Constant describing the earliest OMAP version supported by this file format. + */ + static const int least_supported_file_format_version; + + /** Constant describing the current OMAP version used by this file format for saving. + */ + static const int current_file_format_version; + + /** The file magic: "OMAP" + */ + static const char magic_bytes[4]; +}; + +#endif // NO_NATIVE_FILE_FORMAT + +#endif // NATIVE_FILE_FORMAT_H diff --git a/src/file_format_ocad8.cpp b/src/file_format_ocad8.cpp new file mode 100644 index 0000000..954fd41 --- /dev/null +++ b/src/file_format_ocad8.cpp @@ -0,0 +1,2722 @@ +/* + * Copyright 2012, 2013 Pete Curtis + * Copyright 2013-2016 Kai Pastor + * + * This file is part of OpenOrienteering. + * + * OpenOrienteering is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenOrienteering is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenOrienteering. If not, see . + */ + +#include "file_format_ocad8.h" +#include "file_format_ocad8_p.h" + +#include +#include +#include +#include +#include +#include +#include + +#include "core/georeferencing.h" +#include "core/map_color.h" +#include "core/map_coord.h" +#include "core/map_view.h" +#include "file_format_xml.h" +#include "file_import_export.h" +#include "map.h" +#include "map_part.h" +#include "object.h" +#include "object_text.h" +#include "settings.h" +#include "symbol.h" +#include "symbol_area.h" +#include "symbol_combined.h" +#include "symbol_line.h" +#include "symbol_point.h" +#include "symbol_text.h" +#include "template.h" +#include "template_image.h" +#include "template_map.h" +#include "util.h" +#include "util/encoding.h" + +// ### OCAD8FileFormat ### + +OCAD8FileFormat::OCAD8FileFormat() + : FileFormat(MapFile, "OCAD78", ImportExport::tr("OCAD Versions 7, 8"), QString::fromLatin1("ocd"), + ImportSupported | ExportSupported | ExportLossy) +{ + // Nothing +} + +bool OCAD8FileFormat::understands(const unsigned char* buffer, size_t sz) const +{ + // The first two bytes of the file must be AD 0C. + if (sz >= 2 && buffer[0] == 0xAD && buffer[1] == 0x0C) return true; + return false; +} + +Importer* OCAD8FileFormat::createImporter(QIODevice* stream, Map *map, MapView *view) const +{ + return new OCAD8FileImport(stream, map, view); +} + +Exporter* OCAD8FileFormat::createExporter(QIODevice* stream, Map* map, MapView* view) const +{ + return new OCAD8FileExport(stream, map, view); +} + +// ### OCAD8FileImport ### + +OCAD8FileImport::OCAD8FileImport(QIODevice* stream, Map* map, MapView* view) : Importer(stream, map, view), file(NULL) +{ + ocad_init(); + const QByteArray enc_name = Settings::getInstance().getSetting(Settings::General_Local8BitEncoding).toByteArray(); + encoding_1byte = Util::codecForName(enc_name); + if (!encoding_1byte) encoding_1byte = QTextCodec::codecForLocale(); + encoding_2byte = QTextCodec::codecForName("UTF-16LE"); + offset_x = offset_y = 0; +} + +OCAD8FileImport::~OCAD8FileImport() +{ + ocad_shutdown(); +} + +bool OCAD8FileImport::isRasterImageFile(const QString &filename) +{ + int dot_pos = filename.lastIndexOf(QLatin1Char('.')); + if (dot_pos < 0) + return false; + QString extension = filename.right(filename.length() - dot_pos - 1).toLower(); + return QImageReader::supportedImageFormats().contains(extension.toLatin1()); +} + +void OCAD8FileImport::import(bool load_symbols_only) +{ + //qint64 start = QDateTime::currentMSecsSinceEpoch(); + + u32 size = stream->bytesAvailable(); + u8* buffer = (u8*)malloc(size); + if (!buffer) + throw FileFormatException(tr("Could not allocate buffer.")); + if (stream->read((char*)buffer, size) != size) + throw FileFormatException(Importer::tr("Could not read file: %1").arg(stream->errorString())); + int err = ocad_file_open_memory(&file, buffer, size); + if (err != 0) throw FileFormatException(Importer::tr("Could not read file: %1").arg(tr("libocad returned %1").arg(err))); + + if (file->header->major <= 5 || file->header->major >= 9) + throw FileFormatException(Importer::tr("Could not read file: %1").arg(tr("OCAD files of version %1 are not supported!").arg(file->header->major))); + + //qDebug() << "file version is" << file->header->major << ", type is" + // << ((file->header->ftype == 2) ? "normal" : "other"); + //qDebug() << "map scale is" << file->setup->scale; + + // Scale and georeferencing parameters + Georeferencing georef; + georef.setScaleDenominator(file->setup->scale); + georef.setProjectedRefPoint(QPointF(file->setup->offsetx, file->setup->offsety)); + if (qAbs(file->setup->angle) >= 0.01) /* degrees */ + { + georef.setGrivation(file->setup->angle); + } + map->setGeoreferencing(georef); + + map->setMapNotes(convertCString((const char*)file->buffer + file->header->infopos, file->header->infosize, false)); + + // TODO: print parameters + + // Load the separations to a temporary stack + std::vector< MapColor* > separations; + int num_separations = ocad_separation_count(file); +#if 1 + addWarning(tr("%n color separation(s) were skipped, reason: Import disabled.", "", num_separations)); + num_separations = 0; +#endif + if (num_separations < 0) + { + addWarning(tr("Could not load the spot color definitions, error: %1").arg(num_separations)); + num_separations = 0; + } + separations.reserve(num_separations); + for (int i = 0; i < num_separations; i++) + { + const OCADColorSeparation *ocad_separation = ocad_separation_at(file, i); + MapColor* color = new MapColor(convertPascalString(ocad_separation->sep_name), MapColor::Reserved); + color->setSpotColorName(convertPascalString(ocad_separation->sep_name).toUpper()); + // OCD stores CMYK values as integers from 0-200. + const MapColorCmyk cmyk( + 0.005f * ocad_separation->cyan, + 0.005f * ocad_separation->magenta, + 0.005f * ocad_separation->yellow, + 0.005f * ocad_separation->black ); + color->setCmyk(cmyk); + color->setOpacity(1.0f); + separations.push_back(color); + } + + // Load colors + int num_colors = ocad_color_count(file); + for (int i = 0; i < num_colors; i++) + { + OCADColor *ocad_color = ocad_color_at(file, i); + MapColor* color = new MapColor(convertPascalString(ocad_color->name), map->color_set->colors.size()); + // OCD stores CMYK values as integers from 0-200. + MapColorCmyk cmyk( + 0.005f * ocad_color->cyan, + 0.005f * ocad_color->magenta, + 0.005f * ocad_color->yellow, + 0.005f * ocad_color->black ); + color->setCmyk(cmyk); + color->setOpacity(1.0f); + + SpotColorComponents components; + for (int j = 0; j < num_separations; ++j) + { + const u8& ocad_halftone = ocad_color->spot[j]; + if (ocad_halftone <= 200) + { + float halftone = 0.005f * ocad_halftone; + components.push_back(SpotColorComponent(separations[j], halftone)); + } + } + if (!components.empty()) + { + color->setSpotColorComposition(components); + const MapColorCmyk cmyk(color->getCmyk()); + color->setCmykFromSpotColors(); + if (cmyk != color->getCmyk()) + // The color's CMYK was customized. + color->setCmyk(cmyk); + } + + if (i == 0 && color->isBlack() && color->getName() == QLatin1String("Registration black") + && XMLFileFormat::active_version >= 6 ) + { + delete color; color = NULL; + color_index[ocad_color->number] = Map::getRegistrationColor(); + addWarning(tr("Color \"Registration black\" is imported as a special color.")); + // NOTE: This does not make a difference in output + // as long as no spot colors are created, + // but as a special color, it is protected from modification, + // and it will be saved as number 0 in OCD export. + } + else + { + map->color_set->colors.push_back(color); + color_index[ocad_color->number] = color; + } + } + + // Insert the spot colors into the map + for (int i = 0; i < num_separations; ++i) + { + map->addColor(separations[i], map->color_set->colors.size()); + } + + // Load symbols + for (OCADSymbolIndex *idx = ocad_symidx_first(file); idx != NULL; idx = ocad_symidx_next(file, idx)) + { + for (int i = 0; i < 256; i++) + { + OCADSymbol *ocad_symbol = ocad_symbol_at(file, idx, i); + if (ocad_symbol != NULL && ocad_symbol->number != 0) + { + Symbol *symbol = NULL; + if (ocad_symbol->type == OCAD_POINT_SYMBOL) + { + symbol = importPointSymbol((OCADPointSymbol *)ocad_symbol); + } + else if (ocad_symbol->type == OCAD_LINE_SYMBOL) + { + symbol = importLineSymbol((OCADLineSymbol *)ocad_symbol); + } + else if (ocad_symbol->type == OCAD_AREA_SYMBOL) + { + symbol = importAreaSymbol((OCADAreaSymbol *)ocad_symbol); + } + else if (ocad_symbol->type == OCAD_TEXT_SYMBOL) + { + symbol = importTextSymbol((OCADTextSymbol *)ocad_symbol); + } + else if (ocad_symbol->type == OCAD_RECT_SYMBOL) + { + RectangleInfo* rect = importRectSymbol((OCADRectSymbol *)ocad_symbol); + map->symbols.push_back(rect->border_line); + if (rect->has_grid) + { + map->symbols.push_back(rect->inner_line); + map->symbols.push_back(rect->text); + } + continue; + } + + + if (symbol) + { + map->symbols.push_back(symbol); + symbol_index[ocad_symbol->number] = symbol; + } + else + { + addWarning(tr("Unable to import symbol \"%3\" (%1.%2)") + .arg(ocad_symbol->number / 10).arg(ocad_symbol->number % 10) + .arg(convertPascalString(ocad_symbol->name))); + } + } + } + } + + if (!load_symbols_only) + { + // Load objects + + // Place all objects into a single OCAD import part + MapPart* part = new MapPart(tr("OCAD import layer"), map); + for (OCADObjectIndex *idx = ocad_objidx_first(file); idx != NULL; idx = ocad_objidx_next(file, idx)) + { + for (int i = 0; i < 256; i++) + { + OCADObjectEntry *entry = ocad_object_entry_at(file, idx, i); + OCADObject *ocad_obj = ocad_object(file, entry); + if (ocad_obj != NULL) + { + Object *object = importObject(ocad_obj, part); + if (object != NULL) { + part->objects.push_back(object); + } + } + } + } + delete map->parts[0]; + map->parts[0] = part; + map->current_part_index = 0; + + // Load templates + map->templates.clear(); + for (OCADStringIndex *idx = ocad_string_index_first(file); idx != NULL; idx = ocad_string_index_next(file, idx)) + { + for (int i = 0; i < 256; i++) + { + OCADStringEntry *entry = ocad_string_entry_at(file, idx, i); + if (entry->type != 0 && entry->size > 0) + importString(entry); + } + } + map->first_front_template = map->templates.size(); // Templates in front of the map are not supported by OCD + + // Fill view with relevant fields from OCD file + if (view) + { + if (file->setup->zoom >= MapView::zoom_out_limit && file->setup->zoom <= MapView::zoom_in_limit) + view->setZoom(file->setup->zoom); + + s32 buf[3]; + ocad_point(buf, &file->setup->center); + MapCoord center_pos; + convertPoint(center_pos, buf[0], buf[1]); + view->setCenter(center_pos); + } + + // TODO: read template visibilities + /* + int num_template_visibilities; + file->read((char*)&num_template_visibilities, sizeof(int)); + + for (int i = 0; i < num_template_visibilities; ++i) + { + int pos; + file->read((char*)&pos, sizeof(int)); + + TemplateVisibility* vis = getTemplateVisibility(map->getTemplate(pos)); + file->read((char*)&vis->visible, sizeof(bool)); + file->read((char*)&vis->opacity, sizeof(float)); + } + } + */ + + // Undo steps are not supported in OCAD + } + + ocad_file_close(file); + + //qint64 elapsed = QDateTime::currentMSecsSinceEpoch() - start; + //qDebug() << "OCAD map imported:"<getNumSymbols()<<"symbols and"<getNumObjects()<<"objects in"<currentMapPartIndexChanged(map->current_part_index); + emit map->currentMapPartChanged(map->getPart(map->current_part_index)); +} + +void OCAD8FileImport::setStringEncodings(const char *narrow, const char *wide) { + encoding_1byte = QTextCodec::codecForName(narrow); + encoding_2byte = QTextCodec::codecForName(wide); +} + +Symbol *OCAD8FileImport::importPointSymbol(const OCADPointSymbol *ocad_symbol) +{ + PointSymbol *symbol = importPattern(ocad_symbol->ngrp, (OCADPoint *)ocad_symbol->pts); + fillCommonSymbolFields(symbol, (OCADSymbol *)ocad_symbol); + symbol->setRotatable(ocad_symbol->base_flags & 1); + + return symbol; +} + +Symbol *OCAD8FileImport::importLineSymbol(const OCADLineSymbol *ocad_symbol) +{ + LineSymbol* line_for_borders = NULL; + + // Import a main line? + LineSymbol* main_line = NULL; + if (ocad_symbol->dmode == 0 || ocad_symbol->width > 0) + { + main_line = new LineSymbol(); + line_for_borders = main_line; + fillCommonSymbolFields(main_line, (OCADSymbol *)ocad_symbol); + + // Basic line options + main_line->line_width = convertSize(ocad_symbol->width); + main_line->color = convertColor(ocad_symbol->color); + + // Cap and join styles + if (ocad_symbol->ends == 0) + { + main_line->cap_style = LineSymbol::FlatCap; + main_line->join_style = LineSymbol::BevelJoin; + } + else if (ocad_symbol->ends == 1) + { + main_line->cap_style = LineSymbol::RoundCap; + main_line->join_style = LineSymbol::RoundJoin; + } + else if (ocad_symbol->ends == 2) + { + main_line->cap_style = LineSymbol::PointedCap; + main_line->join_style = LineSymbol::BevelJoin; + } + else if (ocad_symbol->ends == 3) + { + main_line->cap_style = LineSymbol::PointedCap; + main_line->join_style = LineSymbol::RoundJoin; + } + else if (ocad_symbol->ends == 4) + { + main_line->cap_style = LineSymbol::FlatCap; + main_line->join_style = LineSymbol::MiterJoin; + } + else if (ocad_symbol->ends == 6) + { + main_line->cap_style = LineSymbol::PointedCap; + main_line->join_style = LineSymbol::MiterJoin; + } + + if (main_line->cap_style == LineSymbol::PointedCap) + { + if (ocad_symbol->bdist != ocad_symbol->edist) + addWarning(tr("In dashed line symbol %1, pointed cap lengths for begin and end are different (%2 and %3). Using %4.") + .arg(0.1 * ocad_symbol->number).arg(ocad_symbol->bdist).arg(ocad_symbol->edist).arg((ocad_symbol->bdist + ocad_symbol->edist) / 2)); + main_line->pointed_cap_length = convertSize((ocad_symbol->bdist + ocad_symbol->edist) / 2); // FIXME: Different lengths for start and end length of pointed line ends are not supported yet, so take the average + main_line->join_style = LineSymbol::RoundJoin; // NOTE: while the setting may be different (see what is set in the first place), OCAD always draws round joins if the line cap is pointed! + } + + // Handle the dash pattern + if( ocad_symbol->gap > 0 || ocad_symbol->gap2 > 0 ) + { + main_line->dashed = true; + + // Detect special case + if (ocad_symbol->gap2 > 0 && ocad_symbol->gap == 0) + { + main_line->dash_length = convertSize(ocad_symbol->len - ocad_symbol->gap2); + main_line->break_length = convertSize(ocad_symbol->gap2); + if (!(ocad_symbol->elen >= ocad_symbol->len / 2 - 1 && ocad_symbol->elen <= ocad_symbol->len / 2 + 1)) + addWarning(tr("In dashed line symbol %1, the end length cannot be imported correctly.").arg(0.1 * ocad_symbol->number)); + if (ocad_symbol->egap != 0) + addWarning(tr("In dashed line symbol %1, the end gap cannot be imported correctly.").arg(0.1 * ocad_symbol->number)); + } + else + { + if (ocad_symbol->len != ocad_symbol->elen) + { + if (ocad_symbol->elen >= ocad_symbol->len / 2 - 1 && ocad_symbol->elen <= ocad_symbol->len / 2 + 1) + main_line->half_outer_dashes = true; + else + addWarning(tr("In dashed line symbol %1, main and end length are different (%2 and %3). Using %4.") + .arg(0.1 * ocad_symbol->number).arg(ocad_symbol->len).arg(ocad_symbol->elen).arg(ocad_symbol->len)); + } + + main_line->dash_length = convertSize(ocad_symbol->len); + main_line->break_length = convertSize(ocad_symbol->gap); + if (ocad_symbol->gap2 > 0) + { + main_line->dashes_in_group = 2; + if (ocad_symbol->gap2 != ocad_symbol->egap) + addWarning(tr("In dashed line symbol %1, gaps D and E are different (%2 and %3). Using %4.") + .arg(0.1 * ocad_symbol->number).arg(ocad_symbol->gap2).arg(ocad_symbol->egap).arg(ocad_symbol->gap2)); + main_line->in_group_break_length = convertSize(ocad_symbol->gap2); + main_line->dash_length = (main_line->dash_length - main_line->in_group_break_length) / 2; + } + } + } + else + { + main_line->segment_length = convertSize(ocad_symbol->len); + main_line->end_length = convertSize(ocad_symbol->elen); + } + } + + // Import a 'framing' line? + LineSymbol* framing_line = NULL; + if (ocad_symbol->fwidth > 0) + { + framing_line = new LineSymbol(); + if (!line_for_borders) + line_for_borders = framing_line; + fillCommonSymbolFields(framing_line, (OCADSymbol *)ocad_symbol); + + // Basic line options + framing_line->line_width = convertSize(ocad_symbol->fwidth); + framing_line->color = convertColor(ocad_symbol->fcolor); + + // Cap and join styles + if (ocad_symbol->fstyle == 0) + { + framing_line->cap_style = LineSymbol::FlatCap; + framing_line->join_style = LineSymbol::BevelJoin; + } + else if (ocad_symbol->fstyle == 1) + { + framing_line->cap_style = LineSymbol::RoundCap; + framing_line->join_style = LineSymbol::RoundJoin; + } + else if (ocad_symbol->fstyle == 4) + { + framing_line->cap_style = LineSymbol::FlatCap; + framing_line->join_style = LineSymbol::MiterJoin; + } + } + + // Import a 'double' line? + bool has_border_line = ocad_symbol->lwidth > 0 || ocad_symbol->rwidth > 0; + LineSymbol *double_line = NULL; + if (ocad_symbol->dmode != 0 && (ocad_symbol->dflags & 1 || (has_border_line && !line_for_borders))) + { + double_line = new LineSymbol(); + line_for_borders = double_line; + fillCommonSymbolFields(double_line, (OCADSymbol *)ocad_symbol); + + double_line->line_width = convertSize(ocad_symbol->dwidth); + if (ocad_symbol->dflags & 1) + double_line->color = convertColor(ocad_symbol->dcolor); + else + double_line->color = NULL; + + double_line->cap_style = LineSymbol::FlatCap; + double_line->join_style = LineSymbol::MiterJoin; + + double_line->segment_length = convertSize(ocad_symbol->len); + double_line->end_length = convertSize(ocad_symbol->elen); + } + + // Border lines + if (has_border_line) + { + Q_ASSERT(line_for_borders); + line_for_borders->have_border_lines = true; + LineSymbolBorder& border = line_for_borders->getBorder(); + LineSymbolBorder& right_border = line_for_borders->getRightBorder(); + + // Border color and width + border.color = convertColor(ocad_symbol->lcolor); + border.width = convertSize(ocad_symbol->lwidth); + border.shift = convertSize(ocad_symbol->lwidth) / 2 + (convertSize(ocad_symbol->dwidth) - line_for_borders->line_width) / 2; + + right_border.color = convertColor(ocad_symbol->rcolor); + right_border.width = convertSize(ocad_symbol->rwidth); + right_border.shift = convertSize(ocad_symbol->rwidth) / 2 + (convertSize(ocad_symbol->dwidth) - line_for_borders->line_width) / 2; + + // The borders may be dashed + if (ocad_symbol->dgap > 0 && ocad_symbol->dmode > 1) + { + border.dashed = true; + border.dash_length = convertSize(ocad_symbol->dlen); + border.break_length = convertSize(ocad_symbol->dgap); + + // If ocad_symbol->dmode == 2, only the left border should be dashed + if (ocad_symbol->dmode > 2) + { + right_border.dashed = border.dashed; + right_border.dash_length = border.dash_length; + right_border.break_length = border.break_length; + } + } + } + + // Create point symbols along line; middle ("normal") dash, corners, start, and end. + LineSymbol* symbol_line = main_line ? main_line : double_line; // Find the line to attach the symbols to + if (symbol_line == NULL) + { + main_line = new LineSymbol(); + symbol_line = main_line; + fillCommonSymbolFields(main_line, (OCADSymbol *)ocad_symbol); + + main_line->segment_length = convertSize(ocad_symbol->len); + main_line->end_length = convertSize(ocad_symbol->elen); + } + OCADPoint * symbolptr = (OCADPoint *)ocad_symbol->pts; + symbol_line->mid_symbol = importPattern( ocad_symbol->smnpts, symbolptr); + symbol_line->mid_symbols_per_spot = ocad_symbol->snum; + symbol_line->mid_symbol_distance = convertSize(ocad_symbol->sdist); + symbolptr += ocad_symbol->smnpts; + if( ocad_symbol->ssnpts > 0 ) + { + //symbol_line->dash_symbol = importPattern( ocad_symbol->ssnpts, symbolptr); + symbolptr += ocad_symbol->ssnpts; + } + if( ocad_symbol->scnpts > 0 ) + { + symbol_line->dash_symbol = importPattern( ocad_symbol->scnpts, symbolptr); + symbol_line->dash_symbol->setName(LineSymbolSettings::tr("Dash symbol")); + symbolptr += ocad_symbol->scnpts; + } + if( ocad_symbol->sbnpts > 0 ) + { + symbol_line->start_symbol = importPattern( ocad_symbol->sbnpts, symbolptr); + symbol_line->start_symbol->setName(LineSymbolSettings::tr("Start symbol")); + symbolptr += ocad_symbol->sbnpts; + } + if( ocad_symbol->senpts > 0 ) + { + symbol_line->end_symbol = importPattern( ocad_symbol->senpts, symbolptr); + } + // FIXME: not really sure how this translates... need test cases + symbol_line->minimum_mid_symbol_count = 0; //1 + ocad_symbol->smin; + symbol_line->minimum_mid_symbol_count_when_closed = 0; //1 + ocad_symbol->smin; + symbol_line->show_at_least_one_symbol = false; // NOTE: this works in a different way than OCAD's 'at least X symbols' setting (per-segment instead of per-object) + + // Suppress dash symbol at line ends if both start symbol and end symbol exist, + // but don't create a warning unless a dash symbol is actually defined + // and the line symbol is not Mapper's 799 Simple orienteering course. + if (symbol_line->start_symbol != NULL && symbol_line->end_symbol != NULL) + { + symbol_line->setSuppressDashSymbolAtLineEnds(true); + if (symbol_line->dash_symbol && symbol_line->number[0] != 799) + addWarning(tr("Line symbol %1: suppressing dash symbol at line ends.").arg(QString::number(0.1 * ocad_symbol->number) + QLatin1Char(' ') + symbol_line->getName())); + } + + // TODO: taper fields (tmode and tlast) + + if (main_line == NULL && framing_line == NULL) + return double_line; + else if (double_line == NULL && framing_line == NULL) + return main_line; + else if (main_line == NULL && double_line == NULL) + return framing_line; + else + { + CombinedSymbol* full_line = new CombinedSymbol(); + fillCommonSymbolFields(full_line, (OCADSymbol *)ocad_symbol); + full_line->setNumParts(3); + int part = 0; + if (main_line) + { + full_line->setPart(part++, main_line, true); + main_line->setHidden(false); + main_line->setProtected(false); + } + if (double_line) + { + full_line->setPart(part++, double_line, true); + double_line->setHidden(false); + double_line->setProtected(false); + } + if (framing_line) + { + full_line->setPart(part++, framing_line, true); + framing_line->setHidden(false); + framing_line->setProtected(false); + } + full_line->setNumParts(part); + return full_line; + } +} + +Symbol *OCAD8FileImport::importAreaSymbol(const OCADAreaSymbol *ocad_symbol) +{ + AreaSymbol *symbol = new AreaSymbol(); + fillCommonSymbolFields(symbol, (OCADSymbol *)ocad_symbol); + + // Basic area symbol fields: minimum_area, color + symbol->minimum_area = 0; + symbol->color = ocad_symbol->fill ? convertColor(ocad_symbol->color) : NULL; + symbol->patterns.clear(); + AreaSymbol::FillPattern *pat = NULL; + + // Hatching + if (ocad_symbol->hmode > 0) + { + int n = symbol->patterns.size(); symbol->patterns.resize(n + 1); pat = &(symbol->patterns[n]); + pat->type = AreaSymbol::FillPattern::LinePattern; + pat->angle = convertRotation(ocad_symbol->hangle1); + pat->rotatable = true; + pat->line_spacing = convertSize(ocad_symbol->hdist + ocad_symbol->hwidth); + pat->line_offset = 0; + pat->line_color = convertColor(ocad_symbol->hcolor); + pat->line_width = convertSize(ocad_symbol->hwidth); + if (ocad_symbol->hmode == 2) + { + // Second hatch, same as the first, just a different angle + symbol->patterns.push_back(*pat); + symbol->patterns.back().angle = convertRotation(ocad_symbol->hangle2); + } + } + + if (ocad_symbol->pmode > 0) + { + // OCAD 8 has a "staggered" pattern mode, where successive rows are shifted width/2 relative + // to each other. We need to simulate this in Mapper with two overlapping patterns, each with + // twice the height. The second is then offset by width/2, height/2. + auto spacing = convertSize(ocad_symbol->pheight); + if (ocad_symbol->pmode == 2) spacing *= 2; + int n = symbol->patterns.size(); symbol->patterns.resize(n + 1); pat = &(symbol->patterns[n]); + pat->type = AreaSymbol::FillPattern::PointPattern; + pat->angle = convertRotation(ocad_symbol->pangle); + pat->rotatable = true; + pat->point_distance = convertSize(ocad_symbol->pwidth); + pat->line_spacing = spacing; + pat->line_offset = 0; + pat->offset_along_line = 0; + // FIXME: somebody needs to own this symbol and be responsible for deleting it + // Right now it looks like a potential memory leak + pat->point = importPattern(ocad_symbol->npts, (OCADPoint *)ocad_symbol->pts); + if (ocad_symbol->pmode == 2) + { + int n = symbol->patterns.size(); symbol->patterns.resize(n + 1); pat = &(symbol->patterns[n]); + pat->type = AreaSymbol::FillPattern::PointPattern; + pat->angle = convertRotation(ocad_symbol->pangle); + pat->rotatable = true; + pat->point_distance = convertSize(ocad_symbol->pwidth); + pat->line_spacing = spacing; + pat->line_offset = pat->line_spacing / 2; + pat->offset_along_line = pat->point_distance / 2; + pat->point = importPattern(ocad_symbol->npts, (OCADPoint *)ocad_symbol->pts); + } + } + + return symbol; +} + +Symbol *OCAD8FileImport::importTextSymbol(const OCADTextSymbol *ocad_symbol) +{ + TextSymbol *symbol = new TextSymbol(); + fillCommonSymbolFields(symbol, (OCADSymbol *)ocad_symbol); + + symbol->font_family = convertPascalString(ocad_symbol->font); // FIXME: font mapping? + symbol->color = convertColor(ocad_symbol->color); + double d_font_size = (0.1 * ocad_symbol->dpts) / 72.0 * 25.4; + symbol->font_size = qRound(1000 * d_font_size); + symbol->bold = (ocad_symbol->bold >= 550) ? true : false; + symbol->italic = (ocad_symbol->italic) ? true : false; + symbol->underline = false; + symbol->paragraph_spacing = convertSize(ocad_symbol->pspace); + symbol->character_spacing = ocad_symbol->cspace / 100.0; + symbol->kerning = false; + symbol->line_below = ocad_symbol->under; + symbol->line_below_color = convertColor(ocad_symbol->ucolor); + symbol->line_below_width = convertSize(ocad_symbol->uwidth); + symbol->line_below_distance = convertSize(ocad_symbol->udist); + symbol->custom_tabs.resize(ocad_symbol->ntabs); + for (int i = 0; i < ocad_symbol->ntabs; ++i) + symbol->custom_tabs[i] = convertSize(ocad_symbol->tab[i]); + + int halign = (int)TextObject::AlignHCenter; + if (ocad_symbol->halign == 0) + halign = (int)TextObject::AlignLeft; + else if (ocad_symbol->halign == 1) + halign = (int)TextObject::AlignHCenter; + else if (ocad_symbol->halign == 2) + halign = (int)TextObject::AlignRight; + else if (ocad_symbol->halign == 3) + { + // TODO: implement justified alignment + addWarning(tr("During import of text symbol %1: ignoring justified alignment").arg(0.1 * ocad_symbol->number)); + } + text_halign_map[symbol] = halign; + + if (ocad_symbol->bold != 400 && ocad_symbol->bold != 700) + { + addWarning(tr("During import of text symbol %1: ignoring custom weight (%2)") + .arg(0.1 * ocad_symbol->number).arg(ocad_symbol->bold)); + } + if (ocad_symbol->cspace != 0) + { + addWarning(tr("During import of text symbol %1: custom character spacing is set, its implementation does not match OCAD's behavior yet") + .arg(0.1 * ocad_symbol->number)); + } + if (ocad_symbol->wspace != 100) + { + addWarning(tr("During import of text symbol %1: ignoring custom word spacing (%2%)") + .arg(0.1 * ocad_symbol->number).arg(ocad_symbol->wspace)); + } + if (ocad_symbol->indent1 != 0 || ocad_symbol->indent2 != 0) + { + addWarning(tr("During import of text symbol %1: ignoring custom indents (%2/%3)") + .arg(0.1 * ocad_symbol->number).arg(ocad_symbol->indent1).arg(ocad_symbol->indent2)); + } + + if (ocad_symbol->fmode > 0) + { + symbol->framing = true; + symbol->framing_color = convertColor(ocad_symbol->fcolor); + if (ocad_symbol->fmode == 1) + { + symbol->framing_mode = TextSymbol::ShadowFraming; + symbol->framing_shadow_x_offset = convertSize(ocad_symbol->fdx); + symbol->framing_shadow_y_offset = -1 * convertSize(ocad_symbol->fdy); + } + else if (ocad_symbol->fmode == 2) + { + symbol->framing_mode = TextSymbol::LineFraming; + symbol->framing_line_half_width = convertSize(ocad_symbol->fdpts); + } + else + { + addWarning(tr("During import of text symbol %1: ignoring text framing (mode %2)") + .arg(0.1 * ocad_symbol->number).arg(ocad_symbol->fmode)); + } + } + + symbol->updateQFont(); + + // Convert line spacing + double absolute_line_spacing = d_font_size * 0.01 * ocad_symbol->lspace; + symbol->line_spacing = absolute_line_spacing / (symbol->getFontMetrics().lineSpacing() / symbol->calculateInternalScaling()); + + return symbol; +} +OCAD8FileImport::RectangleInfo* OCAD8FileImport::importRectSymbol(const OCADRectSymbol* ocad_symbol) +{ + RectangleInfo rect; + rect.border_line = new LineSymbol(); + fillCommonSymbolFields(rect.border_line, (OCADSymbol *)ocad_symbol); + rect.border_line->line_width = convertSize(ocad_symbol->width); + rect.border_line->color = convertColor(ocad_symbol->color); + rect.border_line->cap_style = LineSymbol::FlatCap; + rect.border_line->join_style = LineSymbol::RoundJoin; + rect.corner_radius = 0.001 * convertSize(ocad_symbol->corner); + rect.has_grid = ocad_symbol->flags & 1; + + if (rect.has_grid) + { + rect.inner_line = new LineSymbol(); + fillCommonSymbolFields(rect.inner_line, (OCADSymbol *)ocad_symbol); + rect.inner_line->setNumberComponent(2, 1); + rect.inner_line->line_width = qRound(1000 * 0.15); + rect.inner_line->color = rect.border_line->color; + + rect.text = new TextSymbol(); + fillCommonSymbolFields(rect.text, (OCADSymbol *)ocad_symbol); + rect.text->setNumberComponent(2, 2); + rect.text->font_family = QString::fromLatin1("Arial"); + rect.text->font_size = qRound(1000 * (15 / 72.0 * 25.4)); + rect.text->color = rect.border_line->color; + rect.text->bold = true; + rect.text->updateQFont(); + + rect.number_from_bottom = ocad_symbol->flags & 2; + rect.cell_width = 0.001 * convertSize(ocad_symbol->cwidth); + rect.cell_height = 0.001 * convertSize(ocad_symbol->cheight); + rect.unnumbered_cells = ocad_symbol->gcells; + rect.unnumbered_text = convertPascalString(ocad_symbol->gtext); + } + + return &rectangle_info.insert(ocad_symbol->number, rect).value(); +} + +PointSymbol *OCAD8FileImport::importPattern(s16 npts, OCADPoint *pts) +{ + PointSymbol *symbol = new PointSymbol(); + symbol->rotatable = true; + OCADPoint *p = pts, *end = pts + npts; + while (p < end) { + OCADSymbolElement *elt = (OCADSymbolElement *)p; + int element_index = symbol->getNumElements(); + bool multiple_elements = p + (2 + elt->npts) < end || p > pts; + if (elt->type == OCAD_DOT_ELEMENT) + { + int inner_radius = (int)convertSize(elt->diameter) / 2; + if (inner_radius > 0) + { + PointSymbol* element_symbol = multiple_elements ? (new PointSymbol()) : symbol; + element_symbol->inner_color = convertColor(elt->color); + element_symbol->inner_radius = inner_radius; + element_symbol->outer_color = NULL; + element_symbol->outer_width = 0; + if (multiple_elements) + { + element_symbol->rotatable = false; + PointObject* element_object = new PointObject(element_symbol); + element_object->coords.resize(1); + symbol->addElement(element_index, element_object, element_symbol); + } + } + } + else if (elt->type == OCAD_CIRCLE_ELEMENT) + { + int inner_radius = (int)convertSize(elt->diameter) / 2 - (int)convertSize(elt->width); + int outer_width = (int)convertSize(elt->width); + if (outer_width > 0 && inner_radius > 0) + { + PointSymbol* element_symbol = (multiple_elements) ? (new PointSymbol()) : symbol; + element_symbol->inner_color = NULL; + element_symbol->inner_radius = inner_radius; + element_symbol->outer_color = convertColor(elt->color); + element_symbol->outer_width = outer_width; + if (multiple_elements) + { + element_symbol->rotatable = false; + PointObject* element_object = new PointObject(element_symbol); + element_object->coords.resize(1); + symbol->addElement(element_index, element_object, element_symbol); + } + } + } + else if (elt->type == OCAD_LINE_ELEMENT) + { + LineSymbol* element_symbol = new LineSymbol(); + element_symbol->line_width = convertSize(elt->width); + element_symbol->color = convertColor(elt->color); + PathObject* element_object = new PathObject(element_symbol); + fillPathCoords(element_object, false, elt->npts, elt->pts); + element_object->recalculateParts(); + symbol->addElement(element_index, element_object, element_symbol); + } + else if (elt->type == OCAD_AREA_ELEMENT) + { + AreaSymbol* element_symbol = new AreaSymbol(); + element_symbol->color = convertColor(elt->color); + PathObject* element_object = new PathObject(element_symbol); + fillPathCoords(element_object, true, elt->npts, elt->pts); + element_object->recalculateParts(); + symbol->addElement(element_index, element_object, element_symbol); + } + p += (2 + elt->npts); + } + return symbol; +} + + +void OCAD8FileImport::fillCommonSymbolFields(Symbol *symbol, const OCADSymbol *ocad_symbol) +{ + // common fields are name, number, description, helper_symbol, hidden/protected status + symbol->name = convertPascalString(ocad_symbol->name); + symbol->number[0] = ocad_symbol->number / 10; + symbol->number[1] = ocad_symbol->number % 10; + symbol->number[2] = -1; + symbol->is_helper_symbol = false; // no such thing in OCAD + if (ocad_symbol->status & 1) + symbol->setProtected(true); + if (ocad_symbol->status & 2) + symbol->setHidden(true); +} + +Object *OCAD8FileImport::importObject(const OCADObject* ocad_object, MapPart* part) +{ + Symbol* symbol; + if (!symbol_index.contains(ocad_object->symbol)) + { + if (!rectangle_info.contains(ocad_object->symbol)) + { + if (ocad_object->type == 1) + symbol = map->getUndefinedPoint(); + else if (ocad_object->type == 2 || ocad_object->type == 3) + symbol = map->getUndefinedLine(); + else if (ocad_object->type == 4 || ocad_object->type == 5) + symbol = map->getUndefinedText(); + else + { + addWarning(tr("Unable to load object")); + return NULL; + } + } + else + { + if (!importRectangleObject(ocad_object, part, rectangle_info[ocad_object->symbol])) + addWarning(tr("Unable to import rectangle object")); + return NULL; + } + } + else + symbol = symbol_index[ocad_object->symbol]; + + if (symbol->getType() == Symbol::Point) + { + PointObject *p = new PointObject(); + p->symbol = symbol; + + // extra properties: rotation + PointSymbol* point_symbol = reinterpret_cast(symbol); + if (point_symbol->isRotatable()) + p->setRotation(convertRotation(ocad_object->angle)); + else if (ocad_object->angle != 0) + { + if (!point_symbol->isSymmetrical()) + { + point_symbol->setRotatable(true); + p->setRotation(convertRotation(ocad_object->angle)); + } + } + + // only 1 coordinate is allowed, enforce it even if the OCAD object claims more. + fillPathCoords(p, false, 1, ocad_object->pts); + p->setMap(map); + return p; + } + else if (symbol->getType() == Symbol::Text) + { + TextObject *t = new TextObject(symbol); + + // extra properties: rotation, horizontalAlignment, verticalAlignment, text + t->setRotation(convertRotation(ocad_object->angle)); + t->setHorizontalAlignment((TextObject::HorizontalAlignment)text_halign_map.value(symbol)); + t->setVerticalAlignment(TextObject::AlignBaseline); + + const char *text_ptr = (const char *)(ocad_object->pts + ocad_object->npts); + size_t text_len = sizeof(OCADPoint) * ocad_object->ntext; + if (ocad_object->unicode) t->setText(convertWideCString(text_ptr, text_len, true)); + else t->setText(convertCString(text_ptr, text_len, true)); + + // Text objects need special path translation + if (!fillTextPathCoords(t, reinterpret_cast(symbol), ocad_object->npts, (OCADPoint *)ocad_object->pts)) + { + addWarning(tr("Not importing text symbol, couldn't figure out path' (npts=%1): %2") + .arg(ocad_object->npts).arg(t->getText())); + delete t; + return NULL; + } + t->setMap(map); + return t; + } + else if (symbol->getType() == Symbol::Line || symbol->getType() == Symbol::Area || symbol->getType() == Symbol::Combined) { + PathObject *p = new PathObject(symbol); + + p->setPatternRotation(convertRotation(ocad_object->angle)); + + // Normal path + fillPathCoords(p, symbol->getType() == Symbol::Area, ocad_object->npts, ocad_object->pts); + p->recalculateParts(); + p->setMap(map); + return p; + } + + return NULL; +} + +bool OCAD8FileImport::importRectangleObject(const OCADObject* ocad_object, MapPart* part, const OCAD8FileImport::RectangleInfo& rect) +{ + if (ocad_object->npts != 4) + return false; + + // Convert corner points +#ifdef Q_CC_CLANG +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Warray-bounds" +#endif + s32 buf[3]; + ocad_point(buf, &(ocad_object->pts[3])); + MapCoord top_left; + convertPoint(top_left, buf[0], buf[1]); + ocad_point(buf, &(ocad_object->pts[0])); + MapCoord bottom_left; + convertPoint(bottom_left, buf[0], buf[1]); + ocad_point(buf, &(ocad_object->pts[2])); + MapCoord top_right; + convertPoint(top_right, buf[0], buf[1]); + ocad_point(buf, &(ocad_object->pts[1])); + MapCoord bottom_right; + convertPoint(bottom_right, buf[0], buf[1]); +#ifdef Q_CC_CLANG +#pragma clang diagnostic pop +#endif + + MapCoordF top_left_f = MapCoordF(top_left); + MapCoordF top_right_f = MapCoordF(top_right); + MapCoordF bottom_left_f = MapCoordF(bottom_left); + MapCoordF bottom_right_f = MapCoordF(bottom_right); + MapCoordF right = MapCoordF(top_right.x() - top_left.x(), top_right.y() - top_left.y()); + double angle = right.angle(); + MapCoordF down = MapCoordF(bottom_left.x() - top_left.x(), bottom_left.y() - top_left.y()); + right.normalize(); + down.normalize(); + + // Create border line + MapCoordVector coords; + if (rect.corner_radius == 0) + { + coords.emplace_back(top_left); + coords.emplace_back(top_right); + coords.emplace_back(bottom_right); + coords.emplace_back(bottom_left); + } + else + { + double handle_radius = (1 - BEZIER_KAPPA) * rect.corner_radius; + coords.emplace_back(top_right_f - right * rect.corner_radius, MapCoord::CurveStart); + coords.emplace_back(top_right_f - right * handle_radius); + coords.emplace_back(top_right_f + down * handle_radius); + coords.emplace_back(top_right_f + down * rect.corner_radius); + coords.emplace_back(bottom_right_f - down * rect.corner_radius, MapCoord::CurveStart); + coords.emplace_back(bottom_right_f - down * handle_radius); + coords.emplace_back(bottom_right_f - right * handle_radius); + coords.emplace_back(bottom_right_f - right * rect.corner_radius); + coords.emplace_back(bottom_left_f + right * rect.corner_radius, MapCoord::CurveStart); + coords.emplace_back(bottom_left_f + right * handle_radius); + coords.emplace_back(bottom_left_f - down * handle_radius); + coords.emplace_back(bottom_left_f - down * rect.corner_radius); + coords.emplace_back(top_left_f + down * rect.corner_radius, MapCoord::CurveStart); + coords.emplace_back(top_left_f + down * handle_radius); + coords.emplace_back(top_left_f + right * handle_radius); + coords.emplace_back(top_left_f + right * rect.corner_radius); + } + PathObject *border_path = new PathObject(rect.border_line, coords, map); + border_path->parts().front().setClosed(true, false); + part->objects.push_back(border_path); + + if (rect.has_grid && rect.cell_width > 0 && rect.cell_height > 0) + { + // Calculate grid sizes + double width = top_left.distanceTo(top_right); + double height = top_left.distanceTo(bottom_left); + int num_cells_x = qMax(1, qRound(width / rect.cell_width)); + int num_cells_y = qMax(1, qRound(height / rect.cell_height)); + + float cell_width = width / num_cells_x; + float cell_height = height / num_cells_y; + + // Create grid lines + coords.resize(2); + for (int x = 1; x < num_cells_x; ++x) + { + coords[0] = MapCoord(top_left_f + x * cell_width * right); + coords[1] = MapCoord(bottom_left_f + x * cell_width * right); + + PathObject *path = new PathObject(rect.inner_line, coords, map); + part->objects.push_back(path); + } + for (int y = 1; y < num_cells_y; ++y) + { + coords[0] = MapCoord(top_left_f + y * cell_height * down); + coords[1] = MapCoord(top_right_f + y * cell_height * down); + + PathObject *path = new PathObject(rect.inner_line, coords, map); + part->objects.push_back(path); + } + + // Create grid text + if (height >= rect.cell_height / 2) + { + for (int y = 0; y < num_cells_y; ++y) + { + for (int x = 0; x < num_cells_x; ++x) + { + int cell_num; + QString cell_text; + + if (rect.number_from_bottom) + cell_num = y * num_cells_x + x + 1; + else + cell_num = (num_cells_y - 1 - y) * num_cells_x + x + 1; + + if (cell_num > num_cells_x * num_cells_y - rect.unnumbered_cells) + cell_text = rect.unnumbered_text; + else + cell_text = QString::number(cell_num); + + TextObject* object = new TextObject(rect.text); + object->setMap(map); + object->setText(cell_text); + object->setRotation(-angle); + object->setHorizontalAlignment(TextObject::AlignLeft); + object->setVerticalAlignment(TextObject::AlignTop); + double position_x = (x + 0.07f) * cell_width; + double position_y = (y + 0.04f) * cell_height + rect.text->getFontMetrics().ascent() / rect.text->calculateInternalScaling() - rect.text->getFontSize(); + object->setAnchorPosition(top_left_f + position_x * right + position_y * down); + part->objects.push_back(object); + + //pts[0].Y -= rectinfo.gridText.FontAscent - rectinfo.gridText.FontEmHeight; + } + } + } + } + + return true; +} + +void OCAD8FileImport::importString(OCADStringEntry *entry) +{ + OCADCString *ocad_str = ocad_string(file, entry); + if (entry->type == 8) + { + // Template + importTemplate(ocad_str); + } + + // TODO: parse more types of strings, maybe the print parameters? +} + +Template *OCAD8FileImport::importTemplate(OCADCString* ocad_str) +{ + Template* templ = NULL; + QByteArray data(ocad_str->str); // copies the data. + QString filename = encoding_1byte->toUnicode(data.left(data.indexOf('\t', 0))); + QString clean_path = QDir::cleanPath(QString(filename).replace(QLatin1Char('\\'), QLatin1Char('/'))); + QString extension = QFileInfo(clean_path).suffix(); + if (extension.compare(QLatin1String("ocd"), Qt::CaseInsensitive) == 0) + { + templ = new TemplateMap(clean_path, map); + } + else if (QImageReader::supportedImageFormats().contains(extension.toLatin1())) + { + templ = new TemplateImage(clean_path, map); + } + else + { + addWarning(tr("Unable to import template: background \"%1\" doesn't seem to be a raster image").arg(filename)); + return NULL; + } + + OCADBackground background = importBackground(data); + MapCoord c; + convertPoint(c, background.trnx, background.trny); + templ->setTemplatePosition(c); + templ->setTemplateRotation(M_PI / 180 * background.angle); + templ->setTemplateScaleX(convertTemplateScale(background.sclx)); + templ->setTemplateScaleY(convertTemplateScale(background.scly)); + + map->templates.insert(map->templates.begin(), templ); + + if (view) + { + auto opacity = qMax(0.0, qMin(1.0, 0.01 * (100 - background.dimming))); + view->setTemplateVisibility(templ, { float(opacity), bool(background.s) }); + } + + return templ; +} + +// A more flexible reimplementation of libocad's ocad_to_background(). +OCADBackground OCAD8FileImport::importBackground(const QByteArray& data) +{ + unsigned int num_angles = 0; + OCADBackground background; + background.filename = data.data(); // tab-terminated, not 0-terminated! + background.trnx = 0; + background.trny = 0; + background.angle = 0.0; + background.sclx = 100.0; + background.scly = 100.0; + background.dimming = 0; + background.s = 1; + + int i = data.indexOf('\t', 0); + while (i >= 0) + { + double value; + bool ok; + int next_i = data.indexOf('\t', i+1); + int len = (next_i > 0 ? next_i : data.length()) - i - 2; + switch (data[i+1]) + { + case 'x': + background.trnx = qRound(data.mid(i + 2, len).toDouble()); + break; + case 'y': + background.trny = qRound(data.mid(i + 2, len).toDouble()); + break; + case 'a': + case 'b': + // TODO: use the distinct angles correctly, not just the average + background.angle += data.mid(i + 2, len).toDouble(&ok); + if (ok) + ++num_angles; + break; + case 'u': + value = data.mid(i + 2, len).toDouble(&ok); + if (ok && qAbs(value) >= 0.0001) + background.sclx = value; + break; + case 'v': + value = data.mid(i + 2, len).toDouble(&ok); + if (ok && qAbs(value) >= 0.0001) + background.scly = value; + break; + case 'd': + background.dimming = data.mid(i + 2, len).toInt(); + break; + case 's': + background.s = data.mid(i + 2, len).toInt(); + break; + default: + ; // nothing + } + i = next_i; + } + + if (num_angles) + background.angle = background.angle / num_angles; + + return background; +} + +Template *OCAD8FileImport::importRasterTemplate(const OCADBackground &background) +{ + QString filename(encoding_1byte->toUnicode(background.filename)); + filename = QDir::cleanPath(filename.replace(QLatin1Char('\\'), QLatin1Char('/'))); + if (isRasterImageFile(filename)) + { + TemplateImage* templ = new TemplateImage(filename, map); + MapCoord c; + convertPoint(c, background.trnx, background.trny); + templ->setTemplateX(c.nativeX()); + templ->setTemplateY(c.nativeY()); + templ->setTemplateRotation(M_PI / 180 * background.angle); + templ->setTemplateScaleX(convertTemplateScale(background.sclx)); + templ->setTemplateScaleY(convertTemplateScale(background.scly)); + // FIXME: import template view parameters: background.dimming and background.transparent + // TODO: import template visibility + return templ; + } + else + { + addWarning(tr("Unable to import template: background \"%1\" doesn't seem to be a raster image").arg(filename)); + } + return NULL; +} + +void OCAD8FileImport::setPathHolePoint(Object *object, int i) +{ + // Look for curve start points before the current point and apply hole point only if no such point is there. + // This prevents hole points in the middle of a curve caused by incorrect map objects. + if (i >= 1 && object->coords[i].isCurveStart()) + ; //object->coords[i-1].setHolePoint(true); + else if (i >= 2 && object->coords[i-1].isCurveStart()) + ; //object->coords[i-2].setHolePoint(true); + else if (i >= 3 && object->coords[i-2].isCurveStart()) + ; //object->coords[i-3].setHolePoint(true); + else + object->coords[i].setHolePoint(true); +} + +/** Translates the OCAD path given in the last two arguments into an Object. + */ +void OCAD8FileImport::fillPathCoords(Object *object, bool is_area, u16 npts, const OCADPoint *pts) +{ + object->coords.resize(npts); + s32 buf[3]; + for (int i = 0; i < npts; i++) + { + ocad_point(buf, &(pts[i])); + MapCoord &coord = object->coords[i]; + convertPoint(coord, buf[0], buf[1]); + // We can support CurveStart, HolePoint, DashPoint. + // CurveStart needs to be applied to the main point though, not the control point, and + // hole points need to bet set as the last point of a part of an area object instead of the first point of the next part + if (buf[2] & PX_CTL1 && i > 0) + object->coords[i-1].setCurveStart(true); + if ((buf[2] & (PY_DASH << 8)) || (buf[2] & (PY_CORNER << 8))) + coord.setDashPoint(true); + if (buf[2] & (PY_HOLE << 8)) + setPathHolePoint(object, is_area ? (i - 1) : i); + } + + // For path objects, create closed parts where the position of the last point is equal to that of the first point + if (object->getType() == Object::Path) + { + int start = 0; + for (int i = 0; i < (int)object->coords.size(); ++i) + { + if (!object->coords[i].isHolePoint() && i < (int)object->coords.size() - 1) + continue; + + if (object->coords[i].isPositionEqualTo(object->coords[start])) + { + MapCoord coord = object->coords[start]; + coord.setCurveStart(false); + coord.setHolePoint(true); + coord.setClosePoint(true); + object->coords[i] = coord; + } + + start = i + 1; + } + } +} + +/** Translates an OCAD text object path into a Mapper text object specifier, if possible. + * If successful, sets either 1 or 2 coordinates in the text object and returns true. + * If the OCAD path was not importable, leaves the TextObject alone and returns false. + */ +bool OCAD8FileImport::fillTextPathCoords(TextObject *object, TextSymbol *symbol, u16 npts, OCADPoint *pts) +{ + // text objects either have 1 point (free anchor) or 2 (midpoint/size) + // OCAD appears to always have 5 or 4 points (possible single anchor, then 4 corner coordinates going clockwise from anchor). + if (npts == 0) return false; + + if (npts == 4) + { + // Box text + s32 buf[3]; + ocad_point(buf, &(pts[3])); + MapCoord top_left; + convertPoint(top_left, buf[0], buf[1]); + ocad_point(buf, &(pts[0])); + MapCoord bottom_left; + convertPoint(bottom_left, buf[0], buf[1]); + ocad_point(buf, &(pts[2])); + MapCoord top_right; + convertPoint(top_right, buf[0], buf[1]); + + // According to Purple Pen source code: OCAD adds an extra internal leading (incorrectly). + QFontMetricsF metrics = symbol->getFontMetrics(); + double top_adjust = -symbol->getFontSize() + (metrics.ascent() + metrics.descent() + 0.5) / symbol->calculateInternalScaling(); + + MapCoordF adjust_vector = MapCoordF(top_adjust * sin(object->getRotation()), top_adjust * cos(object->getRotation())); + top_left = MapCoord(top_left.x() + adjust_vector.x(), top_left.y() + adjust_vector.y()); + top_right = MapCoord(top_right.x() + adjust_vector.x(), top_right.y() + adjust_vector.y()); + + object->setBox((bottom_left.nativeX() + top_right.nativeX()) / 2, (bottom_left.nativeY() + top_right.nativeY()) / 2, + top_left.distanceTo(top_right), top_left.distanceTo(bottom_left)); + + object->setVerticalAlignment(TextObject::AlignTop); + } + else + { + // Single anchor text + if (npts != 5) + addWarning(tr("Trying to import a text object with unknown coordinate format")); + + s32 buf[3]; + ocad_point(buf, &(pts[0])); // anchor point + + MapCoord coord; + convertPoint(coord, buf[0], buf[1]); + object->setAnchorPosition(coord.nativeX(), coord.nativeY()); + + object->setVerticalAlignment(TextObject::AlignBaseline); + } + + return true; +} + +/** Converts a single-byte-per-character, length-payload string to a QString. + * + * The byte sequence will be: LEN C0 C1 C2 C3... + * + * Obviously this will only hold up to 255 characters. By default, we interpret the + * bytes using Windows-1252, as that's the most likely candidate for OCAD files in + * the wild. + */ +QString OCAD8FileImport::convertPascalString(const char *p) { + int len = *((unsigned char *)p); + return encoding_1byte->toUnicode((p + 1), len); +} + +/** Converts a single-byte-per-character, zero-terminated string to a QString. + * + * The byte sequence will be: C0 C1 C2 C3 ... 00. n describes the maximum + * length (in bytes) that will be scanned for a zero terminator; if none is found, + * the string will be truncated at that location. + */ +QString OCAD8FileImport::convertCString(const char *p, size_t n, bool ignore_first_newline) { + size_t i = 0; + for (; i < n; i++) { + if (p[i] == 0) break; + } + if (ignore_first_newline && n >= 2 && p[0] == '\r' && p[1] == '\n') + { + // Remove "\r\n" at the beginning of texts, somehow OCAD seems to add this sometimes but ignores it + p += 2; + i -= 2; + } + return encoding_1byte->toUnicode(p, i); +} + +/** Converts a two-byte-per-character, zero-terminated string to a QString. By default, + * we interpret the bytes using UTF-16LE, as that's the most likely candidate for + * OCAD files in the wild. + * + * The byte sequence will be: L0 H0 L1 H1 L2 H2... 00 00. n describes the maximum + * length (in bytes) that will be scanned for a zero terminator; if none is found, + * the string will be truncated at that location. + */ +QString OCAD8FileImport::convertWideCString(const char *p, size_t n, bool ignore_first_newline) { + const u16 *q = (const u16 *)p; + size_t i = 0; + for (; i < n; i++) { + if (q[i] == 0) break; + } + if (ignore_first_newline && n >= 4 && p[0] == '\r' && p[2] == '\n') + { + // Remove "\r\n" at the beginning of texts, somehow OCAD seems to add this sometimes but ignores it + p += 4; + i -= 2; + } + return encoding_2byte->toUnicode(p, i * 2); +} + +float OCAD8FileImport::convertRotation(int angle) { + // OCAD uses tenths of a degree, counterclockwise + // BUG: if sin(rotation) is < 0 for a hatched area pattern, the pattern's createRenderables() will go into an infinite loop. + // So until that's fixed, we keep a between 0 and PI + double a = (M_PI / 180) * (0.1f * angle); + while (a < 0) a += 2 * M_PI; + //if (a < 0 || a > M_PI) qDebug() << "Found angle" << a; + return (float)a; +} + +void OCAD8FileImport::convertPoint(MapCoord &coord, s32 ocad_x, s32 ocad_y) +{ + // Recover from broken coordinate export from Mapper 0.6.2 ... 0.6.4 (#749) + // Cf. broken::convertPointMember below: + // The values -4 ... -1 (-0.004 mm ... -0.001 mm) were converted to 0x80000000u instead of 0. + // This is the maximum value. Thus it is okay to assume it won't occur in regular data, + // and we can safely replace it with 0 here. + // But the input parameter were already subject to right shift in ocad_point ... + constexpr auto invalid_value = s32(0x80000000u) >> 8; // ... so we use this value here. + if (ocad_x == invalid_value) + ocad_x = 0; + if (ocad_y == invalid_value) + ocad_y = 0; + + // OCAD uses hundredths of a millimeter. + // oo-mapper uses 1/1000 mm + coord.setNativeX(offset_x + (qint32)ocad_x * 10); + // Y-axis is flipped. + coord.setNativeY(offset_y + (qint32)ocad_y * (-10)); +} + +qint32 OCAD8FileImport::convertSize(int ocad_size) { + // OCAD uses hundredths of a millimeter. + // oo-mapper uses 1/1000 mm + return ((qint32)ocad_size) * 10; +} + +const MapColor *OCAD8FileImport::convertColor(int color) { + if (!color_index.contains(color)) + { + addWarning(tr("Color id not found: %1, ignoring this color").arg(color)); + return NULL; + } + else + return color_index[color]; +} + +double OCAD8FileImport::convertTemplateScale(double ocad_scale) +{ + return ocad_scale * 0.01; // millimeters(on map) per pixel +} + + +// ### OCAD8FileExport ### + +OCAD8FileExport::OCAD8FileExport(QIODevice* stream, Map* map, MapView* view) + : Exporter(stream, map, view), + uses_registration_color(false), + file(NULL) +{ + ocad_init(); + encoding_1byte = QTextCodec::codecForName("Windows-1252"); + encoding_2byte = QTextCodec::codecForName("UTF-16LE"); + + origin_point_object = new PointObject(); +} + +OCAD8FileExport::~OCAD8FileExport() +{ + delete origin_point_object; +} + +void OCAD8FileExport::doExport() +{ + uses_registration_color = map->isColorUsedByASymbol(map->getRegistrationColor()); + if (map->getNumColors() > (uses_registration_color ? 255 : 256)) + throw FileFormatException(tr("The map contains more than 256 colors which is not supported by ocd version 8.")); + + // Create struct in memory + int err = ocad_file_new(&file); + if (err != 0) throw FileFormatException(Exporter::tr("Could not create new file: %1").arg(tr("libocad returned %1").arg(err))); + + // Fill header struct + OCADFileHeader* header = file->header; + *(((u8*)&header->magic) + 0) = 0xAD; + *(((u8*)&header->magic) + 1) = 0x0C; + header->ftype = 2; + header->major = 8; + header->minor = 0; + if (map->getMapNotes().size() > 0) + { + header->infosize = map->getMapNotes().length() + 1; + ocad_file_reserve(file, header->infosize); + header->infopos = &file->buffer[file->size] - file->buffer; + convertCString(map->getMapNotes(), &file->buffer[file->size], header->infosize); + file->size += header->infosize; + } + + // Fill setup struct + OCADSetup* setup = file->setup; + if (view) + { + setup->center = convertPoint(view->center()); + setup->zoom = view->getZoom(); + } + else + setup->zoom = 1; + + // Scale and georeferencing parameters + const Georeferencing& georef = map->getGeoreferencing(); + setup->scale = georef.getScaleDenominator(); + const QPointF offset(georef.toProjectedCoords(MapCoord {0, 0})); + setup->offsetx = offset.x(); + setup->offsety = offset.y(); + setup->angle = georef.getGrivation(); + + // TODO: print parameters + + // Colors + int ocad_color_index = 0; + if (uses_registration_color) + { + addWarning(tr("Registration black is exported as a regular color.")); + + ++file->header->ncolors; + OCADColor *ocad_color = ocad_color_at(file, ocad_color_index); + ocad_color->number = ocad_color_index; + + const MapColor* color = Map::getRegistrationColor(); + const MapColorCmyk& cmyk = color->getCmyk(); + ocad_color->cyan = qRound(1 / 0.005f * cmyk.c); + ocad_color->magenta = qRound(1 / 0.005f * cmyk.m); + ocad_color->yellow = qRound(1 / 0.005f * cmyk.y); + ocad_color->black = qRound(1 / 0.005f * cmyk.k); + convertPascalString(QString::fromLatin1("Registration black"), ocad_color->name, 32); // not translated + + ++ocad_color_index; + } + for (int i = 0; i < map->getNumColors(); i++) + { + ++file->header->ncolors; + OCADColor *ocad_color = ocad_color_at(file, ocad_color_index); + ocad_color->number = ocad_color_index; + + const MapColor* color = map->getColor(i); + const MapColorCmyk& cmyk = color->getCmyk(); + ocad_color->cyan = qRound(1 / 0.005f * cmyk.c); + ocad_color->magenta = qRound(1 / 0.005f * cmyk.m); + ocad_color->yellow = qRound(1 / 0.005f * cmyk.y); + ocad_color->black = qRound(1 / 0.005f * cmyk.k); + convertPascalString(color->getName(), ocad_color->name, 32); + + ++ocad_color_index; + } + + // Symbols + for (int i = 0; i < map->getNumSymbols(); ++i) + { + const Symbol* symbol = map->getSymbol(i); + + s16 index = -1; + if (symbol->getType() == Symbol::Point) + index = exportPointSymbol(symbol->asPoint()); + else if (symbol->getType() == Symbol::Line) + index = exportLineSymbol(symbol->asLine()); + else if (symbol->getType() == Symbol::Area) + index = exportAreaSymbol(symbol->asArea()); + else if (symbol->getType() == Symbol::Text) + index = exportTextSymbol(symbol->asText()); + else if (symbol->getType() == Symbol::Combined) + ; // This is done as a second pass to ensure that all dependencies are added to the symbol_index + else + Q_ASSERT(false); + + if (index >= 0) + { + std::set number; + number.insert(index); + symbol_index.insert(symbol, number); + } + } + + // Separate pass for combined symbols + for (int i = 0; i < map->getNumSymbols(); ++i) + { + const Symbol* symbol = map->getSymbol(i); + if (symbol->getType() == Symbol::Combined) + symbol_index.insert(symbol, exportCombinedSymbol(static_cast(symbol))); + } + + // Objects + OCADObject* ocad_object = ocad_object_alloc(NULL); + for (int l = 0; l < map->getNumParts(); ++l) + { + for (int o = 0; o < map->getPart(l)->getNumObjects(); ++o) + { + memset(ocad_object, 0, sizeof(OCADObject) - sizeof(OCADPoint) + 8 * (ocad_object->npts + ocad_object->ntext)); + Object* object = map->getPart(l)->getObject(o); + object->update(); + + // Fill some common entries of object struct + OCADPoint* coord_buffer = ocad_object->pts; + if (object->getType() != Object::Text) + ocad_object->npts = exportCoordinates(object->getRawCoordinateVector(), &coord_buffer, object->getSymbol()); + else + ocad_object->npts = exportTextCoordinates(static_cast(object), &coord_buffer); + + if (object->getType() == Object::Point) + { + PointObject* point = static_cast(object); + ocad_object->angle = convertRotation(point->getRotation()); + } + else if (object->getType() == Object::Path) + { + PathObject* path = static_cast(object); + ocad_object->angle = convertRotation(path->getPatternRotation()); + if (path->getPatternOrigin() != MapCoord(0, 0)) + addWarning(tr("Unable to export fill pattern shift for an area object")); + } + else if (object->getType() == Object::Text) + { + TextObject* text = static_cast(object); + ocad_object->unicode = 1; + ocad_object->angle = convertRotation(text->getRotation()); + int num_letters = convertWideCString(text->getText(), (unsigned char*)coord_buffer, 8 * (OCAD_MAX_OBJECT_PTS - ocad_object->npts)); + ocad_object->ntext = qCeil(num_letters / 4.0f); + } + + // Insert an object into the map for every symbol contained in the symbol_index + std::set index_set; + if (symbol_index.contains(object->getSymbol())) + index_set = symbol_index[object->getSymbol()]; + else + index_set.insert(-1); // export as undefined symbol + + for (std::set::const_iterator it = index_set.begin(), end = index_set.end(); it != end; ++it) + { + s16 index_to_use = *it; + + // For text objects, check if we have to change / create a new text symbol because of the formatting + if (object->getType() == Object::Text && symbol_index.contains(object->getSymbol())) + { + TextObject* text_object = static_cast(object); + const TextSymbol* text_symbol = static_cast(object->getSymbol()); + if (!text_format_map.contains(text_symbol)) + { + // Adjust the formatting in the first created symbol to this object + OCADTextSymbol* ocad_text_symbol = (OCADTextSymbol*)ocad_symbol(file, *it); + setTextSymbolFormatting(ocad_text_symbol, text_object); + + TextFormatList new_list; + new_list.push_back(std::make_pair(text_object, *it)); + text_format_map.insert(text_symbol, new_list); + } + else + { + // Check if this formatting has already been created as symbol. + // If yes, use this symbol, else create a new symbol + TextFormatList& format_list = text_format_map[text_symbol]; + bool found = false; + for (size_t i = 0, end = format_list.size(); i < end; ++i) + { + if (format_list[i].first->getHorizontalAlignment() == text_object->getHorizontalAlignment()) + { + index_to_use = format_list[i].second; + found = true; + break; + } + } + if (!found) + { + // Copy the symbol and adjust the formatting + // TODO: insert these symbols directly after the original symbols + OCADTextSymbol* ocad_text_symbol = (OCADTextSymbol*)ocad_symbol(file, *it); + OCADTextSymbol* new_symbol = (OCADTextSymbol*)ocad_symbol_new(file, ocad_text_symbol->size); + // Get the pointer to the first symbol again as it might have changed during ocad_symbol_new() + ocad_text_symbol = (OCADTextSymbol*)ocad_symbol(file, *it); + + memcpy(new_symbol, ocad_text_symbol, ocad_text_symbol->size); + setTextSymbolFormatting(new_symbol, text_object); + + // Give the new symbol a unique number + while (symbol_numbers.find(new_symbol->number) != symbol_numbers.end()) + ++new_symbol->number; + symbol_numbers.insert(new_symbol->number); + index_to_use = new_symbol->number; + + // Store packed new_symbol->number in separate variable first, + // otherwise when compiling for Android this causes the error: + // cannot bind packed field 'new_symbol->_OCADTextSymbol::number' to 'short int&' + s16 new_symbol_number = new_symbol->number; + format_list.push_back(std::make_pair(text_object, new_symbol_number)); + } + } + } + + ocad_object->symbol = index_to_use; + if (object->getType() == Object::Point) + ocad_object->type = 1; + else if (object->getType() == Object::Path) + { + OCADSymbol* ocad_sym = ocad_symbol(file, index_to_use); + if (!ocad_sym) + ocad_object->type = 2; // This case is for undefined lines; TODO: make another case for undefined areas, as soon as they are implemented + else if (ocad_sym->type == 2) + ocad_object->type = 2; // Line + else //if (ocad_symbol->type == 3) + ocad_object->type = 3; // Area + } + else if (object->getType() == Object::Text) + { + TextObject* text_object = static_cast(object); + if (text_object->hasSingleAnchor()) + ocad_object->type = 4; + else + ocad_object->type = 5; + } + + OCADObjectEntry* entry; + ocad_object_add(file, ocad_object, &entry); + // This is done internally by libocad (in a slightly more imprecise way using the extent specified in the symbol) + //entry->rect.min = convertPoint(MapCoord(object->getExtent().topLeft())); + //entry->rect.max = convertPoint(MapCoord(object->getExtent().bottomRight())); + entry->npts = ocad_object->npts + ocad_object->ntext; + //entry->symbol = index_to_use; + } + } + } + + // Templates + for (int i = map->getNumTemplates() - 1; i >= 0; --i) + { + const Template* temp = map->getTemplate(i); + + QString template_path = temp->getTemplatePath(); + if (qstrcmp(temp->getTemplateType(), "TemplateImage") == 0 + || QFileInfo(template_path).suffix().compare(QLatin1String("ocd"), Qt::CaseInsensitive) == 0) + { + // FIXME: export template view parameters + + double a = temp->getTemplateRotation() * 180 / M_PI; + int d = 0; + int o = 0; + int p = 0; + int s = 1; // enabled + int t = 0; + OCADPoint pos = convertPoint(temp->getTemplateX(), temp->getTemplateY()); + int x = pos.x >> 8; + int y = pos.y >> 8; + double u = convertTemplateScale(temp->getTemplateScaleX()); + double v = convertTemplateScale(temp->getTemplateScaleY()); + + template_path.replace(QLatin1Char('/'), QLatin1Char('\\')); + + QString string; + string.sprintf("%s\ts%d\tx%d\ty%d\ta%f\tu%f\tv%f\td%d\tp%d\tt%d\to%d", + encoding_1byte->fromUnicode(template_path).data(), s, x, y, a, u, v, d, p, t, o + ); + + OCADStringEntry* entry = ocad_string_entry_new(file, string.length() + 1); + entry->type = 8; + convertCString(string, file->buffer + entry->ptr, entry->size); + } + else + { + addWarning(tr("Unable to export template: file type of \"%1\" is not supported yet").arg(temp->getTemplateFilename())); + } + } + + stream->write((char*)file->buffer, file->size); + + ocad_file_close(file); +} + +void OCAD8FileExport::exportCommonSymbolFields(const Symbol* symbol, OCADSymbol* ocad_symbol, int size) +{ + ocad_symbol->size = (s16)size; + convertPascalString(symbol->getPlainTextName(), ocad_symbol->name, 32); + ocad_symbol->number = symbol->getNumberComponent(0) * 10; + if (symbol->getNumberComponent(1) >= 0) + ocad_symbol->number += (symbol->getNumberComponent(1) % 10); + // Symbol number 0.0 is not valid + if (ocad_symbol->number == 0) + ocad_symbol->number = 1; + // Ensure uniqueness of the symbol number + while (symbol_numbers.find(ocad_symbol->number) != symbol_numbers.end()) + ++ocad_symbol->number; + symbol_numbers.insert(ocad_symbol->number); + + if (symbol->isProtected()) + ocad_symbol->status |= 1; + if (symbol->isHidden()) + ocad_symbol->status |= 2; + + // Set of used colors + u8 bitmask = 1; + u8* bitpos = ocad_symbol->colors; + for (int c = 0; c < map->getNumColors(); ++c) + { + if (symbol->containsColor(map->getColor(c))) + *bitpos |= bitmask; + + bitmask = bitmask << 1; + if (bitmask == 0) + { + bitmask = 1; + ++bitpos; + } + } + + // Icon: 22x22 with 4 bit color code, origin at bottom left, some padding + const int icon_size = 22; + QImage image = symbol->createIcon(map, icon_size, false, 0); + u8* ocad_icon = (u8*)ocad_symbol->icon; + for (int y = icon_size - 1; y >= 0; --y) + { + for (int x = 0; x < icon_size; x += 2) + { + int first = getOcadColor(image.pixel(x, y)); + int second = getOcadColor(image.pixel(x + 1, y)); + *(ocad_icon++) = (first << 4) + (second); + } + ocad_icon++; + } +} + +int OCAD8FileExport::getPatternSize(const PointSymbol* point) +{ + if (!point) + return 0; + + int npts = 0; + for (int i = 0; i < point->getNumElements(); ++i) + { + int factor = 1; + if (point->getElementSymbol(i)->getType() == Symbol::Point) + { + factor = 0; + const PointSymbol* point_symbol = static_cast(point->getElementSymbol(i)); + if (point_symbol->getInnerRadius() > 0 && point_symbol->getInnerColor() != NULL) + ++factor; + if (point_symbol->getOuterWidth() > 0 && point_symbol->getOuterColor() != NULL) + ++factor; + } + npts += factor * (2 + point->getElementObject(i)->getRawCoordinateVector().size()); + } + if (point->getInnerRadius() > 0 && point->getInnerColor() != NULL) + npts += 2 + 1; + if (point->getOuterWidth() > 0 && point->getOuterColor() != NULL) + npts += 2 + 1; + + return npts * sizeof(OCADPoint); +} + +s16 OCAD8FileExport::exportPattern(const PointSymbol* point, OCADPoint** buffer) +{ + if (!point) + return 0; + + s16 num_coords = exportSubPattern(origin_point_object, point, buffer); + for (int i = 0; i < point->getNumElements(); ++i) + { + num_coords += exportSubPattern(point->getElementObject(i), point->getElementSymbol(i), buffer); + } + return num_coords; +} + +s16 OCAD8FileExport::exportSubPattern(const Object* object, const Symbol* symbol, OCADPoint** buffer) +{ + s16 num_coords = 0; + OCADSymbolElement* element = (OCADSymbolElement*)*buffer; + + if (symbol->getType() == Symbol::Point) + { + const PointSymbol* point_symbol = static_cast(symbol); + if (point_symbol->getInnerRadius() > 0 && point_symbol->getInnerColor() != NULL) + { + element->type = 4; + element->color = convertColor(point_symbol->getInnerColor()); + element->diameter = convertSize(2 * point_symbol->getInnerRadius()); + (*buffer) += 2; + element->npts = exportCoordinates(object->getRawCoordinateVector(), buffer, point_symbol); + num_coords += 2 + element->npts; + } + if (point_symbol->getOuterWidth() > 0 && point_symbol->getOuterColor() != NULL) + { + element = (OCADSymbolElement*)*buffer; + element->type = 3; + element->color = convertColor(point_symbol->getOuterColor()); + element->width = convertSize(point_symbol->getOuterWidth()); + element->diameter = convertSize(2 * point_symbol->getInnerRadius() + 2 * point_symbol->getOuterWidth()); + (*buffer) += 2; + element->npts = exportCoordinates(object->getRawCoordinateVector(), buffer, point_symbol); + num_coords += 2 + element->npts; + } + } + else if (symbol->getType() == Symbol::Line) + { + const LineSymbol* line_symbol = static_cast(symbol); + element->type = 1; + if (line_symbol->getCapStyle() == LineSymbol::RoundCap) + element->flags |= 1; + else if (line_symbol->getJoinStyle() == LineSymbol::MiterJoin) + element->flags |= 4; + element->color = convertColor(line_symbol->getColor()); + element->width = convertSize(line_symbol->getLineWidth()); + (*buffer) += 2; + element->npts = exportCoordinates(object->getRawCoordinateVector(), buffer, line_symbol); + num_coords += 2 + element->npts; + } + else if (symbol->getType() == Symbol::Area) + { + const AreaSymbol* area_symbol = static_cast(symbol); + element->type = 2; + element->color = convertColor(area_symbol->getColor()); + (*buffer) += 2; + element->npts = exportCoordinates(object->getRawCoordinateVector(), buffer, area_symbol); + num_coords += 2 + element->npts; + } + else + Q_ASSERT(false); + return num_coords; +} + +s16 OCAD8FileExport::exportPointSymbol(const PointSymbol* point) +{ + int data_size = (sizeof(OCADPointSymbol) - sizeof(OCADPoint)) + getPatternSize(point); + OCADPointSymbol* ocad_symbol = (OCADPointSymbol*)ocad_symbol_new(file, data_size); + exportCommonSymbolFields(point, (OCADSymbol*)ocad_symbol, data_size); + + ocad_symbol->type = OCAD_POINT_SYMBOL; + ocad_symbol->extent = getPointSymbolExtent(point); + if (ocad_symbol->extent <= 0) + ocad_symbol->extent = 100; + if (point->isRotatable()) + ocad_symbol->base_flags |= 1; + ocad_symbol->ngrp = (data_size - (sizeof(OCADPointSymbol) - sizeof(OCADPoint))) / 8; + + OCADPoint* pattern_buffer = ocad_symbol->pts; + exportPattern(point, &pattern_buffer); + Q_ASSERT((u8*)ocad_symbol + data_size == (u8*)pattern_buffer); + return ocad_symbol->number; +} + +s16 OCAD8FileExport::exportLineSymbol(const LineSymbol* line) +{ + int data_size = (sizeof(OCADLineSymbol) - sizeof(OCADPoint)) + + getPatternSize(line->getStartSymbol()) + + getPatternSize(line->getEndSymbol()) + + getPatternSize(line->getMidSymbol()) + + getPatternSize(line->getDashSymbol()); + OCADLineSymbol* ocad_symbol = (OCADLineSymbol*)ocad_symbol_new(file, data_size); + exportCommonSymbolFields(line, (OCADSymbol*)ocad_symbol, data_size); + + // Basic settings + ocad_symbol->type = OCAD_LINE_SYMBOL; + s16 extent = convertSize(0.5f * line->getLineWidth()); + if (line->hasBorder()) + extent = qMax(extent, (s16)convertSize(0.5f * line->getLineWidth() + line->getBorder().shift + 0.5f * line->getBorder().width)); + extent = qMax(extent, getPointSymbolExtent(line->getStartSymbol())); + extent = qMax(extent, getPointSymbolExtent(line->getEndSymbol())); + extent = qMax(extent, getPointSymbolExtent(line->getMidSymbol())); + extent = qMax(extent, getPointSymbolExtent(line->getDashSymbol())); + ocad_symbol->extent = extent; + ocad_symbol->color = convertColor(line->getColor()); + if (line->getColor() != NULL) + ocad_symbol->width = convertSize(line->getLineWidth()); + + // Cap and Join + if (line->getCapStyle() == LineSymbol::FlatCap && line->getJoinStyle() == LineSymbol::BevelJoin) + ocad_symbol->ends = 0; + else if (line->getCapStyle() == LineSymbol::RoundCap && line->getJoinStyle() == LineSymbol::RoundJoin) + ocad_symbol->ends = 1; + else if (line->getCapStyle() == LineSymbol::PointedCap && line->getJoinStyle() == LineSymbol::BevelJoin) + ocad_symbol->ends = 2; + else if (line->getCapStyle() == LineSymbol::PointedCap && line->getJoinStyle() == LineSymbol::RoundJoin) + ocad_symbol->ends = 3; + else if (line->getCapStyle() == LineSymbol::FlatCap && line->getJoinStyle() == LineSymbol::MiterJoin) + ocad_symbol->ends = 4; + else if (line->getCapStyle() == LineSymbol::PointedCap && line->getJoinStyle() == LineSymbol::MiterJoin) + ocad_symbol->ends = 6; + else + { + addWarning(tr("In line symbol \"%1\", cannot represent cap/join combination.").arg(line->getPlainTextName())); + // Decide based on the caps + if (line->getCapStyle() == LineSymbol::FlatCap) + ocad_symbol->ends = 0; + else if (line->getCapStyle() == LineSymbol::RoundCap) + ocad_symbol->ends = 1; + else if (line->getCapStyle() == LineSymbol::PointedCap) + ocad_symbol->ends = 3; + else if (line->getCapStyle() == LineSymbol::SquareCap) + ocad_symbol->ends = 0; + } + + if (line->getCapStyle() == LineSymbol::PointedCap) + { + ocad_symbol->bdist = convertSize(line->getPointedCapLength()); + ocad_symbol->edist = convertSize(line->getPointedCapLength()); + } + + // Dash pattern + if (line->isDashed()) + { + if (line->getMidSymbol() != NULL && !line->getMidSymbol()->isEmpty()) + { + if (line->getDashesInGroup() > 1) + addWarning(tr("In line symbol \"%1\", neglecting the dash grouping.").arg(line->getPlainTextName())); + + ocad_symbol->len = convertSize(line->getDashLength() + line->getBreakLength()); + ocad_symbol->elen = ocad_symbol->len / 2; + ocad_symbol->gap2 = convertSize(line->getBreakLength()); + } + else + { + if (line->getDashesInGroup() > 1) + { + if (line->getDashesInGroup() > 2) + addWarning(tr("In line symbol \"%1\", the number of dashes in a group has been reduced to 2.").arg(line->getPlainTextName())); + + ocad_symbol->len = convertSize(2 * line->getDashLength() + line->getInGroupBreakLength()); + ocad_symbol->elen = convertSize(2 * line->getDashLength() + line->getInGroupBreakLength()); + ocad_symbol->gap = convertSize(line->getBreakLength()); + ocad_symbol->gap2 = convertSize(line->getInGroupBreakLength()); + ocad_symbol->egap = ocad_symbol->gap2; + } + else + { + ocad_symbol->len = convertSize(line->getDashLength()); + ocad_symbol->elen = ocad_symbol->len / (line->getHalfOuterDashes() ? 2 : 1); + ocad_symbol->gap = convertSize(line->getBreakLength()); + } + } + } + else + { + ocad_symbol->len = convertSize(line->getSegmentLength()); + ocad_symbol->elen = convertSize(line->getEndLength()); + } + + ocad_symbol->smin = line->getShowAtLeastOneSymbol() ? 0 : -1; + + // Double line + if (line->hasBorder() && (line->getBorder().isVisible() || line->getRightBorder().isVisible())) + { + ocad_symbol->dwidth = convertSize(line->getLineWidth() - line->getBorder().width + 2 * line->getBorder().shift); + if (line->getBorder().dashed && !line->getRightBorder().dashed) + ocad_symbol->dmode = 2; + else + ocad_symbol->dmode = line->getBorder().dashed ? 3 : 1; + // ocad_symbol->dflags + + ocad_symbol->lwidth = convertSize(line->getBorder().width); + ocad_symbol->rwidth = convertSize(line->getRightBorder().width); + + ocad_symbol->lcolor = convertColor(line->getBorder().color); + ocad_symbol->rcolor = convertColor(line->getRightBorder().color); + + if (line->getBorder().dashed) + { + ocad_symbol->dlen = convertSize(line->getBorder().dash_length); + ocad_symbol->dgap = convertSize(line->getBorder().break_length); + } + else if (line->getRightBorder().dashed) + { + ocad_symbol->dlen = convertSize(line->getRightBorder().dash_length); + ocad_symbol->dgap = convertSize(line->getRightBorder().break_length); + } + + if (((line->getBorder().dashed && line->getRightBorder().dashed) && + (line->getBorder().dash_length != line->getRightBorder().dash_length || + line->getBorder().break_length != line->getRightBorder().break_length)) || + (!line->getBorder().dashed && line->getRightBorder().dashed)) + { + addWarning(tr("In line symbol \"%1\", cannot export the borders correctly.").arg(line->getPlainTextName())); + } + } + + // Mid symbol + OCADPoint* pattern_buffer = ocad_symbol->pts; + ocad_symbol->smnpts = exportPattern(line->getMidSymbol(), &pattern_buffer); + ocad_symbol->snum = line->getMidSymbolsPerSpot(); + ocad_symbol->sdist = convertSize(line->getMidSymbolDistance()); + + // No secondary symbol + ocad_symbol->ssnpts = 0; + + // Export dash symbol as corner symbol + ocad_symbol->scnpts = exportPattern(line->getDashSymbol(), &pattern_buffer); + + // Start symbol + ocad_symbol->sbnpts = exportPattern(line->getStartSymbol(), &pattern_buffer); + + // End symbol + ocad_symbol->senpts = exportPattern(line->getEndSymbol(), &pattern_buffer); + + Q_ASSERT((u8*)ocad_symbol + data_size == (u8*)pattern_buffer); + return ocad_symbol->number; +} + +s16 OCAD8FileExport::exportAreaSymbol(const AreaSymbol* area) +{ + int data_size = (sizeof(OCADAreaSymbol) - sizeof(OCADPoint)); + for (int i = 0, end = area->getNumFillPatterns(); i < end; ++i) + { + if (area->getFillPattern(i).type == AreaSymbol::FillPattern::PointPattern) + { + data_size += getPatternSize(area->getFillPattern(i).point); + break; + } + } + OCADAreaSymbol* ocad_symbol = (OCADAreaSymbol*)ocad_symbol_new(file, data_size); + exportCommonSymbolFields(area, (OCADSymbol*)ocad_symbol, data_size); + + // Basic settings + ocad_symbol->type = OCAD_AREA_SYMBOL; + ocad_symbol->extent = 0; + if (area->getColor() != NULL) + { + ocad_symbol->fill = 1; + ocad_symbol->color = convertColor(area->getColor()); + } + + // Hatch + ocad_symbol->hmode = 0; + for (int i = 0, end = area->getNumFillPatterns(); i < end; ++i) + { + const AreaSymbol::FillPattern& pattern = area->getFillPattern(i); + if (pattern.type == AreaSymbol::FillPattern::LinePattern) + { + if ( (ocad_symbol->hmode == 1 && ocad_symbol->hcolor != convertColor(pattern.line_color)) || + ocad_symbol->hmode == 2 ) + { + addWarning(tr("In area symbol \"%1\", skipping a fill pattern.").arg(area->getPlainTextName())); + continue; + } + + if (pattern.rotatable) + ocad_symbol->base_flags |= 1; + + ++ocad_symbol->hmode; + if (ocad_symbol->hmode == 1) + { + ocad_symbol->hcolor = convertColor(pattern.line_color); + ocad_symbol->hwidth = convertSize(pattern.line_width); + ocad_symbol->hdist = convertSize(pattern.line_spacing - pattern.line_width); + ocad_symbol->hangle1 = convertRotation(pattern.angle); + } + else if (ocad_symbol->hmode == 2) + { + ocad_symbol->hwidth = (ocad_symbol->hwidth + convertSize(pattern.line_width)) / 2; + ocad_symbol->hdist = (ocad_symbol->hdist + convertSize(pattern.line_spacing - pattern.line_width)) / 2; + ocad_symbol->hangle2 = convertRotation(pattern.angle); + } + } + } + + // Struct + PointSymbol* point_pattern = NULL; + for (int i = 0, end = area->getNumFillPatterns(); i < end; ++i) + { + const AreaSymbol::FillPattern& pattern = area->getFillPattern(i); + if (pattern.type == AreaSymbol::FillPattern::PointPattern) + { + if (pattern.rotatable) + ocad_symbol->base_flags |= 1; + + ++ocad_symbol->pmode; + if (ocad_symbol->pmode == 1) + { + ocad_symbol->pwidth = convertSize(pattern.point_distance); + ocad_symbol->pheight = convertSize(pattern.line_spacing); + ocad_symbol->pangle = convertRotation(pattern.angle); + point_pattern = pattern.point; + } + else if (ocad_symbol->pmode == 2) + { + // NOTE: This is only a heuristic which works for the orienteering symbol sets, not a real conversion, which would be impossible in most cases. + // There are no further checks done to find out if the conversion is applicable because with these checks, already a tiny (not noticeable) error + // in the symbol definition would make it take the wrong choice. + addWarning(tr("In area symbol \"%1\", assuming a \"shifted rows\" point pattern. This might be correct as well as incorrect.").arg(area->getPlainTextName())); + + if (pattern.line_offset != 0) + ocad_symbol->pheight /= 2; + else + ocad_symbol->pwidth /= 2; + + break; + } + } + } + + if (point_pattern) + { + OCADPoint* pattern_buffer = ocad_symbol->pts; + ocad_symbol->npts = exportPattern(point_pattern, &pattern_buffer); + Q_ASSERT((u8*)ocad_symbol + data_size == (u8*)pattern_buffer); + } + return ocad_symbol->number; +} + +s16 OCAD8FileExport::exportTextSymbol(const TextSymbol* text) +{ + int data_size = sizeof(OCADTextSymbol); + OCADTextSymbol* ocad_symbol = (OCADTextSymbol*)ocad_symbol_new(file, data_size); + exportCommonSymbolFields(text, (OCADSymbol*)ocad_symbol, data_size); + + ocad_symbol->type = OCAD_TEXT_SYMBOL; + ocad_symbol->subtype = 1; + ocad_symbol->extent = 0; + + convertPascalString(text->getFontFamily(), ocad_symbol->font, 32); + ocad_symbol->color = convertColor(text->getColor()); + ocad_symbol->dpts = qRound(10 * text->getFontSize() / 25.4 * 72.0); + ocad_symbol->bold = text->isBold() ? 700 : 400; + ocad_symbol->italic = text->isItalic() ? 1 : 0; + //ocad_symbol->charset + ocad_symbol->cspace = convertSize(1000 * text->getCharacterSpacing()); + if (ocad_symbol->cspace != 0) + addWarning(tr("In text symbol %1: custom character spacing is set, its implementation does not match OCAD's behavior yet").arg(text->getPlainTextName())); + ocad_symbol->wspace = 100; + ocad_symbol->halign = 0; // Default value, we might have to change this or even create copies of this symbol with other alignments later + double absolute_line_spacing = text->getLineSpacing() * (text->getFontMetrics().lineSpacing() / text->calculateInternalScaling()); + ocad_symbol->lspace = qRound(absolute_line_spacing / (text->getFontSize() * 0.01)); + ocad_symbol->pspace = convertSize(1000 * text->getParagraphSpacing()); + if (text->isUnderlined()) + addWarning(tr("In text symbol %1: ignoring underlining").arg(text->getPlainTextName())); + if (text->usesKerning()) + addWarning(tr("In text symbol %1: ignoring kerning").arg(text->getPlainTextName())); + + ocad_symbol->under = text->hasLineBelow() ? 1 : 0; + ocad_symbol->ucolor = convertColor(text->getLineBelowColor()); + ocad_symbol->uwidth = convertSize(1000 * text->getLineBelowWidth()); + ocad_symbol->udist = convertSize(1000 * text->getLineBelowDistance()); + + ocad_symbol->ntabs = text->getNumCustomTabs(); + for (int i = 0; i < qMin((s16)32, ocad_symbol->ntabs); ++i) + ocad_symbol->tab[i] = convertSize(text->getCustomTab(i)); + + if (text->getFramingMode() != TextSymbol::NoFraming && text->getFramingColor() != NULL) + { + ocad_symbol->fcolor = convertColor(text->getFramingColor()); + if (text->getFramingMode() == TextSymbol::ShadowFraming) + { + ocad_symbol->fmode = 1; + ocad_symbol->fdx = convertSize(text->getFramingShadowXOffset()); + ocad_symbol->fdy = -1 * convertSize(text->getFramingShadowYOffset()); + } + else if (text->getFramingMode() == TextSymbol::LineFraming) + { + ocad_symbol->fmode = 2; + ocad_symbol->fdpts = convertSize(text->getFramingLineHalfWidth()); + } + else + Q_ASSERT(false); + } + + return ocad_symbol->number; +} + +void OCAD8FileExport::setTextSymbolFormatting(OCADTextSymbol* ocad_symbol, TextObject* formatting) +{ + if (formatting->getHorizontalAlignment() == TextObject::AlignLeft) + ocad_symbol->halign = 0; + else if (formatting->getHorizontalAlignment() == TextObject::AlignHCenter) + ocad_symbol->halign = 1; + else if (formatting->getHorizontalAlignment() == TextObject::AlignRight) + ocad_symbol->halign = 2; +} + +std::set< s16 > OCAD8FileExport::exportCombinedSymbol(const CombinedSymbol* combination) +{ + // Insert public parts + std::vector map_bitfield; + map_bitfield.assign(map->getNumSymbols(), false); + map_bitfield[map->findSymbolIndex(combination)] = true; + map->determineSymbolUseClosure(map_bitfield); + + std::set result; + for (size_t i = 0, end = map_bitfield.size(); i < end; ++i) + { + if (map_bitfield[i] && symbol_index.contains(map->getSymbol(i))) + { + result.insert(symbol_index[map->getSymbol(i)].begin(), + symbol_index[map->getSymbol(i)].end()); + } + } + + // Insert private parts + for (int i = 0; i < combination->getNumParts(); ++i) + { + if (combination->isPartPrivate(i)) + { + const Symbol* part = combination->getPart(i); + int index = 0; + if (part->getType() == Symbol::Line) + index = exportLineSymbol(part->asLine()); + else if (part->getType() == Symbol::Area) + index = exportAreaSymbol(part->asArea()); + else + Q_ASSERT(false); + result.insert(index); + } + } + + return result; +} + +u16 OCAD8FileExport::exportCoordinates(const MapCoordVector& coords, OCADPoint** buffer, const Symbol* symbol) +{ + s16 num_points = 0; + bool curve_start = false; + bool hole_point = false; + bool curve_continue = false; + for (size_t i = 0, end = coords.size(); i < end; ++i) + { + const MapCoord& point = coords[i]; + OCADPoint p = convertPoint(point); + if (point.isDashPoint()) + { + if (symbol == NULL || symbol->getType() != Symbol::Line) + p.y |= PY_CORNER; + else + { + const LineSymbol* line_symbol = static_cast(symbol); + if ((line_symbol->getDashSymbol() == NULL || line_symbol->getDashSymbol()->isEmpty()) && line_symbol->isDashed()) + p.y |= PY_DASH; + else + p.y |= PY_CORNER; + } + } + if (curve_start) + p.x |= PX_CTL1; + if (hole_point) + p.y |= PY_HOLE; + if (curve_continue) + p.x |= PX_CTL2; + + curve_continue = curve_start; + curve_start = point.isCurveStart(); + hole_point = point.isHolePoint(); + + **buffer = p; + ++(*buffer); + ++num_points; + } + return num_points; +} + +u16 OCAD8FileExport::exportTextCoordinates(TextObject* object, OCADPoint** buffer) +{ + if (object->getNumLines() == 0) + return 0; + + QTransform text_to_map = object->calcTextToMapTransform(); + QTransform map_to_text = object->calcMapToTextTransform(); + + if (object->hasSingleAnchor()) + { + // Create 5 coordinates: + // 0 - baseline anchor point + // 1 - bottom left + // 2 - bottom right + // 3 - top right + // 4 - top left + + QPointF anchor = QPointF(object->getAnchorCoordF()); + QPointF anchor_text = map_to_text.map(anchor); + + TextObjectLineInfo* line0 = object->getLineInfo(0); + **buffer = convertPoint(MapCoord(text_to_map.map(QPointF(anchor_text.x(), line0->line_y)))); + ++(*buffer); + + QRectF bounding_box_text; + for (int i = 0; i < object->getNumLines(); ++i) + { + TextObjectLineInfo* info = object->getLineInfo(i); + rectIncludeSafe(bounding_box_text, QPointF(info->line_x, info->line_y - info->ascent)); + rectIncludeSafe(bounding_box_text, QPointF(info->line_x + info->width, info->line_y + info->descent)); + } + + **buffer = convertPoint(MapCoord(text_to_map.map(bounding_box_text.bottomLeft()))); + ++(*buffer); + **buffer = convertPoint(MapCoord(text_to_map.map(bounding_box_text.bottomRight()))); + ++(*buffer); + **buffer = convertPoint(MapCoord(text_to_map.map(bounding_box_text.topRight()))); + ++(*buffer); + **buffer = convertPoint(MapCoord(text_to_map.map(bounding_box_text.topLeft()))); + ++(*buffer); + + return 5; + } + else + { + // As OCD 8 only supports Top alignment, we have to replace the top box coordinates by the top coordinates of the first line + const TextSymbol* text_symbol = static_cast(object->getSymbol()); + QFontMetricsF metrics = text_symbol->getFontMetrics(); + double internal_scaling = text_symbol->calculateInternalScaling(); + TextObjectLineInfo* line0 = object->getLineInfo(0); + + double new_top = (object->getVerticalAlignment() == TextObject::AlignTop) ? (-object->getBoxHeight() / 2) : ((line0->line_y - line0->ascent) / internal_scaling); + // Account for extra internal leading + double top_adjust = -text_symbol->getFontSize() + (metrics.ascent() + metrics.descent() + 0.5) / internal_scaling; + new_top = new_top - top_adjust; + + QTransform transform; + transform.rotate(-object->getRotation() * 180 / M_PI); + **buffer = convertPoint(MapCoord(transform.map(QPointF(-object->getBoxWidth() / 2, object->getBoxHeight() / 2)) + object->getAnchorCoordF())); + ++(*buffer); + **buffer = convertPoint(MapCoord(transform.map(QPointF(object->getBoxWidth() / 2, object->getBoxHeight() / 2)) + object->getAnchorCoordF())); + ++(*buffer); + **buffer = convertPoint(MapCoord(transform.map(QPointF(object->getBoxWidth() / 2, new_top)) + object->getAnchorCoordF())); + ++(*buffer); + **buffer = convertPoint(MapCoord(transform.map(QPointF(-object->getBoxWidth() / 2, new_top)) + object->getAnchorCoordF())); + ++(*buffer); + + return 4; + } +} + +int OCAD8FileExport::getOcadColor(QRgb rgb) +{ + // Simple comparison function which takes the best matching color. + static const QColor ocad_colors[16] = { + QColor( 0, 0, 0).toHsv(), + QColor(128, 0, 0).toHsv(), + QColor(0, 128, 0).toHsv(), + QColor(128, 128, 0).toHsv(), + QColor( 0, 0, 128).toHsv(), + QColor(128, 0, 128).toHsv(), + QColor( 0, 128, 128).toHsv(), + QColor(128, 128, 128).toHsv(), + QColor(192, 192, 192).toHsv(), + QColor(255, 0, 0).toHsv(), + QColor( 0, 255, 0).toHsv(), + QColor(255, 255, 0).toHsv(), + QColor( 0, 0, 255).toHsv(), + QColor(255, 0, 255).toHsv(), + QColor( 0, 255, 255).toHsv(), + QColor(255, 255, 255).toHsv() + }; + + // Return white for transparent areas + if (qAlpha(rgb) < 128) + return 15; + + QColor color = QColor(rgb).toHsv(); + int best_index = 0; + float best_distance = 999999; + for (int i = 0; i < 16; ++i) + { + int hue_dist = qAbs(color.hue() - ocad_colors[i].hue()); + hue_dist = qMin(hue_dist, 360 - hue_dist); + float distance = qPow(hue_dist, 2) + + 0.1f * qPow(color.saturation() - ocad_colors[i].saturation(), 2) + + 0.1f * qPow(color.value() - ocad_colors[i].value(), 2); + + // (Too much) manual tweaking for orienteering colors + if (i == 1) + distance *= 1.5; // Dark red + else if (i == 3) + distance *= 2; // Olive + else if (i == 7) + distance *= 2; // Dark gray + else if (i == 8) + distance *= 3; // Light gray + else if (i == 11) + distance *= 2; // Yellow + else if (i == 9) + distance *= 3; // Red is unlikely + else if (i == 15) + distance *= 4; // White is very unlikely + + if (distance < best_distance) + { + best_distance = distance; + best_index = i; + } + } + return best_index; +} + +s16 OCAD8FileExport::getPointSymbolExtent(const PointSymbol* symbol) +{ + if (!symbol) + return 0; + QRectF extent; + for (int i = 0; i < symbol->getNumElements(); ++i) + { + QScopedPointer object(symbol->getElementObject(i)->duplicate()); + object->setSymbol(symbol->getElementSymbol(i), true); + object->update(); + rectIncludeSafe(extent, object->getExtent()); + object->clearRenderables(); + } + float float_extent = 0.5f * qMax(extent.width(), extent.height()); + if (symbol->getInnerColor() != NULL) + float_extent = qMax(float_extent, 0.001f * symbol->getInnerRadius()); + if (symbol->getOuterColor() != NULL) + float_extent = qMax(float_extent, 0.001f * (symbol->getInnerRadius() + symbol->getOuterWidth())); + return convertSize(1000 * float_extent); +} + +void OCAD8FileExport::convertPascalString(const QString& text, char* buffer, int buffer_size) +{ + Q_ASSERT(buffer_size <= 256); // not possible to store a bigger length in the first byte + int max_size = buffer_size - 1; + + if (text.length() > max_size) + addStringTruncationWarning(text, max_size); + + QByteArray data = encoding_1byte->fromUnicode(text); + int min_size = qMin(text.length(), max_size); + *((unsigned char *)buffer) = min_size; + memcpy(buffer + 1, data.data(), min_size); +} + +void OCAD8FileExport::convertCString(const QString& text, unsigned char* buffer, int buffer_size) +{ + if (text.length() + 1 > buffer_size) + addStringTruncationWarning(text, buffer_size - 1); + + QByteArray data = encoding_1byte->fromUnicode(text); + int min_size = qMin(buffer_size - 1, data.length()); + memcpy(buffer, data.data(), min_size); + buffer[min_size] = 0; +} + +int OCAD8FileExport::convertWideCString(const QString& text, unsigned char* buffer, int buffer_size) +{ + // Convert text to Windows-OCAD format: + // - if it starts with a newline, add another + // - convert \n to \r\n + QString exported_text; + if (text.startsWith(QLatin1Char('\n'))) + exported_text = QLatin1Char('\n') + text; + else + exported_text = text; + exported_text.replace(QLatin1Char('\n'), QLatin1String("\r\n")); + + if (2 * (exported_text.length() + 1) > buffer_size) + addStringTruncationWarning(exported_text, buffer_size - 1); + + // Do not add a byte order mark by using QTextCodec::IgnoreHeader + QTextEncoder* encoder = encoding_2byte->makeEncoder(QTextCodec::IgnoreHeader); + QByteArray data = encoder->fromUnicode(exported_text); + delete encoder; + + int min_size = qMin(buffer_size - 2, data.length()); + memcpy(buffer, data.data(), min_size); + buffer[min_size] = 0; + buffer[min_size + 1] = 0; + return min_size + 2; +} + +int OCAD8FileExport::convertRotation(float angle) +{ + return qRound(10 * (angle * 180 / M_PI)); +} + +namespace +{ + constexpr s32 convertPointMember(s32 value) + { + return (value < -5) ? s32(0x80000000u | ((0x7fffffu & u32((value-4)/10)) << 8)) : s32((0x7fffffu & u32((value+5)/10)) << 8); + } + + // convertPointMember() shall round half up. + Q_STATIC_ASSERT(convertPointMember(-16) == s32(0xfffffe00u)); // __ down __ + Q_STATIC_ASSERT(convertPointMember(-15) == s32(0xffffff00u)); // up + Q_STATIC_ASSERT(convertPointMember( -6) == s32(0xffffff00u)); // __ down __ + Q_STATIC_ASSERT(convertPointMember( -5) == s32(0x00000000u)); // up + Q_STATIC_ASSERT(convertPointMember( -1) == s32(0x00000000u)); // up + Q_STATIC_ASSERT(convertPointMember( 0) == s32(0x00000000u)); // unchanged + Q_STATIC_ASSERT(convertPointMember( +1) == s32(0x00000000u)); // down + Q_STATIC_ASSERT(convertPointMember( +4) == s32(0x00000000u)); // __ down __ + Q_STATIC_ASSERT(convertPointMember( +5) == s32(0x00000100u)); // up + Q_STATIC_ASSERT(convertPointMember(+14) == s32(0x00000100u)); // __ down __ + Q_STATIC_ASSERT(convertPointMember(+15) == s32(0x00000200u)); // up + +#ifdef MAPPER_DEVELOPMENT_BUILD + namespace broken + { + // Previous, broken implementation (#749) + // Left here for reference. + constexpr s32 convertPointMember(s32 value) + { + return (value < 0) ? (0x80000000 | ((0x7fffffu & ((value-5)/10)) << 8)) : ((0x7fffffu & ((value+5)/10)) << 8); + } + } + // Actual behaviour of the broken implementation + Q_STATIC_ASSERT(broken::convertPointMember(-16) == s32(0xfffffe00u)); // down + Q_STATIC_ASSERT(broken::convertPointMember(-15) == s32(0xfffffe00u)); // __ down __ (should be up) + Q_STATIC_ASSERT(broken::convertPointMember(-14) == s32(0xffffff00u)); // up + Q_STATIC_ASSERT(broken::convertPointMember( -6) == s32(0xffffff00u)); // down + Q_STATIC_ASSERT(broken::convertPointMember( -5) == s32(0xffffff00u)); // __ down __ (should be up) + Q_STATIC_ASSERT(broken::convertPointMember( -4) == s32(0x80000000u)); // wrong (should be 0x00000000u) + Q_STATIC_ASSERT(broken::convertPointMember( -3) == s32(0x80000000u)); // wrong (should be 0x00000000u) + Q_STATIC_ASSERT(broken::convertPointMember( -2) == s32(0x80000000u)); // wrong (should be 0x00000000u) + Q_STATIC_ASSERT(broken::convertPointMember( -1) == s32(0x80000000u)); // wrong (should be 0x00000000u) + Q_STATIC_ASSERT(broken::convertPointMember( 0) == s32(0x00000000u)); // unchanged + Q_STATIC_ASSERT(broken::convertPointMember( +1) == s32(0x00000000u)); // down + Q_STATIC_ASSERT(broken::convertPointMember( +4) == s32(0x00000000u)); // __ down __ + Q_STATIC_ASSERT(broken::convertPointMember( +5) == s32(0x00000100u)); // up + Q_STATIC_ASSERT(broken::convertPointMember(+14) == s32(0x00000100u)); // __ down __ + Q_STATIC_ASSERT(broken::convertPointMember(+15) == s32(0x00000200u)); // up +#endif +} + +OCADPoint OCAD8FileExport::convertPoint(qint32 x, qint32 y) +{ + return { convertPointMember(x), convertPointMember(-y) }; +} + +OCADPoint OCAD8FileExport::convertPoint(const MapCoord& coord) +{ + return convertPoint(coord.nativeX(), coord.nativeY()); +} + +s32 OCAD8FileExport::convertSize(qint32 size) +{ + return (s32)((size+5) / 10); +} + +s16 OCAD8FileExport::convertColor(const MapColor* color) const +{ + int index = map->findColorIndex(color); + if (index >= 0) + { + return uses_registration_color ? (index + 1) : index; + } + return 0; +} + +double OCAD8FileExport::convertTemplateScale(double mapper_scale) +{ + return mapper_scale * (1 / 0.01); +} + +void OCAD8FileExport::addStringTruncationWarning(const QString& text, int truncation_pos) +{ + QString temp = text; + temp.insert(truncation_pos, QLatin1String("|||")); + addWarning(tr("String truncated (truncation marked with three '|'): %1").arg(temp)); +} diff --git a/src/file_format_ocad8.h b/src/file_format_ocad8.h new file mode 100644 index 0000000..e21fada --- /dev/null +++ b/src/file_format_ocad8.h @@ -0,0 +1,37 @@ +/* + * Copyright 2012, 2013 Pete Curtis + * + * This file is part of OpenOrienteering. + * + * OpenOrienteering is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenOrienteering is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenOrienteering. If not, see . + */ + +#ifndef OCAD8_FILE_IMPORT_H +#define OCAD8_FILE_IMPORT_H + +#include "file_format.h" + +/** Representation of the format used by OCAD 8. + */ +class OCAD8FileFormat : public FileFormat +{ +public: + OCAD8FileFormat(); + + bool understands(const unsigned char *buffer, size_t sz) const; + virtual Importer* createImporter(QIODevice* stream, Map *map, MapView *view) const; + virtual Exporter* createExporter(QIODevice* stream, Map* map, MapView* view) const; +}; + +#endif // OCAD8_FILE_IMPORT_H diff --git a/src/file_format_ocad8_p.h b/src/file_format_ocad8_p.h new file mode 100644 index 0000000..f6b756c --- /dev/null +++ b/src/file_format_ocad8_p.h @@ -0,0 +1,229 @@ +/* + * Copyright 2012, 2013 Pete Curtis + * Copyright 2014, 2015 Kai Pastor + * + * This file is part of OpenOrienteering. + * + * OpenOrienteering is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenOrienteering is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenOrienteering. If not, see . + */ + +#ifndef _OPENORIENTEERING_FILE_FORMAT_OCAD_P_H +#define _OPENORIENTEERING_FILE_FORMAT_OCAD_P_H + +#include "file_import_export.h" + +#include + +#include + +#include "libocad/libocad.h" + +#include "core/map_coord.h" + +class Map; +class MapColor; +class MapPart; +class Object; +class PointObject; +class TextObject; +class Symbol; +class AreaSymbol; +class CombinedSymbol; +class LineSymbol; +class PointSymbol; +class Template; +class TextSymbol; + +/** Importer for OCD version 8 files. */ +class OCAD8FileImport : public Importer +{ + friend class OcdFileImport; +Q_OBJECT +private: + /// Information about an OCAD rectangle symbol + struct RectangleInfo + { + LineSymbol* border_line; + double corner_radius; + bool has_grid; + + // Only valid if has_grid is true + LineSymbol* inner_line; + TextSymbol* text; + bool number_from_bottom; + double cell_width; + double cell_height; + int unnumbered_cells; + QString unnumbered_text; + }; + +public: + OCAD8FileImport(QIODevice* stream, Map *map, MapView *view); + ~OCAD8FileImport(); + + void setStringEncodings(const char *narrow, const char *wide = "UTF-16LE"); + +protected: + void import(bool load_symbols_only); + + // Symbol import + Symbol *importPointSymbol(const OCADPointSymbol *ocad_symbol); + Symbol *importLineSymbol(const OCADLineSymbol *ocad_symbol); + Symbol *importAreaSymbol(const OCADAreaSymbol *ocad_symbol); + Symbol *importTextSymbol(const OCADTextSymbol *ocad_symbol); + RectangleInfo *importRectSymbol(const OCADRectSymbol *ocad_symbol); + + // Object import + Object *importObject(const OCADObject *ocad_object, MapPart* part); + bool importRectangleObject(const OCADObject* ocad_object, MapPart* part, const RectangleInfo& rect); + + // String import + virtual void importString(OCADStringEntry *entry); + + Template *importTemplate(OCADCString* ocad_str); + OCADBackground importBackground(const QByteArray& data); + /// @deprecated Replaced by Template *importTemplate(OCADCString* string). + Template *importRasterTemplate(const OCADBackground &background); + + // Some helper functions that are used in multiple places + PointSymbol *importPattern(s16 npts, OCADPoint *pts); + void fillCommonSymbolFields(Symbol *symbol, const OCADSymbol *ocad_symbol); + void setPathHolePoint(Object *object, int i); + void fillPathCoords(Object* object, bool is_area, u16 npts, const OCADPoint* pts); + bool fillTextPathCoords(TextObject* object, TextSymbol* symbol, u16 npts, OCADPoint* pts); + + + // Unit conversion functions + QString convertPascalString(const char *p); + QString convertCString(const char *p, size_t n, bool ignore_first_newline); + QString convertWideCString(const char *p, size_t n, bool ignore_first_newline); + float convertRotation(int angle); + void convertPoint(MapCoord &c, s32 ocad_x, s32 ocad_y); + qint32 convertSize(int ocad_size); + const MapColor *convertColor(int color); + double convertTemplateScale(double ocad_scale); + + static bool isRasterImageFile(const QString &filename); + +private: + /// Handle to the open OCAD file + OCADFile *file; + + /// Character encoding to use for 1-byte (narrow) strings + QTextCodec *encoding_1byte; + + /// Character encoding to use for 2-byte (wide) strings + QTextCodec *encoding_2byte; + + /// maps OCAD color number to oo-mapper color object + QHash color_index; + + /// maps OCAD symbol number to oo-mapper symbol object + QHash symbol_index; + + /// maps OO Mapper text symbol pointer to OCAD text symbol horizontal alignment (stored in objects instead of symbols in OO Mapper) + QHash text_halign_map; + + /// maps OCAD symbol number to rectangle information struct + QHash rectangle_info; + + /// Offset between OCAD map origin and Mapper map origin (in Mapper coordinates) + qint64 offset_x, offset_y; +}; + + +/** Exporter for OCD version 8 files. */ +class OCAD8FileExport : public Exporter +{ +Q_OBJECT +public: + OCAD8FileExport(QIODevice* stream, Map *map, MapView *view); + ~OCAD8FileExport(); + + void doExport(); + +protected: + + // Symbol export + void exportCommonSymbolFields(const Symbol* symbol, OCADSymbol* ocad_symbol, int size); + int getPatternSize(const PointSymbol* point); + s16 exportPattern(const PointSymbol* point, OCADPoint** buffer); // returns the number of written coordinates, including the headers + s16 exportSubPattern(const Object* object, const Symbol* symbol, OCADPoint** buffer); + + s16 exportPointSymbol(const PointSymbol* point); + s16 exportLineSymbol(const LineSymbol* line); + s16 exportAreaSymbol(const AreaSymbol* area); + s16 exportTextSymbol(const TextSymbol* text); + void setTextSymbolFormatting(OCADTextSymbol* ocad_symbol, TextObject* formatting); + std::set exportCombinedSymbol(const CombinedSymbol* combination); + + // Helper functions + /// Returns the number of exported coordinates. If not NULL, the given symbol is used to determine the meaning of dash points. + u16 exportCoordinates(const MapCoordVector& coords, OCADPoint** buffer, const Symbol* symbol); + u16 exportTextCoordinates(TextObject* object, OCADPoint** buffer); + int getOcadColor(QRgb rgb); + s16 getPointSymbolExtent(const PointSymbol* symbol); + + // Conversion functions + void convertPascalString(const QString& text, char* buffer, int buffer_size); + void convertCString(const QString& text, unsigned char* buffer, int buffer_size); + /// Returns the number of bytes written into buffer + int convertWideCString(const QString& text, unsigned char* buffer, int buffer_size); + int convertRotation(float angle); + OCADPoint convertPoint(qint32 x, qint32 y); + /// Attention: this ignores the coordinate flags! + OCADPoint convertPoint(const MapCoord& coord); + s32 convertSize(qint32 size); + s16 convertColor(const MapColor* color) const; + double convertTemplateScale(double mapper_scale); + +private: + /** Indicates that the map uses the special registration color. */ + bool uses_registration_color; + + /// Handle to the open OCAD file + OCADFile *file; + + /// Character encoding to use for 1-byte (narrow) strings + QTextCodec *encoding_1byte; + + /// Character encoding to use for 2-byte (wide) strings + QTextCodec *encoding_2byte; + + /// Set of used symbol numbers. Needed to ensure uniqueness of the symbol number as Mapper does not enforce it, + /// but the indexing of symbols in OCAD depends on it. + std::set symbol_numbers; + + /// Maps OO Mapper symbol pointer to a list of OCAD symbol numbers. + /// Usually the list contains only one entry, except for combined symbols, + /// for which it contains the indices of all basic parts + QHash > symbol_index; + + /// In .ocd 8, text alignment needs to be specified in the text symbols instead of objects, so it is possible + /// that multiple ocd text symbols have to be created for one native TextSymbol. + /// This structure maps text symbols to lists containing information about the already created ocd symbols. + /// The TextObject in each pair just gives information about the alignment option used for the symbol indexed by the + /// second part of the pair. + /// If there is no entry for a TextSymbol in this map yet, no object using this symbol has been encountered yet, + /// no no specific formatting was set in the corresponding symbol (which has to be looked up using symbol_index). + typedef std::vector< std::pair< TextObject*, s16 > > TextFormatList; + QHash text_format_map; + + /// Helper object for pattern export + PointObject* origin_point_object; + + void addStringTruncationWarning(const QString& text, int truncation_pos); +}; + +#endif diff --git a/src/file_format_registry.cpp b/src/file_format_registry.cpp new file mode 100644 index 0000000..e9aeda6 --- /dev/null +++ b/src/file_format_registry.cpp @@ -0,0 +1,90 @@ +/* + * Copyright 2012, 2013 Pete Curtis + * Copyright 2013, 2015, 2016 Kai Pastor + * + * This file is part of OpenOrienteering. + * + * OpenOrienteering is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenOrienteering is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenOrienteering. If not, see . + */ + +#include "file_format_registry.h" + +#include + +#include "map.h" +#include "symbol.h" +#include "template.h" +#include "object.h" + + +FileFormatRegistry FileFormats; + + +// ### FormatRegistry ### + +void FileFormatRegistry::registerFormat(FileFormat *format) +{ + fmts.push_back(format); + if (fmts.size() == 1) default_format_id = format->id(); + Q_ASSERT(findFormatForFilename(QLatin1String("filename.") + format->primaryExtension()) != nullptr); // There may be more than one format! + Q_ASSERT(findFormatByFilter(format->filter()) == format); // The filter shall be unique at least by description. +} + +std::unique_ptr FileFormatRegistry::unregisterFormat(const FileFormat* format) +{ + std::unique_ptr ret; + auto it = std::find(begin(fmts), end(fmts), format); + if (it != end(fmts)) + { + ret.reset(*it); + fmts.erase(it); + } + return ret; +} + +const FileFormat *FileFormatRegistry::findFormat(const char* id) const +{ + for (auto format : fmts) + { + if (qstrcmp(format->id(), id) == 0) return format; + } + return NULL; +} + +const FileFormat *FileFormatRegistry::findFormatByFilter(const QString& filter) const +{ + for (auto format : fmts) + { + if (format->filter() == filter) return format; + } + return NULL; +} + +const FileFormat *FileFormatRegistry::findFormatForFilename(const QString& filename) const +{ + QString file_extension = QFileInfo(filename).suffix(); + for (auto format : fmts) + { + if (format->fileExtensions().contains(file_extension, Qt::CaseInsensitive)) return format; + } + return NULL; +} + +FileFormatRegistry::~FileFormatRegistry() +{ + for (std::vector::reverse_iterator it = fmts.rbegin(); it != fmts.rend(); ++it) + { + delete *it; + } +} diff --git a/src/file_format_registry.h b/src/file_format_registry.h new file mode 100644 index 0000000..a687d18 --- /dev/null +++ b/src/file_format_registry.h @@ -0,0 +1,98 @@ +/* + * Copyright 2012, 2013 Pete Curtis + * Copyright 2013, 2016 Kai Pastor + * + * This file is part of OpenOrienteering. + * + * OpenOrienteering is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenOrienteering is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenOrienteering. If not, see . + */ + +#ifndef _OPENORIENTEERING_FILE_FORMAT_REGISTRY_H +#define _OPENORIENTEERING_FILE_FORMAT_REGISTRY_H + +#include +#include + +#include +#include + +class QIODevice; + +class Importer; +class Exporter; +class Map; +class MapView; + +class FileFormat; + +/** Provides a registry for file formats, and takes ownership of the supported format objects. + */ +class FileFormatRegistry +{ +public: + /** Creates an empty file format registry. + */ + FileFormatRegistry() {}; + + /** Destroys a file format registry. + */ + ~FileFormatRegistry(); + + /** Returns an immutable list of the available file formats. + */ + inline const std::vector &formats() const { return fmts; } + + /** Finds a file format with the given internal ID, or returns NULL if no format + * is found. + */ + const FileFormat *findFormat(const char* id) const; + + /** Finds a file format which implements the given filter, or returns NULL if no + * format is found. + */ + const FileFormat *findFormatByFilter(const QString& filter) const; + + /** Finds a file format whose file extension matches the fie extension of the given + * path, or returns NULL if no matching format is found. + */ + const FileFormat *findFormatForFilename(const QString& filename) const; + + /** Returns the ID of default file format for this registry. This will automatically + * be set to the first registered format. + */ + const char* defaultFormat() const { return default_format_id; } + + /** Registers a new file format. The registry takes ownership of the provided Format. + */ + void registerFormat(FileFormat *format); + + /** + * Unregisters a file format. + * + * Returns a non-const pointer to the file format and transfers ownership to the caller. + */ + std::unique_ptr unregisterFormat(const FileFormat *format); + +private: + std::vector fmts; + const char* default_format_id; +}; + +/** A FileFormatRegistry that is globally defined for convenience. Within the scope of a single + * application, you can simply use calls of the form "FileFormats.findFormat(...)". + */ +extern FileFormatRegistry FileFormats; + + +#endif // _OPENORIENTEERING_FILE_FORMAT_REGISTRY_H diff --git a/src/file_format_xml.cpp b/src/file_format_xml.cpp new file mode 100644 index 0000000..de0aefc --- /dev/null +++ b/src/file_format_xml.cpp @@ -0,0 +1,908 @@ +/* + * Copyright 2012 Pete Curtis + * Copyright 2012, 2013 Thomas Schöps + * Copyright 2012-2016 Kai Pastor + * + * This file is part of OpenOrienteering. + * + * OpenOrienteering is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenOrienteering is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenOrienteering. If not, see . + */ + +#include "file_format_xml.h" +#include "file_format_xml_p.h" + +#include +#include +#include +#include +#include +#include + +#ifdef QT_PRINTSUPPORT_LIB +# include +#endif + +#include "core/georeferencing.h" +#include "core/map_color.h" +#include "core/map_grid.h" +#include "core/map_printer.h" +#include "core/map_view.h" +#include "file_import_export.h" +#include "map.h" +#include "object.h" +#include "object_text.h" +#include "settings.h" +#include "symbol_area.h" +#include "symbol_combined.h" +#include "symbol_line.h" +#include "symbol_point.h" +#include "symbol_text.h" +#include "template.h" +#include "undo_manager.h" +#include "util/xml_stream_util.h" + +// ### XMLFileFormat definition ### + +const int XMLFileFormat::minimum_version = 2; +const int XMLFileFormat::current_version = 6; + +int XMLFileFormat::active_version = 5; // updated by XMLFileExporter::doExport() + +namespace { +const char* magic_string = "= len && memcmp(buffer, magic_string, len) == 0); +} + +Importer *XMLFileFormat::createImporter(QIODevice* stream, Map *map, MapView *view) const +{ + return new XMLFileImporter(stream, map, view); +} + +Exporter *XMLFileFormat::createExporter(QIODevice* stream, Map *map, MapView *view) const +{ + return new XMLFileExporter(stream, map, view); +} + + + +// ### A namespace which collects various string constants of type QLatin1String. ### + +namespace literal +{ + static const QLatin1String map("map"); + static const QLatin1String version("version"); + static const QLatin1String notes("notes"); + + static const QLatin1String barrier("barrier"); + static const QLatin1String required("required"); + + static const QLatin1String count("count"); + static const QLatin1String current("current"); + + static const QLatin1String georeferencing("georeferencing"); + + static const QLatin1String colors("colors"); + static const QLatin1String color("color"); + static const QLatin1String priority("priority"); + static const QLatin1String name("name"); + static const QLatin1String method("method"); + static const QLatin1String spotcolor("spotcolor"); + static const QLatin1String cmyk("cmyk"); + static const QLatin1String rgb("rgb"); + static const QLatin1String custom("custom"); + static const QLatin1String spotcolors("spotcolors"); + static const QLatin1String knockout("knockout"); + static const QLatin1String namedcolor("namedcolor"); + static const QLatin1String component("component"); + static const QLatin1String factor("factor"); + static const QLatin1String c("c"); + static const QLatin1String m("m"); + static const QLatin1String y("y"); + static const QLatin1String k("k"); + static const QLatin1String r("r"); + static const QLatin1String g("g"); + static const QLatin1String b("b"); + static const QLatin1String opacity("opacity"); + + static const QLatin1String symbols("symbols"); + static const QLatin1String symbol("symbol"); + + static const QLatin1String parts("parts"); + static const QLatin1String part("part"); + + static const QLatin1String templates("templates"); + static const QLatin1String template_string("template"); + static const QLatin1String first_front_template("first_front_template"); + + static const QLatin1String defaults("defaults"); + static const QLatin1String use_meters_per_pixel("use_meters_per_pixel"); + static const QLatin1String meters_per_pixel("meters_per_pixel"); + static const QLatin1String dpi("dpi"); + static const QLatin1String scale("scale"); + + static const QLatin1String view("view"); + static const QLatin1String area_hatching_enabled("area_hatching_enabled"); + static const QLatin1String baseline_view_enabled("baseline_view_enabled"); + static const QLatin1String grid("grid"); + static const QLatin1String map_view("map_view"); + + static const QLatin1String print("print"); + + static const QLatin1String undo("undo"); + static const QLatin1String redo("redo"); +} + + + +// ### XMLFileExporter definition ### + +XMLFileExporter::XMLFileExporter(QIODevice* stream, Map *map, MapView *view) +: Exporter(stream, map, view), + xml(stream) +{ + // Determine auto-formatting default from filename, if possible. + auto file = qobject_cast(stream); + bool auto_formatting = (file && file->fileName().contains(QLatin1String(".xmap"))); + setOption(QString::fromLatin1("autoFormatting"), auto_formatting); +} + +void XMLFileExporter::doExport() +{ + if (option(QString::fromLatin1("autoFormatting")).toBool()) + xml.setAutoFormatting(true); + + int current_version = XMLFileFormat::current_version; + bool retain_compatibility = Settings::getInstance().getSetting(Settings::General_RetainCompatiblity).toBool(); + XMLFileFormat::active_version = retain_compatibility ? current_version-1 : current_version; + + if (XMLFileFormat::active_version < 6 && map->getNumParts() != 1) + { + throw FileFormatException(tr("Older versions of Mapper do not support multiple map parts. To save the map in compatibility mode, you must first merge all map parts.")); + } + + xml.writeDefaultNamespace(mapper_namespace); + xml.writeStartDocument(); + + { + XmlElementWriter map_element(xml, literal::map); + map_element.writeAttribute(literal::version, XMLFileFormat::active_version); + + xml.writeTextElement(literal::notes, map->getMapNotes()); + + exportGeoreferencing(); + exportColors(); + + XmlElementWriter* barrier = NULL; + if (XMLFileFormat::active_version >= 6) + { + // Prevent Mapper versions < 0.6.0 from crashing + // when compatibilty mode is NOT activated + // Incompatible feature: dense coordinates + barrier = new XmlElementWriter(xml, literal::barrier); + barrier->writeAttribute(literal::version, 6); + barrier->writeAttribute(literal::required, "0.6.0"); + } + exportSymbols(); + exportMapParts(); + exportTemplates(); + exportView(); + exportPrint(); + delete barrier; + + // Prevent Mapper versions < 0.6.0 from crashing + // when compatibilty mode IS activated + // Incompatible feature: new undo step types + barrier = new XmlElementWriter(xml, literal::barrier); + barrier->writeAttribute(literal::version, 6); + barrier->writeAttribute(literal::required, "0.6.0"); + exportUndo(); + exportRedo(); + delete barrier; + } + + xml.writeEndDocument(); +} + +void XMLFileExporter::exportGeoreferencing() +{ + map->getGeoreferencing().save(xml); +} + +void XMLFileExporter::exportColors() +{ + XmlElementWriter all_colors_element(xml, literal::colors); + std::size_t num_colors = map->color_set->colors.size(); + all_colors_element.writeAttribute(literal::count, num_colors); + for (std::size_t i = 0; i < num_colors; ++i) + { + MapColor* color = map->color_set->colors[i]; + const MapColorCmyk &cmyk = color->getCmyk(); + XmlElementWriter color_element(xml, literal::color); + color_element.writeAttribute(literal::priority, color->getPriority()); + color_element.writeAttribute(literal::name, color->getName()); + color_element.writeAttribute(literal::c, cmyk.c, 3); + color_element.writeAttribute(literal::m, cmyk.m, 3); + color_element.writeAttribute(literal::y, cmyk.y, 3); + color_element.writeAttribute(literal::k, cmyk.k, 3); + color_element.writeAttribute(literal::opacity, color->getOpacity(), 3); + + if (color->getSpotColorMethod() != MapColor::UndefinedMethod) + { + XmlElementWriter spotcolors_element(xml, literal::spotcolors); + spotcolors_element.writeAttribute(literal::knockout, color->getKnockout()); + SpotColorComponent component; + switch(color->getSpotColorMethod()) + { + case MapColor::SpotColor: + xml.writeTextElement(literal::namedcolor, color->getSpotColorName()); + break; + case MapColor::CustomColor: + for (auto&& component : color->getComponents()) + { + XmlElementWriter component_element(xml, literal::component); + component_element.writeAttribute(literal::factor, component.factor); + component_element.writeAttribute(literal::spotcolor, component.spot_color->getPriority()); + } + default: + ; // nothing + } + } + + { + XmlElementWriter cmyk_element(xml, literal::cmyk); + switch(color->getCmykColorMethod()) + { + case MapColor::SpotColor: + cmyk_element.writeAttribute(literal::method, literal::spotcolor); + break; + case MapColor::RgbColor: + cmyk_element.writeAttribute(literal::method, literal::rgb); + break; + default: + cmyk_element.writeAttribute(literal::method, literal::custom); + } + } + + { + XmlElementWriter rgb_element(xml, literal::rgb); + switch(color->getCmykColorMethod()) + { + case MapColor::SpotColor: + rgb_element.writeAttribute(literal::method, literal::spotcolor); + break; + case MapColor::CmykColor: + rgb_element.writeAttribute(literal::method, literal::cmyk); + break; + default: + rgb_element.writeAttribute(literal::method, literal::custom); + } + const MapColorRgb &rgb = color->getRgb(); + rgb_element.writeAttribute(literal::r, rgb.r, 3); + rgb_element.writeAttribute(literal::g, rgb.g, 3); + rgb_element.writeAttribute(literal::b, rgb.b, 3); + } + } +} + +void XMLFileExporter::exportSymbols() +{ + XmlElementWriter symbols_element(xml, literal::symbols); + int num_symbols = map->getNumSymbols(); + symbols_element.writeAttribute(literal::count, num_symbols); + for (int i = 0; i < num_symbols; ++i) + { + map->getSymbol(i)->save(xml, *map); + } +} + +void XMLFileExporter::exportMapParts() +{ + XmlElementWriter parts_element(xml, literal::parts); + + int num_parts = map->getNumParts(); + parts_element.writeAttribute(literal::count, num_parts); + parts_element.writeAttribute(literal::current, map->current_part_index); + for (int i = 0; i < num_parts; ++i) + map->getPart(i)->save(xml); +} + +void XMLFileExporter::exportTemplates() +{ + XmlElementWriter templates_element(xml, literal::templates); + + int num_templates = map->getNumTemplates() + map->getNumClosedTemplates(); + templates_element.writeAttribute(literal::count, num_templates); + templates_element.writeAttribute(literal::first_front_template, map->first_front_template); + for (int i = 0; i < map->getNumTemplates(); ++i) + map->getTemplate(i)->saveTemplateConfiguration(xml, true); + for (int i = 0; i < map->getNumClosedTemplates(); ++i) + map->getClosedTemplate(i)->saveTemplateConfiguration(xml, false); + + { + XmlElementWriter defaults_element(xml, literal::defaults); + defaults_element.writeAttribute(literal::use_meters_per_pixel, map->image_template_use_meters_per_pixel); + defaults_element.writeAttribute(literal::meters_per_pixel, map->image_template_meters_per_pixel); + defaults_element.writeAttribute(literal::dpi, map->image_template_dpi); + defaults_element.writeAttribute(literal::scale, map->image_template_scale); + } +} + +void XMLFileExporter::exportView() +{ + XmlElementWriter view_element(xml, literal::view); + + view_element.writeAttribute(literal::area_hatching_enabled, bool(map->renderable_options & Symbol::RenderAreasHatched)); + view_element.writeAttribute(literal::baseline_view_enabled, bool(map->renderable_options & Symbol::RenderBaselines)); + + map->getGrid().save(xml); + + if (view) + view->save(xml, literal::map_view); +} + +void XMLFileExporter::exportPrint() +{ + if (map->hasPrinterConfig()) + map->printerConfig().save(xml, literal::print); +} + +void XMLFileExporter::exportUndo() +{ + map->undoManager().saveUndo(xml); +} + +void XMLFileExporter::exportRedo() +{ + map->undoManager().saveRedo(xml); +} + + + +// ### XMLFileImporter definition ### + +XMLFileImporter::XMLFileImporter(QIODevice* stream, Map *map, MapView *view) +: Importer(stream, map, view), + xml(stream) +{ + //NOP +} + +void XMLFileImporter::addWarningUnsupportedElement() +{ + addWarning(tr("Unsupported element: %1 (line %2 column %3)"). + arg(xml.name().toString()). + arg(xml.lineNumber()). + arg(xml.columnNumber()) + ); +} + +void XMLFileImporter::import(bool load_symbols_only) +{ + if (!xml.readNextStartElement() || xml.name() != literal::map) + { + xml.raiseError(Importer::tr("Unsupported file format.")); + } + + XmlElementReader map_element(xml); + const int version = map_element.attribute(literal::version); + if (version < 1) + xml.raiseError(Importer::tr("Invalid file format version.")); + else if (version < XMLFileFormat::minimum_version) + xml.raiseError(Importer::tr("Unsupported old file format version. Please use an older program version to load and update the file.")); + else if (version > XMLFileFormat::current_version) + addWarning(Importer::tr("Unsupported new file format version. Some map features will not be loaded or saved by this version of the program.")); + + QScopedValueRollback rollback { MapCoord::boundsOffset() }; + MapCoord::boundsOffset().reset(true); + georef_offset_adjusted = false; + importElements(load_symbols_only); + + auto offset = MapCoord::boundsOffset(); + if (!load_symbols_only && !offset.isZero()) + { + addWarning(tr("Some coordinates were out of bounds for printing. Map content was adjusted.")); + + MapCoordF offset_f { offset.x / 1000.0, offset.y / 1000.0 }; + + // Apply the offset + auto printer_config = map->printerConfig(); + auto& print_area = printer_config.print_area; + print_area.translate( -offset_f ); + + // Verify the adjusted print area, and readjust if necessary + if (print_area.top() <= -1000000.0 || print_area.bottom() > 1000000.0) + print_area.moveTop(-print_area.width() / 2); + if (print_area.left() <= -1000000.0 || print_area.right() > 1000000.0) + print_area.moveLeft(-print_area.width() / 2); + + map->setPrinterConfig(printer_config); + + if (!georef_offset_adjusted) + { + // We need to adjust the georeferencing. + auto georef = map->getGeoreferencing(); + auto ref_point = MapCoordF { georef.getMapRefPoint() }; + auto new_projected = georef.toProjectedCoords(ref_point + offset_f); + georef.setProjectedRefPoint(new_projected, false); + map->setGeoreferencing(georef); + } + } +} + +void XMLFileImporter::importElements(bool load_symbols_only) +{ + while (xml.readNextStartElement()) + { + const QStringRef name(xml.name()); + + if (name == literal::colors) + importColors(); + else if (name == literal::symbols) + importSymbols(); + else if (name == literal::georeferencing) + importGeoreferencing(load_symbols_only); + else if (name == literal::view) + importView(); + else if (name == literal::barrier) + { + XmlElementReader barrier(xml); + if (barrier.attribute(literal::version) > XMLFileFormat::current_version) + { + QString required_version = barrier.attribute(literal::required); + if (required_version.isEmpty()) + required_version = tr("unknown"); + addWarning(tr("Parts of this file cannot be read by this version of Mapper. Minimum required version: %1").arg(required_version)); + xml.skipCurrentElement(); + } + else + { + importElements(load_symbols_only); + } + } + else if (load_symbols_only) + xml.skipCurrentElement(); + /****************************************************** + * The remainder is skipped when loading a symbol set! * + ******************************************************/ + else if (name == literal::notes) + importMapNotes(); + else if (name == literal::parts) + importMapParts(); + else if (name == literal::templates) + importTemplates(); + else if (name == literal::print) + importPrint(); + else if (name == literal::undo) + importUndo(); + else if (name == literal::redo) + importRedo(); + else + { + addWarningUnsupportedElement(); + xml.skipCurrentElement(); + } + } + + if (xml.error()) + throw FileFormatException( + tr("Error at line %1 column %2: %3") + .arg(xml.lineNumber()) + .arg(xml.columnNumber()) + .arg(xml.errorString()) ); +} + +void XMLFileImporter::importMapNotes() +{ + auto recovery = XmlRecoveryHelper(xml); + map->setMapNotes(xml.readElementText()); + if (xml.hasError() && recovery()) + { + addWarning(tr("Some invalid characters had to be removed.")); + map->setMapNotes(xml.readElementText()); + } +} + +void XMLFileImporter::importGeoreferencing(bool load_symbols_only) +{ + Q_ASSERT(xml.name() == literal::georeferencing); + + bool check_for_offset = MapCoord::boundsOffset().check_for_offset; + + Georeferencing georef; + georef.load(xml, load_symbols_only); + map->setGeoreferencing(georef); + if (!georef.isValid()) + { + QString error_text = georef.getErrorText(); + if (error_text.isEmpty()) + error_text = tr("Unknown error"); + addWarning(tr("Unsupported or invalid georeferencing specification '%1': %2"). + arg(georef.getProjectedCRSSpec()). + arg(error_text)); + } + + if (MapCoord::boundsOffset().isZero()) + // Georeferencing was not adjusted on import. + MapCoord::boundsOffset().reset(check_for_offset); + else if (check_for_offset) + // Georeferencing was adjusted on import, before other coordinates. + georef_offset_adjusted = true; +} + +/** Helper for delayed actions */ +struct XMLFileImporterColorBacklogItem +{ + MapColor* color; // color which needs updating + SpotColorComponents components; // components of the color + bool knockout; + bool cmyk_from_spot; // determine CMYK from spot + bool rgb_from_spot; // determine RGB from spot + + XMLFileImporterColorBacklogItem(MapColor* color) + : color(color), knockout(false), cmyk_from_spot(false), rgb_from_spot(false) + {} +}; +typedef std::vector XMLFileImporterColorBacklog; + + +void XMLFileImporter::importColors() +{ + XmlElementReader all_colors_element(xml); + int num_colors = all_colors_element.attribute(literal::count); + + Map::ColorVector& colors(map->color_set->colors); + colors.reserve(qMin(num_colors, 100)); // 100 is not a limit + XMLFileImporterColorBacklog backlog; + backlog.reserve(colors.size()); + while (xml.readNextStartElement()) + { + if (xml.name() == literal::color) + { + XmlElementReader color_element(xml); + MapColor* color = new MapColor( + color_element.attribute(literal::name), + color_element.attribute(literal::priority) ); + if (color_element.hasAttribute(literal::opacity)) + color->setOpacity(color_element.attribute(literal::opacity)); + + MapColorCmyk cmyk; + cmyk.c = color_element.attribute(literal::c); + cmyk.m = color_element.attribute(literal::m); + cmyk.y = color_element.attribute(literal::y); + cmyk.k = color_element.attribute(literal::k); + color->setCmyk(cmyk); + + bool knockout = false; + SpotColorComponents components; + QString cmyk_method; + QString rgb_method; + MapColorRgb rgb; + + while (xml.readNextStartElement()) + { + if (xml.name() == literal::spotcolors) + { + XmlElementReader spotcolors_element(xml); + knockout = spotcolors_element.attribute(literal::knockout); + + while(xml.readNextStartElement()) + { + if (xml.name() == literal::namedcolor) + { + color->setSpotColorName(xml.readElementText()); + color->setKnockout(knockout); + } + else if (xml.name() == literal::component) + { + XmlElementReader component_element(xml); + SpotColorComponent component; + component.factor = component_element.attribute(literal::factor); + // We can't know if the spot color is already loaded. Create a temporary proxy. + component.spot_color = new MapColor(component_element.attribute(literal::spotcolor)); + components.push_back(component); + } + else + xml.skipCurrentElement(); // unsupported + } + } + else if (xml.name() == literal::cmyk) + { + XmlElementReader cmyk_element(xml); + cmyk_method = cmyk_element.attribute(literal::method); + } + else if (xml.name() == literal::rgb) + { + XmlElementReader rgb_element(xml); + rgb_method = rgb_element.attribute(literal::method); + rgb.r = rgb_element.attribute(literal::r); + rgb.g = rgb_element.attribute(literal::g); + rgb.b = rgb_element.attribute(literal::b); + color->setRgbFromSpotColors(); + } + else + xml.skipCurrentElement(); // unsupported + } + + if (!components.empty()) + { + backlog.push_back(XMLFileImporterColorBacklogItem(color)); + XMLFileImporterColorBacklogItem& item = backlog.back(); + item.components = components; + item.knockout = knockout; + item.cmyk_from_spot = (cmyk_method == literal::spotcolor); + item.rgb_from_spot = (rgb_method == literal::spotcolor); + } + else if (knockout && !color->getKnockout()) + { + addWarning(tr("Could not set knockout property of color '%1'.").arg(color->getName())); + } + + if (cmyk_method == literal::rgb) + color->setCmykFromRgb(); + + if (rgb_method == literal::cmyk) + color->setRgbFromCmyk(); + + colors.push_back(color); + } + else + { + addWarningUnsupportedElement(); + xml.skipCurrentElement(); + } + } + + if (num_colors > 0 && num_colors != (int)colors.size()) + addWarning(tr("Expected %1 colors, found %2."). + arg(num_colors). + arg(colors.size()) + ); + + // All spot colors are loaded at this point. + // Now deal with depending color compositions from the backlog. + for (auto&& item : backlog) + { + // Process the list of spot color components. + SpotColorComponents out_components; + for (auto&& in_component : item.components) + { + const MapColor* out_color = map->getColor(in_component.spot_color->getPriority()); + if (out_color == NULL || out_color->getSpotColorMethod() != MapColor::SpotColor) + { + addWarning(tr("Spot color %1 not found while processing %2 (%3)."). + arg(in_component.spot_color->getPriority()). + arg(item.color->getPriority()). + arg(item.color->getName()) + ); + continue; // Drop this color, invalid reference + } + + out_components.push_back(in_component); + SpotColorComponent& out_component = out_components.back(); + out_component.spot_color = out_color; // That is the major point! + delete in_component.spot_color; // Delete the temporary proxy. + } + + // Update the current color + item.color->setSpotColorComposition(out_components); + item.color->setKnockout(item.knockout); + if (item.cmyk_from_spot) + item.color->setCmykFromSpotColors(); + if (item.rgb_from_spot) + item.color->setRgbFromSpotColors(); + + if (item.knockout && !item.color->getKnockout()) + { + addWarning(tr("Could not set knockout property of color '%1'.").arg(item.color->getName())); + } + } +} + +void XMLFileImporter::importSymbols() +{ + QScopedValueRollback offset { MapCoord::boundsOffset() }; + MapCoord::boundsOffset().reset(false); + + XmlElementReader symbols_element(xml); + int num_symbols = symbols_element.attribute(literal::count); + map->symbols.reserve(qMin(num_symbols, 1000)); // 1000 is not a limit + + symbol_dict[QString::number(map->findSymbolIndex(map->getUndefinedPoint()))] = map->getUndefinedPoint(); + symbol_dict[QString::number(map->findSymbolIndex(map->getUndefinedLine()))] = map->getUndefinedLine(); + + while (xml.readNextStartElement()) + { + if (xml.name() == literal::symbol) + { + map->symbols.push_back(Symbol::load(xml, *map, symbol_dict)); + } + else + { + addWarningUnsupportedElement(); + xml.skipCurrentElement(); + } + } + + if (num_symbols > 0 && num_symbols != map->getNumSymbols()) + addWarning(tr("Expected %1 symbols, found %2."). + arg(num_symbols). + arg(map->getNumSymbols()) + ); +} + +void XMLFileImporter::importMapParts() +{ + XmlElementReader mapparts_element(xml); + int num_parts = mapparts_element.attribute(literal::parts); + int current_part_index = mapparts_element.attribute(literal::current); + map->parts.clear(); + map->parts.reserve(qMin(num_parts, 20)); // 20 is not a limit + + while (xml.readNextStartElement()) + { + if (xml.name() == literal::part) + { + auto recovery = XmlRecoveryHelper(xml); + auto part = MapPart::load(xml, *map, symbol_dict); + if (xml.hasError() && recovery()) + { + addWarning(tr("Some invalid characters had to be removed.")); + delete part; + part = MapPart::load(xml, *map, symbol_dict); + } + map->parts.push_back(part); + } + else + { + addWarningUnsupportedElement(); + xml.skipCurrentElement(); + } + } + + if (0 <= current_part_index && current_part_index < map->getNumParts()) + map->current_part_index = current_part_index; + + if (num_parts > 0 && num_parts != map->getNumParts()) + addWarning(tr("Expected %1 map parts, found %2."). + arg(num_parts). + arg(map->getNumParts()) + ); + + emit map->currentMapPartIndexChanged(map->current_part_index); + emit map->currentMapPartChanged(map->getPart(map->current_part_index)); +} + +void XMLFileImporter::importTemplates() +{ + Q_ASSERT(xml.name() == literal::templates); + + XmlElementReader templates_element(xml); + int first_front_template = templates_element.attribute(literal::first_front_template); + + int num_templates = templates_element.attribute(literal::count); + map->templates.reserve(qMin(num_templates, 20)); // 20 is not a limit + map->closed_templates.reserve(qMin(num_templates, 20)); // 20 is not a limit + + while (xml.readNextStartElement()) + { + if (xml.name() == literal::template_string) + { + bool opened = true; + auto temp = Template::loadTemplateConfiguration(xml, *map, opened); + if (opened) + map->templates.push_back(temp.release()); + else + map->closed_templates.push_back(temp.release()); + } + else if (xml.name() == literal::defaults) + { + XmlElementReader defaults_element(xml); + map->image_template_use_meters_per_pixel = defaults_element.attribute(literal::use_meters_per_pixel); + map->image_template_meters_per_pixel = defaults_element.attribute(literal::meters_per_pixel); + map->image_template_dpi = defaults_element.attribute(literal::dpi); + map->image_template_scale = defaults_element.attribute(literal::scale); + } + else + { + qDebug() << "Unsupported element: " << xml.qualifiedName(); + xml.skipCurrentElement(); + } + } + + map->first_front_template = qMax(0, qMin(map->getNumTemplates(), first_front_template)); +} + +void XMLFileImporter::importView() +{ + Q_ASSERT(xml.name() == literal::view); + + XmlElementReader view_element(xml); + if (view_element.attribute(literal::area_hatching_enabled)) + map->renderable_options |= Symbol::RenderAreasHatched; + if (view_element.attribute(literal::baseline_view_enabled)) + map->renderable_options |= Symbol::RenderBaselines; + + while (xml.readNextStartElement()) + { + if (xml.name() == literal::grid) + { + map->setGrid(MapGrid().load(xml)); + } + else if (xml.name() == literal::map_view) + { + if (view) + view->load(xml); + } + else + { + xml.skipCurrentElement(); // unsupported + } + } +} + +void XMLFileImporter::importPrint() +{ + Q_ASSERT(xml.name() == literal::print); + + try + { + map->setPrinterConfig(MapPrinterConfig(*map, xml)); + } + catch (FileFormatException& e) + { + addWarning(ImportExport::tr("Error while loading the printing configuration at %1:%2: %3") + .arg(xml.lineNumber()).arg(xml.columnNumber()).arg(e.message())); + } +} + +void XMLFileImporter::importUndo() +{ + try + { + map->undoManager().loadUndo(xml, symbol_dict); + } + catch (FileFormatException& e) + { + addWarning(ImportExport::tr("Error while loading the undo/redo steps at %1:%2: %3") + .arg(xml.lineNumber()).arg(xml.columnNumber()).arg(e.message())); + map->undoManager().clear(); + } +} + +void XMLFileImporter::importRedo() +{ + try + { + map->undoManager().loadRedo(xml, symbol_dict); + } + catch (FileFormatException& e) + { + addWarning(ImportExport::tr("Error while loading the undo/redo steps at %1:%2: %3") + .arg(xml.lineNumber()).arg(xml.columnNumber()).arg(e.message())); + map->undoManager().clear(); + } +} diff --git a/src/file_format_xml.h b/src/file_format_xml.h new file mode 100644 index 0000000..de10c05 --- /dev/null +++ b/src/file_format_xml.h @@ -0,0 +1,64 @@ +/* + * Copyright 2012, 2013, 2014 Pete Curtis, Kai Pastor + * + * This file is part of OpenOrienteering. + * + * OpenOrienteering is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenOrienteering is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenOrienteering. If not, see . + */ + +#ifndef _OPENORIENTEERING_FILE_FORMAT_XML_H +#define _OPENORIENTEERING_FILE_FORMAT_XML_H + +#include "file_format.h" + +/** @brief Interface for dealing with XML files of maps. + */ +class XMLFileFormat : public FileFormat +{ +public: + /** @brief Creates a new file format of type XML. + */ + XMLFileFormat(); + + /** @brief Returns true if the file starts with the character sequence ". + */ + +#ifndef _OPENORIENTEERING_FILE_FORMAT_XML_P_H +#define _OPENORIENTEERING_FILE_FORMAT_XML_P_H + +#include "file_import_export.h" + +#include +#include + +#include "symbol.h" + +/** Map exporter for the xml based map format. */ +class XMLFileExporter : public Exporter +{ +Q_OBJECT +public: + XMLFileExporter(QIODevice* stream, Map *map, MapView *view); + virtual ~XMLFileExporter() {} + + virtual void doExport(); + +protected: + void exportGeoreferencing(); + void exportColors(); + void exportSymbols(); + void exportMapParts(); + void exportTemplates(); + void exportView(); + void exportPrint(); + void exportUndo(); + void exportRedo(); + +private: + QXmlStreamWriter xml; +}; + + +/** Map importer for the xml based map format. */ +class XMLFileImporter : public Importer +{ +Q_OBJECT +public: + XMLFileImporter(QIODevice* stream, Map *map, MapView *view); + virtual ~XMLFileImporter() {} + +protected: + virtual void import(bool load_symbols_only); + + void importElements(bool load_symbols_only); + + void addWarningUnsupportedElement(); + void importMapNotes(); + void importGeoreferencing(bool load_symbols_only); + void importColors(); + void importSymbols(); + void importMapParts(); + void importTemplates(); + void importView(); + void importPrint(); + void importUndo(); + void importRedo(); + + QXmlStreamReader xml; + SymbolDictionary symbol_dict; + bool georef_offset_adjusted; +}; + +#endif diff --git a/src/file_import_export.cpp b/src/file_import_export.cpp new file mode 100644 index 0000000..3b0ed40 --- /dev/null +++ b/src/file_import_export.cpp @@ -0,0 +1,151 @@ +/* + * Copyright 2012, 2013 Pete Curtis + * Copyright 2013, 2014 Thomas Schöps + * Copyright 2013-2015 Kai Pastor + * + * This file is part of OpenOrienteering. + * + * OpenOrienteering is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenOrienteering is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenOrienteering. If not, see . + */ + +#include "file_import_export.h" + +#include + +#include "map.h" +#include "symbol.h" +#include "template.h" +#include "object.h" +#include "symbol_line.h" +#include "symbol_point.h" + + +// ### ImportExport ### + +ImportExport::~ImportExport() +{ + // Nothing, not inlined +} + + +// ### Importer ### + +Importer::~Importer() +{ + // Nothing, not inlined +} + +void Importer::doImport(bool load_symbols_only, const QString& map_path) +{ + import(load_symbols_only); + + // Object post processing: + // - make sure that there is no object without symbol + // - make sure that all area-only path objects are closed + // - make sure that there are no special points in wrong places (e.g. curve starts inside curves) + for (int p = 0; p < map->getNumParts(); ++p) + { + MapPart* part = map->getPart(p); + for (int o = 0; o < part->getNumObjects(); ++o) + { + Object* object = part->getObject(o); + if (object->getSymbol() == NULL) + { + addWarning(Importer::tr("Found an object without symbol.")); + if (object->getType() == Object::Point) + object->setSymbol(map->getUndefinedPoint(), true); + else if (object->getType() == Object::Path) + object->setSymbol(map->getUndefinedLine(), true); + else + { + // There is no undefined symbol for this type of object, delete the object + part->deleteObject(o, false); + --o; + continue; + } + } + + if (object->getType() == Object::Path) + { + PathObject* path = object->asPath(); + Symbol::Type contained_types = path->getSymbol()->getContainedTypes(); + if (contained_types & Symbol::Area && !(contained_types & Symbol::Line)) + path->closeAllParts(); + + path->normalize(); + } + } + } + + if (auto deleted = map->deleteIrregularObjects()) + { + addWarning(tr("Dropped %n irregular object(s).", 0, deleted)); + } + + // Symbol post processing + for (int i = 0; i < map->getNumSymbols(); ++i) + { + if (!map->getSymbol(i)->loadFinished(map)) + throw FileFormatException(Importer::tr("Error during symbol post-processing.")); + } + + // Template loading: try to find all template files + bool have_lost_template = false; + for (int i = 0; i < map->getNumTemplates(); ++i) + { + Template* temp = map->getTemplate(i); + + bool loaded_from_template_dir = false; + temp->tryToFindAndReloadTemplateFile(map_path, &loaded_from_template_dir); + + if (loaded_from_template_dir) + { + addWarning(Importer::tr("Template \"%1\" has been loaded from the map's directory instead of the relative location to the map file where it was previously.").arg(temp->getTemplateFilename())); + } + + if (temp->getTemplateState() != Template::Loaded) + { + have_lost_template = true; + addWarning(tr("Failed to load template '%1', reason: %2") + .arg(temp->getTemplateFilename(), temp->errorString())); + } + else if (!temp->errorString().isEmpty()) + { + addWarning(tr("Warnings when loading template '%1':\n%2") + .arg(temp->getTemplateFilename(), temp->errorString())); + } + } + if (have_lost_template) + { +#if defined(Q_OS_ANDROID) + addWarning(tr("At least one template file could not be found.")); +#else + addWarning(tr("At least one template file could not be found.") + QLatin1Char(' ') + + tr("Click the red template name(s) in the Templates -> Template setup window to locate the template file name(s).")); +#endif + } +} + +void Importer::finishImport() +{ + // Nothing, not inlined +} + + +// ### Exporter ### + +Exporter::~Exporter() +{ + // Nothing, not inlined +} diff --git a/src/file_import_export.h b/src/file_import_export.h new file mode 100644 index 0000000..168e790 --- /dev/null +++ b/src/file_import_export.h @@ -0,0 +1,267 @@ +/* + * Copyright 2012, 2013 Pete Curtis + * + * This file is part of OpenOrienteering. + * + * OpenOrienteering is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenOrienteering is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenOrienteering. If not, see . + */ + +#ifndef _OPENORIENTEERING_IMPORT_EXPORT_H +#define _OPENORIENTEERING_IMPORT_EXPORT_H + +#include + +#include +#include +#include + +#include "file_format.h" + +class QIODevice; + +class Importer; +class Exporter; +class Map; +class MapView; + + +/** Abstract base class for both importer and exporters; provides support for configuring the map and + * view to manipulate, setting and retrieving options, and collecting a list of warnings. + * + * Subclasses should define default values for options they intend to use in their constructors, + * by calling setOption() with the relevant values. There is no such thing as an "implicit default" + * for options. + * + * ImportExport inherits QObject for translation purposes. + */ +class ImportExport : public QObject +{ +Q_OBJECT +public: + /** Creates a new importer or exporter with the given input stream, map, and view. + */ + ImportExport(QIODevice* stream, Map *map, MapView *view); + + /** Destroys an importer or exporter. + */ + virtual ~ImportExport(); + + /** Returns the current list of warnings collected by this object. + */ + const std::vector &warnings() const; + + /** Sets an option in this importer or exporter. + */ + void setOption(const QString& name, QVariant value); + + /** Retrieves the value of an options in this importer or exporter. If the option does not have + * a value - either a default value assigned in the constructor, or a custom value assigned + * through setOption() - then a FormatException will be thrown. + */ + QVariant option(const QString& name) const; + + protected: + /** Adds an import/export warning to the current list of warnings. The provided message + * should be translated. + */ + void addWarning(const QString& str); + +protected: + /// The input / output stream + QIODevice* stream; + + /// The Map to import or export + Map *map; + + /// The MapView to import or export + MapView *view; + +private: + /// A list of options for the import/export + QHash options; + + /// A list of warnings + std::vector warn; +}; + + +/** + * Represents an action that the user must take to successfully complete an import. + * TODO: Currently not fully implemented, as this should be done using the + * planned ProblemWidget instead, which works independently of import / export. + */ +class ImportAction +{ + // Nothing +}; + + +/** Base class for all importers. An Importer has the following lifecycle: + * -# The Importer is constructed, with pointers to the map and view. The Importer + * should also set default values for any options it will read. The base class + * will throw an exception if the importer reads an option that does not have a value. + * -# setOption() will be called zero or more times to customize the options. + * -# doImport() will be called to perform the initial import. The implementation of + * this method will try to populate the map and view from the given file, and may + * optionally register action items for the user via addAction(). + * -# If action items are present, then they will be presented to the user. Each + * action item will have its satisfy() method called with the user's choice. + * -# finishImport() will be called. If any action items were created, this method + * should finish the import based on the values supplied by the user. + */ +class Importer : public ImportExport +{ +Q_OBJECT +public: + /** Creates a new Importer with the given output stream, map, and view. + */ + Importer(QIODevice* stream, Map *map, MapView *view); + + /** Destroys this Importer. + */ + virtual ~Importer(); + + /** Returns the current list of action items. + */ + inline const std::vector &actions() const; + + /** Begins the import process. The implementation of this method should read the file + * and populate the map and view from it. If a fatal error is encountered (such as a + * missing or corrupt file), than it should throw a FormatException. If the import can + * proceed, but information might be lost in the process, than it should call + * addWarning() with a translated, useful description of the issue. The line between + * errors and warnings is somewhat of a judgement call on the part of the author, but + * generally an Importer should not succeed unless the map is populated sufficiently + * to be useful. + */ + void doImport(bool load_symbols_only, const QString& map_path = QString()); + + /** Once all action items are satisfied, this method should be called to complete the + * import process. This class defines a default implementation, that does nothing. + */ + virtual void finishImport(); + +protected: + /** Implementation of doImport(). + */ + virtual void import(bool load_symbols_only) = 0; + + /** Adds an action item to the current list. + */ + inline void addAction(const ImportAction &action); + +private: + /// A list of action items that must be resolved before the import can be completed + std::vector act; +}; + + +/** Base class for all exporters. An Exporter has the following lifecycle: + * + * 1. The Exporter is constructed, with pointers to the filename, map and view. The Exporter + * should also set default values for any options it will read. The base class + * will throw an exception if the exporter reads an option that does not have a value. + * 2. setOption() will be called zero or more times to customize the options. + * 3. doExport() will be called to perform the export. + */ +class Exporter : public ImportExport +{ +Q_OBJECT +public: + /** Creates a new Importer with the given i/o stream, map, and view. + */ + Exporter(QIODevice* stream, Map *map, MapView *view); + + /** Destroys the current Exporter. + */ + virtual ~Exporter(); + + /** Exports the map and view to the given file. If a fatal error is encountered (such as a + * permission problem), than this method should throw a FormatException. If the export can + * proceed, but information might be lost in the process, than it should call + * addWarning() with a translated, useful description of the issue. + */ + virtual void doExport() = 0; +}; + + +// ### ImportExport inline code ### + +inline +ImportExport::ImportExport(QIODevice* stream, Map* map, MapView* view) + : stream(stream), map(map), view(view) +{ + // Nothing +} + +inline +const std::vector< QString >& ImportExport::warnings() const +{ + return warn; +} + +inline +void ImportExport::addWarning(const QString& str) +{ + warn.push_back(str); +} + +inline +void ImportExport::setOption(const QString& name, QVariant value) +{ + options[name] = value; +} + +inline +QVariant ImportExport::option(const QString& name) const +{ + if (!options.contains(name)) + throw FileFormatException(ImportExport::tr("No such option: %1", "No such import / export option").arg(name)); + return options[name]; +} + + +// ### Importer inline code ### + +inline +Importer::Importer(QIODevice* stream, Map* map, MapView* view) + : ImportExport(stream, map, view) +{ + // Nothing +} + +inline +const std::vector< ImportAction >& Importer::actions() const +{ + return act; +} + +inline +void Importer::addAction(const ImportAction& action) +{ + act.push_back(action); +} + + +// ### Exporter ### + +inline +Exporter::Exporter(QIODevice* stream, Map* map, MapView* view) + : ImportExport(stream, map, view) +{ + // Nothing +} + + +#endif // _OPENORIENTEERING_IMPORT_EXPORT_H diff --git a/src/fileformats/ocd_file_export.cpp b/src/fileformats/ocd_file_export.cpp new file mode 100644 index 0000000..6a67ed8 --- /dev/null +++ b/src/fileformats/ocd_file_export.cpp @@ -0,0 +1,47 @@ +/* + * Copyright 2016 Kai Pastor + * + * Some parts taken from file_format_oc*d8{.h,_p.h,cpp} which are + * Copyright 2012 Pete Curtis + * + * This file is part of OpenOrienteering. + * + * OpenOrienteering is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenOrienteering is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenOrienteering. If not, see . + */ + +#include "ocd_file_export.h" + +#include "../file_format_ocad8_p.h" + + +OcdFileExport::OcdFileExport(QIODevice* stream, Map* map, MapView* view) +: Exporter { stream, map, view } +{ + // nothing else +} + +OcdFileExport::~OcdFileExport() +{ + // nothing +} + +void OcdFileExport::doExport() +{ + OCAD8FileExport delegate { stream, map, view }; + delegate.doExport(); + for (auto&& w : delegate.warnings()) + { + addWarning(w); + } +} diff --git a/src/fileformats/ocd_file_export.h b/src/fileformats/ocd_file_export.h new file mode 100644 index 0000000..79a2188 --- /dev/null +++ b/src/fileformats/ocd_file_export.h @@ -0,0 +1,49 @@ +/* + * Copyright 2016 Kai Pastor + * + * Some parts taken from file_format_oc*d8{.h,_p.h,cpp} which are + * Copyright 2012 Pete Curtis + * + * This file is part of OpenOrienteering. + * + * OpenOrienteering is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenOrienteering is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenOrienteering. If not, see . + */ + +#ifndef OPENORIENTEERING_OCD_FILE_EXPORT_H +#define OPENORIENTEERING_OCD_FILE_EXPORT_H + +#include "../file_import_export.h" + + +/** + * An exporter for OCD files. + */ +class OcdFileExport : public Exporter +{ +Q_OBJECT +public: + OcdFileExport(QIODevice* stream, Map *map, MapView *view); + + ~OcdFileExport() override; + + /** + * Exports an OCD file. + * + * For now, this simply uses the OCAD8FileExport class. + */ + void doExport() override; + +}; + +#endif diff --git a/src/fileformats/ocd_file_format.cpp b/src/fileformats/ocd_file_format.cpp new file mode 100644 index 0000000..05d1080 --- /dev/null +++ b/src/fileformats/ocd_file_format.cpp @@ -0,0 +1,55 @@ +/* + * Copyright 2013-2016 Kai Pastor + * + * Some parts taken from file_format_oc*d8{.h,_p.h,cpp} which are + * Copyright 2012 Pete Curtis + * + * This file is part of OpenOrienteering. + * + * OpenOrienteering is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenOrienteering is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenOrienteering. If not, see . + */ + +#include "ocd_file_format.h" + +#include "ocd_file_export.h" +#include "ocd_file_import.h" + + +// ### OcdFileFormat ### + +OcdFileFormat::OcdFileFormat() +: FileFormat { MapFile, "OCD", ImportExport::tr("OCAD"), QString::fromLatin1("ocd"), + ImportSupported | ExportSupported | ExportLossy } +{ + // Nothing +} + +bool OcdFileFormat::understands(const unsigned char* buffer, size_t sz) const +{ + // The first two bytes of the file must be 0x0cad in litte endian ordner. + // This test will refuse to understand OCD files on big endian systems: + // The importer's current implementation won't work there. + return (sz >= 2 && *reinterpret_cast(buffer) == 0x0cad); +} + +Importer* OcdFileFormat::createImporter(QIODevice* stream, Map *map, MapView *view) const +{ + return new OcdFileImport(stream, map, view); +} + +Exporter* OcdFileFormat::createExporter(QIODevice* stream, Map* map, MapView* view) const +{ + return new OcdFileExport(stream, map, view); +} + diff --git a/src/fileformats/ocd_file_format.h b/src/fileformats/ocd_file_format.h new file mode 100644 index 0000000..793d3b5 --- /dev/null +++ b/src/fileformats/ocd_file_format.h @@ -0,0 +1,51 @@ +/* + * Copyright 2013, 2016 Kai Pastor + * + * This file is part of OpenOrienteering. + * + * OpenOrienteering is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenOrienteering is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenOrienteering. If not, see . + */ + +#ifndef OPENORIENTEERING_OCD_FILE_FORMAT +#define OPENORIENTEERING_OCD_FILE_FORMAT + +#include "../file_format.h" + +/** + * The map file format known as OC*D. + */ +class OcdFileFormat : public FileFormat +{ +public: + /** + * Constructs a new OcdFileFormat. + */ + OcdFileFormat(); + + /** + * Detects whether the buffer may be the start of a valid OCD file. + * + * At the moment, it requires at least two bytes of data. + * It will return false if compiled for a big endian system. + */ + bool understands(const unsigned char *buffer, size_t sz) const override; + + /// \copydoc FileFormat::createImporter() + virtual Importer* createImporter(QIODevice* stream, Map *map, MapView *view) const override; + + /// \copydoc FileFormat::createExporter() + virtual Exporter* createExporter(QIODevice* stream, Map* map, MapView* view) const override; +}; + +#endif // OPENORIENTEERING_OCD_FILE_FORMAT diff --git a/src/fileformats/ocd_file_import.cpp b/src/fileformats/ocd_file_import.cpp new file mode 100644 index 0000000..12805bd --- /dev/null +++ b/src/fileformats/ocd_file_import.cpp @@ -0,0 +1,2096 @@ +/* + * Copyright 2013-2016 Kai Pastor + * + * Some parts taken from file_format_oc*d8{.h,_p.h,cpp} which are + * Copyright 2012 Pete Curtis + * + * This file is part of OpenOrienteering. + * + * OpenOrienteering is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenOrienteering is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenOrienteering. If not, see . + */ + +#include "ocd_file_import.h" + +#include + +#include +#include +#include +#include +#include + +#include "ocd_types_v9.h" +#include "ocd_types_v10.h" +#include "ocd_types_v11.h" +#include "ocd_types_v12.h" +#include "../core/crs_template.h" +#include "../core/map_color.h" +#include "../core/map_view.h" +#include "../core/georeferencing.h" +#include "../file_format_ocad8.h" +#include "../file_format_ocad8_p.h" +#include "../map.h" +#include "../object_text.h" +#include "../settings.h" +#include "../symbol_area.h" +#include "../symbol_combined.h" +#include "../symbol_line.h" +#include "../symbol_point.h" +#include "../symbol_text.h" +#include "../template.h" +#include "../template_image.h" +#include "../template_map.h" +#include "../util.h" +#include "../util/encoding.h" + + +namespace { + +static QTextCodec* codecFromSettings() +{ + const auto& settings = Settings::getInstance(); + const auto name = settings.getSetting(Settings::General_Local8BitEncoding).toByteArray(); + return Util::codecForName(name); +} + +} // namespace + + +OcdFileImport::OcdImportedPathObject::~OcdImportedPathObject() +{ + // nothing, not inlined +} + +OcdFileImport::OcdFileImport(QIODevice* stream, Map* map, MapView* view) + : Importer { stream, map, view } + , delegate { nullptr } + , custom_8bit_encoding { codecFromSettings() } +{ + if (!custom_8bit_encoding) + { + addWarning(tr("Encoding '%1' is not available. Check the settings.")); + custom_8bit_encoding = QTextCodec::codecForLocale(); + } +} + +OcdFileImport::~OcdFileImport() +{ + // nothing +} + + +void OcdFileImport::setCustom8BitEncoding(QTextCodec* encoding) +{ + custom_8bit_encoding = encoding; +} + + +QString OcdFileImport::convertOcdString(const QChar* input, uint maxlen) const +{ + auto last = input; + if (input) + { + while (maxlen && *last != 0) + { + last ++; + --maxlen; + } + } + QTextCodec* utf16 = QTextCodec::codecForName("UTF-16LE"); + Q_ASSERT(utf16); + auto decoder = std::unique_ptr(utf16->makeDecoder(QTextCodec::ConvertInvalidToNull)); + return decoder->toUnicode(reinterpret_cast(input), 2*int(last - input)); +} + + +void OcdFileImport::addSymbolWarning(const AreaSymbol* symbol, const QString& warning) +{ + addWarning( tr("In area symbol %1 '%2': %3"). + arg(symbol->getNumberAsString(), symbol->getName(), warning) ); +} + +void OcdFileImport::addSymbolWarning(const LineSymbol* symbol, const QString& warning) +{ + addWarning( tr("In line symbol %1 '%2': %3"). + arg(symbol->getNumberAsString(), symbol->getName(), warning) ); +} + +void OcdFileImport::addSymbolWarning(const TextSymbol* symbol, const QString& warning) +{ + addWarning( tr("In text symbol %1 '%2': %3"). + arg(symbol->getNumberAsString(), symbol->getName(), warning) ); +} + + +#ifndef NDEBUG + +// Heuristic detection of implementation errors +template< > +inline +qint64 OcdFileImport::convertLength< quint8 >(quint8 ocd_length) const +{ + // OC*D uses hundredths of a millimeter. + // oo-mapper uses 1/1000 mm + if (ocd_length > 200) + qDebug() << "quint8 has value" << ocd_length << ", might be qint8" << (qint8)ocd_length; + return ((qint64)ocd_length) * 10; +} + +template< > +inline +qint64 OcdFileImport::convertLength< quint16 >(quint16 ocd_length) const +{ + // OC*D uses hundredths of a millimeter. + // oo-mapper uses 1/1000 mm + if (ocd_length > 50000) + qDebug() << "quint16 has value" << ocd_length << ", might be qint16" << (qint16)ocd_length; + return ((qint64)ocd_length) * 10; +} + +template< > +inline +qint64 OcdFileImport::convertLength< quint32 >(quint32 ocd_length) const +{ + // OC*D uses hundredths of a millimeter. + // oo-mapper uses 1/1000 mm + if (ocd_length > 3000000) + qDebug() << "quint32 has value" << ocd_length << ", might be qint32" << (qint32)ocd_length; + return ((qint64)ocd_length) * 10; +} + +#endif // !NDEBUG + + +void OcdFileImport::importImplementationLegacy(bool load_symbols_only) +{ + QBuffer new_stream(&buffer); + new_stream.open(QIODevice::ReadOnly); + delegate.reset(new OCAD8FileImport(&new_stream, map, view)); + + delegate->import(load_symbols_only); + + for (auto&& w : delegate->warnings()) + { + addWarning(w); + } + + for (auto&& a : delegate->actions()) + { + addAction(a); + } +} + +template< class F > +void OcdFileImport::importImplementation(bool load_symbols_only) +{ + OcdFile< F > file(buffer); +#ifdef MAPPER_DEVELOPMENT_BUILD + if (!qApp->applicationName().endsWith(QLatin1String("Test"))) + { + qDebug("*** OcdFileImport: Importing a version %d.%d file", file.header()->version, file.header()->subversion); + for (const auto& string : file.strings()) + { + qDebug(" %d \t%s", string.type, qPrintable(convertOcdString< typename F::Encoding >(file[string]))); + } + } +#endif + + importGeoreferencing(file); + importColors(file); + importSymbols(file); + if (!load_symbols_only) + { + importExtras(file); + importObjects(file); + importTemplates(file); + if (view) + { + importView(file); + } + } +} + + +void OcdFileImport::importGeoreferencing(const OcdFile& file) +{ + const Ocd::FileHeaderV8* header = file.header(); + const Ocd::SetupV8* setup = reinterpret_cast< const Ocd::SetupV8* >(file.byteArray().data() + header->setup_pos); + + Georeferencing georef; + georef.setScaleDenominator(qRound(setup->map_scale)); + georef.setProjectedRefPoint(QPointF(setup->real_offset_x, setup->real_offset_y)); + if (qAbs(setup->real_angle) >= 0.01) /* degrees */ + { + georef.setGrivation(setup->real_angle); + } + map->setGeoreferencing(georef); +} + +template< class F > +void OcdFileImport::importGeoreferencing(const OcdFile< F >& file) +{ + handleStrings(file, { { 1039, &OcdFileImport::importGeoreferencing } }); +} + +void OcdFileImport::importGeoreferencing(const QString& param_string, int) +{ + const QChar* unicode = param_string.unicode(); + + Georeferencing georef; + QString combined_grid_zone; + QPointF proj_ref_point; + bool x_ok = false, y_ok = false; + + int i = param_string.indexOf(QLatin1Char('\t'), 0); + ; // skip first word for this entry type + while (i >= 0) + { + bool ok; + int next_i = param_string.indexOf(QLatin1Char('\t'), i+1); + int len = (next_i > 0 ? next_i : param_string.length()) - i - 2; + const QString param_value = QString::fromRawData(unicode+i+2, len); // no copying! + switch (param_string[i+1].toLatin1()) + { + case 'm': + { + double scale = param_value.toDouble(&ok); + if (ok && scale >= 0) + georef.setScaleDenominator(qRound(scale)); + } + break; + case 'a': + { + double angle = param_value.toDouble(&ok); + if (ok && qAbs(angle) >= 0.01) + georef.setGrivation(angle); + } + break; + case 'x': + proj_ref_point.setX(param_value.toDouble(&x_ok)); + break; + case 'y': + proj_ref_point.setY(param_value.toDouble(&y_ok)); + break; + case 'd': + { + auto spacing = param_value.toDouble(&ok); + if (ok && spacing >= 0.001) + { + auto grid = map->getGrid(); + grid.setUnit(MapGrid::MetersInTerrain); + grid.setHorizontalSpacing(spacing); + grid.setVerticalSpacing(spacing); + map->setGrid(grid); + } + } + break; + case 'i': + combined_grid_zone = param_value; + break; + case '\t': + // empty item, fall through + default: + ; // nothing + } + i = next_i; + } + + if (!combined_grid_zone.isEmpty()) + { + applyGridAndZone(georef, combined_grid_zone); + } + + if (x_ok && y_ok) + { + georef.setProjectedRefPoint(proj_ref_point); + } + + map->setGeoreferencing(georef); +} + +void OcdFileImport::applyGridAndZone(Georeferencing& georef, const QString& combined_grid_zone) +{ + bool zone_ok = false; + const CRSTemplate* crs_template = nullptr; + QString id; + QString spec; + std::vector values; + + if (combined_grid_zone.startsWith(QLatin1String("20"))) + { + auto zone = combined_grid_zone.midRef(2).toUInt(&zone_ok); + zone_ok &= (zone >= 1 && zone <= 60); + if (zone_ok) + { + id = QLatin1String{"UTM"}; + crs_template = CRSTemplateRegistry().find(id); + values.reserve(1); + values.push_back(QString::number(zone)); + } + } + else if (combined_grid_zone.startsWith(QLatin1String("80"))) + { + auto zone = combined_grid_zone.midRef(2).toUInt(&zone_ok); + if (zone_ok) + { + id = QLatin1String{"Gauss-Krueger, datum: Potsdam"}; + crs_template = CRSTemplateRegistry().find(id); + values.reserve(1); + values.push_back(QString::number(zone)); + } + } + else if (combined_grid_zone == QLatin1String("6005")) + { + id = QLatin1String{"EPSG"}; + crs_template = CRSTemplateRegistry().find(id); + values.reserve(1); + values.push_back(QLatin1String{"3067"}); + } + else if (combined_grid_zone == QLatin1String("14000")) + { + id = QLatin1String{"EPSG"}; + crs_template = CRSTemplateRegistry().find(id); + values.reserve(1); + values.push_back(QLatin1String{"21781"}); + } + else if (combined_grid_zone == QLatin1String("1000")) + { + return; + } + + if (crs_template) + { + spec = crs_template->specificationTemplate(); + auto param = crs_template->parameters().begin(); + for (const auto& value : values) + { + for (const auto& spec_value : (*param)->specValues(value)) + { + spec = spec.arg(spec_value); + } + ++param; + } + } + + if (spec.isEmpty()) + { + addWarning(tr("Could not load the coordinate reference system '%1'.").arg(combined_grid_zone)); + } + else + { + georef.setProjectedCRS(id, spec, std::move(values)); + } +} + + +void OcdFileImport::importColors(const OcdFile& file) +{ + const Ocd::SymbolHeaderV8 & symbol_header = file.header()->symbol_header; + int num_colors = symbol_header.num_colors; + + for (int i = 0; i < num_colors && i < 256; i++) + { + const Ocd::ColorInfoV8& color_info = symbol_header.color_info[i]; + const QString name = convertOcdString(color_info.name); + int color_pos = map->getNumColors(); + MapColor* color = new MapColor(name, color_pos); + + // OC*D stores CMYK values as integers from 0-200. + MapColorCmyk cmyk; + cmyk.c = 0.005f * color_info.cmyk.cyan; + cmyk.m = 0.005f * color_info.cmyk.magenta; + cmyk.y = 0.005f * color_info.cmyk.yellow; + cmyk.k = 0.005f * color_info.cmyk.black; + color->setCmyk(cmyk); + color->setOpacity(1.0f); + + map->addColor(color, color_pos); + color_index[color_info.number] = color; + } + + addWarning(OcdFileImport::tr("Spot color information was ignored.")); +} + +template< class F > +void OcdFileImport::importColors(const OcdFile< F >& file) +{ + handleStrings(file, { { 9, &OcdFileImport::importColor } }); + addWarning(OcdFileImport::tr("Spot color information was ignored.")); +} + +void OcdFileImport::importColor(const QString& param_string, int) +{ + const QChar* unicode = param_string.unicode(); + + int i = param_string.indexOf(QLatin1Char('\t'), 0); + const QString name = param_string.left(qMax(-1, i)); // copied + + int number; + bool number_ok = false; + MapColorCmyk cmyk { 0.0, 0.0, 0.0, 0.0 }; + bool overprinting = false; + float opacity = 1.0f; + + while (i >= 0) + { + float f_value; + int i_value; + bool ok; + int next_i = param_string.indexOf(QLatin1Char('\t'), i+1); + int len = (next_i > 0 ? next_i : param_string.length()) - i - 2; + const QString param_value = QString::fromRawData(unicode+i+2, len); // no copying! + switch (param_string[i+1].toLatin1()) + { + case '\t': + // empty item + break; + case 'n': + number = param_value.toInt(&number_ok); + break; + case 'c': + f_value = param_value.toFloat(&ok); + if (ok && f_value >= 0 && f_value <= 100) + cmyk.c = 0.01f * f_value; + break; + case 'm': + f_value = param_value.toFloat(&ok); + if (ok && f_value >= 0 && f_value <= 100) + cmyk.m = 0.01f * f_value; + break; + case 'y': + f_value = param_value.toFloat(&ok); + if (ok && f_value >= 0 && f_value <= 100) + cmyk.y = 0.01f * f_value; + break; + case 'k': + f_value = param_value.toFloat(&ok); + if (ok && f_value >= 0 && f_value <= 100) + cmyk.k = 0.01f * f_value; + break; + case 'o': + i_value = param_value.toInt(&ok); + if (ok) + overprinting = i_value; + break; + case 't': + f_value = param_value.toFloat(&ok); + if (ok && f_value >= 0.f && f_value <= 100.f) + opacity = 0.01f * f_value; + break; + default: + ; // nothing + } + i = next_i; + } + + if (!number_ok) + return; + + int color_pos = map->getNumColors(); + MapColor* color = new MapColor(name, color_pos); + color->setCmyk(cmyk); + color->setKnockout(!overprinting); + color->setOpacity(opacity); + map->addColor(color, color_pos); + color_index[number] = color; +} + +namespace { + quint16 symbolType(const Ocd::BaseSymbolV8& ocd_symbol) + { + if (ocd_symbol.type == Ocd::SymbolTypeLine && ocd_symbol.type2 == 1) + return Ocd::SymbolTypeLineText; + return ocd_symbol.type; + } + + template< class T > + quint8 symbolType(const T& ocd_symbol) + { + return ocd_symbol.type; + } +} + +template< class F > +void OcdFileImport::importSymbols(const OcdFile< F >& file) +{ + auto ocd_version = file.header()->version; + for (const auto& ocd_symbol : file.symbols()) + { + // When extra symbols are created, we want to insert the main symbol + // before them. That is why pos needs to be determined first. + auto pos = map->getNumSymbols(); + + Symbol* symbol = nullptr; + switch (symbolType(ocd_symbol)) + { + case Ocd::SymbolTypePoint: + symbol = importPointSymbol(reinterpret_cast(ocd_symbol), ocd_version); + break; + case Ocd::SymbolTypeLine: + symbol = importLineSymbol(reinterpret_cast(ocd_symbol), ocd_version); + break; + case Ocd::SymbolTypeArea: + symbol = importAreaSymbol(reinterpret_cast(ocd_symbol), ocd_version); + break; + case Ocd::SymbolTypeText: + symbol = importTextSymbol(reinterpret_cast(ocd_symbol), ocd_version); + break; + case Ocd::SymbolTypeRectangle_V8: + case Ocd::SymbolTypeRectangle_V9: + symbol = importRectangleSymbol(reinterpret_cast(ocd_symbol)); + break; + case Ocd::SymbolTypeLineText: + symbol = importLineTextSymbol(reinterpret_cast(ocd_symbol), ocd_version); + break; + default: + addWarning(OcdFileImport::tr("Unable to import symbol %1.%2 \"%3\": %4") . + arg(ocd_symbol.number / F::BaseSymbol::symbol_number_factor) . + arg(ocd_symbol.number % F::BaseSymbol::symbol_number_factor) . + arg(convertOcdString(ocd_symbol.description)). + arg(OcdFileImport::tr("Unsupported type \"%1\".").arg(ocd_symbol.type)) ); + continue; + } + + map->addSymbol(symbol, pos); + symbol_index[ocd_symbol.number] = symbol; + } + resolveSubsymbols(); +} + +void OcdFileImport::resolveSubsymbols() +{ + for (auto i = 0; i < map->getNumSymbols(); ++i) + { + auto symbol = map->getSymbol(i); + if (symbol->getType() == Symbol::Combined) + { + auto combined = symbol->asCombined(); + if (combined->getNumParts() == 2) + { + auto number = combined->getPart(1)->getNumberComponent(2); + if (number >= 0 && symbol_index.contains(static_cast(number))) + { + combined->setPart(1, symbol_index[static_cast(number)], false); + } + } + } + } +} + + +void OcdFileImport::importObjects(const OcdFile& file) +{ + auto ocd_version = file.header()->version; + MapPart* part = map->getCurrentPart(); + Q_ASSERT(part); + + for (const auto& object_entry : file.objects()) + { + if (object_entry.symbol) + { + if (auto object = importObject(file[object_entry], part, ocd_version)) + part->addObject(object, part->getNumObjects()); + } + } +} + +template< class F > +void OcdFileImport::importObjects(const OcdFile< F >& file) +{ + auto ocd_version = file.header()->version; + MapPart* part = map->getCurrentPart(); + Q_ASSERT(part); + + for (const auto& object_entry : file.objects()) + { + if ( object_entry.symbol + && object_entry.status != Ocd::ObjectDeleted + && object_entry.status != Ocd::ObjectDeletedForUndo ) + { + if (auto object = importObject(file[object_entry], part, ocd_version)) + part->addObject(object, part->getNumObjects()); + } + } +} + + +template< class F > +void OcdFileImport::importTemplates(const OcdFile< F >& file) +{ + handleStrings(file, { { 8, &OcdFileImport::importTemplate } }); +} + +void OcdFileImport::importTemplate(const QString& param_string, int ocd_version) +{ + const QChar* unicode = param_string.unicode(); + + int i = param_string.indexOf(QLatin1Char('\t'), 0); + const QString filename = QString::fromRawData(unicode, qMax(-1, i)); + const QString clean_path = QDir::cleanPath(QString(filename).replace(QLatin1Char('\\'), QLatin1Char('/'))); + const QString extension = QFileInfo(clean_path).suffix().toLower(); + + Template* templ = nullptr; + if (extension.compare(QLatin1String("ocd")) == 0) + { + templ = new TemplateMap(clean_path, map); + } + else if (QImageReader::supportedImageFormats().contains(extension.toLatin1())) + { + templ = new TemplateImage(clean_path, map); + } + else + { + addWarning(tr("Unable to import template: \"%1\" is not a supported template type.").arg(filename)); + return; + } + + // 8 or 9 or 10 ? Only tested with 8 and 11 + double scale_factor = (ocd_version <= 8) ? 0.01 : 1.0; + unsigned int num_rotation_params = 0; + double rotation = 0.0; + double scale_x = 1.0; + double scale_y = 1.0; + int dimming = 0; + bool visible = false; + + while (i >= 0) + { + double value; + bool ok; + int next_i = param_string.indexOf(QLatin1Char('\t'), i+1); + int len = (next_i > 0 ? next_i : param_string.length()) - i - 2; + const QString param_value = QString::fromRawData(unicode+i+2, len); // no copying! + switch (param_string[i+1].toLatin1()) + { + case '\t': + // empty item + break; + case 'x': + value = param_value.toDouble(&ok); + if (ok) + templ->setTemplateX(qRound64(value*1000*scale_factor)); + break; + case 'y': + value = param_value.toDouble(&ok); + if (ok) + templ->setTemplateY(-qRound64(value*1000*scale_factor)); + break; + case 'a': + case 'b': + // TODO: use the distinct angles correctly, not just the average + rotation += param_value.toDouble(&ok); + if (ok) + ++num_rotation_params; + break; + case 'u': + value = param_value.toDouble(&ok); + if (ok && qAbs(value) >= 0.0000000001) + scale_x = value; + break; + case 'v': + value = param_value.toDouble(&ok); + if (ok && qAbs(value) >= 0.0000000001) + scale_y = value; + break; + case 'd': + dimming = param_value.toInt(); + break; + case 's': + visible = param_value.toInt(); + break; + default: + ; // nothing + } + i = next_i; + } + + if (num_rotation_params) + templ->setTemplateRotation(Georeferencing::degToRad(rotation / num_rotation_params)); + + templ->setTemplateScaleX(scale_x * scale_factor); + templ->setTemplateScaleY(scale_y * scale_factor); + + int template_pos = map->getFirstFrontTemplate(); + map->addTemplate(templ, 0); + map->setFirstFrontTemplate(template_pos+1); + + if (view) + { + auto opacity = qMax(0.0, qMin(1.0, 0.01 * (100 - dimming))); + view->setTemplateVisibility(templ, { float(opacity), visible }); + } +} + + +void OcdFileImport::importExtras(const OcdFile& file) +{ + const Ocd::FileHeaderV8* header = file.header(); + map->setMapNotes(convertOcdString< Ocd::FormatV8::Encoding >(file.byteArray().data() + header->info_pos, header->info_size)); +} + +template< class F > +void OcdFileImport::importExtras(const OcdFile< F >& file) +{ + map->setMapNotes({ }); + handleStrings(file, extraStringHandlers); +} + +const std::initializer_list OcdFileImport::extraStringHandlers = { + { 11, &OcdFileImport::appendNotes }, + { 1061, &OcdFileImport::appendNotes } +}; + +void OcdFileImport::appendNotes(const QString& param_string, int ocd_version) +{ + QString notes = map->getMapNotes(); + notes.append(param_string); + if (ocd_version <= 10) + notes.append(QLatin1Char('\n')); + map->setMapNotes(notes); +} + + +void OcdFileImport::importView(const OcdFile& file) +{ + if (view) + { + const Ocd::FileHeaderV8* header = file.header(); + const Ocd::SetupV8* setup = reinterpret_cast< const Ocd::SetupV8* >(file.byteArray().data() + header->setup_pos); + + if (setup->zoom >= MapView::zoom_out_limit && setup->zoom <= MapView::zoom_in_limit) + view->setZoom(setup->zoom); + + view->setCenter(convertOcdPoint(setup->center)); + } +} + +template< class F > +void OcdFileImport::importView(const OcdFile< F >& file) +{ + handleStrings(file, { { 1030, &OcdFileImport::importView } }); +} + +void OcdFileImport::importView(const QString& param_string, int) +{ + const QChar* unicode = param_string.unicode(); + + bool zoom_ok = false; + double zoom=1.0, offset_x=0.0, offset_y=0.0; + + int i = param_string.indexOf(QLatin1Char('\t'), 0); + ; // skip first word for this entry type + while (i >= 0) + { + int next_i = param_string.indexOf(QLatin1Char('\t'), i+1); + int len = (next_i > 0 ? next_i : param_string.length()) - i - 2; + const QString param_value = QString::fromRawData(unicode+i+2, len); // no copying! + switch (param_string[i+1].toLatin1()) + { + case '\t': + // empty item + break; + case 'x': + { + offset_x = param_value.toDouble(); + break; + } + case 'y': + { + offset_y = param_value.toDouble(); + break; + } + case 'z': + { + zoom = param_value.toDouble(&zoom_ok); + break; + } + default: + ; // nothing + } + i = next_i; + } + + if (view) + { + view->setCenter(MapCoord(offset_x, -offset_y)); + if (zoom_ok) + { + view->setZoom(zoom); + } + } +} + + +template< class S > +void OcdFileImport::setupBaseSymbol(Symbol* symbol, const S& ocd_symbol) +{ + typedef typename S::BaseSymbol BaseSymbol; + const BaseSymbol& base_symbol = ocd_symbol.base; + // common fields are name, number, description, helper_symbol, hidden/protected status + symbol->setName(convertOcdString(base_symbol.description)); + symbol->setNumberComponent(0, base_symbol.number / BaseSymbol::symbol_number_factor); + symbol->setNumberComponent(1, base_symbol.number % BaseSymbol::symbol_number_factor); + symbol->setNumberComponent(2, -1); + symbol->setIsHelperSymbol(false); + symbol->setProtected(base_symbol.status & Ocd::SymbolProtected); + symbol->setHidden(base_symbol.status & Ocd::SymbolHidden); +} + +template< class S > +PointSymbol* OcdFileImport::importPointSymbol(const S& ocd_symbol, int ocd_version) +{ + OcdImportedPointSymbol* symbol = new OcdImportedPointSymbol(); + setupBaseSymbol(symbol, ocd_symbol); + setupPointSymbolPattern(symbol, ocd_symbol.data_size, ocd_symbol.begin_of_elements, ocd_version); + symbol->setRotatable(ocd_symbol.base.flags & 1); + return symbol; +} + +template< class S > +Symbol* OcdFileImport::importLineSymbol(const S& ocd_symbol, int ocd_version) +{ + using LineStyle = Ocd::LineSymbolCommonV8; + + OcdImportedLineSymbol* line_for_borders = nullptr; + + // Import a main line? + OcdImportedLineSymbol* main_line = nullptr; + if (ocd_symbol.common.double_mode == 0 || ocd_symbol.common.line_width > 0) + { + main_line = importLineSymbolBase(ocd_symbol.common); + setupBaseSymbol(main_line, ocd_symbol); + line_for_borders = main_line; + } + + // Import a 'framing' line? + OcdImportedLineSymbol* framing_line = nullptr; + if (ocd_symbol.common.framing_width > 0 && ocd_version >= 7) + { + framing_line = importLineSymbolFraming(ocd_symbol.common, main_line); + setupBaseSymbol(framing_line, ocd_symbol); + if (!line_for_borders) + line_for_borders = framing_line; + } + + // Import a 'double' line? + bool has_border_line = + (ocd_symbol.common.double_mode != 0) && + (ocd_symbol.common.double_left_width > 0 || ocd_symbol.common.double_right_width > 0); + OcdImportedLineSymbol *double_line = nullptr; + if ( has_border_line && + (ocd_symbol.common.double_flags & LineStyle::DoubleFillColorOn || !line_for_borders) ) + { + double_line = importLineSymbolDoubleBorder(ocd_symbol.common); + setupBaseSymbol(double_line, ocd_symbol); + line_for_borders = double_line; + } + + // Border lines + if (has_border_line) + { + Q_ASSERT(line_for_borders); + setupLineSymbolForBorder(line_for_borders, ocd_symbol.common); + } + + // Create point symbols along line; middle ("normal") dash, corners, start, and end. + OcdImportedLineSymbol* symbol_line = main_line ? main_line : double_line; // Find the line to attach the symbols to + if (symbol_line == nullptr) + { + main_line = new OcdImportedLineSymbol(); + symbol_line = main_line; + setupBaseSymbol(main_line, ocd_symbol); + + main_line->segment_length = convertLength(ocd_symbol.common.main_length); + main_line->end_length = convertLength(ocd_symbol.common.end_length); + } + + setupLineSymbolPointSymbol(symbol_line, ocd_symbol.common, ocd_symbol.begin_of_elements, ocd_version); + + // TODO: taper fields (tmode and tlast) + + if (main_line == nullptr && framing_line == nullptr) + { + return double_line; + } + else if (double_line == nullptr && framing_line == nullptr) + { + return main_line; + } + else if (main_line == nullptr && double_line == nullptr) + { + return framing_line; + } + else + { + CombinedSymbol* full_line = new CombinedSymbol(); + setupBaseSymbol(full_line, ocd_symbol); + mergeLineSymbol(full_line, main_line, framing_line, double_line); + addSymbolWarning(symbol_line, OcdFileImport::tr("This symbol cannot be saved as a proper OCD symbol again.")); + return full_line; + } +} + +OcdFileImport::OcdImportedLineSymbol* OcdFileImport::importLineSymbolBase(const Ocd::LineSymbolCommonV8& attributes) +{ + using LineStyle = Ocd::LineSymbolCommonV8; + + // Basic line options + auto symbol = new OcdImportedLineSymbol(); + symbol->line_width = convertLength(attributes.line_width); + symbol->color = convertColor(attributes.line_color); + + // Cap and join styles + switch (attributes.line_style) + { + default: + addSymbolWarning( symbol, + tr("Unsupported line style '%1'."). + arg(attributes.line_style) ); + // fall through + case LineStyle::BevelJoin_FlatCap: + symbol->join_style = LineSymbol::BevelJoin; + symbol->cap_style = LineSymbol::FlatCap; + break; + case LineStyle::RoundJoin_RoundCap: + symbol->join_style = LineSymbol::RoundJoin; + symbol->cap_style = LineSymbol::RoundCap; + break; + case LineStyle::BevelJoin_PointedCap: + symbol->join_style = LineSymbol::BevelJoin; + symbol->cap_style = LineSymbol::PointedCap; + break; + case LineStyle::RoundJoin_PointedCap: + symbol->join_style = LineSymbol::RoundJoin; + symbol->cap_style = LineSymbol::PointedCap; + break; + case LineStyle::MiterJoin_FlatCap: + symbol->join_style = LineSymbol::MiterJoin; + symbol->cap_style = LineSymbol::FlatCap; + break; + case LineStyle::MiterJoin_PointedCap: + symbol->join_style = LineSymbol::MiterJoin; + symbol->cap_style = LineSymbol::PointedCap; + break; + } + + if (symbol->cap_style == LineSymbol::PointedCap) + { + auto ocd_length = attributes.dist_from_start; + if (attributes.dist_from_start != attributes.dist_from_end) + { + // FIXME: Different lengths for start and end length of pointed line ends are not supported yet, so take the average + ocd_length = (attributes.dist_from_start + attributes.dist_from_end) / 2; + addSymbolWarning( symbol, + tr("Different lengths for pointed caps at begin (%1 mm) and end (%2 mm) are not supported. Using %3 mm."). + arg(locale.toString(0.001f * convertLength(attributes.dist_from_start))). + arg(locale.toString(0.001f * convertLength(attributes.dist_from_end))). + arg(locale.toString(0.001f * convertLength(ocd_length))) ); + } + symbol->pointed_cap_length = convertLength(ocd_length); + symbol->join_style = LineSymbol::RoundJoin; // NOTE: while the setting may be different (see what is set in the first place), OC*D always draws round joins if the line cap is pointed! + } + + // Handle the dash pattern + if (attributes.main_gap || attributes.sec_gap) + { + if (!attributes.main_length) + { + // Invalid dash pattern + addSymbolWarning( symbol, + tr("The dash pattern cannot be imported correctly.") ); + } + else if (attributes.sec_gap && !attributes.main_gap) + { + // Special case main_gap == 0 + symbol->dashed = true; + symbol->dash_length = convertLength(attributes.main_length) - convertLength(attributes.sec_gap); + symbol->break_length = convertLength(attributes.sec_gap); + + if (attributes.end_length) + { + if (qAbs(qint32(attributes.main_length) - 2*attributes.end_length) > 1) + { + // End length not equal to 0.5 * main length + addSymbolWarning( symbol, + tr("The dash pattern's end length (%1 mm) cannot be imported correctly. Using %2 mm."). + arg(locale.toString(0.001f * convertLength(attributes.end_length))). + arg(locale.toString(0.001f * symbol->dash_length)) ); + } + if (attributes.end_gap) + { + addSymbolWarning( symbol, + tr("The dash pattern's end gap (%1 mm) cannot be imported correctly. Using %2 mm."). + arg(locale.toString(0.001f * convertLength(attributes.end_gap))). + arg(locale.toString(0.001f * symbol->break_length)) ); + } + } + } + else + { + // Standard case + symbol->dashed = true; + symbol->dash_length = convertLength(attributes.main_length); + symbol->break_length = convertLength(attributes.main_gap); + + if (attributes.end_length && attributes.end_length != attributes.main_length) + { + if (attributes.main_length && 0.75 >= attributes.end_length / attributes.main_length) + { + // End length max. 75 % of main length + symbol->half_outer_dashes = true; + } + + if (qAbs(qint32(attributes.main_length) - 2*attributes.end_length) > 1) + { + // End length not equal to 0.5 * main length + addSymbolWarning( symbol, + tr("The dash pattern's end length (%1 mm) cannot be imported correctly. Using %2 mm."). + arg(locale.toString(0.001f * convertLength(attributes.end_length))). + arg(locale.toString(0.001f * (symbol->half_outer_dashes ? (symbol->dash_length/2) : symbol->dash_length))) ); + } + } + + if (attributes.sec_gap) + { + symbol->dashes_in_group = 2; + symbol->in_group_break_length = convertLength(attributes.sec_gap); + symbol->dash_length = (symbol->dash_length - symbol->in_group_break_length) / 2; + + if (attributes.end_length && attributes.end_gap != attributes.sec_gap) + { + addSymbolWarning( symbol, + tr("The dash pattern's end gap (%1 mm) cannot be imported correctly. Using %2 mm."). + arg(locale.toString(0.001f * convertLength(attributes.end_gap))). + arg(locale.toString(0.001f * symbol->in_group_break_length)) ); + } + } + } + } + else + { + symbol->segment_length = convertLength(attributes.main_length); + symbol->end_length = convertLength(attributes.end_length); + } + + return symbol; +} + +OcdFileImport::OcdImportedLineSymbol* OcdFileImport::importLineSymbolFraming(const Ocd::LineSymbolCommonV8& attributes, const LineSymbol* main_line) +{ + using LineStyle = Ocd::LineSymbolCommonV8; + + // Basic line options + auto framing_line = new OcdImportedLineSymbol(); + framing_line->line_width = convertLength(attributes.framing_width); + framing_line->color = convertColor(attributes.framing_color); + + // Cap and join styles + switch (attributes.framing_style) + { + case LineStyle::BevelJoin_FlatCap: + framing_line->join_style = LineSymbol::BevelJoin; + framing_line->cap_style = LineSymbol::FlatCap; + break; + case LineStyle::RoundJoin_RoundCap: + framing_line->join_style = LineSymbol::RoundJoin; + framing_line->cap_style = LineSymbol::RoundCap; + break; + case LineStyle::MiterJoin_FlatCap: + framing_line->join_style = LineSymbol::MiterJoin; + framing_line->cap_style = LineSymbol::FlatCap; + break; + default: + addSymbolWarning( main_line, + tr("Unsupported framing line style '%1'."). + arg(attributes.line_style) ); + } + + return framing_line; +} + +OcdFileImport::OcdImportedLineSymbol* OcdFileImport::importLineSymbolDoubleBorder(const Ocd::LineSymbolCommonV8& attributes) +{ + using LineStyle = Ocd::LineSymbolCommonV8; + + auto double_line = new OcdImportedLineSymbol(); + double_line->line_width = convertLength(attributes.double_width); + double_line->cap_style = LineSymbol::FlatCap; + double_line->join_style = LineSymbol::MiterJoin; + double_line->segment_length = convertLength(attributes.main_length); + double_line->end_length = convertLength(attributes.end_length); + + if (attributes.double_flags & LineStyle::DoubleFillColorOn) + double_line->color = convertColor(attributes.double_color); + else + double_line->color = nullptr; + + return double_line; +} + +void OcdFileImport::setupLineSymbolForBorder(OcdFileImport::OcdImportedLineSymbol* line_for_borders, const Ocd::LineSymbolCommonV8& attributes) +{ + line_for_borders->have_border_lines = true; + LineSymbolBorder& border = line_for_borders->getBorder(); + LineSymbolBorder& right_border = line_for_borders->getRightBorder(); + + // Border color and width + border.color = convertColor(attributes.double_left_color); + border.width = convertLength(attributes.double_left_width); + border.shift = convertLength(attributes.double_left_width) / 2 + (convertLength(attributes.double_width) - line_for_borders->line_width) / 2; + + right_border.color = convertColor(attributes.double_right_color); + right_border.width = convertLength(attributes.double_right_width); + right_border.shift = convertLength(attributes.double_right_width) / 2 + (convertLength(attributes.double_width) - line_for_borders->line_width) / 2; + + // The borders may be dashed + if (attributes.double_gap > 0 && attributes.double_mode > 1) + { + border.dashed = true; + border.dash_length = convertLength(attributes.double_length); + border.break_length = convertLength(attributes.double_gap); + + // If ocd_symbol->dmode == 2, only the left border should be dashed + if (attributes.double_mode > 2) + { + right_border.dashed = border.dashed; + right_border.dash_length = border.dash_length; + right_border.break_length = border.break_length; + } + } +} + +void OcdFileImport::setupLineSymbolPointSymbol(OcdFileImport::OcdImportedLineSymbol* line_symbol, const Ocd::LineSymbolCommonV8& attributes, const Ocd::PointSymbolElementV8* elements, int ocd_version) +{ + const Ocd::OcdPoint32* coords = reinterpret_cast(elements); + + line_symbol->mid_symbols_per_spot = attributes.num_prim_sym; + line_symbol->mid_symbol_distance = convertLength(attributes.prim_sym_dist); + line_symbol->mid_symbol = new OcdImportedPointSymbol(); + setupPointSymbolPattern(line_symbol->mid_symbol, attributes.primary_data_size, elements, ocd_version); + coords += attributes.primary_data_size; + + if (attributes.secondary_data_size > 0) + { + //symbol_line->dash_symbol = importPattern( ocd_symbol->ssnpts, symbolptr); + coords += attributes.secondary_data_size; + addSymbolWarning(line_symbol, tr("Skipped secondary point symbol.")); + } + if (attributes.corner_data_size > 0) + { + line_symbol->dash_symbol = new OcdImportedPointSymbol(); + setupPointSymbolPattern(line_symbol->dash_symbol, attributes.corner_data_size, reinterpret_cast(coords), ocd_version); + line_symbol->dash_symbol->setName(LineSymbolSettings::tr("Dash symbol")); + coords += attributes.corner_data_size; + } + if (attributes.start_data_size > 0) + { + line_symbol->start_symbol = new OcdImportedPointSymbol(); + setupPointSymbolPattern(line_symbol->start_symbol, attributes.start_data_size, reinterpret_cast(coords), ocd_version); + line_symbol->start_symbol->setName(LineSymbolSettings::tr("Start symbol")); + coords += attributes.start_data_size; + } + if (attributes.end_data_size > 0) + { + line_symbol->end_symbol = new OcdImportedPointSymbol(); + setupPointSymbolPattern(line_symbol->end_symbol, attributes.end_data_size, reinterpret_cast(coords), ocd_version); + line_symbol->end_symbol->setName(LineSymbolSettings::tr("End symbol")); + } + + // FIXME: not really sure how this translates... need test cases + line_symbol->minimum_mid_symbol_count = 0; //1 + ocd_symbol->smin; + line_symbol->minimum_mid_symbol_count_when_closed = 0; //1 + ocd_symbol->smin; + line_symbol->show_at_least_one_symbol = false; // NOTE: this works in a different way than OC*D's 'at least X symbols' setting (per-segment instead of per-object) + + // Suppress dash symbol at line ends if both start symbol and end symbol exist, + // but don't create a warning unless a dash symbol is actually defined + // and the line symbol is not Mapper's 799 Simple orienteering course. + if (line_symbol->start_symbol && line_symbol->end_symbol) + { + line_symbol->setSuppressDashSymbolAtLineEnds(true); + if (line_symbol->dash_symbol && line_symbol->number[0] != 799) + { + addSymbolWarning(line_symbol, tr("Suppressing dash symbol at line ends.")); + } + } +} + +void OcdFileImport::mergeLineSymbol(CombinedSymbol* full_line, LineSymbol* main_line, LineSymbol* framing_line, LineSymbol* double_line) +{ + full_line->setNumParts(3); // reserve + int part = 0; + if (main_line) + { + full_line->setPart(part++, main_line, true); + main_line->setHidden(false); + main_line->setProtected(false); + } + if (double_line) + { + full_line->setPart(part++, double_line, true); + double_line->setHidden(false); + double_line->setProtected(false); + } + if (framing_line) + { + full_line->setPart(part++, framing_line, true); + framing_line->setHidden(false); + framing_line->setProtected(false); + } + full_line->setNumParts(part); +} + +Symbol* OcdFileImport::importAreaSymbol(const Ocd::AreaSymbolV8& ocd_symbol, int ocd_version) +{ + Q_ASSERT(ocd_version <= 8); + OcdImportedAreaSymbol* symbol = new OcdImportedAreaSymbol(); + setupBaseSymbol(symbol, ocd_symbol); + setupAreaSymbolCommon( + symbol, + ocd_symbol.fill_on, + ocd_symbol.common, + ocd_symbol.data_size, + ocd_symbol.begin_of_elements, + ocd_version); + return symbol; +} + +template< class S > +Symbol* OcdFileImport::importAreaSymbol(const S& ocd_symbol, int ocd_version) +{ + Q_ASSERT(ocd_version >= 9); + OcdImportedAreaSymbol* symbol = new OcdImportedAreaSymbol(); + setupBaseSymbol(symbol, ocd_symbol); + setupAreaSymbolCommon( + symbol, + ocd_symbol.common.fill_on_V9, + ocd_symbol.common, + ocd_symbol.data_size, + ocd_symbol.begin_of_elements, + ocd_version); + if (ocd_symbol.common.border_on_V9) + { + CombinedSymbol* combined = new CombinedSymbol(); + setupBaseSymbol(combined, ocd_symbol); + combined->setNumParts(2); + combined->setPart(0, symbol, true); + auto border = map->getUndefinedLine()->duplicate(); + border->setNumberComponent(0, symbol->getNumberComponent(0)); + border->setNumberComponent(1, symbol->getNumberComponent(1)); + border->setNumberComponent(2, static_cast(ocd_symbol.border_symbol)); + combined->setPart(1, border, true); + addSymbolWarning(symbol, OcdFileImport::tr("This symbol cannot be saved as a proper OCD symbol again.")); + return combined; + } + return symbol; +} + +void OcdFileImport::setupAreaSymbolCommon(OcdImportedAreaSymbol* symbol, bool fill_on, const Ocd::AreaSymbolCommonV8& ocd_symbol, std::size_t data_size, const Ocd::PointSymbolElementV8* elements, int ocd_version) +{ + // Basic area symbol fields: minimum_area, color + symbol->minimum_area = 0; + symbol->color = fill_on ? convertColor(ocd_symbol.fill_color) : nullptr; + symbol->patterns.clear(); + symbol->patterns.reserve(4); + + // Hatching + if (ocd_symbol.hatch_mode != Ocd::HatchNone) + { + AreaSymbol::FillPattern pattern; + pattern.type = AreaSymbol::FillPattern::LinePattern; + pattern.angle = convertAngle(ocd_symbol.hatch_angle_1); + pattern.rotatable = true; + pattern.line_spacing = convertLength(ocd_symbol.hatch_dist); + pattern.line_offset = 0; + pattern.line_color = convertColor(ocd_symbol.hatch_color); + pattern.line_width = convertLength(ocd_symbol.hatch_line_width); + if (ocd_version <= 8) + { + pattern.line_spacing += pattern.line_width; + } + symbol->patterns.push_back(pattern); + + if (ocd_symbol.hatch_mode == Ocd::HatchCross) + { + // Second hatch, same as the first, just a different angle + pattern.angle = convertAngle(ocd_symbol.hatch_angle_2); + symbol->patterns.push_back(pattern); + } + } + + if (ocd_symbol.structure_mode != Ocd::StructureNone) + { + AreaSymbol::FillPattern pattern; + pattern.type = AreaSymbol::FillPattern::PointPattern; + pattern.angle = convertAngle(ocd_symbol.structure_angle); + pattern.rotatable = true; + pattern.point_distance = convertLength(ocd_symbol.structure_width); + pattern.line_spacing = convertLength(ocd_symbol.structure_height); + pattern.line_offset = 0; + pattern.offset_along_line = 0; + // FIXME: somebody needs to own this symbol and be responsible for deleting it + // Right now it looks like a potential memory leak + pattern.point = new OcdImportedPointSymbol(); + setupPointSymbolPattern(pattern.point, data_size, elements, ocd_version); + + // OC*D 8 has a "staggered" pattern mode, where successive rows are shifted width/2 relative + // to each other. We need to simulate this in Mapper with two overlapping patterns, each with + // twice the height. The second is then offset by width/2, height/2. + if (ocd_symbol.structure_mode == Ocd::StructureShiftedRows) + { + pattern.line_spacing *= 2; + symbol->patterns.push_back(pattern); + + pattern.line_offset = pattern.line_spacing / 2; + pattern.offset_along_line = pattern.point_distance / 2; + pattern.point = pattern.point->duplicate()->asPoint(); + } + symbol->patterns.push_back(pattern); + } +} + +template< class S > +TextSymbol* OcdFileImport::importTextSymbol(const S& ocd_symbol, int /*ocd_version*/) +{ + OcdImportedTextSymbol* symbol = new OcdImportedTextSymbol(); + setupBaseSymbol(symbol, ocd_symbol); + setBasicAttributes(symbol, convertOcdString(ocd_symbol.font_name), ocd_symbol.basic); + setSpecialAttributes(symbol, ocd_symbol.special); + setFraming(symbol, ocd_symbol.framing); + return symbol; +} + +template< class S > +TextSymbol* OcdFileImport::importLineTextSymbol(const S& ocd_symbol, int /*ocd_version*/) +{ + OcdImportedTextSymbol* symbol = new OcdImportedTextSymbol(); + setupBaseSymbol(symbol, ocd_symbol); + setBasicAttributes(symbol, convertOcdString(ocd_symbol.font_name), ocd_symbol.basic); + setFraming(symbol, ocd_symbol.framing); + + addSymbolWarning(symbol, OcdFileImport::tr("Line text symbols are not yet supported. Marking the symbol as hidden.")); + symbol->setHidden(true); + return symbol; +} + +template< class S > +LineSymbol* OcdFileImport::importRectangleSymbol(const S& ocd_symbol) +{ + OcdImportedLineSymbol* symbol = new OcdImportedLineSymbol(); + setupBaseSymbol(symbol, ocd_symbol); + + symbol->line_width = convertLength(ocd_symbol.line_width); + symbol->color = convertColor(ocd_symbol.line_color); + symbol->cap_style = LineSymbol::RoundCap; + symbol->join_style = LineSymbol::RoundJoin; + + auto rect = RectangleInfo(); + rect.border_line = symbol; + rect.corner_radius = 0.001 * convertLength(ocd_symbol.corner_radius); + rect.has_grid = ocd_symbol.grid_flags & 1; + + if (rect.has_grid) + { + OcdImportedLineSymbol* inner_line = new OcdImportedLineSymbol(); + setupBaseSymbol(inner_line, ocd_symbol); + inner_line->setNumberComponent(2, 1); // TODO: Dynamic + inner_line->line_width = qRound(1000 * 0.15); + inner_line->color = symbol->color; + map->addSymbol(inner_line, map->getNumSymbols()); + + OcdImportedTextSymbol* text = new OcdImportedTextSymbol(); + setupBaseSymbol(text, ocd_symbol); + text->setNumberComponent(2, 2); // TODO: Dynamic + text->font_family = QString::fromLatin1("Arial"); + text->font_size = qRound(1000 * (15 / 72.0 * 25.4)); + text->color = symbol->color; + text->bold = true; + text->updateQFont(); + map->addSymbol(text, map->getNumSymbols()); + + rect.inner_line = inner_line; + rect.text = text; + rect.number_from_bottom = ocd_symbol.grid_flags & 2; + rect.cell_width = 0.001 * convertLength(ocd_symbol.cell_width); + rect.cell_height = 0.001 * convertLength(ocd_symbol.cell_height); + rect.unnumbered_cells = ocd_symbol.unnumbered_cells; + rect.unnumbered_text = convertOcdString(ocd_symbol.unnumbered_text); + } + rectangle_info.insert(ocd_symbol.base.number, rect); + + return symbol; +} + +void OcdFileImport::setupPointSymbolPattern(PointSymbol* symbol, std::size_t data_size, const Ocd::PointSymbolElementV8* elements, int version) +{ + Q_ASSERT(symbol != nullptr); + + symbol->setRotatable(true); + bool base_symbol_used = false; + + for (std::size_t i = 0; i < data_size; i += 2) + { + const Ocd::PointSymbolElementV8* element = reinterpret_cast(&reinterpret_cast(elements)[i]); + const Ocd::OcdPoint32* const coords = reinterpret_cast(elements) + i + 2; + switch (element->type) + { + case Ocd::PointSymbolElementV8::TypeDot: + if (element->diameter > 0) + { + bool can_use_base_symbol = (!base_symbol_used && (!element->num_coords || (!coords[0].x && !coords[0].y))); + PointSymbol* working_symbol = can_use_base_symbol ? symbol : new PointSymbol(); + working_symbol->setInnerColor(convertColor(element->color)); + working_symbol->setInnerRadius(convertLength(element->diameter) / 2); + working_symbol->setOuterColor(nullptr); + working_symbol->setOuterWidth(0); + if (can_use_base_symbol) + { + base_symbol_used = true; + } + else + { + working_symbol->setRotatable(false); + PointObject* element_object = new PointObject(working_symbol); + if (element->num_coords) + { + const MapCoord coord = convertOcdPoint(coords[0]); + element_object->setPosition(coord.nativeX(), coord.nativeY()); + } + symbol->addElement(symbol->getNumElements(), element_object, working_symbol); + } + } + break; + case Ocd::PointSymbolElementV8::TypeCircle: + { + decltype(element->diameter) element_radius = + (version <= 8) ? (element->diameter / 2 - element->line_width) + : ((element->diameter - element->line_width) / 2); + if (element_radius > 0 && element->line_width > 0) + { + bool can_use_base_symbol = (!base_symbol_used && (!element->num_coords || (!coords[0].x && !coords[0].y))); + PointSymbol* working_symbol = can_use_base_symbol ? symbol : new PointSymbol(); + working_symbol->setInnerColor(nullptr); + working_symbol->setInnerRadius(convertLength(element_radius)); + working_symbol->setOuterColor(convertColor(element->color)); + working_symbol->setOuterWidth(convertLength(element->line_width)); + if (can_use_base_symbol) + { + base_symbol_used = true; + } + else + { + working_symbol->setRotatable(false); + PointObject* element_object = new PointObject(working_symbol); + if (element->num_coords) + { + const MapCoord coord = convertOcdPoint(coords[0]); + element_object->setPosition(coord.nativeX(), coord.nativeY()); + } + symbol->addElement(symbol->getNumElements(), element_object, working_symbol); + } + } + break; + } + case Ocd::PointSymbolElementV8::TypeLine: + if (element->line_width > 0) + { + OcdImportedLineSymbol* element_symbol = new OcdImportedLineSymbol(); + element_symbol->line_width = convertLength(element->line_width); + element_symbol->color = convertColor(element->color); + OcdImportedPathObject* element_object = new OcdImportedPathObject(element_symbol); + fillPathCoords(element_object, false, element->num_coords, coords); + element_object->recalculateParts(); + symbol->addElement(symbol->getNumElements(), element_object, element_symbol); + } + break; + case Ocd::PointSymbolElementV8::TypeArea: + { + OcdImportedAreaSymbol* element_symbol = new OcdImportedAreaSymbol(); + element_symbol->color = convertColor(element->color); + OcdImportedPathObject* element_object = new OcdImportedPathObject(element_symbol); + fillPathCoords(element_object, true, element->num_coords, coords); + element_object->recalculateParts(); + symbol->addElement(symbol->getNumElements(), element_object, element_symbol); + } + break; + default: + ; // TODO: not-supported warning + } + i += element->num_coords; + } +} + +template< class O > +Object* OcdFileImport::importObject(const O& ocd_object, MapPart* part, int ocd_version) +{ + Symbol* symbol = nullptr; + if (ocd_object.symbol >= 0) + { + symbol = symbol_index[ocd_object.symbol]; + } + + if (!symbol) + { + switch (ocd_object.type) + { + case 1: + symbol = map->getUndefinedPoint(); + break; + case 2: + case 3: + symbol = map->getUndefinedLine(); + break; + case 4: + case 5: + symbol = map->getUndefinedText(); + break; + default: + addWarning(OcdFileImport::tr("Unable to load object")); + qDebug() << "Undefined object type" << ocd_object.type << " for object of symbol" << ocd_object.symbol; + return nullptr; + } + } + + if (symbol->getType() == Symbol::Line && rectangle_info.contains(ocd_object.symbol)) + { + Object* object = importRectangleObject(ocd_object, part, rectangle_info[ocd_object.symbol]); + if (!object) + addWarning(OcdFileImport::tr("Unable to import rectangle object")); + return object; + } + + if (symbol->getType() == Symbol::Point) + { + PointObject* p = new PointObject(); + p->setSymbol(symbol, true); + + // extra properties: rotation + PointSymbol* point_symbol = reinterpret_cast(symbol); + if (point_symbol->isRotatable()) + { + p->setRotation(convertAngle(ocd_object.angle)); + } + else if (ocd_object.angle != 0) + { + if (!point_symbol->isSymmetrical()) + { + point_symbol->setRotatable(true); + p->setRotation(convertAngle(ocd_object.angle)); + } + } + + const MapCoord pos = convertOcdPoint(ocd_object.coords[0]); + p->setPosition(pos.nativeX(), pos.nativeY()); + + p->setMap(map); + return p; + } + else if (symbol->getType() == Symbol::Text) + { + TextObject *t = new TextObject(symbol); + t->setText(getObjectText(ocd_object, ocd_version)); + t->setRotation(convertAngle(ocd_object.angle)); + t->setHorizontalAlignment(text_halign_map.value(symbol)); + // Vertical alignment is set in fillTextPathCoords(). + + // Text objects need special path translation + if (!fillTextPathCoords(t, reinterpret_cast(symbol), ocd_object.num_items, reinterpret_cast(ocd_object.coords))) + { + addWarning(OcdFileImport::tr("Not importing text symbol, couldn't figure out path' (npts=%1): %2") + .arg(ocd_object.num_items).arg(t->getText())); + delete t; + return nullptr; + } + t->setMap(map); + return t; + } + else if (symbol->getType() == Symbol::Line || symbol->getType() == Symbol::Area || symbol->getType() == Symbol::Combined) + { + OcdImportedPathObject *p = new OcdImportedPathObject(symbol); + p->setPatternRotation(convertAngle(ocd_object.angle)); + + // Normal path + fillPathCoords(p, symbol->getType() == Symbol::Area, ocd_object.num_items, reinterpret_cast(ocd_object.coords)); + p->recalculateParts(); + p->setMap(map); + return p; + } + + return nullptr; +} + +QString OcdFileImport::getObjectText(const Ocd::ObjectV8& ocd_object, int ocd_version) const +{ + auto input = ocd_object.coords + ocd_object.num_items; + auto maxlen = uint(sizeof(Ocd::OcdPoint32) * ocd_object.num_text); + QString object_text; + if (ocd_object.unicode && ocd_version >= 8) + { + object_text = convertOcdString(reinterpret_cast(input), maxlen/2); + } + else + { + object_text = convertOcdString(reinterpret_cast(input), maxlen); + } + + // Remove leading "\r\n" + if (object_text.startsWith(QLatin1String("\r\n"))) + { + object_text.remove(0, 2); + } + + return object_text; +} + +template< class O > +inline +QString OcdFileImport::getObjectText(const O& ocd_object, int /*ocd_version*/) const +{ + auto data = reinterpret_cast(ocd_object.coords + ocd_object.num_items); + if (data[0] == QLatin1Char{'\r'} && data[1] == QLatin1Char{'\n'}) + data += 2; + return QString(data); +} + + +template< class O > +Object* OcdFileImport::importRectangleObject(const O& ocd_object, MapPart* part, const OcdFileImport::RectangleInfo& rect) +{ + if (ocd_object.num_items != 4) + { + qDebug() << "importRectangleObject called with num_items =" << ocd_object.num_items << "for object of symbol" << ocd_object.symbol; + if (ocd_object.num_items != 5) // 5 coords are handled like 4 coords now + return nullptr; + } + return importRectangleObject(ocd_object.coords, part, rect); +} + +Object* OcdFileImport::importRectangleObject(const Ocd::OcdPoint32* ocd_points, MapPart* part, const OcdFileImport::RectangleInfo& rect) +{ + // Convert corner points + MapCoord bottom_left = convertOcdPoint(ocd_points[0]); + MapCoord bottom_right = convertOcdPoint(ocd_points[1]); + MapCoord top_right = convertOcdPoint(ocd_points[2]); + MapCoord top_left = convertOcdPoint(ocd_points[3]); + + MapCoordF top_left_f = MapCoordF(top_left); + MapCoordF top_right_f = MapCoordF(top_right); + MapCoordF bottom_left_f = MapCoordF(bottom_left); + MapCoordF bottom_right_f = MapCoordF(bottom_right); + MapCoordF right = MapCoordF(top_right.x() - top_left.x(), top_right.y() - top_left.y()); + auto angle = right.angle(); + MapCoordF down = MapCoordF(bottom_left.x() - top_left.x(), bottom_left.y() - top_left.y()); + right.normalize(); + down.normalize(); + + // Create border line + MapCoordVector coords; + if (rect.corner_radius == 0) + { + coords.emplace_back(top_left); + coords.emplace_back(top_right); + coords.emplace_back(bottom_right); + coords.emplace_back(bottom_left); + } + else + { + double handle_radius = (1 - BEZIER_KAPPA) * rect.corner_radius; + coords.emplace_back(top_right_f - right * rect.corner_radius, MapCoord::CurveStart); + coords.emplace_back(top_right_f - right * handle_radius); + coords.emplace_back(top_right_f + down * handle_radius); + coords.emplace_back(top_right_f + down * rect.corner_radius); + coords.emplace_back(bottom_right_f - down * rect.corner_radius, MapCoord::CurveStart); + coords.emplace_back(bottom_right_f - down * handle_radius); + coords.emplace_back(bottom_right_f - right * handle_radius); + coords.emplace_back(bottom_right_f - right * rect.corner_radius); + coords.emplace_back(bottom_left_f + right * rect.corner_radius, MapCoord::CurveStart); + coords.emplace_back(bottom_left_f + right * handle_radius); + coords.emplace_back(bottom_left_f - down * handle_radius); + coords.emplace_back(bottom_left_f - down * rect.corner_radius); + coords.emplace_back(top_left_f + down * rect.corner_radius, MapCoord::CurveStart); + coords.emplace_back(top_left_f + down * handle_radius); + coords.emplace_back(top_left_f + right * handle_radius); + coords.emplace_back(top_left_f + right * rect.corner_radius); + } + PathObject *border_path = new PathObject(rect.border_line, coords, map); + border_path->parts().front().setClosed(true, false); + + if (rect.has_grid && rect.cell_width > 0 && rect.cell_height > 0) + { + // Calculate grid sizes + double width = top_left.distanceTo(top_right); + double height = top_left.distanceTo(bottom_left); + int num_cells_x = qMax(1, qRound(width / rect.cell_width)); + int num_cells_y = qMax(1, qRound(height / rect.cell_height)); + + auto cell_width = width / num_cells_x; + auto cell_height = height / num_cells_y; + + // Create grid lines + coords.resize(2); + for (int x = 1; x < num_cells_x; ++x) + { + coords[0] = MapCoord(top_left_f + x * cell_width * right); + coords[1] = MapCoord(bottom_left_f + x * cell_width * right); + + PathObject *path = new PathObject(rect.inner_line, coords, map); + part->addObject(path, part->getNumObjects()); + } + for (int y = 1; y < num_cells_y; ++y) + { + coords[0] = MapCoord(top_left_f + y * cell_height * down); + coords[1] = MapCoord(top_right_f + y * cell_height * down); + + PathObject *path = new PathObject(rect.inner_line, coords, map); + part->addObject(path, part->getNumObjects()); + } + + // Create grid text + if (height >= rect.cell_height / 2) + { + for (int y = 0; y < num_cells_y; ++y) + { + for (int x = 0; x < num_cells_x; ++x) + { + int cell_num; + QString cell_text; + + if (rect.number_from_bottom) + cell_num = y * num_cells_x + x + 1; + else + cell_num = (num_cells_y - 1 - y) * num_cells_x + x + 1; + + if (cell_num > num_cells_x * num_cells_y - rect.unnumbered_cells) + cell_text = rect.unnumbered_text; + else + cell_text = QString::number(cell_num); + + TextObject* object = new TextObject(rect.text); + object->setMap(map); + object->setText(cell_text); + object->setRotation(-angle); + object->setHorizontalAlignment(TextObject::AlignLeft); + object->setVerticalAlignment(TextObject::AlignTop); + double position_x = (x + 0.07f) * cell_width; + double position_y = (y + 0.04f) * cell_height + rect.text->getFontMetrics().ascent() / rect.text->calculateInternalScaling() - rect.text->getFontSize(); + object->setAnchorPosition(top_left_f + position_x * right + position_y * down); + part->addObject(object, part->getNumObjects()); + + //pts[0].Y -= rectinfo.gridText.FontAscent - rectinfo.gridText.FontEmHeight; + } + } + } + } + + return border_path; +} + +void OcdFileImport::setPathHolePoint(OcdImportedPathObject *object, quint32 pos) +{ + // Look for curve start points before the current point and apply hole point only if no such point is there. + // This prevents hole points in the middle of a curve caused by incorrect map objects. + if (pos >= 1 && object->coords[pos].isCurveStart()) + ; //object->coords[i-1].setHolePoint(true); + else if (pos >= 2 && object->coords[pos-1].isCurveStart()) + ; //object->coords[i-2].setHolePoint(true); + else if (pos >= 3 && object->coords[pos-2].isCurveStart()) + ; //object->coords[i-3].setHolePoint(true); + else if (pos > 0) // Don't start with hole point. + object->coords[pos].setHolePoint(true); +} + +void OcdFileImport::setPointFlags(OcdImportedPathObject* object, quint32 pos, bool is_area, const Ocd::OcdPoint32& ocd_point) +{ + // We can support CurveStart, HolePoint, DashPoint. + // CurveStart needs to be applied to the main point though, not the control point, and + // hole points need to bet set as the last point of a part of an area object instead of the first point of the next part + if (ocd_point.x & Ocd::OcdPoint32::FlagCtl1 && pos > 0) + object->coords[pos-1].setCurveStart(true); + if ((ocd_point.y & Ocd::OcdPoint32::FlagDash) || (ocd_point.y & Ocd::OcdPoint32::FlagCorner)) + object->coords[pos].setDashPoint(true); + if (ocd_point.y & Ocd::OcdPoint32::FlagHole) + { + if (!is_area) + setPathHolePoint(object, pos); + else if (pos > 0) + setPathHolePoint(object, pos - 1); + } +} + +/** Translates the OC*D path given in the last two arguments into an Object. + */ +void OcdFileImport::fillPathCoords(OcdImportedPathObject *object, bool is_area, quint32 num_points, const Ocd::OcdPoint32* ocd_points) +{ + object->coords.resize(num_points); + for (auto i = 0u; i < num_points; i++) + { + object->coords[i] = convertOcdPoint(ocd_points[i]); + setPointFlags(object, i, is_area, ocd_points[i]); + } + + // For path objects, create closed parts where the position of the last point is equal to that of the first point + if (object->getType() == Object::Path) + { + size_t start = 0; + for (size_t i = 0; i < object->coords.size(); ++i) + { + if (!object->coords[i].isHolePoint() && i < object->coords.size() - 1) + continue; + + if (object->coords[i].isPositionEqualTo(object->coords[start])) + { + MapCoord coord = object->coords[start]; + coord.setCurveStart(false); + coord.setHolePoint(true); + coord.setClosePoint(true); + object->coords[i] = coord; + } + + start = i + 1; + } + } +} + +/** Translates an OCAD text object path into a Mapper text object specifier, if possible. + * If successful, sets either 1 or 2 coordinates in the text object and returns true. + * If the OCAD path was not importable, leaves the TextObject alone and returns false. + */ +bool OcdFileImport::fillTextPathCoords(TextObject *object, TextSymbol *symbol, quint32 npts, const Ocd::OcdPoint32 *ocd_points) +{ + // text objects either have 1 point (free anchor) or 2 (midpoint/size) + // OCAD appears to always have 5 or 4 points (possible single anchor, then 4 corner coordinates going clockwise from anchor). + if (npts == 0) return false; + + if (npts == 4) + { + // Box text + MapCoord bottom_left = convertOcdPoint(ocd_points[0]); + MapCoord top_right = convertOcdPoint(ocd_points[2]); + MapCoord top_left = convertOcdPoint(ocd_points[3]); + + // According to Purple Pen source code: OC*D adds an extra internal leading (incorrectly). + QFontMetricsF metrics = symbol->getFontMetrics(); + double top_adjust = -symbol->getFontSize() + (metrics.ascent() + metrics.descent() + 0.5) / symbol->calculateInternalScaling(); + + MapCoordF adjust_vector = MapCoordF(top_adjust * sin(object->getRotation()), top_adjust * cos(object->getRotation())); + top_left = MapCoord(top_left.x() + adjust_vector.x(), top_left.y() + adjust_vector.y()); + top_right = MapCoord(top_right.x() + adjust_vector.x(), top_right.y() + adjust_vector.y()); + + object->setBox((bottom_left.nativeX() + top_right.nativeX()) / 2, (bottom_left.nativeY() + top_right.nativeY()) / 2, + top_left.distanceTo(top_right), top_left.distanceTo(bottom_left)); + object->setVerticalAlignment(TextObject::AlignTop); + } + else + { + // Single anchor text + if (npts != 5) + addWarning(tr("Trying to import a text object with unknown coordinate format")); + + // anchor point + MapCoord coord = convertOcdPoint(ocd_points[0]); + object->setAnchorPosition(coord.nativeX(), coord.nativeY()); + object->setVerticalAlignment(text_valign_map.value(symbol)); + } + + return true; +} + +void OcdFileImport::setBasicAttributes(OcdFileImport::OcdImportedTextSymbol* symbol, const QString& font_name, const Ocd::BasicTextAttributesV8& attributes) +{ + symbol->font_family = font_name; + symbol->color = convertColor(attributes.color); + symbol->font_size = qRound(100.0 * attributes.font_size / 72.0 * 25.4); + symbol->bold = (attributes.font_weight>= 550) ? true : false; + symbol->italic = (attributes.font_italic) ? true : false; + symbol->underline = false; + symbol->kerning = false; + symbol->line_below = false; + symbol->custom_tabs.resize(0); + + if (attributes.font_weight != 400 && attributes.font_weight != 700) + { + addSymbolWarning(symbol, tr("Ignoring custom weight (%1).").arg(attributes.font_weight)); + } + + switch (attributes.alignment & Ocd::HAlignMask) + { + case Ocd::HAlignLeft: + text_halign_map[symbol] = TextObject::AlignLeft; + break; + case Ocd::HAlignRight: + text_halign_map[symbol] = TextObject::AlignRight; + break; + case Ocd::HAlignJustified: + /// \todo Implement justified alignment + addSymbolWarning(symbol, tr("Justified alignment is not supported.")); + // fall through + default: + text_halign_map[symbol] = TextObject::AlignHCenter; + } + + switch (attributes.alignment & Ocd::VAlignMask) + { + case Ocd::VAlignTop: + text_valign_map[symbol] = TextObject::AlignTop; + break; + case Ocd::VAlignMiddle: + text_valign_map[symbol] = TextObject::AlignVCenter; + break; + default: + addSymbolWarning(symbol, tr("Vertical alignment '%1' is not supported.").arg(attributes.alignment & Ocd::VAlignMask)); + // fall through + case Ocd::VAlignBottom: + text_valign_map[symbol] = TextObject::AlignBaseline; + } + + if (attributes.char_spacing != 0) + { + symbol->character_spacing = attributes.char_spacing / 100.0f; + addSymbolWarning(symbol, tr("Custom character spacing may be incorrect.")); + } + + if (attributes.word_spacing != 100) + { + addSymbolWarning(symbol, tr("Ignoring custom word spacing (%1 %).").arg(attributes.word_spacing)); + } + + symbol->updateQFont(); +} + +void OcdFileImport::setSpecialAttributes(OcdFileImport::OcdImportedTextSymbol* symbol, const Ocd::SpecialTextAttributesV8& attributes) +{ + // Convert line spacing + double absolute_line_spacing = 0.00001 * symbol->font_size * attributes.line_spacing; + symbol->line_spacing = absolute_line_spacing / (symbol->getFontMetrics().lineSpacing() / symbol->calculateInternalScaling()); + symbol->paragraph_spacing = convertLength(attributes.para_spacing); + + symbol->line_below = attributes.line_below_on; + symbol->line_below_color = convertColor(attributes.line_below_color); + symbol->line_below_width = convertLength(attributes.line_below_width); + symbol->line_below_distance = convertLength(attributes.line_below_offset); + + symbol->custom_tabs.resize(attributes.num_tabs); + for (auto i = 0u; i < attributes.num_tabs; ++i) + symbol->custom_tabs[i] = convertLength(attributes.tab_pos[i]); + + if (attributes.indent_first_line != 0 || attributes.indent_other_lines != 0) + { + addSymbolWarning(symbol, tr("Ignoring custom indents (%1/%2).").arg(attributes.indent_first_line).arg(attributes.indent_other_lines)); + } +} + +void OcdFileImport::setFraming(OcdFileImport::OcdImportedTextSymbol* symbol, const Ocd::FramingAttributesV8& framing) +{ + switch (framing.mode) + { + case Ocd::FramingShadow: + symbol->framing = true; + symbol->framing_mode = TextSymbol::ShadowFraming; + symbol->framing_color = convertColor(framing.color); + symbol->framing_shadow_x_offset = convertLength(framing.offset_x); + symbol->framing_shadow_y_offset = -1 * convertLength(framing.offset_y); + break; + case Ocd::FramingLine: // since V7 + symbol->framing = true; + symbol->framing_mode = TextSymbol::LineFraming; + symbol->framing_line_half_width = convertLength(framing.line_width); + break; + case Ocd::FramingRectangle: + default: + addSymbolWarning(symbol, tr("Ignoring text framing (mode %1).").arg(framing.mode)); + // fall through + case Ocd::FramingNone: + symbol->framing = false; + } +} + +void OcdFileImport::import(bool load_symbols_only) +{ + Q_ASSERT(buffer.isEmpty()); + + buffer.clear(); + buffer.append(stream->readAll()); + if (buffer.isEmpty()) + throw FileFormatException(Importer::tr("Could not read file: %1").arg(stream->errorString())); + + if (size_t(buffer.size()) < sizeof(Ocd::FormatGeneric::FileHeader)) + throw FileFormatException(Importer::tr("Could not read file: %1").arg(tr("Invalid data."))); + + OcdFile< Ocd::FormatGeneric > generic_file(buffer); + if (generic_file.header()->vendor_mark != 0x0cad) // This also tests correct endianess... + throw FileFormatException(Importer::tr("Could not read file: %1").arg(tr("Invalid data."))); + + int version = generic_file.header()->version; + switch (version) + { + case 6: + case 7: + case 8: + // Note: Version 6 and 7 do have some differences, which will need to be + // handled in the version 8 implementation by looking up the + // actual format version in the file header. + if (Settings::getInstance().getSetting(Settings::General_NewOcd8Implementation).toBool()) + importImplementation< Ocd::FormatV8 >(load_symbols_only); + else + importImplementationLegacy(load_symbols_only); + break; + case 9: + case 10: + using FormatV10Assumption = std::is_same; + Q_STATIC_ASSERT(FormatV10Assumption::value); + importImplementation< Ocd::FormatV9 >(load_symbols_only); + break; + case 11: + importImplementation< Ocd::FormatV11 >(load_symbols_only); + break; + case 12: + importImplementation< Ocd::FormatV12 >(load_symbols_only); + break; + default: + throw FileFormatException( + Importer::tr("Could not read file: %1"). + arg(tr("OCD files of version %1 are not supported!").arg(version)) + ); + } +} + +void OcdFileImport::finishImport() +{ + if (delegate) + { + // The current warnings and actions are already propagated. + auto warnings_size = ptrdiff_t(delegate->warnings().size()); + auto actions_size = ptrdiff_t(delegate->actions().size()); + + delegate->finishImport(); + + // Propagate new warnings and actions from the delegate to this importer. + std::for_each(begin(delegate->warnings()) + warnings_size, end(delegate->warnings()), [this](const QString& w) { addWarning(w); }); + std::for_each(begin(delegate->actions()) + actions_size, end(delegate->actions()), [this](const ImportAction& a) { addAction(a); }); + } +} + +template< class F > +void OcdFileImport::handleStrings(const OcdFile& file, std::initializer_list handlers) +{ + for (const auto& string : file.strings()) + { + for (const auto& handler : handlers) + { + if (string.type == handler.type) + { + (this->*handler.callback)(convertOcdString(file[string]), file.header()->version); + } + } + } +} diff --git a/src/fileformats/ocd_file_import.h b/src/fileformats/ocd_file_import.h new file mode 100644 index 0000000..923036d --- /dev/null +++ b/src/fileformats/ocd_file_import.h @@ -0,0 +1,441 @@ +/* + * Copyright 2013-2016 Kai Pastor + * + * Some parts taken from file_format_oc*d8{.h,_p.h,cpp} which are + * Copyright 2012 Pete Curtis + * + * This file is part of OpenOrienteering. + * + * OpenOrienteering is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenOrienteering is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenOrienteering. If not, see . + */ + +#ifndef OPENORIENTEERING_OCD_FILE_IMPORT +#define OPENORIENTEERING_OCD_FILE_IMPORT + +#include "../file_import_export.h" + +#include + +#include +#include + +#include "ocd_types.h" +#include "ocd_types_v8.h" +#include "../object.h" +#include "../object_text.h" +#include "../symbol.h" +#include "../symbol_area.h" +#include "../symbol_line.h" +#include "../symbol_point.h" +#include "../symbol_text.h" + +class Georeferencing; +class MapColor; +class MapPart; +class OCAD8FileImport; +class Template; + +/** + * An map file importer for OC*D files. + */ +class OcdFileImport : public Importer +{ +Q_OBJECT +protected: + /// Information about an OC*D rectangle symbol + struct RectangleInfo + { + LineSymbol* border_line; + double corner_radius; + bool has_grid; + + // Only valid if has_grid is true + LineSymbol* inner_line; + TextSymbol* text; + bool number_from_bottom; + double cell_width; + double cell_height; + int unnumbered_cells; + QString unnumbered_text; + }; + + // Helper classes that provide to core classes' protected members + + class OcdImportedAreaSymbol : public AreaSymbol + { + friend class OcdFileImport; + }; + + class OcdImportedLineSymbol : public LineSymbol + { + friend class OcdFileImport; + }; + + class OcdImportedPointSymbol : public PointSymbol + { + friend class OcdFileImport; + }; + + class OcdImportedTextSymbol : public TextSymbol + { + friend class OcdFileImport; + }; + + class OcdImportedPathObject : public PathObject + { + friend class OcdFileImport; + + public: + OcdImportedPathObject(Symbol* symbol = nullptr) : PathObject(symbol) { } + ~OcdImportedPathObject() override; + }; + +public: + OcdFileImport(QIODevice* stream, Map *map, MapView *view); + + virtual ~OcdFileImport() override; + + + void setCustom8BitEncoding(QTextCodec* encoding); + + + template< std::size_t N > + QString convertOcdString(const Ocd::PascalString& src) const; + + template< std::size_t N > + QString convertOcdString(const Ocd::Utf8PascalString& src) const; + + template< std::size_t N > + QString convertOcdString(const Ocd::Utf16PascalString& src) const; + + template< class E > + QString convertOcdString(const char* src, uint len) const; + + template< class E > + QString convertOcdString(const QByteArray& data) const; + + QString convertOcdString(const QChar* src, uint maxlen) const; + + MapCoord convertOcdPoint(const Ocd::OcdPoint32& ocd_point) const; + + float convertAngle(int ocd_angle) const; + + int convertLength(qint16 ocd_length) const; + + int convertLength(quint16 ocd_length) const; + + template< class T, class R = qint64 > + R convertLength(T ocd_length) const; + + MapColor* convertColor(int ocd_color); + + void addSymbolWarning(const AreaSymbol* symbol, const QString& warning); + + void addSymbolWarning(const LineSymbol* symbol, const QString& warning); + + void addSymbolWarning(const TextSymbol* symbol, const QString& warning); + + virtual void finishImport() override; + +protected: + virtual void import(bool load_symbols_only) override; + + void importImplementationLegacy(bool load_symbols_only); + + template< class F > + void importImplementation(bool load_symbols_only); + + + struct StringHandler + { + using Callback = void (OcdFileImport::*)(const QString&, int); + qint32 type; + Callback callback; + }; + + template< class F > + void handleStrings(const OcdFile< F >& file, std::initializer_list handlers); + + + void importGeoreferencing(const OcdFile& file); + + template< class F > + void importGeoreferencing(const OcdFile< F >& file); + + /// Imports string 1039. + void importGeoreferencing(const QString& param_string, int ocd_version); + + /// Imports string 1039 field i. + void applyGridAndZone(Georeferencing& georef, const QString& combined_grid_zone); + + + void importColors(const OcdFile& file); + + template< class F > + void importColors(const OcdFile< F >& file); + + void importColor(const QString& param_string, int ocd_version); + + + template< class F > + void importSymbols(const OcdFile< F >& file); + + void resolveSubsymbols(); + + + void importObjects(const OcdFile& file); + + template< class F > + void importObjects(const OcdFile< F >& file); + + + template< class F > + void importTemplates(const OcdFile< F >& file); + + void importTemplate(const QString& param_string, int ocd_version); + + + void importExtras(const OcdFile& file); + + template< class F > + void importExtras(const OcdFile< F >& file); + + static const std::initializer_list extraStringHandlers; + + void appendNotes(const QString& param_string, int ocd_version); + + + void importView(const OcdFile& file); + + template< class F > + void importView(const OcdFile< F >& file); + + void importView(const QString& param_string, int ocd_version); + + + // Symbol import + + template< class S > + PointSymbol* importPointSymbol(const S& ocd_symbol, int ocd_version); + + template< class S > + Symbol* importLineSymbol(const S& ocd_symbol, int ocd_version); + + OcdImportedLineSymbol* importLineSymbolBase(const Ocd::LineSymbolCommonV8& attributes); + + OcdImportedLineSymbol* importLineSymbolFraming(const Ocd::LineSymbolCommonV8& attributes, const LineSymbol* main_line); + + OcdImportedLineSymbol* importLineSymbolDoubleBorder(const Ocd::LineSymbolCommonV8& attributes); + + void setupLineSymbolForBorder(OcdImportedLineSymbol* line_for_borders, const Ocd::LineSymbolCommonV8& attributes); + + void setupLineSymbolPointSymbol(OcdImportedLineSymbol* line_symbol, const Ocd::LineSymbolCommonV8& attributes, const Ocd::PointSymbolElementV8* elements, int ocd_version); + + void mergeLineSymbol(CombinedSymbol* full_line, LineSymbol* main_line, LineSymbol* framing_line, LineSymbol* double_line); + + Symbol* importAreaSymbol(const Ocd::AreaSymbolV8& ocd_symbol, int ocd_version); + + template< class S > + Symbol* importAreaSymbol(const S& ocd_symbol, int ocd_version); + + void setupAreaSymbolCommon( + OcdImportedAreaSymbol* symbol, + bool fill_on, + const Ocd::AreaSymbolCommonV8& ocd_symbol, + std::size_t data_size, + const Ocd::PointSymbolElementV8* elements, + int ocd_version + ); + + template< class S > + TextSymbol* importTextSymbol(const S& ocd_symbol, int ocd_version); + + template< class S > + TextSymbol* importLineTextSymbol(const S& ocd_symbol, int ocd_version); + + template< class S > + LineSymbol* importRectangleSymbol(const S& ocd_symbol); + + template< class S > + void setupBaseSymbol(Symbol* symbol, const S& ocd_symbol); + + void setupPointSymbolPattern(PointSymbol* symbol, std::size_t data_size, const Ocd::PointSymbolElementV8* elements, int version); + + + // Object import + + template< class O > + Object* importObject(const O& ocd_object, MapPart* part, int ocd_version); + + QString getObjectText(const Ocd::ObjectV8& ocd_object, int ocd_version) const; + + template< class O > + QString getObjectText(const O& ocd_object, int ocd_version) const; + + template< class O > + Object* importRectangleObject(const O& ocd_object, MapPart* part, const OcdFileImport::RectangleInfo& rect); + + Object* importRectangleObject(const Ocd::OcdPoint32* ocd_points, MapPart* part, const OcdFileImport::RectangleInfo& rect); + + // Some helper functions that are used in multiple places + + void setPointFlags(OcdImportedPathObject* object, quint32 pos, bool is_area, const Ocd::OcdPoint32& ocd_point); + + void setPathHolePoint(OcdFileImport::OcdImportedPathObject* object, quint32 i); + + void fillPathCoords(OcdFileImport::OcdImportedPathObject* object, bool is_area, quint32 num_points, const Ocd::OcdPoint32* ocd_points); + + bool fillTextPathCoords(TextObject* object, TextSymbol* symbol, quint32 npts, const Ocd::OcdPoint32* ocd_points); + + void setBasicAttributes(OcdImportedTextSymbol* symbol, const QString& font_name, const Ocd::BasicTextAttributesV8& attributes); + + void setSpecialAttributes(OcdImportedTextSymbol* symbol, const Ocd::SpecialTextAttributesV8& attributes); + + void setFraming(OcdImportedTextSymbol* symbol, const Ocd::FramingAttributesV8& framing); + +protected: + /// The locale is used for number formatting. + QLocale locale; + + QByteArray buffer; + + QScopedPointer< OCAD8FileImport > delegate; + + /// Character encoding to use for 1-byte (narrow) strings + QTextCodec *custom_8bit_encoding; + + /// maps OCD color number to oo-mapper color object + QHash color_index; + + /// maps OCD symbol number to oo-mapper symbol object + QHash symbol_index; + + /// maps OO Mapper text symbol pointer to OCD defined horizontal alignment (stored in objects instead of symbols in OO Mapper) + QHash text_halign_map; + + /// maps OO Mapper text symbol pointer to OCD defined vertical alignment (stored in objects instead of symbols in OO Mapper) + QHash text_valign_map; + + /// maps OCD symbol number to rectangle information struct + QHash rectangle_info; +}; + + + +// ### OcdFileImport inline code ### + +template< std::size_t N > +QString OcdFileImport::convertOcdString(const Ocd::PascalString& src) const +{ + return custom_8bit_encoding->toUnicode(src.data, src.length); +} + +template< std::size_t N > +QString OcdFileImport::convertOcdString(const Ocd::Utf8PascalString& src) const +{ + return QString::fromUtf8(src.data, src.length); +} + +template< std::size_t N > +QString OcdFileImport::convertOcdString(const Ocd::Utf16PascalString& src) const +{ + Q_STATIC_ASSERT(N <= std::numeric_limits::max() / 2); + return convertOcdString(src.data, N); +} + +template< > +inline +QString OcdFileImport::convertOcdString< Ocd::Custom8BitEncoding >(const char* src, uint len) const +{ + len = qMin(uint(std::numeric_limits::max()), qstrnlen(src, len)); + return custom_8bit_encoding->toUnicode(src, int(len)); +} + +template< > +inline +QString OcdFileImport::convertOcdString< Ocd::Utf8Encoding >(const char* src, uint len) const +{ + len = qMin(uint(std::numeric_limits::max()), qstrnlen(src, len)); + return QString::fromUtf8(src, int(len)); +} + +template< class E > +QString OcdFileImport::convertOcdString(const QByteArray& data) const +{ + return OcdFileImport::convertOcdString< E >(data.constData(), data.length()); +} + +inline +MapCoord OcdFileImport::convertOcdPoint(const Ocd::OcdPoint32& ocd_point) const +{ + qint32 ocad_x = ocd_point.x >> 8; + qint32 ocad_y = ocd_point.y >> 8; + // Recover from broken coordinate export from Mapper 0.6.2 ... 0.6.4 (#749) + // Cf. broken::convertPointMember in file_format_ocad8.cpp: + // The values -4 ... -1 (-0.004 mm ... -0.001 mm) were converted to 0x80000000u instead of 0. + // This is the maximum value. Thus it is okay to assume it won't occur in regular data, + // and we can safely replace it with 0 here. + // But the input parameter were already subject to right shift ... + constexpr auto invalid_value = qint32(0x80000000u) >> 8; // ... so we use this value here. + if (ocad_x == invalid_value) + ocad_x = 0; + if (ocad_y == invalid_value) + ocad_y = 0; + return MapCoord::fromNative(ocad_x * 10, ocad_y * -10); +} + +inline +float OcdFileImport::convertAngle(int ocd_angle) const +{ + // OC*D uses tenths of a degree, counterclockwise + // BUG: if sin(rotation) is < 0 for a hatched area pattern, the pattern's createRenderables() will go into an infinite loop. + // So until that's fixed, we keep a between 0 and PI + return (M_PI / 1800) * ((ocd_angle + 3600) % 3600); +} + +inline +int OcdFileImport::convertLength(qint16 ocd_length) const +{ + return convertLength(ocd_length); +} + +inline +int OcdFileImport::convertLength(quint16 ocd_length) const +{ + return convertLength(ocd_length); +} + +template< class T, class R > +inline +R OcdFileImport::convertLength(T ocd_length) const +{ + // OC*D uses hundredths of a millimeter. + // oo-mapper uses 1/1000 mm + return static_cast(ocd_length) * 10; +} + +inline +MapColor *OcdFileImport::convertColor(int ocd_color) +{ + if (!color_index.contains(ocd_color)) + { + addWarning(tr("Color id not found: %1, ignoring this color").arg(ocd_color)); + return nullptr; + } + + return color_index[ocd_color]; +} + + +#endif // OPENORIENTEERING_OCD_FILE_IMPORT diff --git a/src/fileformats/ocd_types.cpp b/src/fileformats/ocd_types.cpp new file mode 100644 index 0000000..e4bb5b4 --- /dev/null +++ b/src/fileformats/ocd_types.cpp @@ -0,0 +1,46 @@ +/* + * Copyright 2013, 2016 Kai Pastor + * + * This file is part of OpenOrienteering. + * + * OpenOrienteering is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenOrienteering is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenOrienteering. If not, see . + */ + +#include "ocd_types.h" +#include "ocd_types_v8.h" +#include "ocd_types_v9.h" +#include "ocd_types_v10.h" +#include "ocd_types_v11.h" +#include "ocd_types_v12.h" + +namespace Ocd +{ + // Verify at compile time that a double is 8 bytes big. + + Q_STATIC_ASSERT(sizeof(double) == 8); + + // Verify at compile time that data structures are packed, not aligned. + + Q_STATIC_ASSERT(sizeof(FileHeaderGeneric) == 8); + + Q_STATIC_ASSERT(sizeof(FormatV8::FileHeader) - sizeof(SymbolHeaderV8) == 48); + + Q_STATIC_ASSERT(sizeof(FormatV9::FileHeader) == 48); + + Q_STATIC_ASSERT(sizeof(FormatV10::FileHeader) == 48); + + Q_STATIC_ASSERT(sizeof(FormatV11::FileHeader) == 48); + + Q_STATIC_ASSERT(sizeof(FormatV12::FileHeader) == 60); +} diff --git a/src/fileformats/ocd_types.h b/src/fileformats/ocd_types.h new file mode 100644 index 0000000..b58fc13 --- /dev/null +++ b/src/fileformats/ocd_types.h @@ -0,0 +1,870 @@ +/* + * Copyright 2013, 2015, 2016 Kai Pastor + * + * This file is part of OpenOrienteering. + * + * OpenOrienteering is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenOrienteering is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenOrienteering. If not, see . + */ + +#ifndef OPENORIENTEERING_OCD_TYPES_H +#define OPENORIENTEERING_OCD_TYPES_H + +#include +#include +#include + + +// Helper macro +#define RESERVED_MEMBER_CONCAT2(A,B) A ## B +// Helper macro +#define RESERVED_MEMBER_CONCAT(A,B) RESERVED_MEMBER_CONCAT2(A,B) + +/** + * A macro which generates a unique member name of the format + * reserved_member_LINE_NUMBER. + */ +#define RESERVED_MEMBER RESERVED_MEMBER_CONCAT( reserved_member_ , __LINE__ ) + + +namespace Ocd +{ + /** OCD filetypes */ + enum FileType + { + Map = 0x0000001, + CourseSetting = 0x0000002 + }; + +// This pragma should be supported by msvc, gcc, clang [-fms-compatibility] +#pragma pack(push, 1) + + /** + * A trait for strings and file formats that use a custom 8 bit encoding. + */ + struct Custom8BitEncoding + { + // nothing + }; + + /** + * A trait for strings and file formats that use UTF-8 encoding. + */ + struct Utf8Encoding + { + // nothing + }; + + /** + * A string of max. N characters with a pascal-style binary representation: + * the first byte indicates the length, + * the following N bytes contain the actual character data. + */ + template< std::size_t N > + struct PascalString + { + unsigned char length; + char data[N]; + }; + + /** + * A UTF-8-encoded string of max. N characters with a pascal-style binary representation: + * the first byte indicates the length, + * the following N bytes contain the actual character data. + */ + template< std::size_t N > + struct Utf8PascalString + { + unsigned char length; + char data[N]; + }; + + /** + * A UTF-16LE-encoded string of max. N characters, zero-terminated. + */ + template< std::size_t N > + struct Utf16PascalString + { + QChar data[N]; + }; + + /** + * The generic header at the beginning of all supported OCD file formats. + * + * For implementation efficiency, this header is generalized in comparison + * to the upstream documentation: + * + * - Until V8, the format actually used a 16 bit file type field called + * "section mark", but no file status field. + * - Until V9, the format actually used a 16 bit subversion field, but no + * subsubversion field. + */ + struct FileHeaderGeneric + { + quint16 vendor_mark; + quint8 file_type; /// aka "section mark" until V8 + quint8 file_status_V9; /// \since V9 + quint16 version; + quint8 subversion; + quint8 subsubversion_V10; /// \since V10 + }; + + /** + * An IndexBlock collects 256 index entries, and the file position of the + * next index block if more index entries exist. + */ + template< class E > + struct IndexBlock + { + typedef E IndexEntryType; + + quint32 next_block; + IndexEntryType entries[256]; + }; + + /** + * An index entry for a parameter string. + */ + struct ParameterStringIndexEntry + { + quint32 pos; + quint32 size; + qint32 type; + quint32 obj_index; + }; + + /** + * The parameter string trait. + * + * OCD strings are raw data, so this is more a trait rather than an actual + * structure. + */ + struct ParameterString + { + typedef ParameterStringIndexEntry IndexEntryType; + }; + + /** + * The OCD file point data type. + * + * The coordinates are not raw 32 bit signed integers but contain flags + * in the lowest 8 bits. + */ + struct OcdPoint32 + { + qint32 x; + qint32 y; + + // Flags in x coordinate + enum XFlags + { + FlagCtl1 = 0x01, + FlagCtl2 = 0x02, + FlagLeft = 0x04 + }; + + // Flags in Y coordinate + enum YFlags + { + FlagCorner = 0x01, + FlagHole = 0x02, + FlagRight = 0x04, + FlagDash = 0x08 + }; + }; + +#pragma pack(pop) + + /** + * Symbol type values. + */ + enum SymbolType + { + SymbolTypePoint = 1, + SymbolTypeLine = 2, + SymbolTypeArea = 3, + SymbolTypeText = 4, + SymbolTypeRectangle_V8 = 5, /// Until V8 + SymbolTypeLineText = 6, /// \since V9 + SymbolTypeRectangle_V9 = 7 /// \since V9 + }; + + /** + * Status flags for symbols. + */ + enum SymbolStatus + { + SymbolNormal = 0, + SymbolProtected = 1, + SymbolHidden = 2 + }; + + /** + * Status values for objects. + */ + enum ObjectStatus + { + ObjectDeleted = 0, + ObjectNormal = 1, + ObjectHidden = 2, + ObjectDeletedForUndo = 3 + }; + + /** + * Text alignment flags. + */ + enum TextAlignment + { + HAlignMask = 0x03, + HAlignLeft = 0x00, + HAlignCenter = 0x01, + HAlignRight = 0x02, + HAlignJustified = 0x03, /// All-line for line text symbols + VAlignMask = 0x0c, /// \since V10 + VAlignBottom = 0x00, /// \since V10 + VAlignMiddle = 0x04, /// \since V10 + VAlignTop = 0x08 /// \since V10 + }; + + /** + * Area hatch mode values. + */ + enum HatchMode + { + HatchNone = 0, + HatchSingle = 1, + HatchCross = 2 + }; + + /** + * Area pattern structure values. + */ + enum StructureMode + { + StructureNone = 0, + StructureAlignedRows = 1, + StructureShiftedRows = 2 + }; + + /** + * + */ + enum FramingMode + { + FramingNone = 0, + FramingShadow = 1, /// Somehow different in older versions + FramingLine = 2, /// \since V7 + FramingRectangle = 3 /// \since V8; Not for line text symbols + }; + + /** + * A generic OCD file format trait. + * + * It is suitable for detecting the actual format. + */ + struct FormatGeneric + { + static constexpr int version() { return -1; } + + typedef FileHeaderGeneric FileHeader; + + struct BaseSymbol { typedef quint32 IndexEntryType; }; + + struct Object { typedef quint32 IndexEntryType; }; + }; + +} + + + +// Forward declaration, needed for class FirstIndexBlock. +template< class F > +class OcdFile; + + + +/** + * A template class which provides an operator() returning the first index + * block for a particular OCD entity index. + * + * The generic template is not meant to be used but will trigger an error. + * Specializations must be provided for entity types to be supported. + * + * @param F: the type defining the file format version type + * @param T: the entity type (string, symbol, object) + */ +template< class F, class T > +class FirstIndexBlock +{ +public: + quint32 operator()(const OcdFile* file) const; +}; + +/** + * A template class which provides an operator() returning the first string + * index block. + * + * @param F: the type defining the file format version type + */ +template< class F > +class FirstIndexBlock +{ +public: + quint32 operator()(const OcdFile* file) const; +}; + +/** + * A template class which provides an operator() returning the first symbol + * index block. + * + * @param F: the type defining the file format version type + */ +template< class F > +class FirstIndexBlock +{ +public: + quint32 operator()(const OcdFile* file) const; +}; + +/** + * A template class which provides an operator() returning the first object + * index block. + * + * @param F: the type defining the file format version type + */ +template< class F > +class FirstIndexBlock +{ +public: + quint32 operator()(const OcdFile* file) const; +}; + + + +/** + * A template class which provides an iterator for OCD entity indices. + * + * @param F: the type defining the file format version type + * @param T: the entity type (string, symbol, object) + * @param E: the index entry type + */ +template< class F, class T, class E > +class OcdEntityIndexIterator +{ +public: + typedef F FileFormat; + typedef T EntityType; + typedef E EntryType; + typedef Ocd::IndexBlock IndexBlock; + + OcdEntityIndexIterator(const OcdFile* file, const IndexBlock* first_block); + + const OcdEntityIndexIterator& operator++(); + + const E& operator*() const; + + const E* operator->() const; + + bool operator==(const OcdEntityIndexIterator& rhs) const; + + bool operator!=(const OcdEntityIndexIterator& rhs) const; + +private: + const OcdFile* data; + const IndexBlock* block; + std::size_t index; +}; + + +/** + * A template class which provides an iterator for OCD entity indices, + * specialized for the case where the index entry is just the quint32 file + * position of the entity data. + * + * @param F: the type defining the file format version type + * @param T: the entity type (string, symbol, object) + */ +template< class F, class T > +class OcdEntityIndexIterator +{ +public: + typedef F FileFormat; + typedef T EntityType; + typedef quint32 EntryType; + typedef Ocd::IndexBlock IndexBlock; + + OcdEntityIndexIterator(const OcdFile* file, const IndexBlock* first_block); + + const OcdEntityIndexIterator& operator++(); + + const T& operator*() const; + + const T* operator->() const; + + bool operator==(const OcdEntityIndexIterator& rhs) const; + + bool operator!=(const OcdEntityIndexIterator& rhs) const; + +private: + const OcdFile* data; + const IndexBlock* block; + std::size_t index; +}; + + + +/** + * A template class for dealing with OCD entity indices. + * + * Instances of this data do not actually copy any data, but rather provide + * an STL container like interface for raw data. The interfaces allows for + * forward iterating over the index for the given entity type. + * + * @param F: the type defining the file format version type + * @param T: the entity type (string, symbol, object) + */ +template< class F, class T > +class OcdEntityIndex +{ +public: + /** The actual file format version type, reexported. */ + typedef F FileFormat; + + /** The actual entity type. */ + typedef T EntityType; + + /** The index entry type for the entity type. */ + typedef typename T::IndexEntryType EntryType; + + /** The index iterator type. */ + typedef OcdEntityIndexIterator iterator; + + /** + * Constructs an entity index object. + * + * You must call setData() before using the container interface. + */ + OcdEntityIndex(); + + /** + * Destroys the object. + */ + ~OcdEntityIndex(); + + /** + * Sets the raw file data to which the object provides access. + * + * The data is not copied and must not be deleted as long as the index + * and its iterators are in use. + */ + void setData(const OcdFile* file); + + /** + * Returns a forward iterator to the beginning. + */ + iterator begin() const; + + /** + * Returns a forward iterator to the end. + */ + iterator end() const; + +private: + const OcdFile* data; +}; + + + +/** + * A template class for dealing with OCD files. + * + * @param F: the type defining the actual file format version + */ +template< class F > +class OcdFile +{ +public: + /** The actual file format version type, reexported. */ + typedef F Format; + + /** The actual file header type. */ + typedef typename F::FileHeader FileHeader; + + /** The actual string index type. */ + typedef OcdEntityIndex< F, Ocd::ParameterString > StringIndex; + + /** The actual symbol index type. */ + typedef OcdEntityIndex< F, typename F::BaseSymbol > SymbolIndex; + + /** The actual object index type. */ + typedef OcdEntityIndex< F, typename F::Object > ObjectIndex; + + /** + * Constructs a new object for the file contents given by data. + * + * We try to avoid copying the data by using the implicit sharing provided + * by QByteArray. + */ + OcdFile(const QByteArray& data); + + /** + * Destructs the object. + */ + ~OcdFile() {} + + /** + * Returns the raw data. + */ + const QByteArray& byteArray() const; + + /** + * Returns a const reference to the byte specified by file_pos. + */ + const char& operator[](quint32 file_pos) const; + + /** + * Returns a pointer to the file header. + */ + const FileHeader* header() const; + + /** + * Returns a const reference to the parameter string index. + */ + const StringIndex& strings() const; + + /** + * Returns the raw data of the string. + */ + const QByteArray operator[](const typename StringIndex::EntryType& string) const; + + /** + * Returns a const reference to the symbol index. + */ + const SymbolIndex& symbols() const; + + /** + * Returns a const reference to the object index. + */ + const ObjectIndex& objects() const; + + /** + * Returns a const referenc to the object referenced by an object index iterator. + */ + const typename F::Object& operator[](const typename ObjectIndex::EntryType& object_entry) const; + +private: + QByteArray byte_array; + StringIndex string_index; + SymbolIndex symbol_index; + ObjectIndex object_index; +}; + + + +// ### FirstIndexBlock implementation ### + +// Unknown entity type T: Return 0. +template< class F, class T > +quint32 FirstIndexBlock::operator()(const OcdFile* file) const +{ + Q_UNUSED(file); + + T* valid_entity_type = nullptr; + Q_ASSERT(valid_entity_type); + + return 0; +} + +template< class F > +quint32 FirstIndexBlock::operator()(const OcdFile* file) const +{ + return (file->header()->version < 8) ? 0 : file->header()->first_string_block; +} + +template< class F > +quint32 FirstIndexBlock::operator()(const OcdFile* file) const +{ + return file->header()->first_symbol_block; +} + +template< class F > +quint32 FirstIndexBlock::operator()(const OcdFile* file) const +{ + return file->header()->first_object_block; +} + + +// ### OcdEntityIndexIterator implementation ### + +template< class F, class T, class E > +OcdEntityIndexIterator::OcdEntityIndexIterator(const OcdFile* file, const IndexBlock* first_block) + : data(nullptr) + , block(nullptr) + , index(0) +{ + if (file && first_block) + { + data = file; + block = first_block; + if (data && block->entries[index].pos == 0) + this->operator++(); + } +} + +template< class F, class T, class E > +const OcdEntityIndexIterator& OcdEntityIndexIterator::operator++() +{ + if (data) + { + do + { + ++index; + if (index == 256) + { + index = 0; + quint32 next_block = block->next_block; + if (next_block == 0) + { + block = nullptr; + data = nullptr; + } + else if (Q_UNLIKELY(next_block >= (unsigned int)data->byteArray().size())) + { + qWarning("OcdEntityIndexIterator: Next index block is out of bounds"); + block = nullptr; + data = nullptr; + } + else + { + block = reinterpret_cast(&(*data)[next_block]); + } + } + } + while (block && !block->entries[index].pos); + } + return *this; +} + +template< class F, class T, class E > +inline +const E& OcdEntityIndexIterator::operator*() const +{ + return block->entries[index]; +} + +template< class F, class T, class E > +inline +const E* OcdEntityIndexIterator::operator->() const +{ + return &(block->entries[index]); +} + +template< class F, class T, class E > +inline +bool OcdEntityIndexIterator::operator==(const OcdEntityIndexIterator& rhs) const +{ + return (data == rhs.data && block == rhs.block && index == rhs.index); +} + +template< class F, class T, class E > +inline +bool OcdEntityIndexIterator::operator!=(const OcdEntityIndexIterator& rhs) const +{ + return (data != rhs.data || block != rhs.block || index != rhs.index); +} + + + +// ### OcdEntityIndexIterator specialization ### + +template< class F, class T > +OcdEntityIndexIterator::OcdEntityIndexIterator(const OcdFile* file, const IndexBlock* first_block) + : data(nullptr), + block(nullptr), + index(0) +{ + if (file && first_block) + { + data = file; + block = first_block; + if (data && block->entries[index] == 0) + this->operator++(); + } +} + +template< class F, class T > +const OcdEntityIndexIterator& OcdEntityIndexIterator::operator++() +{ + if (data) + { + do + { + ++index; + if (index == 256) + { + index = 0; + quint32 next_block = block->next_block; + if (next_block) + { + block = reinterpret_cast(&(*data)[next_block]); + } + else + { + block = nullptr; + data = nullptr; + } + } + } + while ( data && !block->entries[index] ); + } + return *this; +} + +template< class F, class T > +inline +const T& OcdEntityIndexIterator::operator*() const +{ + return reinterpret_cast((*data)[block->entries[index]]); +} + +template< class F, class T > +inline +const T* OcdEntityIndexIterator::operator->() const +{ + return reinterpret_cast(&(*data)[block->entries[index]]); +} + +template< class F, class T > +inline +bool OcdEntityIndexIterator::operator==(const OcdEntityIndexIterator& rhs) const +{ + return (data == rhs.data && block == rhs.block && index == rhs.index); +} + +template< class F, class T > +inline +bool OcdEntityIndexIterator::operator!=(const OcdEntityIndexIterator& rhs) const +{ + return (data != rhs.data || block != rhs.block || index != rhs.index); +} + + + +// ### OcdEntityIndex implementation ### + +template< class F, class T > +OcdEntityIndex::OcdEntityIndex() + : data(nullptr) +{ +} + +template< class F, class T > +OcdEntityIndex::~OcdEntityIndex() +{ +} + +template< class F, class T > +void OcdEntityIndex::setData(const OcdFile< F >* file) +{ + data = file; +} + +template< class F, class T > +typename OcdEntityIndex::iterator OcdEntityIndex::begin() const +{ + Q_ASSERT(data != nullptr); + + quint32 file_pos = FirstIndexBlock()(data); + iterator it(data, reinterpret_cast(file_pos ? &(*data)[file_pos] : nullptr)); + return it; +} + +template< class F, class T > +typename OcdEntityIndex::iterator OcdEntityIndex::end() const +{ + static iterator it(nullptr, nullptr); + return it; +} + + + +// ### OcdFile implementation ### + +template< class F > +inline +OcdFile::OcdFile(const QByteArray& data) +{ + byte_array = data; + Q_ASSERT(byte_array.constData() == data.constData()); // No deep copy + string_index.setData(this); + symbol_index.setData(this); + object_index.setData(this); +} + +template< class F > +inline +const QByteArray& OcdFile::byteArray() const +{ + return byte_array; +} + +template< class F > +inline +const char& OcdFile::operator[](quint32 file_pos) const +{ + return *(byte_array.constData() + file_pos); +} + +template< class F > +inline +const typename F::FileHeader* OcdFile::header() const +{ + return (byte_array.size() < (int)sizeof(FileHeader)) ? nullptr : (const FileHeader*)byte_array.constData(); +} + +template< class F > +inline +const typename OcdFile::StringIndex& OcdFile::strings() const +{ + return string_index; +} + +template< class F > +inline +const QByteArray OcdFile::operator[](const typename OcdFile::StringIndex::EntryType& string) const +{ + return QByteArray::fromRawData(&(*this)[string.pos], string.size); +} + +template< class F > +inline +const typename OcdFile::SymbolIndex& OcdFile::symbols() const +{ + return symbol_index; +} + +template< class F > +inline +const typename OcdFile::ObjectIndex& OcdFile::objects() const +{ + return object_index; +} + +template< class F > +inline +const typename F::Object& OcdFile::operator[](const typename OcdFile::ObjectIndex::EntryType& object_entry) const +{ + return reinterpret_cast((*this)[object_entry.pos]); +} + +#endif // OPENORIENTEERING_OCD_TYPES_H diff --git a/src/fileformats/ocd_types_v10.h b/src/fileformats/ocd_types_v10.h new file mode 100644 index 0000000..837ab5a --- /dev/null +++ b/src/fileformats/ocd_types_v10.h @@ -0,0 +1,33 @@ +/* + * Copyright 2013, 2015, 2016 Kai Pastor + * + * This file is part of OpenOrienteering. + * + * OpenOrienteering is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenOrienteering is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenOrienteering. If not, see . + */ + +#ifndef OPENORIENTEERING_OCD_TYPES_V10 +#define OPENORIENTEERING_OCD_TYPES_V10 + +#include "ocd_types.h" +#include "ocd_types_v9.h" + +namespace Ocd +{ + + using FormatV10 = FormatV9; + +} + +#endif // OPENORIENTEERING_OCD_TYPES_V10_H diff --git a/src/fileformats/ocd_types_v11.h b/src/fileformats/ocd_types_v11.h new file mode 100644 index 0000000..83f80d3 --- /dev/null +++ b/src/fileformats/ocd_types_v11.h @@ -0,0 +1,159 @@ +/* + * Copyright 2013, 2015, 2016 Kai Pastor + * + * This file is part of OpenOrienteering. + * + * OpenOrienteering is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenOrienteering is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenOrienteering. If not, see . + */ + +#ifndef OPENORIENTEERING_OCD_TYPES_V11_H +#define OPENORIENTEERING_OCD_TYPES_V11_H + +#include "ocd_types.h" +#include "ocd_types_v10.h" + +namespace Ocd +{ + +#pragma pack(push, 1) + + struct BaseSymbolV11 + { + using IndexEntryType = quint32; + static const int symbol_number_factor = 1000; + + quint32 size; + quint32 number; + quint8 type; + quint8 flags; + quint8 selected; + quint8 status; + quint8 tool; + quint8 cs_mode; + quint8 cs_type; + quint8 cd_flags; + qint32 extent; + quint32 file_pos; + quint8 RESERVED_MEMBER[2]; + quint16 num_colors; + quint16 colors[14]; + Utf16PascalString<64> description; + quint8 icon_bits[484]; + quint16 group[64]; + }; + + struct PointSymbolV11 + { + using BaseSymbol = BaseSymbolV11; + using Element = FormatV10::PointSymbol::Element; + + BaseSymbol base; + + quint16 data_size; + quint16 RESERVED_MEMBER; + Element begin_of_elements[1]; + }; + + struct LineSymbolV11 + { + using BaseSymbol = BaseSymbolV11; + using Element = FormatV10::LineSymbol::Element; + + BaseSymbol base; + + LineSymbolCommonV8 common; + + Element begin_of_elements[1]; + }; + + struct AreaSymbolV11 + { + using BaseSymbol = BaseSymbolV11; + using Element = FormatV10::AreaSymbol::Element; + + BaseSymbol base; + + quint32 border_symbol; + AreaSymbolCommonV8 common; + quint16 RESERVED_MEMBER; + quint16 data_size; + + Element begin_of_elements[1]; + }; + + struct TextSymbolV11 + { + using BaseSymbol = BaseSymbolV11; + + BaseSymbol base; + + Utf8PascalString<31> font_name; + BasicTextAttributesV8 basic; + SpecialTextAttributesV8 special; + quint16 RESERVED_MEMBER; + FramingAttributesV8 framing; + }; + + struct LineTextSymbolV11 + { + using BaseSymbol = BaseSymbolV11; + + BaseSymbol base; + + Utf8PascalString<31> font_name; + BasicTextAttributesV8 basic; + FramingAttributesV8 framing; + }; + + struct RectangleSymbolV11 + { + using BaseSymbol = BaseSymbolV11; + + BaseSymbol base; + + quint16 line_color; + quint16 line_width; + quint16 corner_radius; + quint16 grid_flags; + quint16 cell_width; + quint16 cell_height; + quint16 RESERVED_MEMBER[2]; + quint16 unnumbered_cells; + Utf8PascalString<3> unnumbered_text; + quint16 line_style; + Utf8PascalString<31> RESERVED_MEMBER; + quint16 RESERVED_MEMBER; + quint16 font_size_V10; /// \since V10 + quint16 RESERVED_MEMBER[4]; + }; + +#pragma pack(pop) + + /** OCD file format version 11 trait. */ + struct FormatV11 + { + using FileHeader = FormatV10::FileHeader; + using BaseSymbol = BaseSymbolV11; + using PointSymbol = PointSymbolV11; + using LineSymbol = LineSymbolV11; + using AreaSymbol = AreaSymbolV11; + using TextSymbol = TextSymbolV11; + using LineTextSymbol = LineTextSymbolV11; + using RectangleSymbol = RectangleSymbolV11; + using Object = FormatV10::Object; + using Encoding = Utf8Encoding; + }; +} + +#endif // OPENORIENTEERING_OCD_TYPES_V11_H diff --git a/src/fileformats/ocd_types_v12.h b/src/fileformats/ocd_types_v12.h new file mode 100644 index 0000000..fa90883 --- /dev/null +++ b/src/fileformats/ocd_types_v12.h @@ -0,0 +1,99 @@ +/* + * Copyright 2013, 2015, 2016 Kai Pastor + * + * This file is part of OpenOrienteering. + * + * OpenOrienteering is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenOrienteering is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenOrienteering. If not, see . + */ + +#ifndef OPENORIENTEERING_OCD_TYPES_V12_H +#define OPENORIENTEERING_OCD_TYPES_V12_H + +#include "ocd_types.h" +#include "ocd_types_v11.h" + +namespace Ocd +{ + +#pragma pack(push, 1) + + struct FileHeaderV12 : public FormatV11::FileHeader + { + quint32 RESERVED_MEMBER[2]; + quint32 first_multi_rep_block; + }; + + struct AreaSymbolV12 + { + using BaseSymbol = FormatV11::BaseSymbol; + using Element = FormatV11::PointSymbol::Element; + + BaseSymbol base; + + quint32 border_symbol; + AreaSymbolCommonV8 common; + quint8 structure_variation_x; + quint8 structure_variation_y; + quint16 structure_minimum_dist; + quint16 RESERVED_MEMBER; + quint16 data_size; + + Element begin_of_elements[1]; + }; + + struct ObjectV12 + { + using IndexEntryType = FormatV11::Object::IndexEntryType; + + quint32 symbol; + quint8 type; + quint8 customer; + qint16 angle; + qint32 color; + quint16 line_width; + quint16 diam_flags; + quint32 server_object_id; + quint32 height; + quint64 creation_date; + quint32 multi_rep_id; + quint64 modification_date; + quint32 num_items; + quint16 num_text; + quint16 object_string_length; + quint16 db_link_length; + quint8 object_string_type; + quint8 RESERVED_MEMBER; + + OcdPoint32 coords[1]; + }; + +#pragma pack(pop) + + /** OCD file format version 11 trait. */ + struct FormatV12 + { + using FileHeader = FileHeaderV12; + using BaseSymbol = FormatV11::BaseSymbol; + using PointSymbol = FormatV11::PointSymbol; + using LineSymbol = FormatV11::LineSymbol; + using AreaSymbol = AreaSymbolV12; + using TextSymbol = FormatV11::TextSymbol; + using LineTextSymbol = FormatV11::LineTextSymbol; + using RectangleSymbol = FormatV11::RectangleSymbol; + using Object = ObjectV12; + using Encoding = Utf8Encoding; + }; +} + +#endif // OPENORIENTEERING_OCD_TYPES_V12_H diff --git a/src/fileformats/ocd_types_v8.h b/src/fileformats/ocd_types_v8.h new file mode 100644 index 0000000..3b5b4e6 --- /dev/null +++ b/src/fileformats/ocd_types_v8.h @@ -0,0 +1,447 @@ +/* + * Copyright 2013, 2015, 2016 Kai Pastor + * + * This file is part of OpenOrienteering. + * + * OpenOrienteering is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenOrienteering is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenOrienteering. If not, see . + */ + +#ifndef OPENORIENTEERING_OCD_TYPES_V8_H +#define OPENORIENTEERING_OCD_TYPES_V8_H + +#include "ocd_types.h" + +namespace Ocd +{ + +#pragma pack(push, 1) + + struct CmykV8 + { + quint8 cyan; + quint8 magenta; + quint8 yellow; + quint8 black; + }; + + struct ColorInfoV8 + { + quint16 number; + quint16 RESERVED_MEMBER; + CmykV8 cmyk; + PascalString<31> name; + quint8 separations[32]; + }; + + struct SeparationInfoV8 + { + PascalString<15> name; + CmykV8 cmyk; + quint16 raster_freq; + quint16 raster_angle; + }; + + struct SymbolHeaderV8 + { + quint16 num_colors; + quint16 num_separations; + quint16 cyan_freq; + quint16 cyan_angle; + quint16 magenta_freq; + quint16 magenta_angle; + quint16 yellow_freq; + quint16 yellow_angle; + quint16 black_freq; + quint16 black_angle; + quint16 RESERVED_MEMBER[2]; + ColorInfoV8 color_info[256]; + SeparationInfoV8 separation_info[32]; + }; + + struct FileHeaderV8 : public FileHeaderGeneric + { + quint32 first_symbol_block; + quint32 first_object_block; + quint32 setup_pos; + quint32 setup_size; + quint32 info_pos; + quint32 info_size; + quint32 first_string_block; + quint32 RESERVED_MEMBER[3]; + SymbolHeaderV8 symbol_header; + }; + + struct BaseSymbolV8 + { + using IndexEntryType = quint32; + static const int symbol_number_factor = 10; + + quint16 size; + quint16 number; + quint16 type; + quint8 type2; + quint8 flags; + quint16 extent; + quint8 selected; + quint8 status; + quint16 RESERVED_MEMBER[2]; + qint32 file_pos; + quint8 colors[32]; + PascalString<31> description; + quint8 icon_bits[264]; + }; + + struct PointSymbolElementV8 + { + quint16 type; + quint16 flags; + quint16 color; + qint16 line_width; + qint16 diameter; + quint16 num_coords; + quint32 RESERVED_MEMBER; + + enum PointSymbolElementTypes + { + TypeLine = 1, + TypeArea = 2, + TypeCircle = 3, + TypeDot = 4 + }; + }; + + struct PointSymbolV8 + { + using BaseSymbol = BaseSymbolV8; + using Element = PointSymbolElementV8; + + BaseSymbol base; + + quint16 data_size; + quint16 RESERVED_MEMBER; + Element begin_of_elements[1]; + }; + + struct LineSymbolCommonV8 + { + quint16 line_color; + quint16 line_width; + quint16 line_style; + qint16 dist_from_start; + qint16 dist_from_end; + qint16 main_length; + qint16 end_length; + qint16 main_gap; + qint16 sec_gap; + qint16 end_gap; + qint16 min_sym; + qint16 num_prim_sym; + qint16 prim_sym_dist; + quint16 double_mode; + quint16 double_flags; + quint16 double_color; + quint16 double_left_color; + quint16 double_right_color; + qint16 double_width; + qint16 double_left_width; + qint16 double_right_width; + qint16 double_length; + qint16 double_gap; + quint16 double_background_color_V11; /// \since V11 + quint16 RESERVED_MEMBER[2]; + quint16 dec_mode; + quint16 dec_last; + quint16 RESERVED_MEMBER; + quint16 framing_color; + qint16 framing_width; + quint16 framing_style; + quint16 primary_data_size; + quint16 secondary_data_size; + quint16 corner_data_size; + quint16 start_data_size; + quint16 end_data_size; + quint8 active_symbols_V11; /// \since V11 + quint8 RESERVED_MEMBER; + + enum LineStyleFlag + { + BevelJoin_FlatCap = 0, + RoundJoin_RoundCap = 1, + BevelJoin_PointedCap = 2, + RoundJoin_PointedCap = 3, + MiterJoin_FlatCap = 4, + MiterJoin_PointedCap = 6 + }; + + enum DoubleLineFlag + { + DoubleFillColorOn = 1, + DoubleBackgroundColorOn = 2 + }; + }; + + struct LineSymbolV8 + { + using BaseSymbol = BaseSymbolV8; + using Element = PointSymbolElementV8; + + BaseSymbol base; + + LineSymbolCommonV8 common; + + Element begin_of_elements[1]; + }; + + struct AreaSymbolCommonV8 + { + quint16 fill_color; + quint16 hatch_mode; + quint16 hatch_color; + quint16 hatch_line_width; + quint16 hatch_dist; + qint16 hatch_angle_1; + qint16 hatch_angle_2; + quint8 fill_on_V9; /// \since V9 + quint8 border_on_V9; /// \since V9 + quint8 structure_mode; + quint8 structure_draw_V12; /// \since V12 + quint16 structure_width; + quint16 structure_height; + qint16 structure_angle; + }; + + struct AreaSymbolV8 + { + using BaseSymbol = BaseSymbolV8; + using Element = PointSymbolElementV8; + + BaseSymbol base; + + quint16 area_flags; + quint16 fill_on; + AreaSymbolCommonV8 common; + quint16 RESERVED_MEMBER; + quint16 data_size; + + Element begin_of_elements[1]; + }; + + struct BasicTextAttributesV8 + { + quint16 color; + quint16 font_size; + quint16 font_weight; + quint8 font_italic; + quint8 charset_V8_ONLY; /// V8 text symbols only + quint16 char_spacing; + quint16 word_spacing; + quint16 alignment; + }; + + struct SpecialTextAttributesV8 + { + quint16 line_spacing; + qint16 para_spacing; + quint16 indent_first_line; + quint16 indent_other_lines; + quint16 num_tabs; + quint32 tab_pos[32]; + quint16 line_below_on; + quint16 line_below_color; + quint16 line_below_width; + quint16 line_below_offset; + }; + + struct FramingAttributesV8 + { + quint8 mode; /// 16 bit in V8 + quint8 line_style_V9; /// \since V9 + quint8 point_symbol_on_V10; /// \since V10 + quint32 point_symbol_number_V10; /// \since V10 + char RESERVED_MEMBER[19]; + quint16 border_left_V9; /// \since V9; TextSymbol only + quint16 border_bottom_V9; /// \since V9; TextSymbol only + quint16 border_right_V9; /// \since V9; TextSymbol only + quint16 border_top_V9; /// \since V9; TextSymbol only + quint16 color; + quint16 line_width; + quint16 font_weight; /// TextSymbol only + quint16 italic; /// TextSymbol only + quint16 offset_x; + quint16 offset_y; + }; + + struct TextSymbolV8 + { + using BaseSymbol = BaseSymbolV8; + + BaseSymbol base; + + PascalString<31> font_name; + BasicTextAttributesV8 basic; + SpecialTextAttributesV8 special; + quint16 RESERVED_MEMBER; + FramingAttributesV8 framing; + }; + + struct LineTextSymbolV8 /// \todo use and test... + { + using BaseSymbol = BaseSymbolV8; + + BaseSymbol base; + + PascalString<31> font_name; + BasicTextAttributesV8 basic; + FramingAttributesV8 framing; + }; + + struct RectangleSymbolV8 + { + using BaseSymbol = BaseSymbolV8; + + BaseSymbol base; + + quint16 line_color; + quint16 line_width; + quint16 corner_radius; + quint16 grid_flags; + quint16 cell_width; + quint16 cell_height; + quint16 RESERVED_MEMBER[2]; + quint16 unnumbered_cells; + PascalString<3> unnumbered_text; + quint16 RESERVED_MEMBER; + PascalString<31> RESERVED_MEMBER; + quint16 RESERVED_MEMBER[6]; + }; + + struct ObjectIndexEntryV8 + { + OcdPoint32 bottom_left_bound; + OcdPoint32 top_right_bound; + quint32 pos; + quint16 size_MISC; /// Different interpretation for version < 8 + qint16 symbol; + }; + + struct ObjectV8 + { + using IndexEntryType = ObjectIndexEntryV8; + + quint16 symbol; + quint8 type; + quint8 unicode; + quint16 num_items; + quint16 num_text; + qint16 angle; + quint16 RESERVED_MEMBER; + quint32 RESERVED_MEMBER; + PascalString<15> reserved; + + OcdPoint32 coords[1]; + }; + + typedef double PascalDouble; + + struct GpsPointV8 + { + OcdPoint32 map_point; + PascalDouble lat; + PascalDouble lon; + PascalString<15> name; + }; + + struct PrintSetupV8 + { + OcdPoint32 bottom_left; + OcdPoint32 top_right; + quint16 grid_enabled; + qint16 grid_color; + qint16 overlap_x; + qint16 overlap_y; + PascalDouble scale; + quint16 intensity; + quint16 line_width; + quint16 RESERVED_MEMBER[4]; + }; + + struct ExportSetupV8 + { + OcdPoint32 bottom_left; + OcdPoint32 top_right; + }; + + struct ZoomRectV8 + { + PascalDouble zoom; + OcdPoint32 center; + }; + + struct SetupV8 + { + OcdPoint32 center; + PascalDouble grid_dist; + quint16 work_mode; + quint16 line_mode; + quint16 edit_mode; + qint16 selected_symbol; + PascalDouble map_scale; + PascalDouble real_offset_x; + PascalDouble real_offset_y; + PascalDouble real_angle; + PascalDouble real_grid; + PascalDouble gps_angle; + GpsPointV8 gps_adjustment[12]; + quint32 num_gps_adjustments; + PascalDouble RESERVED_MEMBER[2]; + OcdPoint32 RESERVED_MEMBER; + char RESERVED_MEMBER[256]; + quint16 RESERVED_MEMBER[2]; + PascalDouble RESERVED_MEMBER; + OcdPoint32 RESERVED_MEMBER; + PascalDouble RESERVED_MEMBER; + PrintSetupV8 print_setup; + ExportSetupV8 export_setup; + PascalDouble zoom; + ZoomRectV8 zoom_history[8]; + quint32 zoom_history_size; + // V6 header ends here, but Mapper doesn't use the following fields. + quint16 real_coords_IGNORED; + char filename_IGNORED[256]; + quint16 hatch_areas_IGNORED; + quint16 dim_templates_IGNORED; + quint16 hide_templates_IGNORED; + quint16 template_mode_IGNORED; + qint16 template_color_IGNORED; + }; + +#pragma pack(pop) + + /** OCD file format version 8 trait. */ + struct FormatV8 + { + using FileHeader = FileHeaderV8; + using BaseSymbol = BaseSymbolV8; + using PointSymbol = PointSymbolV8; + using LineSymbol = LineSymbolV8; + using AreaSymbol = AreaSymbolV8; + using TextSymbol = TextSymbolV8; + using LineTextSymbol = LineTextSymbolV8; + using RectangleSymbol = RectangleSymbolV8; + using Object = ObjectV8; + using Encoding = Custom8BitEncoding; + }; +} + +#endif // OPENORIENTEERING_OCD_TYPES_V8_H diff --git a/src/fileformats/ocd_types_v9.h b/src/fileformats/ocd_types_v9.h new file mode 100644 index 0000000..498d346 --- /dev/null +++ b/src/fileformats/ocd_types_v9.h @@ -0,0 +1,215 @@ +/* + * Copyright 2013, 2015, 2016 Kai Pastor + * + * This file is part of OpenOrienteering. + * + * OpenOrienteering is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenOrienteering is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenOrienteering. If not, see . + */ + +#ifndef OPENORIENTEERING_OCD_TYPES_V9_H +#define OPENORIENTEERING_OCD_TYPES_V9_H + +#include "ocd_types.h" +#include "ocd_types_v8.h" + +namespace Ocd +{ + +#pragma pack(push, 1) + + struct FileHeaderV9 : public FileHeaderGeneric + { + quint32 first_symbol_block; + quint32 first_object_block; + quint32 offline_sync_serial_V11; /// \since V11 + quint32 current_file_version_V12; /// \since V12 + quint32 RESERVED_MEMBER[2]; + quint32 first_string_block; + quint32 file_name_pos; + quint32 file_name_size; + quint32 RESERVED_MEMBER; + }; + + struct BaseSymbolV9 + { + using IndexEntryType = quint32; + static const int symbol_number_factor = 1000; + + quint32 size; + quint32 number; + quint8 type; + quint8 flags; + quint8 selected; + quint8 status; + quint8 tool; + quint8 cs_mode; + quint8 cs_type; + quint8 cd_flags; + qint32 extent; + qint32 file_pos; + quint16 group; + quint16 num_colors; + quint16 colors[14]; + PascalString<31> description; + quint8 icon_bits[484]; + }; + + struct PointSymbolV9 + { + using BaseSymbol = BaseSymbolV9; + using Element = FormatV8::PointSymbol::Element; + + BaseSymbol base; + + quint16 data_size; + quint16 RESERVED_MEMBER; + Element begin_of_elements[1]; + }; + + struct LineSymbolV9 + { + using BaseSymbol = BaseSymbolV9; + using Element = FormatV8::LineSymbol::Element; + + BaseSymbol base; + + LineSymbolCommonV8 common; + + Element begin_of_elements[1]; + }; + + struct AreaSymbolV9 + { + using BaseSymbol = BaseSymbolV9; + using Element = FormatV8::AreaSymbol::Element; + + BaseSymbol base; + + quint32 border_symbol; + AreaSymbolCommonV8 common; + quint16 RESERVED_MEMBER; + quint16 data_size; + + Element begin_of_elements[1]; + }; + + struct TextSymbolV9 + { + using BaseSymbol = BaseSymbolV9; + + BaseSymbol base; + + PascalString<31> font_name; + BasicTextAttributesV8 basic; + SpecialTextAttributesV8 special; + quint16 RESERVED_MEMBER; + FramingAttributesV8 framing; + }; + + struct LineTextSymbolV9 + { + using BaseSymbol = BaseSymbolV9; + + BaseSymbol base; + + PascalString<31> font_name; + BasicTextAttributesV8 basic; + FramingAttributesV8 framing; + }; + + struct RectangleSymbolV9 + { + using BaseSymbol = BaseSymbolV9; + + BaseSymbol base; + + quint16 line_color; + quint16 line_width; + quint16 corner_radius; + quint16 grid_flags; + quint16 cell_width; + quint16 cell_height; + quint16 RESERVED_MEMBER[2]; + quint16 unnumbered_cells; + PascalString<3> unnumbered_text; + quint16 RESERVED_MEMBER; + PascalString<31> RESERVED_MEMBER; + quint16 RESERVED_MEMBER; + quint16 font_size_V10; /// \since V10 + quint16 RESERVED_MEMBER[4]; + }; + + struct ObjectIndexEntryV9 + { + OcdPoint32 bottom_left_bound; + OcdPoint32 top_right_bound; + quint32 pos; + quint32 size; + qint32 symbol; + quint8 type; + quint8 encryption_mode_V11; /// \since V11 + quint8 status; + quint8 view_type; + quint16 color; + quint16 group_V11; /// \since V11 + quint16 layer; + quint8 layout_font_V11_ONLY; /// only in V11 + quint8 RESERVED_MEMBER; + }; + + struct ObjectV9 + { + using IndexEntryType = ObjectIndexEntryV9; + + quint32 symbol; + quint8 type; + quint8 customer_V11; /// \since V11 + qint16 angle; + quint32 num_items; + quint16 num_text; + quint8 mark_V11; /// \since V11 + quint8 snapping_mark_V11; /// \since V11 + quint32 color; + quint16 line_width; + quint16 diam_flags; + // The usage of the following 16 bytes has changed significantly in the + // versions 9 to 12. This is an abstraction, capturing what seems most + // relevant. + quint32 RESERVED_MEMBER; /// V11: Server object ID + quint32 height_V11; /// \since V11; unit: 1/256 mm + quint32 RESERVED_MEMBER; + quint32 height_V10_ONLY; /// V10 only; unit: mm + + OcdPoint32 coords[1]; + }; + +#pragma pack(pop) + + /** OCD file format version 9 trait. */ + struct FormatV9 + { + using FileHeader = FileHeaderV9; + using BaseSymbol = BaseSymbolV9; + using PointSymbol = PointSymbolV9; + using LineSymbol = LineSymbolV9; + using AreaSymbol = AreaSymbolV9; + using TextSymbol = TextSymbolV9; + using LineTextSymbol = LineTextSymbolV9; + using RectangleSymbol = RectangleSymbolV9; + using Object = ObjectV9; + using Encoding = Custom8BitEncoding; + }; +} + +#endif // OPENORIENTEERING_OCD_TYPES_V9_H diff --git a/src/gdal/CMakeLists.txt b/src/gdal/CMakeLists.txt new file mode 100644 index 0000000..acb3a62 --- /dev/null +++ b/src/gdal/CMakeLists.txt @@ -0,0 +1,55 @@ +# +# Copyright 2016 Kai Pastor +# +# This file is part of OpenOrienteering. +# +# OpenOrienteering is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# OpenOrienteering is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with OpenOrienteering. If not, see . + +find_package(GDAL REQUIRED) +find_package(Qt5Core REQUIRED) +find_package(Qt5Gui REQUIRED) +find_package(Qt5Widgets REQUIRED) # TODO: Remove, once Symbol headers don't need it. + +qt_wrap_cpp(mapper-gdal MAPPER_GDAL_MOC + gdal_settings_page.h + ogr_file_format_p.h + ogr_template.h +) + +add_library(mapper-gdal STATIC + ${MAPPER_GDAL_MOC} + gdal_manager.h + gdal_manager.cpp + gdal_settings_page.h + gdal_settings_page.cpp + ogr_file_format.h + ogr_file_format_p.h + ogr_file_format.cpp + ogr_template.h + ogr_template.cpp +) + +target_compile_definitions(mapper-gdal PRIVATE + QT_NO_CAST_FROM_ASCII + QT_NO_CAST_TO_ASCII + QT_USE_QSTRINGBUILDER +) + +target_compile_definitions(mapper-gdal INTERFACE MAPPER_USE_GDAL) + +target_include_directories(mapper-gdal PRIVATE "${GDAL_INCLUDE_DIR}") + +target_link_libraries(mapper-gdal "${GDAL_LIBRARY}" Qt5::Core Qt5::Gui Qt5::Widgets) + +set_target_properties(mapper-gdal PROPERTIES PREFIX "") diff --git a/src/gdal/gdal_manager.cpp b/src/gdal/gdal_manager.cpp new file mode 100644 index 0000000..49f6bd0 --- /dev/null +++ b/src/gdal/gdal_manager.cpp @@ -0,0 +1,267 @@ +/* + * Copyright 2016 Kai Pastor + * + * This file is part of OpenOrienteering. + * + * OpenOrienteering is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenOrienteering is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenOrienteering. If not, see . + */ + +#include "gdal_manager.h" + +#include +#include + +#include +#include + +#include "../mapper_resource.h" + + + +namespace +{ + const QString gdal_manager_group{ QString::fromLatin1("GdalManager") }; + const QString gdal_configuration_group{ QString::fromLatin1("GdalConfiguration") }; + const QString gdal_dxf_key{ QString::fromLatin1("dxf") }; + const QString gdal_gpx_key{ QString::fromLatin1("gpx") }; + const QString gdal_osm_key{ QString::fromLatin1("osm") }; + +} + + + +class GdalManager::GdalManagerPrivate +{ +public: + GdalManagerPrivate() + : dirty{ true } + { + // GDAL 2.0: GDALAllRegister(); + OGRRegisterAll(); + } + + void configure() + { + if (dirty) + update(); + } + + void setFormatEnabled(GdalManager::FileFormat format, bool enabled) + { + QString key; + switch (format) + { + case GdalManager::DXF: + key = gdal_dxf_key; + break; + + case GdalManager::GPX: + key = gdal_gpx_key; + break; + + case GdalManager::OSM: + key = gdal_osm_key; + break; + } + QSettings settings; + settings.beginGroup(gdal_manager_group); + settings.setValue(key, QVariant{ enabled }); + dirty = true; + } + + bool isFormatEnabled(FileFormat format) const + { + QString key; + switch (format) + { + case GdalManager::DXF: + key = gdal_dxf_key; + break; + + case GdalManager::GPX: + key = gdal_gpx_key; + break; + + case GdalManager::OSM: + key = gdal_osm_key; + break; + } + QSettings settings; + settings.beginGroup(gdal_manager_group); + return settings.value(key).toBool(); + } + + const std::vector& supportedRasterExtensions() const + { + /// \todo + static std::vector ret; + return ret; + } + + const std::vector& supportedVectorExtensions() const + { + if (dirty) + update(); + return enabled_vector_extensions; + } + + QStringList parameterKeys() const + { + if (dirty) + update(); + return applied_parameters; + } + + QString parameterValue(const QString& key) const + { + if (dirty) + update(); + QSettings settings; + settings.beginGroup(gdal_configuration_group); + return settings.value(key).toString(); + } + + void setParameterValue(const QString& key, const QString& value) + { + QSettings settings; + settings.beginGroup(gdal_configuration_group); + settings.setValue(key, QVariant{ value }); + dirty = true; + } + + void unsetParameter(const QString& key) + { + QSettings settings; + settings.beginGroup(gdal_configuration_group); + settings.remove(key); + dirty = true; + } + +private: + void update() const + { + QSettings settings; + + /// \todo Build from driver list in GDAL/OGR >= 2.0 + static const std::vector default_extensions = { "shp", "shx" }; + enabled_vector_extensions.reserve(default_extensions.size() + 3); + enabled_vector_extensions = default_extensions; + + settings.beginGroup(gdal_manager_group); + if (settings.value(gdal_dxf_key).toBool()) + enabled_vector_extensions.push_back("dxf"); + if (settings.value(gdal_gpx_key).toBool()) + enabled_vector_extensions.push_back("gpx"); + if (settings.value(gdal_osm_key).toBool()) + enabled_vector_extensions.push_back("osm"); + settings.endGroup(); + + auto gdal_data = MapperResource::locate(MapperResource::GDAL_DATA); + if (!gdal_data.isEmpty()) + { + // The user may overwrite this default in the settings. + CPLSetConfigOption("GDAL_DATA", gdal_data.toLatin1().constData()); + } + + settings.beginGroup(gdal_configuration_group); + QStringList new_parameters = settings.childKeys(); + if (new_parameters.isEmpty()) + { + // Default options for debugging and for some drivers + settings.setValue(QString::fromLatin1("CPL_DEBUG"), QVariant{QLatin1String("OFF")}); + settings.setValue(QString::fromLatin1("USE_PROJ_480_FEATURES"), QVariant{QLatin1String("YES")}); + settings.setValue(QString::fromLatin1("OSM_USE_CUSTOM_INDEXING"), QVariant{QLatin1String("NO")}); + new_parameters = settings.childKeys(); + } + + new_parameters.sort(); + for (auto parameter : new_parameters) + { + CPLSetConfigOption(parameter.toLatin1().constData(), settings.value(parameter).toByteArray().constData()); + } + for (auto parameter : static_cast(applied_parameters)) + { + if (!new_parameters.contains(parameter) + && parameter != QLatin1String{ "GDAL_DATA" }) + { + CPLSetConfigOption(parameter.toLatin1().constData(), nullptr); + } + } + applied_parameters.swap(new_parameters); + + dirty = false; + } + + mutable bool dirty; + + mutable std::vector enabled_vector_extensions; + + mutable QStringList applied_parameters; + +}; + + + +// ### GdalManager ### + +GdalManager::GdalManager() +{ + static GdalManagerPrivate manager; + p = &manager; +} + +void GdalManager::configure() +{ + p->configure(); +} + +void GdalManager::setFormatEnabled(GdalManager::FileFormat format, bool enabled) +{ + p->setFormatEnabled(format, enabled); +} + +bool GdalManager::isFormatEnabled(GdalManager::FileFormat format) const +{ + return p->isFormatEnabled(format); +} + +const std::vector&GdalManager::supportedRasterExtensions() const +{ + return p->supportedRasterExtensions(); +} + +const std::vector& GdalManager::supportedVectorExtensions() const +{ + return p->supportedVectorExtensions(); +} + +QStringList GdalManager::parameterKeys() const +{ + return p->parameterKeys(); +} + +QString GdalManager::parameterValue(const QString& key) const +{ + return p->parameterValue(key); +} + +void GdalManager::setParameterValue(const QString& key, const QString& value) +{ + p->setParameterValue(key, value); +} + +void GdalManager::unsetParameter(const QString& key) +{ + p->unsetParameter(key); +} diff --git a/src/gdal/gdal_manager.h b/src/gdal/gdal_manager.h new file mode 100644 index 0000000..f18f559 --- /dev/null +++ b/src/gdal/gdal_manager.h @@ -0,0 +1,109 @@ +/* + * Copyright 2016 Kai Pastor + * + * This file is part of OpenOrienteering. + * + * OpenOrienteering is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenOrienteering is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenOrienteering. If not, see . + */ + +#ifndef OPENORIENTEERING_GDAL_MANAGER_H +#define OPENORIENTEERING_GDAL_MANAGER_H + + +#include + +class QByteArray; +class QString; +class QStringList; + + +/** + * A utility class which takes care of GDAL settings and options. + * + * This class provides lists of extensions supported via GDAL in Mapper. + * It sets and updates GDAL configuration parameters from Mapper's settings. + * + * There is no need to keep objects of this class for an extended life time: + * instantiation is cheap; the actual state is shared and retained. + */ +class GdalManager +{ +private: + class GdalManagerPrivate; + + GdalManagerPrivate* p; + +public: + enum FileFormat + { + DXF, + GPX, + OSM + }; + + /** + * Constructs a new manager object. + */ + GdalManager(); + + /** + * Sets the GDAL configuration from Mapper's defaults and settings. + */ + void configure(); + + + /** + * Enables or disables handling of a particular file format by GDAL/OGR. + */ + void setFormatEnabled(FileFormat format, bool enabled); + + /** + * Returns if GDAL/OGR will handle a particular file format. + */ + bool isFormatEnabled(FileFormat format) const; + + + /** + * Returns the file name extensions for supported raster formats. + */ + const std::vector& supportedRasterExtensions() const; + + /** + * Returns the file name extensions for supported vector formats. + */ + const std::vector& supportedVectorExtensions() const; + + + /** + * Returns the list of GDAL configuration parameters. + */ + QStringList parameterKeys() const; + + /** + * Returns a GDAL configuration parameter value. + */ + QString parameterValue(const QString& key) const; + + /** + * Sets a GDAL configuration parameter value. + */ + void setParameterValue(const QString& key, const QString& value); + + /** + * Unsets a GDAL configuration parameter value. + */ + void unsetParameter(const QString& key); +}; + +#endif // OPENORIENTEERING_GDAL_MANAGER_H diff --git a/src/gdal/gdal_settings_page.cpp b/src/gdal/gdal_settings_page.cpp new file mode 100644 index 0000000..34093c8 --- /dev/null +++ b/src/gdal/gdal_settings_page.cpp @@ -0,0 +1,221 @@ +/* + * Copyright 2016 Kai Pastor + * + * This file is part of OpenOrienteering. + * + * OpenOrienteering is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenOrienteering is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenOrienteering. If not, see . + */ + + +#include "gdal_settings_page.h" + +#include +#include +#include +#include +#include + +#include "gdal_manager.h" +#include "ogr_file_format.h" +#include "../util_gui.h" +#include "../file_format_registry.h" +#include "../util/scoped_signals_blocker.h" + + +GdalSettingsPage::GdalSettingsPage(QWidget* parent) +: SettingsPage(parent) +{ + auto form_layout = new QFormLayout(); + + form_layout->addRow(Util::Headline::create(tr("Import with GDAL/OGR:"))); + + import_dxf = new QCheckBox(tr("DXF")); + form_layout->addRow(import_dxf); + + import_gpx = new QCheckBox(tr("GPX")); + form_layout->addRow(import_gpx); + + import_osm = new QCheckBox(tr("OSM")); + form_layout->addRow(import_osm); + + form_layout->addItem(Util::SpacerItem::create(this)); + form_layout->addRow(Util::Headline::create(tr("Configuration"))); + + auto layout = new QVBoxLayout(this); + + layout->addLayout(form_layout); + + parameters = new QTableWidget(1, 2); + parameters->verticalHeader()->hide(); + parameters->setHorizontalHeaderLabels({ tr("Parameter"), tr("Value") }); + auto header_view = parameters->horizontalHeader(); + header_view->setSectionResizeMode(0, QHeaderView::Stretch); + header_view->setSectionResizeMode(1, QHeaderView::Stretch); + header_view->setSectionsClickable(false); + layout->addWidget(parameters, 1); + + updateWidgets(); + + connect(parameters, &QTableWidget::cellChanged, this, &GdalSettingsPage::cellChange); +} + +GdalSettingsPage::~GdalSettingsPage() +{ + // nothing, not inlined +} + +QString GdalSettingsPage::title() const +{ + return tr("GDAL/OGR"); +} + +void GdalSettingsPage::apply() +{ + GdalManager manager; + manager.setFormatEnabled(GdalManager::DXF, import_dxf->isChecked()); + manager.setFormatEnabled(GdalManager::GPX, import_gpx->isChecked()); + manager.setFormatEnabled(GdalManager::OSM, import_osm->isChecked()); + + // The file format constructor establishes the extensions. + auto format = new OgrFileFormat(); + FileFormats.unregisterFormat(FileFormats.findFormat(format->id())); + FileFormats.registerFormat(format); + + const auto old_parameters = manager.parameterKeys(); + + QStringList new_parameters; + new_parameters.reserve(parameters->rowCount()); + for (int row = 0, end = parameters->rowCount(); row < end; ++row) + { + auto key = parameters->item(row, 0)->text().trimmed(); + if (!key.isEmpty()) + { + new_parameters.append(key); + auto value = parameters->item(row, 1)->text(); + manager.setParameterValue(key, value.trimmed()); + } + } + for (const auto key : old_parameters) + { + if (!new_parameters.contains(key)) + { + manager.unsetParameter(key); + } + } +} + +void GdalSettingsPage::reset() +{ + updateWidgets(); +} + +void GdalSettingsPage::updateWidgets() +{ + GdalManager manager; + import_dxf->setChecked(manager.isFormatEnabled(GdalManager::DXF)); + import_gpx->setChecked(manager.isFormatEnabled(GdalManager::GPX)); + import_osm->setChecked(manager.isFormatEnabled(GdalManager::OSM)); + + auto options = manager.parameterKeys(); + options.sort(); + parameters->setRowCount(options.size() + 1); + auto row = 0; + for (auto item : static_cast(options)) + { + auto key_item = new QTableWidgetItem(item); + parameters->setItem(row, 0, key_item); + auto value_item = new QTableWidgetItem(manager.parameterValue(item)); + parameters->setItem(row, 1, value_item); + ++row; + } + parameters->setRowCount(row+1); + parameters->setItem(row, 0, new QTableWidgetItem()); + parameters->setItem(row, 1, new QTableWidgetItem()); +} + +void GdalSettingsPage::cellChange(int row, int column) +{ + const QString key = parameters->item(row, 0)->text().trimmed(); + const QString value = parameters->item(row, 1)->text(); + + if (column == 1 && key.isEmpty()) + { + // Shall not happen + qWarning("Empty key for modified tag value!"); + } + else if (column == 0) + { + QSignalBlocker block(parameters); + parameters->item(row, 0)->setText(key); // trimmed + + auto last_row = parameters->rowCount() - 1; + int duplicate = findDuplicateKey(key, row); + if (key.isEmpty()) + { + if (row == last_row) + { + parameters->item(row, 1)->setText({ }); + } + else + { + parameters->model()->removeRow(row); + parameters->setCurrentCell(row, 0); + parameters->setFocus(); + } + } + else if (duplicate != row) + { + if (row == last_row) + { + parameters->item(row, 0)->setText({ }); + parameters->item(row, 0)->setText({ }); + } + else + { + parameters->model()->removeRow(row); + } + parameters->setCurrentCell(duplicate, 0); + parameters->setFocus(); + } + else + { + if (row == last_row) + { + parameters->setRowCount(last_row + 2); + parameters->setItem(last_row + 1, 0, new QTableWidgetItem()); + parameters->setItem(last_row + 1, 1, new QTableWidgetItem()); + } + + if (value.isEmpty()) + { + GdalManager manager; + parameters->item(row, 1)->setText(manager.parameterValue(key)); + } + } + } +} + +int GdalSettingsPage::findDuplicateKey(const QString& key, int row) const +{ + for (int i = 0, end = parameters->rowCount(); i < end; ++i) + { + if (i != row + && parameters->item(i, 0)->text() == key) + { + row = i; + break; + } + } + return row; +} diff --git a/src/gdal/gdal_settings_page.h b/src/gdal/gdal_settings_page.h new file mode 100644 index 0000000..3f1637d --- /dev/null +++ b/src/gdal/gdal_settings_page.h @@ -0,0 +1,58 @@ +/* + * Copyright 2016 Kai Pastor + * + * This file is part of OpenOrienteering. + * + * OpenOrienteering is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenOrienteering is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenOrienteering. If not, see . + */ + +#ifndef OPENORIENTEERING_GDAL_SETTINGS_PAGE_H +#define OPENORIENTEERING_GDAL_SETTINGS_PAGE_H + +#include "../gui/widgets/settings_page.h" + +class QCheckBox; +class QTableWidget; + + +class GdalSettingsPage : public SettingsPage +{ +Q_OBJECT +public: + explicit GdalSettingsPage(QWidget* parent = nullptr); + + ~GdalSettingsPage() override; + + QString title() const override; + + void apply() override; + + void reset() override; + +protected: + void updateWidgets(); + + void cellChange(int row, int column); + + int findDuplicateKey(const QString& key, int row) const; + +private: + QCheckBox* import_dxf; + QCheckBox* import_gpx; + QCheckBox* import_osm; + QTableWidget* parameters; +}; + + +#endif diff --git a/src/gdal/ogr_file_format.cpp b/src/gdal/ogr_file_format.cpp new file mode 100644 index 0000000..117a389 --- /dev/null +++ b/src/gdal/ogr_file_format.cpp @@ -0,0 +1,1070 @@ +/* + * Copyright 2016 Kai Pastor + * + * This file is part of OpenOrienteering. + * + * OpenOrienteering is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenOrienteering is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenOrienteering. If not, see . + */ + +#include "ogr_file_format.h" +#include "ogr_file_format_p.h" + +#include + +#include +#include +#include + +#include +#include +#include +#include + +#include "gdal_manager.h" +#include "../core/georeferencing.h" +#include "../map.h" +#include "../object_text.h" +#include "../symbol_area.h" +#include "../symbol_line.h" +#include "../symbol_point.h" +#include "../symbol_text.h" + + +namespace ogr +{ + class OGRDataSourceHDeleter + { + public: + void operator()(OGRDataSourceH data_source) const + { + OGRReleaseDataSource(data_source); + } + }; + + /** A convenience class for OGR C API datasource handles, similar to std::unique_ptr. */ + using unique_datasource = std::unique_ptr::type, OGRDataSourceHDeleter>; + + + class OGRFeatureHDeleter + { + public: + void operator()(OGRFeatureH feature) const + { + OGR_F_Destroy(feature); + } + }; + + /** A convenience class for OGR C API feature handles, similar to std::unique_ptr. */ + using unique_feature = std::unique_ptr::type, OGRFeatureHDeleter>; + + + class OGRGeometryHDeleter + { + public: + void operator()(OGRGeometryH geometry) const + { + OGR_G_DestroyGeometry(geometry); + } + }; + + /** A convenience class for OGR C API geometry handles, similar to std::unique_ptr. */ + using unique_geometry = std::unique_ptr::type, OGRGeometryHDeleter>; + +} + +namespace +{ + void applyPenWidth(OGRStyleToolH tool, LineSymbol* line_symbol) + { + int is_null; + auto pen_width = OGR_ST_GetParamDbl(tool, OGRSTPenWidth, &is_null); + if (!is_null) + { + Q_ASSERT(OGR_ST_GetUnit(tool) == OGRSTUMM); + + if (pen_width <= 0.01) + pen_width = 0.1; + + line_symbol->setLineWidth(pen_width); + } + } + + void applyPenCap(OGRStyleToolH tool, LineSymbol* line_symbol) + { + int is_null; + auto pen_cap = OGR_ST_GetParamStr(tool, OGRSTPenCap, &is_null); + if (!is_null) + { + switch (pen_cap[0]) + { + case 'p': + line_symbol->setCapStyle(LineSymbol::SquareCap); + break; + case 'r': + line_symbol->setCapStyle(LineSymbol::RoundCap); + break; + default: + ; + } + } + } + + void applyPenJoin(OGRStyleToolH tool, LineSymbol* line_symbol) + { + int is_null; + auto pen_join = OGR_ST_GetParamStr(tool, OGRSTPenJoin, &is_null); + if (!is_null) + { + switch (pen_join[0]) + { + case 'b': + line_symbol->setJoinStyle(LineSymbol::BevelJoin); + break; + case 'r': + line_symbol->setJoinStyle(LineSymbol::RoundJoin); + break; + default: + ; + } + } + } + + void applyPenPattern(OGRStyleToolH tool, LineSymbol* line_symbol) + { + int is_null; + auto raw_pattern = OGR_ST_GetParamStr(tool, OGRSTPenPattern, &is_null); + if (!is_null) + { + auto pattern = QString::fromLatin1(raw_pattern); + auto sub_pattern_re = QRegularExpression(QString::fromLatin1("([0-9.]+)([a-z]*) *([0-9.]+)([a-z]*)")); + auto match = sub_pattern_re.match(pattern); + double length_0, length_1; + bool ok = match.hasMatch(); + if (ok) + length_0 = match.capturedRef(1).toDouble(&ok); + if (ok) + length_1 = match.capturedRef(3).toDouble(&ok); + if (ok) + { + /// \todo Apply units from capture 2 and 4 + line_symbol->setDashed(true); + line_symbol->setDashLength(qMax(100, qRound(length_0 * 1000))); + line_symbol->setBreakLength(qMax(100, qRound(length_1 * 1000))); + } + else + { + qDebug("OgrFileFormat: Failed to parse dash pattern '%s'", raw_pattern); + } + } + } + + int getFontSize(const char* font_size_string) + { + auto pattern = QString::fromLatin1(font_size_string); + auto sub_pattern_re = QRegularExpression(QString::fromLatin1("([0-9.]+)([a-z]*)")); + auto match = sub_pattern_re.match(pattern); + double font_size; + bool ok = match.hasMatch(); + if (ok) + font_size = match.capturedRef(1).toDouble(&ok); + if (ok) + { + auto unit = match.capturedRef(2).toUtf8(); + if (!unit.isEmpty()) + { + if (unit == "pt") + { + + } + else if (unit == "px") + { + + } + else + { + qDebug("OgrFileFormat: Unsupported font size unit '%s'", unit.constData()); + } + } + } + else + { + qDebug("OgrFileFormat: Failed to parse font size '%s'", font_size_string); + font_size = 0; + } + return font_size; + } + + void applyLabelAnchor(int anchor, TextObject* text_object) + { + auto v_align = (anchor - 1) / 3; + switch (v_align) + { + case 0: + text_object->setVerticalAlignment(TextObject::AlignBaseline); + break; + case 1: + text_object->setVerticalAlignment(TextObject::AlignVCenter); + break; + case 2: + text_object->setVerticalAlignment(TextObject::AlignTop); + break; + case 3: + text_object->setVerticalAlignment(TextObject::AlignBottom); + break; + default: + Q_UNREACHABLE(); + } + auto h_align = (anchor - 1) % 3; + switch (h_align) + { + case 0: + text_object->setHorizontalAlignment(TextObject::AlignLeft); + break; + case 1: + text_object->setHorizontalAlignment(TextObject::AlignHCenter); + break; + case 2: + text_object->setHorizontalAlignment(TextObject::AlignRight); + break; + default: + Q_UNREACHABLE(); + } + } +} + + + +// ### OgrFileFormat ### + +OgrFileFormat::OgrFileFormat() + : FileFormat(OgrFile, "OGR", ImportExport::tr("Geospatial vector data"), QString{}, ImportSupported) +{ + for (const auto extension : GdalManager().supportedVectorExtensions()) + addExtension(QString::fromLatin1(extension)); +} + +bool OgrFileFormat::understands(const unsigned char*, size_t) const +{ + return true; +} + +Importer* OgrFileFormat::createImporter(QIODevice* stream, Map *map, MapView *view) const +{ + return new OgrFileImport(stream, map, view); +} + + + +// ### OgrFileImport ### + +OgrFileImport::OgrFileImport(QIODevice* stream, Map* map, MapView* view, bool drawing_from_projected) + : Importer(stream, map, view) + , map_srs{ OSRNewSpatialReference(nullptr) } + , manager{ OGR_SM_Create(nullptr) } + , drawing_from_projected{ drawing_from_projected } +{ + GdalManager().configure(); + + setOption(QLatin1String{ "Separate layers" }, QVariant{ false }); + + auto spec = QByteArray::fromRawData("WGS84", 6); + auto error = OSRSetWellKnownGeogCS(map_srs.get(), spec); + if (!map->getGeoreferencing().isLocal() && !error) + { + spec = map->getGeoreferencing().getProjectedCRSSpec().toLatin1(); + error = OSRImportFromProj4(map_srs.get(), spec.constData()); + } + + if (error) + { + addWarning(tr("Unable to setup \"%1\" SRS for GDAL: %2") + .arg(QString::fromLatin1(spec), QString::number(error))); + } + + // Reasonable default? + + // OGR feature style defaults + default_pen_color = new MapColor(tr("Black"), 0); + default_pen_color->setRgb({0.0, 0.0, 0.0}); + default_pen_color->setCmykFromRgb(); + map->addColor(default_pen_color, 0); + + auto default_brush_color = new MapColor(tr("Black") + QLatin1String(" 50%"), 0); + default_brush_color->setRgb({0.5, 0.5, 0.5}); + default_brush_color->setCmykFromRgb(); + map->addColor(default_brush_color, 1); + + default_point_symbol = new PointSymbol(); + default_point_symbol->setName(tr("Point")); + default_point_symbol->setNumberComponent(0, 1); + default_point_symbol->setInnerColor(default_pen_color); + map->addSymbol(default_point_symbol, 0); + + default_line_symbol = new LineSymbol(); + default_line_symbol->setName(tr("Line")); + default_line_symbol->setNumberComponent(0, 2); + default_line_symbol->setColor(default_pen_color); + default_line_symbol->setLineWidth(0.1); // (0.1 mm, nearly cosmetic) + default_line_symbol->setCapStyle(LineSymbol::FlatCap); + default_line_symbol->setJoinStyle(LineSymbol::MiterJoin); + map->addSymbol(default_line_symbol, 1); + + default_area_symbol = new AreaSymbol(); + default_area_symbol->setName(tr("Area")); + default_area_symbol->setNumberComponent(0, 3); + default_area_symbol->setColor(default_brush_color); + map->addSymbol(default_area_symbol, 2); + + default_text_symbol = new TextSymbol(); + default_text_symbol->setName(tr("Text")); + default_text_symbol->setNumberComponent(0, 4); + default_text_symbol->setColor(default_pen_color); + map->addSymbol(default_text_symbol, 3); +} + +OgrFileImport::~OgrFileImport() +{ + // nothing +} + +void OgrFileImport::import(bool load_symbols_only) +{ + auto file = qobject_cast(stream); + if (!file) + { + throw FileFormatException("Internal error"); /// \todo Review design and/or message + } + + auto filename = file->fileName(); + // GDAL 2.0: ... = GDALOpenEx(template_path.toLatin1(), GDAL_OF_VECTOR, nullptr, nullptr, nullptr); + auto data_source = ogr::unique_datasource(OGROpen(filename.toUtf8().constData(), 0, nullptr)); + if (data_source == nullptr) + { + throw FileFormatException(Importer::tr("Could not read '%1': %2") + .arg(filename, QString::fromLatin1(CPLGetLastErrorMsg()))); + } + + empty_geometries = 0; + no_transformation = 0; + failed_transformation = 0; + unsupported_geometry_type = 0; + too_few_coordinates = 0; + + importStyles(data_source.get()); + + if (!load_symbols_only) + { + if (!drawing_from_projected) + { + Q_ASSERT(MapCoord::boundsOffset().isZero()); + MapCoord::boundsOffset().reset(true); + } + + auto num_layers = OGR_DS_GetLayerCount(data_source.get()); + for (int i = 0; i < num_layers; ++i) + { + auto layer = OGR_DS_GetLayer(data_source.get(), i); + if (!layer) + { + addWarning(tr("Unable to load layer %1.").arg(i)); + continue; + } + + auto part = map->getCurrentPart(); + if (option(QLatin1String("Separate layers")).toBool()) + { + if (num_layers > 0) + { + if (part->getNumObjects() == 0) + { + part->setName(QString::fromUtf8(OGR_L_GetName(layer))); + } + else + { + part = new MapPart(QString::fromUtf8(OGR_L_GetName(layer)), map); + auto index = map->getNumParts(); + map->addPart(part, index); + map->setCurrentPartIndex(index); + } + } + } + + importLayer(part, layer); + } + + if (!drawing_from_projected) + { + MapCoord::boundsOffset().reset(false); + } + } + + if (empty_geometries) + { + addWarning(tr("Unable to load %n objects, reason: %1", nullptr, empty_geometries) + .arg(tr("Empty geometry."))); + } + if (no_transformation) + { + addWarning(tr("Unable to load %n objects, reason: %1", nullptr, no_transformation) + .arg(tr("Can't determine the coordinate transformation: %1").arg(QString::fromUtf8(CPLGetLastErrorMsg())))); + } + if (failed_transformation) + { + addWarning(tr("Unable to load %n objects, reason: %1", nullptr, failed_transformation) + .arg(tr("Failed to transform the coordinates."))); + } + if (unsupported_geometry_type) + { + addWarning(tr("Unable to load %n objects, reason: %1", nullptr, unsupported_geometry_type) + .arg(tr("Unknown or unsupported geometry type."))); + } + if (too_few_coordinates) + { + addWarning(tr("Unable to load %n objects, reason: %1", nullptr, too_few_coordinates) + .arg(tr("Not enough coordinates."))); + } +} + +void OgrFileImport::importStyles(OGRDataSourceH data_source) +{ + //auto style_table = OGR_DS_GetStyleTable(data_source); + Q_UNUSED(data_source) +} + +void OgrFileImport::importLayer(MapPart* map_part, OGRLayerH layer) +{ + Q_ASSERT(map_part); + + auto feature_definition = OGR_L_GetLayerDefn(layer); + + OGR_L_ResetReading(layer); + while (auto feature = ogr::unique_feature(OGR_L_GetNextFeature(layer))) + { + auto geometry = OGR_F_GetGeometryRef(feature.get()); + if (!geometry || OGR_G_IsEmpty(geometry)) + { + ++empty_geometries; + continue; + } + + importFeature(map_part, feature_definition, feature.get(), geometry); + } +} + +void OgrFileImport::importFeature(MapPart* map_part, OGRFeatureDefnH feature_definition, OGRFeatureH feature, OGRGeometryH geometry) +{ + to_map_coord = &OgrFileImport::fromProjected; + auto new_srs = OGR_G_GetSpatialReference(geometry); + if (new_srs && data_srs != new_srs) + { + // New SRS, indeed. + + auto transformation = ogr::unique_transformation{ OCTNewCoordinateTransformation(new_srs, map_srs.get()) }; + if (!transformation) + { + ++no_transformation; + return; + } + + // Commit change to data srs and coordinate transformation + data_srs = new_srs; + data_transform = std::move(transformation); + } + + if (new_srs) + { + auto error = OGR_G_Transform(geometry, data_transform.get()); + if (error) + { + ++failed_transformation; + return; + } + } + else if (!drawing_from_projected) + { + to_map_coord = &OgrFileImport::fromDrawing; + } + + auto object = importGeometry(map_part, feature, geometry); + + if (object && feature_definition) + { + auto num_fields = OGR_FD_GetFieldCount(feature_definition); + for (int i = 0; i < num_fields; ++i) + { + auto value = OGR_F_GetFieldAsString(feature, i); + if (value && qstrlen(value) > 0) + { + auto field_definition = OGR_FD_GetFieldDefn(feature_definition, i); + object->setTag(QString::fromUtf8(OGR_Fld_GetNameRef(field_definition)), QString::fromUtf8(value)); + } + } + } +} + +Object* OgrFileImport::importGeometry(MapPart* map_part, OGRFeatureH feature, OGRGeometryH geometry) +{ + auto geometry_type = wkbFlatten(OGR_G_GetGeometryType(geometry)); + switch (geometry_type) + { + case OGRwkbGeometryType::wkbPoint: + return importPointGeometry(map_part, feature, geometry); + + case OGRwkbGeometryType::wkbLineString: + return importLineStringGeometry(map_part, feature, geometry); + + case OGRwkbGeometryType::wkbPolygon: + return importPolygonGeometry(map_part, feature, geometry); + + case OGRwkbGeometryType::wkbGeometryCollection: + case OGRwkbGeometryType::wkbMultiLineString: + case OGRwkbGeometryType::wkbMultiPoint: + case OGRwkbGeometryType::wkbMultiPolygon: + return importGeometryCollection(map_part, feature, geometry); + + default: + qDebug("OgrFileImport: Unknown or unsupported geometry type: %d", geometry_type); + ++unsupported_geometry_type; + return nullptr; + } +} + +Object* OgrFileImport::importGeometryCollection(MapPart* map_part, OGRFeatureH feature, OGRGeometryH geometry) +{ + auto num_geometries = OGR_G_GetGeometryCount(geometry); + for (int i = 0; i < num_geometries; ++i) + { + importGeometry(map_part, feature, OGR_G_GetGeometryRef(geometry, i)); + } + return nullptr; +} + +Object* OgrFileImport::importPointGeometry(MapPart* map_part, OGRFeatureH feature, OGRGeometryH geometry) +{ + auto style = OGR_F_GetStyleString(feature); + auto symbol = getSymbol(Symbol::Point, style); + if (symbol->getType() == Symbol::Point) + { + auto object = new PointObject(symbol); + object->setPosition(toMapCoord(OGR_G_GetX(geometry, 0), OGR_G_GetY(geometry, 0))); + map_part->addObject(object); + return object; + } + else if (symbol->getType() == Symbol::Text) + { + const auto& description = symbol->getDescription(); + auto length = description.length(); + auto split = description.indexOf(QLatin1Char(' ')); + Q_ASSERT(split > 0); + Q_ASSERT(split < length); + + auto label = description.right(length - split - 1); + if (label.startsWith(QLatin1Char{'{'}) && label.endsWith(QLatin1Char{'}'})) + { + label.remove(0, 1); + label.chop(1); + int index = OGR_F_GetFieldIndex(feature, label.toLatin1().constData()); + if (index >= 0) + { + label = QString::fromUtf8(OGR_F_GetFieldAsString(feature, index)); + } + } + if (!label.isEmpty()) + { + auto object = new TextObject(symbol); + object->setAnchorPosition(toMapCoord(OGR_G_GetX(geometry, 0), OGR_G_GetY(geometry, 0))); + // DXF observation + label.replace(QRegularExpression(QString::fromLatin1("(\\\\[^;]*;)*"), QRegularExpression::MultilineOption), QString{}); + label.replace(QLatin1String("^I"), QLatin1String("\t")); + object->setText(label); + + bool ok; + auto anchor = QStringRef(&description, 1, 2).toInt(&ok); + if (ok) + { + applyLabelAnchor(anchor, object); + } + + auto angle = QStringRef(&description, 3, split-3).toFloat(&ok); + if (ok) + { + object->setRotation(qDegreesToRadians(angle)); + } + + map_part->addObject(object); + return object; + } + } + + return nullptr; +} + +PathObject* OgrFileImport::importLineStringGeometry(MapPart* map_part, OGRFeatureH feature, OGRGeometryH geometry) +{ + auto managed_geometry = ogr::unique_geometry(nullptr); + if (OGR_G_GetGeometryType(geometry) != wkbLineString) + { + geometry = OGR_G_ForceToLineString(OGR_G_Clone(geometry)); + managed_geometry.reset(geometry); + } + + auto num_points = OGR_G_GetPointCount(geometry); + if (num_points < 2) + { + ++too_few_coordinates; + return nullptr; + } + + auto style = OGR_F_GetStyleString(feature); + auto object = new PathObject(getSymbol(Symbol::Line, style)); + for (int i = 0; i < num_points; ++i) + { + object->addCoordinate(toMapCoord(OGR_G_GetX(geometry, i), OGR_G_GetY(geometry, i))); + } + map_part->addObject(object); + return object; +} + +PathObject* OgrFileImport::importPolygonGeometry(MapPart* map_part, OGRFeatureH feature, OGRGeometryH geometry) +{ + auto num_geometries = OGR_G_GetGeometryCount(geometry); + if (num_geometries < 1) + { + ++too_few_coordinates; + return nullptr; + } + + auto outline = OGR_G_GetGeometryRef(geometry, 0); + auto managed_outline = ogr::unique_geometry(nullptr); + if (OGR_G_GetGeometryType(outline) != wkbLineString) + { + outline = OGR_G_ForceToLineString(OGR_G_Clone(outline)); + managed_outline.reset(outline); + } + auto num_points = OGR_G_GetPointCount(outline); + if (num_points < 3) + { + ++too_few_coordinates; + return nullptr; + } + + auto style = OGR_F_GetStyleString(feature); + auto object = new PathObject(getSymbol(Symbol::Area, style)); + for (int i = 0; i < num_points; ++i) + { + object->addCoordinate(toMapCoord(OGR_G_GetX(outline, i), OGR_G_GetY(outline, i))); + } + + for (int g = 1; g < num_geometries; ++g) + { + bool start_new_part = true; + auto hole = /*OGR_G_ForceToLineString*/(OGR_G_GetGeometryRef(geometry, g)); + auto num_points = OGR_G_GetPointCount(hole); + for (int i = 0; i < num_points; ++i) + { + object->addCoordinate(toMapCoord(OGR_G_GetX(hole, i), OGR_G_GetY(hole, i)), start_new_part); + start_new_part = false; + } + } + + object->closeAllParts(); + map_part->addObject(object); + return object; +} + +Symbol* OgrFileImport::getSymbol(Symbol::Type type, const char* raw_style_string) +{ + auto style_string = QByteArray::fromRawData(raw_style_string, qstrlen(raw_style_string)); + Symbol* symbol = nullptr; + switch (type) + { + case Symbol::Point: + case Symbol::Text: + symbol = point_symbols.value(style_string); + if (!symbol) + symbol = getSymbolForPointGeometry(style_string); + break; + + case Symbol::Combined: + /// \todo + // fall through + case Symbol::Line: + symbol = line_symbols.value(style_string); + if (!symbol) + symbol = getLineSymbol(style_string); + if (!symbol) + symbol = default_line_symbol; + break; + + case Symbol::Area: + symbol = area_symbols.value(style_string); + if (!symbol) + symbol = getAreaSymbol(style_string); + if (!symbol) + symbol = default_area_symbol; + break; + + case Symbol::NoSymbol: + case Symbol::AllSymbols: + Q_UNREACHABLE(); + } + + Q_ASSERT(symbol); + return symbol; +} + +MapColor* OgrFileImport::makeColor(OGRStyleToolH tool, const char* color_string) +{ + auto key = QByteArray::fromRawData(color_string, qstrlen(color_string)); + auto color = colors.value(key); + if (!color) + { + int r, g, b, a; + auto success = OGR_ST_GetRGBFromString(tool, color_string, &r, &g, &b, &a); + if (!success) + { + color = default_pen_color; + } + else if (a > 0) + { + color = new MapColor(QString::fromUtf8(color_string), map->getNumColors()); + color->setRgb(QColor{ r, g, b }); + color->setCmykFromRgb(); + map->addColor(color, map->getNumColors()); + } + + key.detach(); + colors.insert(key, color); + } + + return color; +} + +void OgrFileImport::applyPenColor(OGRStyleToolH tool, LineSymbol* line_symbol) +{ + int is_null; + auto color_string = OGR_ST_GetParamStr(tool, OGRSTPenColor, &is_null); + if (!is_null) + { + auto color = makeColor(tool, color_string); + if (color) + line_symbol->setColor(color); + else + line_symbol->setHidden(true); + } +} + +void OgrFileImport::applyBrushColor(OGRStyleToolH tool, AreaSymbol* area_symbol) +{ + int is_null; + auto color_string = OGR_ST_GetParamStr(tool, OGRSTBrushFColor, &is_null); + if (!is_null) + { + auto color = makeColor(tool, color_string); + if (color) + area_symbol->setColor(color); + else + area_symbol->setHidden(true); + } +} + + +Symbol* OgrFileImport::getSymbolForPointGeometry(const QByteArray& style_string) +{ + if (style_string.isEmpty()) + return default_point_symbol; + + auto manager = this->manager.get(); + + auto data = style_string.constData(); + if (!OGR_SM_InitStyleString(manager, data)) + return default_point_symbol; + + auto num_parts = OGR_SM_GetPartCount(manager, data); + if (!num_parts) + return default_point_symbol; + + Symbol* symbol = nullptr; + for (int i = 0; !symbol && i < num_parts; ++i) + { + auto tool = OGR_SM_GetPart(manager, i, nullptr); + if (!tool) + continue; + + OGR_ST_SetUnit(tool, OGRSTUMM, map->getScaleDenominator()); + + auto type = OGR_ST_GetType(tool); + switch (type) + { + case OGRSTCSymbol: + symbol = getSymbolForOgrSymbol(tool, style_string); + break; + + case OGRSTCLabel: + symbol = getSymbolForLabel(tool, style_string); + break; + + default: + ; + } + + OGR_ST_Destroy(tool); + } + + return symbol; +} + +LineSymbol* OgrFileImport::getLineSymbol(const QByteArray& style_string) +{ + if (style_string.isEmpty()) + return nullptr; + + auto manager = this->manager.get(); + + auto data = style_string.constData(); + if (!OGR_SM_InitStyleString(manager, data)) + return nullptr; + + auto num_parts = OGR_SM_GetPartCount(manager, data); + if (!num_parts) + return nullptr; + + LineSymbol* symbol = nullptr; + for (int i = 0; !symbol && i < num_parts; ++i) + { + auto tool = OGR_SM_GetPart(manager, i, nullptr); + if (!tool) + continue; + + OGR_ST_SetUnit(tool, OGRSTUMM, map->getScaleDenominator()); + + auto type = OGR_ST_GetType(tool); + switch (type) + { + case OGRSTCPen: + symbol = getSymbolForPen(tool, style_string); + break; + + default: + ; + } + + OGR_ST_Destroy(tool); + } + + return symbol; +} + +AreaSymbol* OgrFileImport::getAreaSymbol(const QByteArray& style_string) +{ + if (style_string.isEmpty()) + return nullptr; + + auto manager = this->manager.get(); + + auto data = style_string.constData(); + if (!OGR_SM_InitStyleString(manager, data)) + return nullptr; + + auto num_parts = OGR_SM_GetPartCount(manager, data); + if (!num_parts) + return nullptr; + + AreaSymbol* symbol = nullptr; + for (int i = 0; !symbol && i < num_parts; ++i) + { + auto tool = OGR_SM_GetPart(manager, i, nullptr); + if (!tool) + continue; + + OGR_ST_SetUnit(tool, OGRSTUMM, map->getScaleDenominator()); + + auto type = OGR_ST_GetType(tool); + switch (type) + { + case OGRSTCBrush: + symbol = getSymbolForBrush(tool, style_string); + break; + + default: + ; + } + + OGR_ST_Destroy(tool); + } + + return symbol; +} + +PointSymbol* OgrFileImport::getSymbolForOgrSymbol(OGRStyleToolH tool, const QByteArray& style_string) +{ + Q_ASSERT(OGR_ST_GetType(tool) == OGRSTCSymbol); + + auto raw_tool_key = OGR_ST_GetStyleString(tool); + auto tool_key = QByteArray::fromRawData(raw_tool_key, qstrlen(raw_tool_key)); + auto symbol = point_symbols.value(tool_key); + if (symbol && symbol->getType() == Symbol::Point) + return static_cast(symbol); + + int is_null; + auto color_string = OGR_ST_GetParamStr(tool, OGRSTSymbolColor, &is_null); + if (is_null) + return nullptr; + + auto point_symbol = static_cast(default_point_symbol->duplicate()); + auto color = makeColor(tool, color_string); + if (color) + point_symbol->setInnerColor(color); + else + point_symbol->setHidden(true); + + auto key = style_string; + key.detach(); + point_symbols.insert(key, point_symbol); + + if (key != tool_key) + { + tool_key.detach(); + point_symbols.insert(tool_key, point_symbol); + } + + map->addSymbol(point_symbol, map->getNumSymbols()); + return point_symbol; +} + +TextSymbol* OgrFileImport::getSymbolForLabel(OGRStyleToolH tool, const QByteArray&) +{ + Q_ASSERT(OGR_ST_GetType(tool) == OGRSTCLabel); + + int is_null; + auto label_string = OGR_ST_GetParamStr(tool, OGRSTLabelTextString, &is_null); + if (is_null) + return nullptr; + + auto color_string = OGR_ST_GetParamStr(tool, OGRSTLabelFColor, &is_null); + auto font_size_string = OGR_ST_GetParamStr(tool, OGRSTLabelSize, &is_null); + + // Don't use the style string as a key: The style contains the label. + QByteArray key; + key.reserve(qstrlen(color_string) + qstrlen(font_size_string) + 1); + key.append(color_string); + key.append(font_size_string); + auto text_symbol = static_cast(text_symbols.value(key)); + if (!text_symbol) + { + text_symbol = static_cast(default_text_symbol->duplicate()); + + auto color = makeColor(tool, color_string); + if (color) + text_symbol->setColor(color); + else + text_symbol->setHidden(true); + + auto font_size = OGR_ST_GetParamDbl(tool, OGRSTLabelSize, &is_null); + if (!is_null && font_size > 0.0) + text_symbol->scale(font_size / text_symbol->getFontSize()); + + key.detach(); + text_symbols.insert(key, text_symbol); + + map->addSymbol(text_symbol, map->getNumSymbols()); + } + + auto anchor = qBound(1, OGR_ST_GetParamNum(tool, OGRSTLabelAnchor, &is_null), 12); + if (is_null) + anchor = 1; + + auto angle = OGR_ST_GetParamDbl(tool, OGRSTLabelAngle, &is_null); + if (is_null) + angle = 0.0; + + QString description; + description.reserve(qstrlen(label_string) + 100); + description.append(QString::number(100 + anchor)); + description.append(QString::number(angle, 'g', 1)); + description.append(QLatin1Char(' ')); + description.append(QString::fromUtf8(label_string)); + text_symbol->setDescription(description); + + return text_symbol; +} + +LineSymbol* OgrFileImport::getSymbolForPen(OGRStyleToolH tool, const QByteArray& style_string) +{ + Q_ASSERT(OGR_ST_GetType(tool) == OGRSTCPen); + + auto raw_tool_key = OGR_ST_GetStyleString(tool); + auto tool_key = QByteArray::fromRawData(raw_tool_key, qstrlen(raw_tool_key)); + auto symbol = line_symbols.value(tool_key); + if (symbol && symbol->getType() == Symbol::Line) + return static_cast(symbol); + + auto line_symbol = static_cast(default_line_symbol->duplicate()); + applyPenColor(tool, line_symbol); + applyPenWidth(tool, line_symbol); + applyPenCap(tool, line_symbol); + applyPenJoin(tool, line_symbol); + applyPenPattern(tool, line_symbol); + + auto key = style_string; + key.detach(); + line_symbols.insert(key, line_symbol); + + if (key != tool_key) + { + tool_key.detach(); + line_symbols.insert(tool_key, line_symbol); + } + + map->addSymbol(line_symbol, map->getNumSymbols()); + return line_symbol; +} + +AreaSymbol* OgrFileImport::getSymbolForBrush(OGRStyleToolH tool, const QByteArray& style_string) +{ + Q_ASSERT(OGR_ST_GetType(tool) == OGRSTCBrush); + + auto raw_tool_key = OGR_ST_GetStyleString(tool); + auto tool_key = QByteArray::fromRawData(raw_tool_key, qstrlen(raw_tool_key)); + auto symbol = area_symbols.value(tool_key); + if (symbol && symbol->getType() == Symbol::Area) + return static_cast(symbol); + + auto area_symbol = static_cast(default_area_symbol->duplicate()); + applyBrushColor(tool, area_symbol); + + auto key = style_string; + key.detach(); + area_symbols.insert(key, area_symbol); + + if (key != tool_key) + { + tool_key.detach(); + area_symbols.insert(tool_key, area_symbol); + } + + map->addSymbol(area_symbol, map->getNumSymbols()); + return area_symbol; +} + + +MapCoord OgrFileImport::fromDrawing(double x, double y) const +{ + return MapCoord::load(x, y, 0); +} + +MapCoord OgrFileImport::fromProjected(double x, double y) const +{ + return map->getGeoreferencing().toMapCoords(QPointF{ x, y }); +} diff --git a/src/gdal/ogr_file_format.h b/src/gdal/ogr_file_format.h new file mode 100644 index 0000000..64e4184 --- /dev/null +++ b/src/gdal/ogr_file_format.h @@ -0,0 +1,55 @@ +/* + * Copyright 2016 Kai Pastor + * + * This file is part of OpenOrienteering. + * + * OpenOrienteering is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenOrienteering is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenOrienteering. If not, see . + */ + +#ifndef OPENORIENTEERING_OGR_FILE_FORMAT_H +#define OPENORIENTEERING_OGR_FILE_FORMAT_H + +#include "../file_format.h" + +/** + * A FileFormat for geospatial vector data supported by OGR. + * + * Geospatial vector data cannot be loaded as a regular (OpenOrienteering) Map + * because it has no scale. However, it typically has a spatial reference, and + * so it can be imported into an existing map. This is the major reason for + * implementing the OGR support as a FileFormat. + */ +class OgrFileFormat : public FileFormat +{ +public: + /** + * Constructs a new OgrFileFormat. + */ + OgrFileFormat(); + + /** + * Always returns true. + * + * There is no cheap way to determine the answer via OGR. + */ + bool understands(const unsigned char *, size_t) const override; + + /** + * Creates an importer object and configures it for the given input stream + * and output map and view. + */ + Importer* createImporter(QIODevice* stream, Map *map, MapView *view) const override; +}; + +#endif // OPENORIENTEERING_OGR_FILE_FORMAT_H diff --git a/src/gdal/ogr_file_format_p.h b/src/gdal/ogr_file_format_p.h new file mode 100644 index 0000000..a9ab640 --- /dev/null +++ b/src/gdal/ogr_file_format_p.h @@ -0,0 +1,214 @@ +/* + * Copyright 2016 Kai Pastor + * + * This file is part of OpenOrienteering. + * + * OpenOrienteering is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenOrienteering is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenOrienteering. If not, see . + */ + +#ifndef OPENORIENTEERING_OGR_FILE_FORMAT_P_H +#define OPENORIENTEERING_OGR_FILE_FORMAT_P_H + +#include + +#include +#include + +// The GDAL/OGR C API is more stable than the C++ API. +#include +#include + +#include "../core/map_coord.h" +#include "../file_import_export.h" +#include "../symbol.h" + +class AreaSymbol; +class LineSymbol; +class MapColor; +class MapPart; +class Object; +class PathObject; +class PointObject; +class PointSymbol; +class TextSymbol; + + +namespace ogr +{ + class OGRCoordinateTransformationHDeleter + { + public: + void operator()(OGRCoordinateTransformationH ct) const + { + OCTDestroyCoordinateTransformation(ct); + } + }; + + /** + * A convenience class for OGR C API coordinate transformation handles, + * similar to std::unique_ptr. + */ + using unique_transformation = std::unique_ptr::type, OGRCoordinateTransformationHDeleter>; + + + class OGRSpatialReferenceHDeleter + { + public: + void operator()(OGRSpatialReferenceH srs) const + { + OSRDestroySpatialReference(srs); + } + }; + + /** + * A convenience class for OGR C API SRS handles, similar to std::unique_ptr. + */ + using unique_srs = std::unique_ptr::type, OGRSpatialReferenceHDeleter>; + + + class OGRStyleMgrHDeleter + { + public: + void operator()(OGRStyleMgrH manager) const + { + OGR_SM_Destroy(manager); + } + }; + + /** A convenience class for OGR C API feature handles, similar to std::unique_ptr. */ + using unique_stylemanager = std::unique_ptr::type, OGRStyleMgrHDeleter>; +} + + + +/** + * An Importer for geospatial vector data supported by OGR. + * + * OGR needs to know the filename. The filename can be either derived from + * a QFile passed as stream to the constructor, or set directly through the + * option "filename". + * + * The option "separate_layers" will cause OGR layers to be imported as distinct + * map parts if set to true. + */ +class OgrFileImport : public Importer +{ +Q_OBJECT +public: + /** + * A Pointer to a function which creates a MapCoordF from double coordinates. + */ + using MapCoordConstructor = MapCoord (OgrFileImport::*)(double, double) const; + + /** + * Constructs a new importer. + */ + OgrFileImport(QIODevice* stream, Map *map, MapView *view, bool drawing_from_projected = false); + + ~OgrFileImport() override; + +protected: + void import(bool load_symbols_only) override; + + void importStyles(OGRDataSourceH data_source); + + void importLayer(MapPart* map_part, OGRLayerH layer); + + void importFeature(MapPart* map_part, OGRFeatureDefnH feature_definition, OGRFeatureH feature, OGRGeometryH geometry); + + Object* importGeometry(MapPart* map_part, OGRFeatureH feature, OGRGeometryH geometry); + + Object* importGeometryCollection(MapPart* map_part, OGRFeatureH feature, OGRGeometryH geometry); + + Object* importPointGeometry(MapPart* map_part, OGRFeatureH feature, OGRGeometryH geometry); + + PathObject* importLineStringGeometry(MapPart* map_part, OGRFeatureH feature, OGRGeometryH geometry); + + PathObject* importPolygonGeometry(MapPart* map_part, OGRFeatureH feature, OGRGeometryH geometry); + + + Symbol* getSymbol(Symbol::Type type, const char* raw_style_string); + + MapColor* makeColor(OGRStyleToolH tool, const char* color_string); + + void applyPenColor(OGRStyleToolH tool, LineSymbol* line_symbol); + + void applyBrushColor(OGRStyleToolH tool, AreaSymbol* area_symbol); + + + MapCoord toMapCoord(double x, double y) const; + + /** + * A MapCoordConstructor which interpretes the given coordinates in millimeters on paper. + */ + MapCoord fromDrawing(double x, double y) const; + + /** + * A MapCoordConstructor which interpretes the given coordinates as projected. + */ + MapCoord fromProjected(double x, double y) const; + +private: + Symbol* getSymbolForPointGeometry(const QByteArray& style_string); + LineSymbol* getLineSymbol(const QByteArray& style_string); + AreaSymbol* getAreaSymbol(const QByteArray& style_string); + + PointSymbol* getSymbolForOgrSymbol(OGRStyleToolH tool, const QByteArray& style_string); + TextSymbol* getSymbolForLabel(OGRStyleToolH tool, const QByteArray& style_string); + LineSymbol* getSymbolForPen(OGRStyleToolH tool, const QByteArray& style_string); + AreaSymbol* getSymbolForBrush(OGRStyleToolH tool, const QByteArray& style_string); + + QHash point_symbols; + PointSymbol* default_point_symbol; + QHash text_symbols; + TextSymbol* default_text_symbol; + QHash line_symbols; + LineSymbol* default_line_symbol; + QHash area_symbols; + AreaSymbol* default_area_symbol; + QHash colors; + MapColor* default_pen_color; + + MapCoordConstructor to_map_coord; + + ogr::unique_srs map_srs; + + OGRSpatialReferenceH data_srs; + + ogr::unique_transformation data_transform; + + ogr::unique_stylemanager manager; + + unsigned int empty_geometries; + unsigned int no_transformation; + unsigned int failed_transformation; + unsigned int unsupported_geometry_type; + unsigned int too_few_coordinates; + + bool drawing_from_projected; +}; + + + +// ### inline code ### + +inline +MapCoord OgrFileImport::toMapCoord(double x, double y) const +{ + return (this->*to_map_coord)(x, y); +} + + + +#endif // OPENORIENTEERING_OGR_FILE_FORMAT_P_H diff --git a/src/gdal/ogr_template.cpp b/src/gdal/ogr_template.cpp new file mode 100644 index 0000000..6f44f65 --- /dev/null +++ b/src/gdal/ogr_template.cpp @@ -0,0 +1,119 @@ +/* + * Copyright 2016 Kai Pastor + * + * This file is part of OpenOrienteering. + * + * OpenOrienteering is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenOrienteering is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenOrienteering. If not, see . + */ + +#include "ogr_template.h" + +#include +#include + +#include "gdal_manager.h" +#include "ogr_file_format_p.h" +#include "../map.h" +#include "../object.h" + + +const std::vector& OgrTemplate::supportedExtensions() +{ + return GdalManager().supportedVectorExtensions(); +} + + +OgrTemplate::OgrTemplate(const QString& path, Map* map) +: TemplateMap(path, map) +, migrating_from_template_track(false) +{ + // nothing else +} + +OgrTemplate::~OgrTemplate() +{ + if (template_state == Loaded) + unloadTemplateFile(); +} + + +const char* OgrTemplate::getTemplateType() const +{ + return "OgrTemplate"; +} + + +bool OgrTemplate::loadTemplateFileImpl(bool configuring) +{ + Q_UNUSED(configuring); + + std::unique_ptr new_template_map{ new Map() }; + new_template_map->setGeoreferencing(map->getGeoreferencing()); + + QFile stream{ template_path }; + try + { + OgrFileImport importer{ &stream, new_template_map.get(), nullptr, migrating_from_template_track }; + importer.doImport(false, template_path); + setTemplateMap(std::move(new_template_map)); + + if (!importer.warnings().empty()) + { + QString message; + message.reserve((importer.warnings().back().length()+1) * importer.warnings().size()); + for (auto& warning : importer.warnings()) + { + message.append(warning); + message.append(QLatin1Char{'\n'}); + } + message.chop(1); + setErrorString(message); + } + + return true; + } + catch (FileFormatException& e) + { + setErrorString(QString::fromUtf8(e.what())); + return false; + } +} + + +Template* OgrTemplate::duplicateImpl() const +{ + OgrTemplate* copy = new OgrTemplate(template_path, map); + if (template_state == Loaded) + copy->loadTemplateFileImpl(false); + return copy; +} + + +bool OgrTemplate::loadTypeSpecificTemplateConfiguration(QXmlStreamReader& xml) +{ + if (xml.name() == QLatin1String("crs_spec")) + { + migrating_from_template_track = true; + } + xml.skipCurrentElement(); + return true; +} + +void OgrTemplate::saveTypeSpecificTemplateConfiguration(QXmlStreamWriter& xml) const +{ + if (migrating_from_template_track) + { + xml.writeEmptyElement(QLatin1String("crs_spec")); + } +} diff --git a/src/gdal/ogr_template.h b/src/gdal/ogr_template.h new file mode 100644 index 0000000..45aa39d --- /dev/null +++ b/src/gdal/ogr_template.h @@ -0,0 +1,59 @@ +/* + * Copyright 2016 Kai Pastor + * + * This file is part of OpenOrienteering. + * + * OpenOrienteering is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenOrienteering is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenOrienteering. If not, see . + */ + +#ifndef OPENORIENTEERING_OGR_TEMPLATE_H +#define OPENORIENTEERING_OGR_TEMPLATE_H + +#include "../template_map.h" + +#include "../core/georeferencing.h" + + +/** + * Template displaying a file supported by OGR. + */ +class OgrTemplate : public TemplateMap +{ +Q_OBJECT +public: + static const std::vector& supportedExtensions(); + + + OgrTemplate(const QString& path, Map* map); + + ~OgrTemplate() override; + + + const char* getTemplateType() const override; + + + bool loadTemplateFileImpl(bool configuring) override; + +protected: + Template* duplicateImpl() const override; + + bool loadTypeSpecificTemplateConfiguration(QXmlStreamReader& xml) override; + + void saveTypeSpecificTemplateConfiguration(QXmlStreamWriter& xml) const override; + +private: + bool migrating_from_template_track; +}; + +#endif // OPENORIENTEERING_OGR_TEMPLATE_H diff --git a/src/global.cpp b/src/global.cpp new file mode 100644 index 0000000..b918c67 --- /dev/null +++ b/src/global.cpp @@ -0,0 +1,43 @@ +/* + * Copyright 2012, 2013, 2014 Thomas Schöps + * Copyright 2012, 2013, 2014 Kai Pastor + * + * This file is part of OpenOrienteering. + * + * OpenOrienteering is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenOrienteering is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenOrienteering. If not, see . + */ + + +#include "global.h" + +#include + +#include "file_format_registry.h" +#include "file_format_native.h" +#include "file_format_xml.h" +#include "fileformats/ocd_file_format.h" +#include "gdal/ogr_file_format.h" + +void doStaticInitializations() +{ + // Register the supported file formats + FileFormats.registerFormat(new XMLFileFormat()); + FileFormats.registerFormat(new OcdFileFormat()); +#ifdef MAPPER_USE_GDAL + FileFormats.registerFormat(new OgrFileFormat()); +#endif +#ifndef NO_NATIVE_FILE_FORMAT + FileFormats.registerFormat(new NativeFileFormat()); // TODO: Remove before release 1.0 +#endif +} diff --git a/src/global.h b/src/global.h new file mode 100644 index 0000000..8024ba3 --- /dev/null +++ b/src/global.h @@ -0,0 +1,33 @@ +/* + * Copyright 2012, 2013 Thomas Schöps + * + * This file is part of OpenOrienteering. + * + * OpenOrienteering is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenOrienteering is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenOrienteering. If not, see . + */ + +#ifndef _OPENORIENTEERING_GLOBAL_H_ +#define _OPENORIENTEERING_GLOBAL_H_ + +#define QT_USE_FAST_CONCATENATION +#define QT_USE_FAST_OPERATOR_PLUS + +#ifdef _MSC_VER + #pragma warning(disable: 4290) // "C++ exception specification ignored" +#endif + +/// This is called at startup in main() and by the test cases to do the global initializations +void doStaticInitializations(); + +#endif diff --git a/src/gps_display.cpp b/src/gps_display.cpp new file mode 100644 index 0000000..cab2579 --- /dev/null +++ b/src/gps_display.cpp @@ -0,0 +1,361 @@ +/* + * Copyright 2013 Thomas Schöps + * Copyright 2014, 2016 Kai Pastor + * + * This file is part of OpenOrienteering. + * + * OpenOrienteering is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenOrienteering is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenOrienteering. If not, see . + */ + +#include "gps_display.h" + +#if defined(QT_POSITIONING_LIB) +# include +#endif +#if defined(Q_OS_ANDROID) +# include +# include +#endif +#include +#include +#include + +#include "core/georeferencing.h" +#include "compass.h" +#include "map_widget.h" +#include "util.h" +#include "util/backports.h" + +GPSDisplay::GPSDisplay(MapWidget* widget, const Georeferencing& georeferencing, QObject* parent) + : QObject(parent) + , widget(widget) + , georeferencing(georeferencing) + , source(nullptr) + , tracking_lost(false) + , has_valid_position(false) + , gps_updated(false) + , visible(false) + , distance_rings_enabled(false) + , heading_indicator_enabled(false) +{ +#if defined(QT_POSITIONING_LIB) + source = QGeoPositionInfoSource::createDefaultSource(this); + if (!source) + { + qDebug("Cannot create QGeoPositionInfoSource!"); + return; + } + + source->setPreferredPositioningMethods(QGeoPositionInfoSource::SatellitePositioningMethods); + source->setUpdateInterval(1000); + connect(source, &QGeoPositionInfoSource::positionUpdated, this, &GPSDisplay::positionUpdated, Qt::QueuedConnection); + connect(source, QOverload::of(&QGeoPositionInfoSource::error), this, &GPSDisplay::error); + connect(source, &QGeoPositionInfoSource::updateTimeout, this, &GPSDisplay::updateTimeout); +#elif defined(MAPPER_DEVELOPMENT_BUILD) + // DEBUG + QTimer* debug_timer = new QTimer(this); + connect(debug_timer, SIGNAL(timeout()), this, SLOT(debugPositionUpdate())); + debug_timer->start(500); + visible = true; +#endif + + widget->setGPSDisplay(this); +} + +GPSDisplay::~GPSDisplay() +{ + stopUpdates(); + widget->setGPSDisplay(nullptr); +} + +bool GPSDisplay::checkGPSEnabled() +{ +#if defined(Q_OS_ANDROID) + static bool translation_initialized = false; + if (!translation_initialized) + { + QAndroidJniObject gps_disabled_string = QAndroidJniObject::fromString(tr("GPS is disabled in the device settings. Open settings now?")); + QAndroidJniObject yes_string = QAndroidJniObject::fromString(tr("Yes")); + QAndroidJniObject no_string = QAndroidJniObject::fromString(tr("No")); + QAndroidJniObject::callStaticMethod( + "org/openorienteering/mapper/MapperActivity", + "setTranslatableStrings", + "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V", + yes_string.object(), + no_string.object(), + gps_disabled_string.object()); + translation_initialized = true; + } + + QAndroidJniObject::callStaticMethod("org/openorienteering/mapper/MapperActivity", + "checkGPSEnabled", + "()V"); +#endif + return true; +} + +void GPSDisplay::startUpdates() +{ +#if defined(QT_POSITIONING_LIB) + if (source) + { + checkGPSEnabled(); + source->startUpdates(); + } +#endif +} + +void GPSDisplay::stopUpdates() +{ +#if defined(QT_POSITIONING_LIB) + if (source) + { + source->stopUpdates(); + has_valid_position = false; + } +#endif +} + +void GPSDisplay::setVisible(bool visible) +{ + if (this->visible != visible) + { + this->visible = visible; + updateMapWidget(); + } +} + +void GPSDisplay::enableDistanceRings(bool enable) +{ + distance_rings_enabled = enable; + if (visible && has_valid_position) + updateMapWidget(); +} + +void GPSDisplay::enableHeadingIndicator(bool enable) +{ + if (enable && ! heading_indicator_enabled) + Compass::getInstance().startUsage(); + else if (! enable && heading_indicator_enabled) + Compass::getInstance().stopUsage(); + + heading_indicator_enabled = enable; +} + +void GPSDisplay::paint(QPainter* painter) +{ + if (!visible || !has_valid_position) + return; + + // Get GPS position on map widget + bool ok = true; + MapCoordF gps_coord = calcLatestGPSCoord(ok); + if (!ok) + return; + QPointF gps_pos = widget->mapToViewport(gps_coord); + + // Draw center dot or arrow + painter->setPen(Qt::NoPen); + painter->setBrush(QBrush(tracking_lost ? Qt::gray : Qt::red)); + if (heading_indicator_enabled) + { + const qreal base_length_unit = Util::mmToPixelLogical(0.6); + + // For heading indicator, get azimuth from compass and calculate + // the relative rotation to map view rotation, clockwise. + qreal heading_rotation_deg = Compass::getInstance().getCurrentAzimuth() + qRadiansToDegrees(widget->getMapView()->getRotation()); + + painter->save(); + painter->translate(gps_pos); + painter->rotate(heading_rotation_deg); + + // Draw arrow + static const QPointF arrow_points[4] = { + QPointF(0, -2.5 * base_length_unit), + QPointF(base_length_unit, base_length_unit), + QPointF(0, 0), + QPointF(base_length_unit, base_length_unit) + }; + painter->drawPolygon(arrow_points, 4); + + // Draw heading line + painter->setPen(QPen(Qt::gray, base_length_unit / 6)); + painter->setBrush(Qt::NoBrush); + painter->drawLine(QPointF(0, 0), QPointF(0, -10000 * base_length_unit)); // very long + + painter->restore(); + } + else + { + const qreal dot_radius = Util::mmToPixelLogical(0.5f); + painter->drawEllipse(gps_pos, dot_radius, dot_radius); + } + + auto meters_to_pixels = widget->getMapView()->lengthToPixel(qreal(1000000) / georeferencing.getScaleDenominator()); + // Draw distance circles + if (distance_rings_enabled) + { + const int num_distance_rings = 2; + const qreal distance_ring_radius_meters = 10; + + auto distance_ring_radius_pixels = distance_ring_radius_meters * meters_to_pixels; + painter->setPen(QPen(Qt::gray, Util::mmToPixelLogical(0.1))); + painter->setBrush(Qt::NoBrush); + auto radius = distance_ring_radius_pixels; + for (int i = 0; i < num_distance_rings; ++i) + { + painter->drawEllipse(gps_pos, radius, radius); + radius += distance_ring_radius_pixels; + } + } + + // Draw accuracy circle + if (latest_gps_coord_accuracy >= 0) + { + auto accuracy_pixels = latest_gps_coord_accuracy * meters_to_pixels; + + painter->setPen(QPen(tracking_lost ? Qt::gray : Qt::red, Util::mmToPixelLogical(0.2f))); + painter->setBrush(Qt::NoBrush); + painter->drawEllipse(gps_pos, accuracy_pixels, accuracy_pixels); + } +} + +#if defined(QT_POSITIONING_LIB) +void GPSDisplay::positionUpdated(const QGeoPositionInfo& info) +{ + Q_UNUSED(info); + + gps_updated = true; + tracking_lost = false; + has_valid_position = true; + + bool ok = false; + calcLatestGPSCoord(ok); + if (ok) + { + emit mapPositionUpdated(latest_gps_coord, latest_gps_coord_accuracy); + emit latLonUpdated( + info.coordinate().latitude(), + info.coordinate().longitude(), + (info.coordinate().type() == QGeoCoordinate::Coordinate3D) ? info.coordinate().altitude() : -9999, + latest_gps_coord_accuracy + ); + } + + updateMapWidget(); +} + +void GPSDisplay::error(QGeoPositionInfoSource::Error positioningError) +{ + if (positioningError != QGeoPositionInfoSource::NoError) + { + if (!tracking_lost) + { + tracking_lost = true; + emit positionUpdatesInterrupted(); + updateMapWidget(); + } + } +} + +void GPSDisplay::updateTimeout() +{ + // Lost satellite fix + if (!tracking_lost) + { + tracking_lost = true; + emit positionUpdatesInterrupted(); + updateMapWidget(); + } +} +#endif + +void GPSDisplay::debugPositionUpdate() +{ +#if MAPPER_DEVELOPMENT_BUILD + if (!visible) + return; + + QTime now = QTime::currentTime(); + float offset = now.msecsSinceStartOfDay() / (float)(10 * 1000); + float accuracy = 12 + 7 * qSin(2 + offset); + float altitude = 400 + 10 * qSin(1 + 0.1f * offset); + + MapCoordF coord(30 * qSin(0.5f * offset), 30 * qCos(0.53f * offset)); + emit mapPositionUpdated(coord, accuracy); + + if (georeferencing.isValid() && ! georeferencing.isLocal()) + { + bool ok; + LatLon latLon = georeferencing.toGeographicCoords(coord, &ok); + if (ok) + { + emit latLonUpdated(latLon.latitude(), latLon.longitude(), altitude, accuracy); + } + } + + gps_updated = true; + tracking_lost = false; + has_valid_position = true; + latest_gps_coord = coord; + latest_gps_coord_accuracy = accuracy; + updateMapWidget(); +#endif +} + +MapCoordF GPSDisplay::calcLatestGPSCoord(bool& ok) +{ +#if defined(QT_POSITIONING_LIB) + if (!has_valid_position) + { + ok = false; + return latest_gps_coord; + } + if (!gps_updated) + { + ok = true; + return latest_gps_coord; + } + + latest_pos_info = source->lastKnownPosition(true); + latest_gps_coord_accuracy = latest_pos_info.hasAttribute(QGeoPositionInfo::HorizontalAccuracy) ? latest_pos_info.attribute(QGeoPositionInfo::HorizontalAccuracy) : -1; + + QGeoCoordinate qgeo_coord = latest_pos_info.coordinate(); + if (!qgeo_coord.isValid()) + { + ok = false; + return latest_gps_coord; + } + + LatLon latlon(qgeo_coord.latitude(), qgeo_coord.longitude()); + latest_gps_coord = georeferencing.toMapCoordF(latlon, &ok); + if (!ok) + { + qDebug("GPSDisplay::calcLatestGPSCoord(): Cannot convert LatLon to MapCoordF!"); + return latest_gps_coord; + } + + gps_updated = false; + ok = true; +#else + ok = has_valid_position; +#endif + return latest_gps_coord; +} + +void GPSDisplay::updateMapWidget() +{ + // TODO: Limit update region to union of old and new bounding rect + widget->update(); +} diff --git a/src/gps_display.h b/src/gps_display.h new file mode 100644 index 0000000..2101c4f --- /dev/null +++ b/src/gps_display.h @@ -0,0 +1,136 @@ +/* + * Copyright 2013 Thomas Schöps + * Copyright 2016 Kai Pastor + * + * This file is part of OpenOrienteering. + * + * OpenOrienteering is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenOrienteering is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenOrienteering. If not, see . + */ + + +#ifndef _OPENORIENTEERING_GPS_DISPLAY_H_ +#define _OPENORIENTEERING_GPS_DISPLAY_H_ + +#include +#if defined(QT_POSITIONING_LIB) + #include + #include +#endif + +#include "core/map_coord.h" + +QT_BEGIN_NAMESPACE +class QPainter; +class QGeoPositionInfo; +class QGeoPositionInfoSource; +QT_END_NAMESPACE + +class MapWidget; +class Georeferencing; + + +/** + * Retrieves the GPS position and displays a marker at this position on a MapWidget. + */ +class GPSDisplay : public QObject +{ +Q_OBJECT +public: + /// Creates a GPS display for the given map widget and georeferencing. + GPSDisplay(MapWidget* widget, const Georeferencing& georeferencing, QObject* parent = nullptr); + /// Destructor, removes the GPS display from the map widget. + ~GPSDisplay() override; + + /** + * @brief Checks if GPS is enabled and may guide the user to the device settings. + * + * Checks if GPS is enabled in the device settings. If this is not the case, + * it asks the user whether he wishes to open the device's location settings + * dialog. + * + * Returns true if GPS is enabled. Must return true also if the settings + * dialog remains open when returning from this function (i.e. the final + * result is not known. May return false if GPS remains disabled. + */ + bool checkGPSEnabled(); + + /// Starts regular position updates. This will issue redraws of the map widget. + void startUpdates(); + /// Stops regular position updates. + void stopUpdates(); + + /// Sets GPS marker visibility (true by default) + void setVisible(bool visible); + /// Returns GPS marker visibility + inline bool isVisible() const {return visible;} + + /// Sets whether distance rings are drawn + void enableDistanceRings(bool enable); + /// Sets whether the current heading from the Compass is used to draw a heading indicator. + void enableHeadingIndicator(bool enable); + + /// This is called from the MapWidget drawing code to draw the GPS position marker. + void paint(QPainter* painter); + + /// Returns if a valid position was received since the last call to startUpdates(). + inline bool hasValidPosition() const {return has_valid_position;} + /// Returns the latest received GPS coord. Check hasValidPosition() beforehand! + const MapCoordF& getLatestGPSCoord() const {return latest_gps_coord;} + /// Returns the accuracy of the latest received GPS coord, or -1 if unknown. Check hasValidPosition() beforehand! + float getLatestGPSCoordAccuracy() const {return latest_gps_coord_accuracy;} + +signals: + /// Is emitted whenever a new position update happens. + /// If the accuracy is unknown, -1 will be given. + void mapPositionUpdated(MapCoordF coord, float accuracy); + + /// Like mapPositionUpdated(), but gives the values as + /// latitude / longitude in degrees and also gives altitude + /// (meters above sea level; -9999 is unknown) + void latLonUpdated(double latitude, double longitude, double altitude, float accuracy); + + /// Is emitted when updates are interrupted after previously being active, + /// due to loss of satellite reception or another error such as the user + /// turning off the GPS receiver. + void positionUpdatesInterrupted(); + +private slots: +#if defined(QT_POSITIONING_LIB) + void positionUpdated(const QGeoPositionInfo& info); + void error(QGeoPositionInfoSource::Error positioningError); + void updateTimeout(); +#endif + void debugPositionUpdate(); + +private: + MapCoordF calcLatestGPSCoord(bool& ok); + void updateMapWidget(); + + MapWidget* widget; + const Georeferencing& georeferencing; + QGeoPositionInfoSource* source; +#if defined(QT_POSITIONING_LIB) + QGeoPositionInfo latest_pos_info; +#endif + MapCoordF latest_gps_coord; + float latest_gps_coord_accuracy; + bool tracking_lost; + bool has_valid_position; + bool gps_updated; + bool visible; + bool distance_rings_enabled; + bool heading_indicator_enabled; +}; + +#endif diff --git a/src/gps_temporary_markers.cpp b/src/gps_temporary_markers.cpp new file mode 100644 index 0000000..a357137 --- /dev/null +++ b/src/gps_temporary_markers.cpp @@ -0,0 +1,127 @@ +/* + * Copyright 2014 Thomas Schöps + * Copyright 2015 Kai Pastor + * + * This file is part of OpenOrienteering. + * + * OpenOrienteering is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenOrienteering is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenOrienteering. If not, see . + */ + + +#include "gps_temporary_markers.h" + +#include + +#include "map_widget.h" +#include "gps_display.h" +#include "tool.h" +#include "util.h" + + +GPSTemporaryMarkers::GPSTemporaryMarkers(MapWidget* widget, GPSDisplay* gps_display): QObject() +{ + this->widget = widget; + this->gps_display = gps_display; + recording_path = false; + + connect(gps_display, SIGNAL(mapPositionUpdated(MapCoordF,float)), this, SLOT(newGPSPosition(MapCoordF,float))); + + widget->setTemporaryMarkerDisplay(this); +} + +GPSTemporaryMarkers::~GPSTemporaryMarkers() +{ + widget->setTemporaryMarkerDisplay(NULL); +} + +bool GPSTemporaryMarkers::addPoint() +{ + if (!gps_display->hasValidPosition()) + return false; + + points.push_back(gps_display->getLatestGPSCoord()); + updateMapWidget(); + return true; +} + +void GPSTemporaryMarkers::startPath() +{ + paths.push_back(std::vector< QPointF >()); + recording_path = true; + if (gps_display->hasValidPosition()) + newGPSPosition(gps_display->getLatestGPSCoord(), gps_display->getLatestGPSCoordAccuracy()); +} + +void GPSTemporaryMarkers::stopPath() +{ + recording_path = false; +} + +void GPSTemporaryMarkers::clear() +{ + points.clear(); + paths.clear(); + updateMapWidget(); +} + +void GPSTemporaryMarkers::paint(QPainter* painter) +{ + painter->save(); + widget->applyMapTransform(painter); + float scale_factor = 1.0f / widget->getMapView()->getZoom(); + + // Draw paths + painter->setBrush(Qt::NoBrush); + + painter->setPen(QPen(QBrush(qRgb(255, 255, 255)), scale_factor * 0.3f)); + for (size_t path_number = 0; path_number < paths.size(); ++ path_number) + painter->drawPolyline(paths[path_number].data(), paths[path_number].size()); + + painter->setPen(QPen(QBrush(MapEditorTool::active_color), scale_factor * 0.2f)); + for (size_t path_number = 0; path_number < paths.size(); ++ path_number) + painter->drawPolyline(paths[path_number].data(), paths[path_number].size()); + + // Draw points + painter->setPen(Qt::NoPen); + + painter->setBrush(QBrush(qRgb(255, 255, 255))); + float point_radius = scale_factor * 0.5f; + for (size_t point_number = 0; point_number < points.size(); ++ point_number) + painter->drawEllipse(points[point_number], point_radius, point_radius); + + painter->setBrush(QBrush(MapEditorTool::inactive_color)); + point_radius = scale_factor * 0.4f; + for (size_t point_number = 0; point_number < points.size(); ++ point_number) + painter->drawEllipse(points[point_number], point_radius, point_radius); + + painter->restore(); +} + +void GPSTemporaryMarkers::newGPSPosition(MapCoordF coord, float accuracy) +{ + Q_UNUSED(accuracy); + + if (recording_path && ! paths.empty()) + { + std::vector< QPointF >& path_coords = paths.back(); + path_coords.push_back(coord); + updateMapWidget(); + } +} + +void GPSTemporaryMarkers::updateMapWidget() +{ + // NOTE: could limit the updated area here + widget->update(); +} diff --git a/src/gps_temporary_markers.h b/src/gps_temporary_markers.h new file mode 100644 index 0000000..3144055 --- /dev/null +++ b/src/gps_temporary_markers.h @@ -0,0 +1,69 @@ +/* + * Copyright 2014 Thomas Schöps + * + * This file is part of OpenOrienteering. + * + * OpenOrienteering is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenOrienteering is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenOrienteering. If not, see . + */ + + +#ifndef _OPENORIENTEERING_GPS_TEMPORARY_MARKERS_H_ +#define _OPENORIENTEERING_GPS_TEMPORARY_MARKERS_H_ + +#include + +#include "core/map_coord.h" + +QT_BEGIN_NAMESPACE +class QPainter; +QT_END_NAMESPACE + +class MapWidget; +class GPSDisplay; + + +/** Displays temporary markers recorded with GPS. */ +class GPSTemporaryMarkers : public QObject +{ +Q_OBJECT +public: + GPSTemporaryMarkers(MapWidget* widget, GPSDisplay* gps_display); + virtual ~GPSTemporaryMarkers(); + + /** Returns false if no point was added due to not having a valid position yet. */ + bool addPoint(); + /** Starts recording a GPS path. */ + void startPath(); + /** Stops recording a GPS path. */ + void stopPath(); + /** Deletes all temporary markers. */ + void clear(); + + /// This is called from the MapWidget drawing code to draw the markers. + void paint(QPainter* painter); + +public slots: + void newGPSPosition(MapCoordF coord, float accuracy); + +private: + void updateMapWidget(); + + bool recording_path; + std::vector< QPointF > points; + std::vector< std::vector< QPointF > > paths; + GPSDisplay* gps_display; + MapWidget* widget; +}; + +#endif diff --git a/src/gps_track.cpp b/src/gps_track.cpp new file mode 100644 index 0000000..fc79eab --- /dev/null +++ b/src/gps_track.cpp @@ -0,0 +1,645 @@ +/* + * Copyright 2012, 2013 Thomas Schöps + * Copyright 2014 Kai Pastor + * + * This file is part of OpenOrienteering. + * + * OpenOrienteering is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenOrienteering is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenOrienteering. If not, see . + */ + + +#include "gps_track.h" + +#include +#include +#include +#include // TODO: get rid of this +#include +#include +#include + +#include // TODO: Replace APP_NAME by runtime function to remove this dependency + +#include "dxfparser.h" +#include "template_track.h" + + +namespace +{ + // Shared definition of standard geographic CRS. + // TODO: Merge with Georeferencing. + static const QString geographic_crs_spec = QString::fromLatin1("+proj=latlong +datum=WGS84"); +} + + +// There is some (mis?)use of TrackPoint's gps_coord LatLon +// as sort-of MapCoordF. +// This function serves both for explicit conversion and highlighting. +MapCoordF fakeMapCoordF(const LatLon &latlon) +{ + return MapCoordF(latlon.longitude(), latlon.latitude()); +} + +TrackPoint::TrackPoint(LatLon coord, QDateTime datetime, float elevation, int num_satellites, float hDOP) +{ + gps_coord = coord; + is_curve_start = false; + this->datetime = datetime; + this->elevation = elevation; + this->num_satellites = num_satellites; + this->hDOP = hDOP; +} +void TrackPoint::save(QXmlStreamWriter* stream) const +{ + stream->writeAttribute(QStringLiteral("lat"), QString::number(gps_coord.latitude(), 'f', 12)); + stream->writeAttribute(QStringLiteral("lon"), QString::number(gps_coord.longitude(), 'f', 12)); + + if (datetime.isValid()) + stream->writeTextElement(QStringLiteral("time"), datetime.toString(Qt::ISODate) + QLatin1Char('Z')); + if (elevation > -9999) + stream->writeTextElement(QStringLiteral("ele"), QString::number(elevation, 'f', 3)); + if (num_satellites >= 0) + stream->writeTextElement(QStringLiteral("sat"), QString::number(num_satellites)); + if (hDOP >= 0) + stream->writeTextElement(QStringLiteral("hdop"), QString::number(hDOP, 'f', 3)); +} + + + +// ### Track ### + +Track::Track() : track_crs(NULL) +{ + current_segment_finished = true; +} + +Track::Track(const Georeferencing& map_georef) : track_crs(NULL), map_georef(map_georef) +{ + current_segment_finished = true; +} + +Track::Track(const Track& other) +{ + waypoints = other.waypoints; + waypoint_names = other.waypoint_names; + + segment_points = other.segment_points; + segment_starts = other.segment_starts; + segment_names = other.segment_names; + + current_segment_finished = other.current_segment_finished; + + element_tags = other.element_tags; + + map_georef = other.map_georef; + + if (other.track_crs != NULL) + { + track_crs = new Georeferencing(*other.track_crs); + } +} + +Track::~Track() +{ + delete track_crs; +} + +Track& Track::operator=(const Track& rhs) +{ + clear(); + + waypoints = rhs.waypoints; + waypoint_names = rhs.waypoint_names; + + segment_points = rhs.segment_points; + segment_starts = rhs.segment_starts; + segment_names = rhs.segment_names; + + current_segment_finished = rhs.current_segment_finished; + + element_tags = rhs.element_tags; + + map_georef = rhs.map_georef; + + if (rhs.track_crs != NULL) + { + track_crs = new Georeferencing(*rhs.track_crs); + } + + return *this; +} + +void Track::clear() +{ + waypoints.clear(); + waypoint_names.clear(); + segment_points.clear(); + segment_starts.clear(); + segment_names.clear(); + current_segment_finished = true; + element_tags.clear(); + delete track_crs; + track_crs = NULL; +} + +bool Track::loadFrom(const QString& path, bool project_points, QWidget* dialog_parent) +{ + QFile file(path); + if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) + return false; + + clear(); + + if (path.endsWith(QLatin1String(".gpx"), Qt::CaseInsensitive)) + { + if (!loadFromGPX(&file, project_points, dialog_parent)) + return false; + } + else if (path.endsWith(QLatin1String(".dxf"), Qt::CaseInsensitive)) + { + if (!loadFromDXF(&file, project_points, dialog_parent)) + return false; + } + else if (path.endsWith(QLatin1String(".osm"), Qt::CaseInsensitive)) + { + if (!loadFromOSM(&file, project_points, dialog_parent)) + return false; + } + else + return false; + + file.close(); + return true; +} +bool Track::saveTo(const QString& path) const +{ + QFile file(path); + if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) + return false; + + QXmlStreamWriter stream(&file); + stream.writeStartDocument(); + stream.writeStartElement(QString::fromLatin1("gpx")); + stream.writeAttribute(QString::fromLatin1("version"), QString::fromLatin1("1.1")); + stream.writeAttribute(QString::fromLatin1("creator"), APP_NAME); + + int size = getNumWaypoints(); + for (int i = 0; i < size; ++i) + { + stream.writeStartElement(QStringLiteral("wpt")); + const TrackPoint& point = getWaypoint(i); + point.save(&stream); + stream.writeTextElement(QStringLiteral("name"), waypoint_names[i]); + stream.writeEndElement(); + } + + stream.writeStartElement(QStringLiteral("trk")); + for (int i = 0; i < getNumSegments(); ++i) + { + stream.writeStartElement(QStringLiteral("trkseg")); + size = getSegmentPointCount(i); + for (int k = 0; k < size; ++k) + { + stream.writeStartElement(QStringLiteral("trkpt")); + const TrackPoint& point = getSegmentPoint(i, k); + point.save(&stream); + stream.writeEndElement(); + } + stream.writeEndElement(); + } + stream.writeEndElement(); + + stream.writeEndElement(); + stream.writeEndDocument(); + + file.close(); + return true; +} + +void Track::appendTrackPoint(TrackPoint& point) +{ + point.map_coord = map_georef.toMapCoordF(point.gps_coord, NULL); // TODO: check for errors + segment_points.push_back(point); + + if (current_segment_finished) + { + segment_starts.push_back(segment_points.size() - 1); + current_segment_finished = false; + } +} +void Track::finishCurrentSegment() +{ + current_segment_finished = true; +} + +void Track::appendWaypoint(TrackPoint& point, const QString& name) +{ + point.map_coord = map_georef.toMapCoordF(point.gps_coord, NULL); // TODO: check for errors + waypoints.push_back(point); + waypoint_names.push_back(name); +} + +void Track::changeMapGeoreferencing(const Georeferencing& new_map_georef) +{ + map_georef = new_map_georef; + + projectPoints(); +} + +void Track::setTrackCRS(Georeferencing* track_crs) +{ + delete this->track_crs; + this->track_crs = track_crs; + + projectPoints(); +} + +int Track::getNumSegments() const +{ + return (int)segment_starts.size(); +} + +int Track::getSegmentPointCount(int segment_number) const +{ + Q_ASSERT(segment_number >= 0 && segment_number < (int)segment_starts.size()); + if (segment_number == (int)segment_starts.size() - 1) + return segment_points.size() - segment_starts[segment_number]; + else + return segment_starts[segment_number + 1] - segment_starts[segment_number]; +} + +const TrackPoint& Track::getSegmentPoint(int segment_number, int point_number) const +{ + Q_ASSERT(segment_number >= 0 && segment_number < (int)segment_starts.size()); + return segment_points[segment_starts[segment_number] + point_number]; +} + +const QString& Track::getSegmentName(int segment_number) const +{ + // NOTE: Segment names not [yet] supported by most track importers. + if (segment_names.size() == 0) + { + static const QString empty_string; + return empty_string; + } + + return segment_names[segment_number]; +} + +int Track::getNumWaypoints() const +{ + return waypoints.size(); +} + +const TrackPoint& Track::getWaypoint(int number) const +{ + return waypoints[number]; +} + +const QString& Track::getWaypointName(int number) const +{ + return waypoint_names[number]; +} + +LatLon Track::calcAveragePosition() const +{ + double avg_latitude = 0; + double avg_longitude = 0; + int num_samples = 0; + + int size = getNumWaypoints(); + for (int i = 0; i < size; ++i) + { + const TrackPoint& point = getWaypoint(i); + avg_latitude += point.gps_coord.latitude(); + avg_longitude += point.gps_coord.longitude(); + ++num_samples; + } + for (int i = 0; i < getNumSegments(); ++i) + { + size = getSegmentPointCount(i); + for (int k = 0; k < size; ++k) + { + const TrackPoint& point = getSegmentPoint(i, k); + avg_latitude += point.gps_coord.latitude(); + avg_longitude += point.gps_coord.longitude(); + ++num_samples; + } + } + + return LatLon((num_samples > 0) ? (avg_latitude / num_samples) : 0, + (num_samples > 0) ? (avg_longitude / num_samples) : 0); +} + +bool Track::loadFromGPX(QFile* file, bool project_points, QWidget* dialog_parent) +{ + Q_UNUSED(dialog_parent); + + track_crs = new Georeferencing(); + track_crs->setProjectedCRS({}, geographic_crs_spec); + track_crs->setTransformationDirectly(QTransform()); + + TrackPoint point; + QString point_name; + + QXmlStreamReader stream(file); + while (!stream.atEnd()) + { + stream.readNext(); + if (stream.tokenType() == QXmlStreamReader::StartElement) + { + if (stream.name().compare(QLatin1String("wpt"), Qt::CaseInsensitive) == 0 + || stream.name().compare(QLatin1String("trkpt"), Qt::CaseInsensitive) == 0 + || stream.name().compare(QLatin1String("rtept"), Qt::CaseInsensitive) == 0) + { + point = TrackPoint(LatLon(stream.attributes().value(QLatin1String("lat")).toDouble(), + stream.attributes().value(QLatin1String("lon")).toDouble())); + if (project_points) + point.map_coord = map_georef.toMapCoordF(point.gps_coord); // TODO: check for errors + point_name.clear(); + } + else if (stream.name().compare(QLatin1String("trkseg"), Qt::CaseInsensitive) == 0 + || stream.name().compare(QLatin1String("rte"), Qt::CaseInsensitive) == 0) + { + if (segment_starts.size() == 0 || + segment_starts.back() < (int)segment_points.size()) + { + segment_starts.push_back(segment_points.size()); + } + } + else if (stream.name().compare(QLatin1String("ele"), Qt::CaseInsensitive) == 0) + point.elevation = stream.readElementText().toFloat(); + else if (stream.name().compare(QLatin1String("time"), Qt::CaseInsensitive) == 0) + point.datetime = QDateTime::fromString(stream.readElementText(), Qt::ISODate); + else if (stream.name().compare(QLatin1String("sat"), Qt::CaseInsensitive) == 0) + point.num_satellites = stream.readElementText().toInt(); + else if (stream.name().compare(QLatin1String("hdop"), Qt::CaseInsensitive) == 0) + point.hDOP = stream.readElementText().toFloat(); + else if (stream.name().compare(QLatin1String("name"), Qt::CaseInsensitive) == 0) + point_name = stream.readElementText(); + } + else if (stream.tokenType() == QXmlStreamReader::EndElement) + { + if (stream.name().compare(QLatin1String("wpt"), Qt::CaseInsensitive) == 0) + { + waypoints.push_back(point); + waypoint_names.push_back(point_name); + } + else if (stream.name().compare(QLatin1String("trkpt"), Qt::CaseInsensitive) == 0 + || stream.name().compare(QLatin1String("rtept"), Qt::CaseInsensitive) == 0) + { + segment_points.push_back(point); + } + } + } + + if (segment_starts.size() > 0 && + segment_starts.back() == (int)segment_points.size()) + { + segment_starts.pop_back(); + } + + return true; +} + +bool Track::loadFromDXF(QFile* file, bool project_points, QWidget* dialog_parent) +{ + DXFParser* parser = new DXFParser(); + parser->setData(file); + QString result = parser->parse(); + if (!result.isEmpty()) + { + QMessageBox::critical(dialog_parent, TemplateTrack::tr("Error reading"), TemplateTrack::tr("There was an error reading the DXF file %1:\n\n%2").arg(file->fileName(), result)); + delete parser; + return false; + } + QList paths = parser->getData(); + delete parser; + + // TODO: Re-implement the possibility to load degree values somewhere else. + // It does not fit here as this method is called again every time a map + // containing a track is re-loaded, and in this case the question should + // not be asked again. + //int res = QMessageBox::question(dialog_parent, TemplateTrack::tr("Question"), TemplateTrack::tr("Are the coordinates in the DXF file in degrees?"), QMessageBox::Yes|QMessageBox::No); + for (auto&& path : paths) + { + if (path.type == POINT) + { + if(path.coords.size() < 1) + continue; + TrackPoint point = TrackPoint(LatLon(path.coords.at(0).y, path.coords.at(0).x)); + if (project_points) + point.map_coord = map_georef.toMapCoordF(track_crs, fakeMapCoordF(point.gps_coord)); // TODO: check for errors + waypoints.push_back(point); + waypoint_names.push_back(path.layer); + } + if (path.type == LINE || + path.type == SPLINE ) + { + if (path.coords.size() < 1) + continue; + segment_starts.push_back(segment_points.size()); + segment_names.push_back(path.layer); + int i = 0; + for (auto&& coord : path.coords) + { + TrackPoint point = TrackPoint(LatLon(coord.y, coord.x), QDateTime()); + if (project_points) + point.map_coord = map_georef.toMapCoordF(track_crs, fakeMapCoordF(point.gps_coord)); // TODO: check for errors + if (path.type == SPLINE && + i % 3 == 0 && + i < path.coords.size() - 3) + point.is_curve_start = true; + + segment_points.push_back(point); + ++i; + } + if (path.closed && !segment_points.empty()) + { + const TrackPoint& start = segment_points[segment_starts.back()]; + if (start.gps_coord != segment_points.back().gps_coord) + { + segment_points.push_back(start); + segment_points.back().is_curve_start = false; + } + } + } + } + + return true; +} + +bool Track::loadFromOSM(QFile* file, bool project_points, QWidget* dialog_parent) +{ + track_crs = new Georeferencing(); + track_crs->setProjectedCRS({}, geographic_crs_spec); + track_crs->setTransformationDirectly(QTransform()); + + // Basic OSM file support + // Reference: http://wiki.openstreetmap.org/wiki/OSM_XML + const double min_supported_version = 0.5; + const double max_supported_version = 0.6; + QHash nodes; + int node_problems = 0; + + QXmlStreamReader xml(file); + if (xml.readNextStartElement()) + { + if (xml.name() != QLatin1String("osm")) + { + QMessageBox::critical(dialog_parent, TemplateTrack::tr("Error"), TemplateTrack::tr("%1:\nNot an OSM file.")); + return false; + } + else + { + QXmlStreamAttributes attributes(xml.attributes()); + const double osm_version = attributes.value(QLatin1String("version")).toDouble(); + if (osm_version < min_supported_version) + { + QMessageBox::critical(dialog_parent, TemplateTrack::tr("Error"), + TemplateTrack::tr("The OSM file has version %1.\nThe minimum supported version is %2.").arg( + attributes.value(QLatin1String("version")).toString(), QString::number(min_supported_version, 'g', 1))); + return false; + } + if (osm_version > max_supported_version) + { + QMessageBox::critical(dialog_parent, TemplateTrack::tr("Error"), + TemplateTrack::tr("The OSM file has version %1.\nThe maximum supported version is %2.").arg( + attributes.value(QLatin1String("version")).toString(), QString::number(max_supported_version, 'g', 1))); + return false; + } + } + } + + qint64 internal_node_id = 0; + while (xml.readNextStartElement()) + { + const QStringRef name(xml.name()); + QXmlStreamAttributes attributes(xml.attributes()); + if (attributes.value(QLatin1String("visible")) == QLatin1String("false")) + { + xml.skipCurrentElement(); + continue; + } + + QString id(attributes.value(QLatin1String("id")).toString()); + if (id.isEmpty()) + { + id = QLatin1Char('!') + QString::number(++internal_node_id); + } + + if (name == QLatin1String("node")) + { + bool ok = true; + double lat = 0.0, lon = 0.0; + if (ok) lat = attributes.value(QLatin1String("lat")).toDouble(&ok); + if (ok) lon = attributes.value(QLatin1String("lon")).toDouble(&ok); + if (!ok) + { + node_problems++; + xml.skipCurrentElement(); + continue; + } + + TrackPoint point(LatLon(lat, lon)); + if (project_points) + { + point.map_coord = map_georef.toMapCoordF(point.gps_coord); // TODO: check for errors + } + nodes.insert(id, point); + + while (xml.readNextStartElement()) + { + if (xml.name() == QLatin1String("tag")) + { + const QString k(xml.attributes().value(QLatin1String("k")).toString()); + const QString v(xml.attributes().value(QLatin1String("v")).toString()); + element_tags[id][k] = v; + + if (k == QLatin1String("ele")) + { + bool ok; + double elevation = v.toDouble(&ok); + if (ok) nodes[id].elevation = elevation; + } + else if (k == QLatin1String("name")) + { + if (!v.isEmpty() && !nodes.contains(v)) + { + waypoints.push_back(point); + waypoint_names.push_back(v); + } + } + } + xml.skipCurrentElement(); + } + } + else if (name == QLatin1String("way")) + { + segment_starts.push_back(segment_points.size()); + segment_names.push_back(id); + while (xml.readNextStartElement()) + { + if (xml.name() == QLatin1String("nd")) + { + QString ref = xml.attributes().value(QLatin1String("ref")).toString(); + if (ref.isEmpty() || !nodes.contains(ref)) + node_problems++; + else + segment_points.push_back(nodes[ref]); + } + else if (xml.name() == QLatin1String("tag")) + { + const QString k(xml.attributes().value(QLatin1String("k")).toString()); + const QString v(xml.attributes().value(QLatin1String("v")).toString()); + element_tags[id][k] = v; + } + xml.skipCurrentElement(); + } + } + else + { + xml.skipCurrentElement(); + } + } + + if (node_problems > 0) + QMessageBox::warning(dialog_parent, TemplateTrack::tr("Problems"), TemplateTrack::tr("%1 nodes could not be processed correctly.").arg(node_problems)); + + return true; +} + +void Track::projectPoints() +{ + if (track_crs->getProjectedCRSSpec() == geographic_crs_spec) + { + int size = waypoints.size(); + for (int i = 0; i < size; ++i) + waypoints[i].map_coord = map_georef.toMapCoordF(waypoints[i].gps_coord, NULL); // FIXME: check for errors + + size = segment_points.size(); + for (int i = 0; i < size; ++i) + segment_points[i].map_coord = map_georef.toMapCoordF(segment_points[i].gps_coord, NULL); // FIXME: check for errors + } + else + { + int size = waypoints.size(); + for (int i = 0; i < size; ++i) + waypoints[i].map_coord = map_georef.toMapCoordF(track_crs, fakeMapCoordF(waypoints[i].gps_coord), NULL); // FIXME: check for errors + + size = segment_points.size(); + for (int i = 0; i < size; ++i) + segment_points[i].map_coord = map_georef.toMapCoordF(track_crs, fakeMapCoordF(segment_points[i].gps_coord), NULL); // FIXME: check for errors + } +} diff --git a/src/gps_track.h b/src/gps_track.h new file mode 100644 index 0000000..51f9bd5 --- /dev/null +++ b/src/gps_track.h @@ -0,0 +1,178 @@ +/* + * Copyright 2012, 2013 Thomas Schöps + * + * This file is part of OpenOrienteering. + * + * OpenOrienteering is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenOrienteering is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenOrienteering. If not, see . + */ + + +#ifndef _OPENORIENTEERING_GPS_TRACK_H_ +#define _OPENORIENTEERING_GPS_TRACK_H_ + +#include + +#include +#include +#include + +#include "core/georeferencing.h" + +QT_BEGIN_NAMESPACE +class QFile; +class QXmlStreamWriter; +QT_END_NAMESPACE + +class MapEditorController; + +/** + * A point in a track or a waypoint, which stores position on ellipsoid and + * map and more attributes (e.g. number of satellites) + */ +struct TrackPoint +{ + LatLon gps_coord; + MapCoordF map_coord; + bool is_curve_start; + + QDateTime datetime; // QDateTime() if invalid + float elevation; // -9999 if invalid + int num_satellites; // -1 if invalid + float hDOP; // -1 if invalid + + TrackPoint(LatLon coord = LatLon(), QDateTime datetime = QDateTime(), + float elevation = -9999, int num_satellites = -1, float hDOP = -1); + void save(QXmlStreamWriter* stream) const; +}; + +/** + * Stores a set of tracks and / or waypoints, e.g. taken from a GPS device. + * Can optionally store a track coordinate reference system in track_georef; + * if no track CRS is given, assumes that coordinates are geographic WGS84 coordinates + */ +class Track +{ +public: + /// Constructs an empty track + Track(); + Track(const Georeferencing& map_georef); + /// Duplicates a track + Track(const Track& other); + + ~Track(); + + /// Deletes all data of the track, except the projection parameters + void clear(); + + /// Attempts to load the track from the given file. + /// If you choose not to project_point, you have to call changeProjectionParams() afterwards. + bool loadFrom(const QString& path, bool project_points, QWidget* dialog_parent = NULL); + /// Attempts to save the track to the given file + bool saveTo(const QString& path) const; + + // Modifiers + + /** + * @brief Appends the point and updates the point's map coordinates. + * + * The point's map coordinates are determined from its geographic coodinates + * according to the map's georeferencing. + */ + void appendTrackPoint(TrackPoint& point); + + /** + * Marks the current track segment as finished, so the next added point + * will define the start of a new track segment. + */ + void finishCurrentSegment(); + + /** + * @brief Appends the waypoint and updates the point's map coordinates. + * + * The point's map coordinates are determined from its geographic coodinates + * according to the map's georeferencing. + */ + void appendWaypoint(TrackPoint& point, const QString& name); + + /** Updates the map positions of all points based on the new georeferencing. */ + void changeMapGeoreferencing(const Georeferencing& new_georef); + + /// Sets the track coordinate reference system. + /// The Track object takes ownership of the Georeferencing object. + void setTrackCRS(Georeferencing* track_crs); + + // Getters + int getNumSegments() const; + int getSegmentPointCount(int segment_number) const; + const TrackPoint& getSegmentPoint(int segment_number, int point_number) const; + const QString& getSegmentName(int segment_number) const; + + int getNumWaypoints() const; + const TrackPoint& getWaypoint(int number) const; + const QString& getWaypointName(int number) const; + + bool hasTrackCRS() const {return track_crs != NULL;} + Georeferencing* getTrackCRS() const {return track_crs;} + + /// Averages all track coordinates + LatLon calcAveragePosition() const; + + /** A collection of key:value tags. Cf. Object::Tags. */ + typedef QHash Tags; + + /** A mapping of an element name to a tags collection. */ + typedef QHash ElementTags; + + /** Returns the mapping of element names to tag collections. */ + const ElementTags& tags() const; + + /** Assigns a copy of another Track's data to this object. */ + Track& operator=(const Track& rhs); + +private: + bool loadFromGPX(QFile* file, bool project_points, QWidget* dialog_parent); + bool loadFromDXF(QFile* file, bool project_points, QWidget* dialog_parent); + bool loadFromOSM(QFile* file, bool project_points, QWidget* dialog_parent); + + void projectPoints(); + + + /** A mapping of element id to tags. */ + ElementTags element_tags; + + std::vector waypoints; + std::vector waypoint_names; + + std::vector segment_points; + // The indices of the first points of every track segment in this track + std::vector segment_starts; + std::vector segment_names; + + bool current_segment_finished; + + Georeferencing* track_crs; + Georeferencing map_georef; +}; + + +// ### Track inline code ### + +inline +const Track::ElementTags& Track::tags() const +{ + return element_tags; +} + + +#endif diff --git a/src/gps_track_recorder.cpp b/src/gps_track_recorder.cpp new file mode 100644 index 0000000..918c22a --- /dev/null +++ b/src/gps_track_recorder.cpp @@ -0,0 +1,101 @@ +/* + * Copyright 2014 Thomas Schöps + * + * This file is part of OpenOrienteering. + * + * OpenOrienteering is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenOrienteering is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenOrienteering. If not, see . + */ + + +#include "gps_track_recorder.h" + +#include "gps_display.h" +#include "template_track.h" +#include "map.h" +#include "map_widget.h" + + +GPSTrackRecorder::GPSTrackRecorder(GPSDisplay* gps_display, TemplateTrack* target_template, int draw_update_interval_milliseconds, MapWidget* widget) + : QObject() +{ + this->gps_display = gps_display; + this->target_template = target_template; + this->widget = widget; + + track_changed_since_last_update = false; + is_active = true; + + // Start with a new segment + target_template->getTrack().finishCurrentSegment(); + + connect(gps_display, SIGNAL(latLonUpdated(double,double,double,float)), this, SLOT(newPosition(double,double,double,float))); + connect(gps_display, SIGNAL(positionUpdatesInterrupted()), this, SLOT(positionUpdatesInterrupted())); + connect(target_template->getMap(), SIGNAL(templateDeleted(int, const Template*)), this, SLOT(templateDeleted(int, const Template*))); + + if (draw_update_interval_milliseconds > 0) + { + connect(&draw_update_timer, SIGNAL(timeout()), this, SLOT(drawUpdate())); + draw_update_timer.start(draw_update_interval_milliseconds); + } +} + +void GPSTrackRecorder::newPosition(double latitude, double longitude, double altitude, float accuracy) +{ + TrackPoint new_point( + LatLon(latitude, longitude), + QDateTime::currentDateTime(), + altitude, + -1, + accuracy + ); + target_template->getTrack().appendTrackPoint(new_point); + target_template->setHasUnsavedChanges(true); + track_changed_since_last_update = true; +} + +void GPSTrackRecorder::positionUpdatesInterrupted() +{ + target_template->getTrack().finishCurrentSegment(); + target_template->setHasUnsavedChanges(true); + track_changed_since_last_update = true; +} + +void GPSTrackRecorder::templateDeleted(int pos, const Template* old_temp) +{ + Q_UNUSED(pos); + if (!is_active) + return; + + if (old_temp == target_template) + { + // Deactivate + gps_display->disconnect(this); + draw_update_timer.stop(); + is_active = false; + } +} + +void GPSTrackRecorder::drawUpdate() +{ + if (!is_active) + return; + + if (track_changed_since_last_update) + { + if (widget->getMapView()->isTemplateVisible(target_template)) + target_template->setTemplateAreaDirty(); + + track_changed_since_last_update = false; + } +} diff --git a/src/gps_track_recorder.h b/src/gps_track_recorder.h new file mode 100644 index 0000000..ad958c5 --- /dev/null +++ b/src/gps_track_recorder.h @@ -0,0 +1,55 @@ +/* + * Copyright 2014 Thomas Schöps + * + * This file is part of OpenOrienteering. + * + * OpenOrienteering is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenOrienteering is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenOrienteering. If not, see . + */ + + +#ifndef _OPENORIENTEERING_GPS_TRACK_RECORDER_H_ +#define _OPENORIENTEERING_GPS_TRACK_RECORDER_H_ + +#include +#include + +class MapWidget; +class Template; +class TemplateTrack; +class GPSDisplay; + + +/** Records GPS tracks into a TemplateTrack. */ +class GPSTrackRecorder : public QObject +{ +Q_OBJECT +public: + GPSTrackRecorder(GPSDisplay* gps_display, TemplateTrack* target_template, int draw_update_interval_milliseconds = -1, MapWidget* widget = NULL); + +public slots: + void newPosition(double latitude, double longitude, double altitude, float accuracy); + void positionUpdatesInterrupted(); + void templateDeleted(int pos, const Template* old_temp); + void drawUpdate(); + +private: + GPSDisplay* gps_display; + TemplateTrack* target_template; + MapWidget* widget; + QTimer draw_update_timer; + bool track_changed_since_last_update; + bool is_active; +}; + +#endif diff --git a/src/gui/about_dialog.cpp b/src/gui/about_dialog.cpp new file mode 100644 index 0000000..7288598 --- /dev/null +++ b/src/gui/about_dialog.cpp @@ -0,0 +1,184 @@ +/* + * Copyright 2012, 2013, 2014 Thomas Schöps + * Copyright 2012-2015 Kai Pastor + * + * This file is part of OpenOrienteering. + * + * OpenOrienteering is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenOrienteering is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenOrienteering. If not, see . + */ + +#include "about_dialog.h" + +#include + +#include +#include + +#include + + +/** + * @brief An URL identifying the main "about" page. + * + * The main page's text will be set directly, thus not having a valid URL. + * But an empty URL will be ignored by QTextBrowser's history, leading to + * unexpected behaviour of backward navigation. + */ +const QUrl about_page_url = QUrl(QString::fromLatin1("#ABOUT")); + +/** + * Puts the items of a QStringList into an HTML block or a sequence of blocks. + */ +static QString formatBlock(const QStringList& items) +{ +#if defined(Q_OS_ANDROID) // or any other small-screen device + QString block = QLatin1String("

") + + items.join(QString::fromLatin1(", ")) + + QLatin1String("

"); +#else + QString block; + block.reserve(100 + 30 * items.size()); + block.append(QLatin1String("
")); + constexpr int columns = 3; + const int rows = (int)ceil((double)items.size() / columns); + for (int i = 0, row = 1; i < items.size(); ++i) + { + block.append(items[i]); + if (rows != row) + { + block.append(QString::fromLatin1("
")); + ++row; + } + else if (i < items.size()) + { + block.append(QString::fromLatin1("
   ")); + row = 1; + } + } + block.append(QString::fromLatin1("
")); +#endif + return block; +} + + +AboutDialog::AboutDialog(QWidget* parent) + : TextBrowserDialog(about_page_url, parent) +{ + text_browser->setSearchPaths(text_browser->searchPaths() << QString::fromLatin1(":/doc/licensing/html/")); + text_browser->setHtml(about()); + text_browser->document()->adjustSize(); + updateWindowTitle(); +} + +void AboutDialog::sourceChanged(const QUrl& url) +{ + if (url == about_page_url) + text_browser->setHtml(about()); +} + +void AboutDialog::updateWindowTitle() +{ + QString title = text_browser->documentTitle(); + if (title.isEmpty()) + title = tr("About %1").arg(APP_NAME); + setWindowTitle(title); +} + +QString AboutDialog::about() +{ + static QStringList developers_list( QStringList() + << QString::fromLatin1("Peter Curtis (2012-2013)") + << QString::fromLatin1("Kai Pastor") + << QString::fromUtf8("Thomas Schöps (2012-2014, %1)") + ); + + static QStringList contributors_list( QStringList() + << QString::fromLatin1("Arrizal Amin") + << QString::fromLatin1("Javier Arufe") + << QString::fromLatin1("Eric Boulet") + << QString::fromLatin1("Jon Cundill") + << QString::fromUtf8("Sławomir Cygler") + << QString::fromLatin1("Jan Dalheimer") + << QString::fromLatin1("Davide De Nardis") + << QString::fromLatin1("Eugeniy Fedirets") + << QString::fromLatin1("Joao Franco") + << QString::fromLatin1("Pavel Fric") + << QString::fromLatin1("Naofumi Fukue") + << QString::fromLatin1("Anders Gressli") + << QString::fromLatin1("Peter Hoban") + << QString::fromLatin1("Henrik Johansson") + << QString::fromLatin1("Panu Karhu") + << QString::fromLatin1("Oskar Karlin") + << QString::fromLatin1("Nikolay Korotkiy") + << QString::fromLatin1("Mitchell Krome") + << QString::fromUtf8("Matthias Kühlewein") + << QString::fromLatin1("Albin Larsson") + << QString::fromUtf8("István Marczis") + << QString::fromLatin1("Tojo Masaya") + << QString::fromLatin1("Yevhen Mazur") + << QString::fromLatin1("Fraser Mills") + << QString::fromLatin1("Vincent Poinsignon") + << QString::fromLatin1("Russell Porter") + << QString::fromLatin1("Adhika Setya Pramudita") + << QString::fromLatin1("Christopher Schive") + << QString::fromLatin1("Arif Suryawan") + << QString::fromLatin1("Jan-Gerard van der Toorn") + << QString::fromLatin1("Semyon Yakimov") + << QString::fromLatin1("Aivars Zogla") + ); + + QString mapper_about = QString::fromLatin1( + "" + "%0" + "" + "" + "" + "" + "
" + "

%1

" + "

" + "%3
" + "%4

" + "

Copyright (C) 2016 The OpenOrienteering developers

" + "

%5

" + "

%6

" + "

%7

" + "

%8

%9" + "

 
%10

%11" + "" + ).arg( + tr("About %1").arg(APP_NAME), // %0 + qApp->applicationDisplayName(), // %1 + tr("A free software for drawing orienteering maps"), // %3 + QString::fromLatin1("http://openorienteering.org/apps/mapper/"), // %4 + tr("This program is free software: you can redistribute it " + "and/or modify it under the terms of the " + "GNU General Public License (GPL), version 3, " + "as published by the Free Software Foundation.").arg(QString::fromLatin1("href=\"gpl-3-0.html\"")), // %5 + // %6 + tr("This program is distributed in the hope that it will be useful, " + "but WITHOUT ANY WARRANTY; without even the implied warranty of " + "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the " + "GNU General Public License (GPL), version 3, for " + "more details.").arg(QString::fromLatin1("href=\"gpl-3-0.html#15-disclaimer-of-warranty\"")), // %6 + tr("All about licenses, copyright notices, conditions and disclaimers.").arg(QString::fromLatin1("href=\"licensing.html\"")) // %7 + ).arg( + tr("The OpenOrienteering developers in alphabetical order:"), // %8 + formatBlock(developers_list).arg(tr("(project initiator)").replace(QLatin1Char('('), QString{}).replace(QLatin1Char(')'), QString{})), // %9 + tr("For contributions, thanks to:"), // %10 + formatBlock(contributors_list) // %11 + ); + + return mapper_about; +} diff --git a/src/gui/about_dialog.h b/src/gui/about_dialog.h new file mode 100644 index 0000000..de2bd26 --- /dev/null +++ b/src/gui/about_dialog.h @@ -0,0 +1,56 @@ +/* + * Copyright 2012, 2013, 2014 Thomas Schöps + * Copyright 2012-2015 Kai Pastor + * + * This file is part of OpenOrienteering. + * + * OpenOrienteering is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenOrienteering is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenOrienteering. If not, see . + */ + +#ifndef _OPENORIENTEERING_ABOUT_DIALOG_H_ +#define _OPENORIENTEERING_ABOUT_DIALOG_H_ + +#include "text_browser_dialog.h" + +/** + * @brief A dialog which shows information about Mapper and its components. + */ +class AboutDialog : public TextBrowserDialog +{ +Q_OBJECT +public: + /** + * @brief Construct a new AboutDialog. + */ + AboutDialog(QWidget* parent = nullptr); + + /** + * @brief Returns the basic information about this software. + * The return string may contain HTML formatting. + */ + static QString about(); + +protected: + /** + * @brief Sets custom HTML content when the URL identifies the first page. + */ + virtual void sourceChanged(const QUrl& url) override; + + /** + * @brief Updates the window title from the current document title. + */ + void updateWindowTitle() override; +}; + +#endif diff --git a/src/gui/autosave_dialog.cpp b/src/gui/autosave_dialog.cpp new file mode 100644 index 0000000..5cf8247 --- /dev/null +++ b/src/gui/autosave_dialog.cpp @@ -0,0 +1,192 @@ +/* + * Copyright 2014 Kai Pastor + * + * This file is part of OpenOrienteering. + * + * OpenOrienteering is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenOrienteering is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenOrienteering. If not, see . + */ + +#include "autosave_dialog.h" + +#include +#include +#include +#include +#include +#include +#include + +#include "main_window.h" + +AutosaveDialog::AutosaveDialog(QString path, QString autosave_path, QString actual_path, MainWindow* parent, Qt::WindowFlags f) +: QDialog(parent, f) +, main_window(parent) +, original_path(path) +, autosave_path(autosave_path) +, resolved(false) +{ + const QString text_template = QString::fromLatin1("%1
%2
%3"); + + QFileInfo autosaved_file_info(autosave_path); + autosaved_text.setHtml(text_template. + arg(tr("Autosaved file")). + arg(autosaved_file_info.lastModified().toLocalTime().toString()). + arg(tr("%n bytes", 0, autosaved_file_info.size()))); + + QFileInfo user_saved_file_info(path); + user_saved_text.setHtml(text_template. + arg(tr("File saved by the user")). + arg(user_saved_file_info.lastModified().toLocalTime().toString()). + arg(tr("%n bytes", 0, user_saved_file_info.size()))); + + layout = new QVBoxLayout(); + setLayout(layout); + + setWindowTitle(tr("File recovery")); + + QString intro_text = tr("File %1 was not properly closed. At the moment, there are two versions:"); + QLabel* label = new QLabel(intro_text.arg(QString::fromLatin1("%1").arg(user_saved_file_info.fileName()))); + label->setWordWrap(true); + layout->addWidget(label); + + list_widget = new QListWidget(); + list_widget->setItemDelegate(new TextDocItemDelegate(this, this)); + list_widget->setSelectionMode(QAbstractItemView::SingleSelection); + QListWidgetItem* item = new QListWidgetItem(list_widget, QListWidgetItem::UserType); + item->setData(Qt::UserRole, QVariant(1)); + item = new QListWidgetItem(list_widget, QListWidgetItem::UserType); + item->setData(Qt::UserRole, QVariant(2)); + layout->addWidget(list_widget); + + label = new QLabel(tr("Save the active file to remove the conflicting version.")); + label->setWordWrap(true); + layout->addWidget(label); + + setSelectedPath(actual_path); + + connect(list_widget, SIGNAL(currentRowChanged(int)), this, SLOT(currentRowChanged(int)), Qt::QueuedConnection); + +#if defined(Q_OS_ANDROID) + setWindowState((windowState() & ~(Qt::WindowMinimized | Qt::WindowFullScreen)) + | Qt::WindowMaximized); +#endif +} + +AutosaveDialog::~AutosaveDialog() +{ + // Nothing +} + +// slot +int AutosaveDialog::exec() +{ + QDialogButtonBox button_box(QDialogButtonBox::Open | QDialogButtonBox::Cancel); + layout->addWidget(&button_box); + connect(&button_box, SIGNAL(accepted()), this, SLOT(accept())); + connect(&button_box, SIGNAL(rejected()), this, SLOT(reject())); + const int result = QDialog::exec(); + resolved = true; + return result; +} + +// slot +void AutosaveDialog::autosaveConflictResolved() +{ + resolved = true; + if (!isModal()) + close(); +} + +void AutosaveDialog::closeEvent(QCloseEvent *event) +{ + if (main_window && !resolved) + event->setAccepted(main_window->closeFile()); + else + event->setAccepted(resolved); +} + +QString AutosaveDialog::selectedPath() const +{ + const int row = list_widget->currentRow(); + switch (row) + { + case 0: + return autosave_path; + break; + case 1: + return original_path; + break; + case -1: + break; // Nothing selected? + default: + Q_ASSERT(false && "Undefined index"); + } + return QString(); +} + +// slot +void AutosaveDialog::setSelectedPath(QString path) +{ + if (path == original_path) + list_widget->setCurrentRow(1); + else if (path == autosave_path) + list_widget->setCurrentRow(0); + else + list_widget->setCurrentRow(-1); +} + +void AutosaveDialog::currentRowChanged(int row) +{ + switch (row) + { + case 0: + emit pathSelected(autosave_path); + break; + case 1: + emit pathSelected(original_path); + break; + case -1: + return; // Nothing selected? + default: + Q_ASSERT(false && "Undefined index"); + } +} + +const QTextDocument* AutosaveDialog::textDoc(const QModelIndex& index) const +{ + const QTextDocument* ret = NULL; + + bool ok = true; + int i = index.data(Qt::UserRole).toInt(&ok); + if (ok) + { + switch (i) + { + case 1: + ret = &autosaved_text; + break; + case 2: + ret = &user_saved_text; + break; + default: + Q_ASSERT(false && "Undefined index"); + } + } + else + { + Q_ASSERT(false && "Invalid data for UserRole"); + } + + return ret; +} diff --git a/src/gui/autosave_dialog.h b/src/gui/autosave_dialog.h new file mode 100644 index 0000000..5d44e51 --- /dev/null +++ b/src/gui/autosave_dialog.h @@ -0,0 +1,131 @@ +/* + * Copyright 2014 Kai Pastor + * + * This file is part of OpenOrienteering. + * + * OpenOrienteering is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenOrienteering is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenOrienteering. If not, see . + */ + + +#ifndef _OPENORIENTEERING_AUTOSAVE_DIALOG_H_ +#define _OPENORIENTEERING_AUTOSAVE_DIALOG_H_ + +#include +#include + +#include "../util/item_delegates.h" + +class QBoxLayout; +class QListWidget; + +class MainWindow; + + +/** + * @brief A dialog for selection of an autosaved file vs. a user-saved file. + * + * This dialog may be used a modal dialog (via exec()) or as a non-modal dialog + * (via show()). + */ +class AutosaveDialog : public QDialog, public TextDocItemDelegate::Provider +{ +Q_OBJECT +public: + /** + * @brief Constructs the dialog. + * + * @param original_path The path of the file which was originally saved by the user. + * @param autosave_path The path of the file which was autosaved. + * @param actual_path The path which is currently selected. + * @param parent The parent window. + */ + AutosaveDialog(QString original_path, QString autosave_path, QString actual_path, MainWindow* parent = NULL, Qt::WindowFlags f = 0); + + /** + * Destructor. + */ + virtual ~AutosaveDialog(); + + /** + * @brief Returns the currently selected path. + */ + QString selectedPath() const; + + /** + * @brief Provides the text documents for the list widget items. + * + * @param index The model index for which the text documents is requested for. + * @return A QTextDocument representing the list item, or NULL. + */ + const QTextDocument* textDoc(const QModelIndex& index) const; + +public slots: + /** + * @brief Shows this dialog as a modal dialog. + * + * @override + * + * @return The result (QDialog::DialogCode). + */ + virtual int exec(); + + /** + * @brief Sets the selected item to the one representing the given path. + * + * If the path does not match either item, nothing is selected. + */ + void setSelectedPath(QString path); + + /** + * @brief Informs the dialog that the conflict is resolved. + * + * This will close a non-modal dialog. + */ + void autosaveConflictResolved(); + +signals: + /** + * @brief This signal is emitted when the user selects another item. + * + * @param path The path which belongs to the newly selected item. + */ + void pathSelected(QString path); + +protected: + /** + * @brief Ignores the QCloseEvent. + * + * @override + */ + virtual void closeEvent(QCloseEvent* event); + +private slots: + void currentRowChanged(int row); + +private: + MainWindow* const main_window; + + const QString original_path; + const QString autosave_path; + + bool resolved; + + QTextDocument autosaved_text; + QTextDocument user_saved_text; + + QBoxLayout* layout; + QListWidget* list_widget; +}; + +#endif // _OPENORIENTEERING_AUTOSAVE_DIALOG_H_ diff --git a/src/gui/color_dialog.cpp b/src/gui/color_dialog.cpp new file mode 100644 index 0000000..68238a7 --- /dev/null +++ b/src/gui/color_dialog.cpp @@ -0,0 +1,636 @@ +/* + * Copyright 2012, 2013, 2014 Kai Pastor + * + * This file is part of OpenOrienteering. + * + * OpenOrienteering is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenOrienteering is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenOrienteering. If not, see . + */ + + +#include "color_dialog.h" + +#include +#include +#include +#include +#include +#include +#include + +#include "../core/map_color.h" +#include "../map.h" +#include "../util.h" +#include "../util_gui.h" +#include "widgets/color_dropdown.h" + +ColorDialog::ColorDialog(const Map& map, const MapColor& source_color, QWidget* parent, Qt::WindowFlags f) +: QDialog(parent, f), + map(map), + source_color(source_color), + color(source_color), + color_modified(false), + react_to_changes(true) +{ + setWindowTitle(tr("Edit map color")); + setSizeGripEnabled(true); + + color_preview_label = new QLabel(); + mc_name_edit = new QLineEdit(); + + prof_color_layout = new QGridLayout(); + int col = 0; + prof_color_layout->setColumnStretch(col, 1); + prof_color_layout->setColumnStretch(col+1, 3); + + int row = 0; + prof_color_layout->addWidget(Util::Headline::create("Spot color printing"), row, col, 1, 2); + + QButtonGroup* spot_color_options = new QButtonGroup(this); + + ++row; + full_tone_option = new QRadioButton(tr("Defines a spot color:")); + spot_color_options->addButton(full_tone_option, MapColor::SpotColor); + prof_color_layout->addWidget(full_tone_option, row, col, 1, 2); + + ++row; + sc_name_edit = new QLineEdit(); + prof_color_layout->addWidget(sc_name_edit, row, col, 1, 2); + + ++row; + composition_option = new QRadioButton(tr("Mixture of spot colors (screens and overprint):")); + spot_color_options->addButton(composition_option, MapColor::CustomColor); + prof_color_layout->addWidget(composition_option, row, col, 1, 2); + + int num_components = 0 /*color.getComponents().size()*/; // FIXME: cleanup + components_row0 = row+1; + components_col0 = col; + component_colors.resize(num_components+1); + component_halftone.resize(num_components+1); + for (int i = 0; i <= num_components; i++) + { + ++row; + component_colors[i] = new ColorDropDown(&map, &color, true); + component_colors[i]->removeColor(&source_color); + prof_color_layout->addWidget(component_colors[i], row, col); + component_halftone[i] = Util::SpinBox::create(1, 0.0, 100.0, tr("%"), 10.0); + prof_color_layout->addWidget(component_halftone[i], row, col+1); + } + + ++row; + knockout_option = new QCheckBox(tr("Knockout: erases lower colors")); + prof_color_layout->addWidget(knockout_option, row, col, 1, 2); + knockout_option->setEnabled(false); + + row = 0, col += 2; + prof_color_layout->setColumnStretch(col, 1); + + const int spacing = style()->pixelMetric(QStyle::PM_LayoutTopMargin); + prof_color_layout->addItem(new QSpacerItem(3*spacing, spacing), row, col, 7, 1); + + row = 0, col +=1; + prof_color_layout->setColumnStretch(col, 1); + prof_color_layout->setColumnStretch(col+1, 3); + prof_color_layout->addWidget(Util::Headline::create("CMYK"), row, col, 1, 2); + + QButtonGroup* cmyk_color_options = new QButtonGroup(this); + + ++row; + cmyk_spot_color_option = new QRadioButton(tr("Calculate from spot colors")); + cmyk_color_options->addButton(cmyk_spot_color_option, MapColor::SpotColor); + prof_color_layout->addWidget(cmyk_spot_color_option, row, col, 1, 2); + + ++row; + evaluate_rgb_option = new QRadioButton(tr("Calculate from RGB color")); + cmyk_color_options->addButton(evaluate_rgb_option, MapColor::RgbColor); + prof_color_layout->addWidget(evaluate_rgb_option, row, col, 1, 2); + + ++row; + custom_cmyk_option = new QRadioButton(tr("Custom process color:")); + cmyk_color_options->addButton(custom_cmyk_option, MapColor::CustomColor); + prof_color_layout->addWidget(custom_cmyk_option, row, col, 1, 2); + + ++row; + c_edit = Util::SpinBox::create(1, 0.0, 100.0, tr("%"), 10.0); + prof_color_layout->addWidget(new QLabel(tr("Cyan")), row, col); + prof_color_layout->addWidget(c_edit, row, col+1); + + ++row; + m_edit = Util::SpinBox::create(1, 0.0, 100.0, tr("%"), 10.0); + prof_color_layout->addWidget(new QLabel(tr("Magenta")), row, col); + prof_color_layout->addWidget(m_edit, row, col+1); + + ++row; + y_edit = Util::SpinBox::create(1, 0.0, 100.0, tr("%"), 10.0); + prof_color_layout->addWidget(new QLabel(tr("Yellow")), row, col); + prof_color_layout->addWidget(y_edit, row, col+1); + + ++row; + k_edit = Util::SpinBox::create(1, 0.0, 100.0, tr("%"), 10.0); + prof_color_layout->addWidget(new QLabel(tr("Black")), row, col); + prof_color_layout->addWidget(k_edit, row, col+1); + + ++row; + stretch_row0 = row; + stretch_col0 = col; + stretch = new QWidget(); + prof_color_layout->addWidget(stretch, row, col); + prof_color_layout->setRowStretch(row, 1); + + QWidget* prof_color_widget = new QWidget(); + prof_color_widget->setLayout(prof_color_layout); + prof_color_widget->setObjectName(QString::fromLatin1("professional")); + + + QGridLayout* desktop_layout = new QGridLayout(); + col = 0; + desktop_layout->setColumnStretch(col, 1); + desktop_layout->setColumnStretch(col+1, 3); + + row = 0; + desktop_layout->addWidget(Util::Headline::create("RGB"), row, col, 1, 2); + + QButtonGroup* rgb_color_options = new QButtonGroup(this); + + ++row; + rgb_spot_color_option = new QRadioButton(tr("Calculate from spot colors")); + rgb_color_options->addButton(rgb_spot_color_option, MapColor::SpotColor); + desktop_layout->addWidget(rgb_spot_color_option, row, col, 1, 2); + + ++row; + evaluate_cmyk_option = new QRadioButton(tr("Calculate from CMYK color")); + rgb_color_options->addButton(evaluate_cmyk_option, MapColor::CmykColor); + desktop_layout->addWidget(evaluate_cmyk_option, row, col, 1, 2); + + ++row; + custom_rgb_option = new QRadioButton(tr("Custom RGB color:")); + rgb_color_options->addButton(custom_rgb_option, MapColor::CustomColor); + desktop_layout->addWidget(custom_rgb_option, row, col, 1, 2); + + ++row; + r_edit = Util::SpinBox::create(1, 0.0, 255.0, {}, 5); + desktop_layout->addWidget(new QLabel(tr("Red")), row, col); + desktop_layout->addWidget(r_edit, row, col+1); + + ++row; + g_edit = Util::SpinBox::create(1, 0.0, 255.0, {}, 5); + desktop_layout->addWidget(new QLabel(tr("Green")), row, col); + desktop_layout->addWidget(g_edit, row, col+1); + + ++row; + b_edit = Util::SpinBox::create(1, 0.0, 255.0, {}, 5); + desktop_layout->addWidget(new QLabel(tr("Blue")), row, col); + desktop_layout->addWidget(b_edit, row, col+1); + + ++row; + html_edit = new QLineEdit(); + desktop_layout->addWidget(new QLabel(tr("#RRGGBB")), row, col); + desktop_layout->addWidget(html_edit, row, col+1); + + ++row; + desktop_layout->addWidget(new QWidget(), row, col); + desktop_layout->setRowStretch(row, 1); + + row = 0, col += 2; + desktop_layout->setColumnStretch(col, 7); + + desktop_layout->addItem(new QSpacerItem(3*spacing, spacing), row, col, 7, 1); + + QWidget* desktop_color_widget = new QWidget(); + desktop_color_widget->setLayout(desktop_layout); + desktop_color_widget->setObjectName(QString::fromLatin1("desktop")); + + + properties_widget = new QTabWidget(); + properties_widget->addTab(desktop_color_widget, tr("Desktop")); + properties_widget->addTab(prof_color_widget, tr("Professional printing")); + + QDialogButtonBox* button_box = new QDialogButtonBox(QDialogButtonBox::Cancel | QDialogButtonBox::Ok | QDialogButtonBox::Reset | QDialogButtonBox::Help); + ok_button = button_box->button(QDialogButtonBox::Ok); + reset_button = button_box->button(QDialogButtonBox::Reset); + connect(button_box, SIGNAL(rejected()), this, SLOT(reject())); + connect(button_box, SIGNAL(accepted()), this, SLOT(accept())); + connect(reset_button, SIGNAL(clicked(bool)), this, SLOT(reset())); + connect(button_box->button(QDialogButtonBox::Help), SIGNAL(clicked(bool)), this, SLOT(showHelp())); + + QGridLayout* layout = new QGridLayout(); + layout->addWidget(color_preview_label, 0, 0); + layout->addWidget(mc_name_edit, 0, 1); + layout->addWidget(properties_widget, 1, 0, 1, 2); + layout->addWidget(button_box, 2, 0, 1, 2); + layout->setColumnStretch(1, 1); + setLayout(layout); + + updateWidgets(); + updateButtons(); + + connect(mc_name_edit, SIGNAL(textChanged(QString)), this, SLOT(mapColorNameChanged())); + + connect(spot_color_options, SIGNAL(buttonClicked(int)), this, SLOT(spotColorTypeChanged(int))); + connect(sc_name_edit, SIGNAL(textChanged(QString)), this, SLOT(spotColorNameChanged())); + for (int i = 0; i < (int)component_colors.size(); i++) + { + connect(component_colors[i], SIGNAL(currentIndexChanged(int)), this, SLOT(spotColorCompositionChanged())); + connect(component_halftone[i], SIGNAL(valueChanged(double)), this, SLOT(spotColorCompositionChanged())); + } + connect(knockout_option, SIGNAL(clicked(bool)), this, SLOT(knockoutChanged())); + + connect(cmyk_color_options, SIGNAL(buttonClicked(int)), this, SLOT(cmykColorTypeChanged(int))); + connect(c_edit, SIGNAL(valueChanged(double)), this, SLOT(cmykValueChanged())); + connect(m_edit, SIGNAL(valueChanged(double)), this, SLOT(cmykValueChanged())); + connect(y_edit, SIGNAL(valueChanged(double)), this, SLOT(cmykValueChanged())); + connect(k_edit, SIGNAL(valueChanged(double)), this, SLOT(cmykValueChanged())); + + connect(rgb_color_options, SIGNAL(buttonClicked(int)), this, SLOT(rgbColorTypeChanged(int))); + connect(r_edit, SIGNAL(valueChanged(double)), this, SLOT(rgbValueChanged())); + connect(g_edit, SIGNAL(valueChanged(double)), this, SLOT(rgbValueChanged())); + connect(b_edit, SIGNAL(valueChanged(double)), this, SLOT(rgbValueChanged())); + + QSettings settings; + settings.beginGroup(QString::fromLatin1("ColorDialog")); + QString default_view = settings.value(QString::fromLatin1("view")).toString(); + settings.endGroup(); + properties_widget->setCurrentWidget(properties_widget->findChild(default_view)); +} + +void ColorDialog::updateWidgets() +{ + react_to_changes = false; + + QPixmap pixmap(icon_size, icon_size); + pixmap.fill(colorWithOpacity(color)); + color_preview_label->setPixmap(pixmap); + + mc_name_edit->setText(color.getName()); + + sc_name_edit->setText(color.getSpotColorName()); + + const MapColorCmyk& cmyk = color.getCmyk(); + c_edit->setValue(100.0 * cmyk.c); + m_edit->setValue(100.0 * cmyk.m); + y_edit->setValue(100.0 * cmyk.y); + k_edit->setValue(100.0 * cmyk.k); + + knockout_option->setChecked(color.getKnockout()); + + if (color.getSpotColorMethod() == MapColor::SpotColor) + { + full_tone_option->setChecked(true); + sc_name_edit->setEnabled(true); + knockout_option->setEnabled(true); + cmyk_spot_color_option->setEnabled(false); + if (cmyk_spot_color_option->isChecked()) + custom_cmyk_option->setChecked(true); + rgb_spot_color_option->setEnabled(false); + if (rgb_spot_color_option->isChecked()) + custom_rgb_option->setChecked(true); + } + else if (color.getSpotColorMethod() == MapColor::CustomColor) + { + composition_option->setChecked(true); + sc_name_edit->setEnabled(false); + knockout_option->setEnabled(true); + cmyk_spot_color_option->setEnabled(true); + rgb_spot_color_option->setEnabled(true); + } + else + { + composition_option->setChecked(true); + sc_name_edit->setEnabled(false); + cmyk_spot_color_option->setEnabled(false); + if (cmyk_spot_color_option->isChecked()) + { + custom_cmyk_option->setChecked(true); + } + cmyk_spot_color_option->setEnabled(false); + if (rgb_spot_color_option->isChecked()) + { + custom_rgb_option->setChecked(true); + } + rgb_spot_color_option->setEnabled(false); + } + + const SpotColorComponents& color_components = color.getComponents(); + int num_components = color_components.size(); + int num_editors = component_colors.size(); + + for (int i = num_components+1; i < num_editors; ++i) + { + prof_color_layout->removeWidget(component_colors[i]); + delete component_colors[i]; + prof_color_layout->removeWidget(component_halftone[i]); + delete component_halftone[i]; + } + + if (num_editors != num_components+1) + { + prof_color_layout->removeWidget(knockout_option); + prof_color_layout->addWidget(knockout_option, components_row0+num_components+1, components_col0); + } + + component_colors.resize(num_components+1); + component_halftone.resize(num_components+1); + for (int i = num_editors; i <= num_components; ++i) + { + component_colors[i] = new ColorDropDown(&map, &color, true); + component_colors[i]->removeColor(&source_color); + prof_color_layout->addWidget(component_colors[i], components_row0+i, components_col0); + connect(component_colors[i], SIGNAL(currentIndexChanged(int)), this, SLOT(spotColorCompositionChanged())); + component_halftone[i] = Util::SpinBox::create(1, 0.0, 100.0, tr("%"), 10.0); + prof_color_layout->addWidget(component_halftone[i], components_row0+i, components_col0+1); + connect(component_halftone[i], SIGNAL(valueChanged(double)), this, SLOT(spotColorCompositionChanged())); + } + + num_editors = component_colors.size(); + bool enable_component = composition_option->isChecked(); + for (int i = 0; i < num_editors; i++) + { + bool have_component = (i < (int)num_components); + const MapColor* component_color = have_component ? color_components[i].spot_color : NULL; + component_colors[i]->setEnabled(enable_component); + component_colors[i]->setColor(component_color); + + bool enable_halftone = enable_component && have_component; + float component_factor = enable_halftone ? color_components[i].factor : 0.0f; + component_halftone[i]->setEnabled(enable_halftone); + component_halftone[i]->setValue(component_factor * 100.0); + + prof_color_layout->setRowStretch(components_row0 + i, 0); + + enable_component = enable_component && enable_halftone; + } + // At least one component must be editable to create a composition + if (color.getSpotColorMethod() == MapColor::UndefinedMethod) + component_colors[0]->setEnabled(true); + + int stretch_row = qMax(stretch_row0, components_row0+num_editors); + if (stretch_row != stretch_row0) + { + prof_color_layout->removeWidget(stretch); + prof_color_layout->addWidget(stretch, stretch_row, stretch_col0); + prof_color_layout->setRowStretch(stretch_row, 1); + } + + bool custom_cmyk = false; + if (color.getCmykColorMethod() == MapColor::SpotColor) + { + cmyk_spot_color_option->setChecked(true); + } + else if (color.getCmykColorMethod() == MapColor::RgbColor) + { + evaluate_rgb_option->setChecked(true); + } + else if (color.getCmykColorMethod() == MapColor::CustomColor) + { + custom_cmyk_option->setChecked(true); + custom_cmyk = true; + } + c_edit->setEnabled(custom_cmyk); + m_edit->setEnabled(custom_cmyk); + y_edit->setEnabled(custom_cmyk); + k_edit->setEnabled(custom_cmyk); + + + const MapColorRgb& rgb = color.getRgb(); + r_edit->setValue(255.0 * rgb.r); + g_edit->setValue(255.0 * rgb.g); + b_edit->setValue(255.0 * rgb.b); + html_edit->setText(QColor(rgb).name()); + + bool custom_rgb = false; + if (color.getRgbColorMethod() == MapColor::SpotColor) + { + rgb_spot_color_option->setChecked(true); + } + else if (color.getRgbColorMethod() == MapColor::CmykColor) + { + evaluate_cmyk_option->setChecked(true); + } + else if (color.getRgbColorMethod() == MapColor::CustomColor) + { + custom_rgb_option->setChecked(true); + custom_rgb = true; + } + r_edit->setEnabled(custom_rgb); + g_edit->setEnabled(custom_rgb); + b_edit->setEnabled(custom_rgb); + html_edit->setEnabled(false); // TODO: Editor + + + react_to_changes = true; +} + +void ColorDialog::accept() +{ + QSettings settings; + settings.beginGroup(QString::fromLatin1("ColorDialog")); + settings.setValue(QString::fromLatin1("view"), properties_widget->currentWidget()->objectName()); + settings.endGroup(); + + QDialog::accept(); +} + +void ColorDialog::reset() +{ + color = source_color; + updateWidgets(); + setColorModified(false); +} + +void ColorDialog::setColorModified(bool modified) +{ + if (color_modified != modified) + { + color_modified = modified; + updateButtons(); + } +} + +void ColorDialog::updateButtons() +{ + ok_button->setEnabled(color_modified); + reset_button->setEnabled(color_modified); +} + +void ColorDialog::showHelp() +{ + Util::showHelp(this, "color_dock_widget.html", "editor"); +} + +// slot +void ColorDialog::mapColorNameChanged() +{ + if (!react_to_changes) + return; + + color.setName(mc_name_edit->text()); + + setColorModified(); +} + +void ColorDialog::spotColorTypeChanged(int id) +{ + if (!react_to_changes) + return; + + QString name; + switch (id) + { + case MapColor::SpotColor: + name = color.getName(); + if (name.isEmpty()) + name = QLatin1Char('?'); + color.setSpotColorName(name); + break; + case MapColor::CustomColor: + if (source_color.getSpotColorMethod() == MapColor::CustomColor) + color.setSpotColorComposition(source_color.getComponents()); + else + color.setSpotColorComposition({}); + break; + default: + ; // nothing + } + + updateWidgets(); + setColorModified(true); +} + +void ColorDialog::spotColorNameChanged() +{ + if (!react_to_changes) + return; + + Q_ASSERT(full_tone_option->isChecked()); + color.setSpotColorName(sc_name_edit->text()); + + setColorModified(); +} + +void ColorDialog::spotColorCompositionChanged() +{ + if (!react_to_changes) + return; + + SpotColorComponents components; + SpotColorComponent component; + int num_editors = component_colors.size(); + components.reserve(num_editors); + for (int i = 0; i < num_editors; i++) + { + if (!component_colors[i]->isEnabled()) + break; + + const MapColor* spot_color = component_colors[i]->color(); + if (spot_color == NULL) + continue; + + component.spot_color = spot_color; + component.factor = component_halftone[i]->value() / 100.0f; + components.push_back(component); + } + color.setSpotColorComposition(components); + + updateWidgets(); + setColorModified(true); +} + +void ColorDialog::knockoutChanged() +{ + if (!react_to_changes) + return; + + color.setKnockout(knockout_option->isChecked()); + setColorModified(); +} + +void ColorDialog::cmykColorTypeChanged(int id) +{ + if (!react_to_changes) + return; + + switch (id) + { + case MapColor::SpotColor: + color.setCmykFromSpotColors(); + break; + case MapColor::RgbColor: +// color.setRgb(color.getRgb()); + color.setCmykFromRgb(); + break; + case MapColor::CustomColor: + color.setCmyk(color.getCmyk()); + break; + default: + ; // nothing + } + + updateWidgets(); + setColorModified(true); +} + +void ColorDialog::cmykValueChanged() +{ + if (!react_to_changes) + return; + + if (custom_cmyk_option->isChecked()) + { + color.setCmyk( MapColorCmyk( + c_edit->value()/100.0, m_edit->value()/100.0, y_edit->value()/100.0, k_edit->value()/100.0 + ) ); + updateWidgets(); + setColorModified(true); + } +} + +void ColorDialog::rgbColorTypeChanged(int id) +{ + if (!react_to_changes) + return; + + switch (id) + { + case MapColor::SpotColor: + color.setRgbFromSpotColors(); + break; + case MapColor::CmykColor: +// color.setCmyk(color.getCmyk()); + color.setRgbFromCmyk(); + break; + case MapColor::CustomColor: + color.setRgb(color.getRgb()); + break; + default: + ; // nothing + } + + updateWidgets(); + setColorModified(true); +} + +void ColorDialog::rgbValueChanged() +{ + if (!react_to_changes) + return; + + if (custom_rgb_option->isChecked()) + { + color.setRgb( MapColorRgb( + r_edit->value()/255.0, g_edit->value()/255.0, b_edit->value()/255.0 + ) ); + updateWidgets(); + setColorModified(true); + } +} + diff --git a/src/gui/color_dialog.h b/src/gui/color_dialog.h new file mode 100644 index 0000000..9aa1f38 --- /dev/null +++ b/src/gui/color_dialog.h @@ -0,0 +1,140 @@ +/* + * Copyright 2012, 2013, 2014 Kai Pastor + * + * This file is part of OpenOrienteering. + * + * OpenOrienteering is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenOrienteering is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenOrienteering. If not, see . + */ + + +#ifndef _OPENORIENTEERING_COLOR_DIALOG_H_ +#define _OPENORIENTEERING_COLOR_DIALOG_H_ + +#include + +#include + +#include "../core/map_color.h" + +class QAbstractButton; +class QCheckBox; +class QDoubleSpinBox; +class QGridLayout; +class QLabel; +class QLineEdit; +class QRadioButton; +class QTabWidget; + +class ColorDropDown; +class Map; + +/** + * A dialog for editing a single map color. + */ +class ColorDialog: public QDialog +{ +Q_OBJECT +public: + /** Constructs a new dialog for the given map and color. */ + ColorDialog(const Map& map, const MapColor& source_color, QWidget* parent = 0, Qt::WindowFlags f = 0); + + /** + * Returns the edited color. + */ + const MapColor& getColor() const { return color; } + +protected slots: + void accept(); + + void reset(); + + void showHelp(); + + void mapColorNameChanged(); + + void spotColorTypeChanged(int id); + + void spotColorNameChanged(); + + void spotColorCompositionChanged(); + + void knockoutChanged(); + + void cmykColorTypeChanged(int id); + + void cmykValueChanged(); + + void rgbColorTypeChanged(int id); + + void rgbValueChanged(); + + void setColorModified() { setColorModified(true); } + +protected: + void setColorModified(bool modified); + + void updateWidgets(); + + void updateButtons(); + + const Map& map; + const MapColor& source_color; + + MapColor color; + bool color_modified; + + bool react_to_changes; + + QLabel* color_preview_label; + QLineEdit* mc_name_edit; + + QRadioButton* full_tone_option; + QRadioButton* composition_option; + QLineEdit* sc_name_edit; + QCheckBox* knockout_option; + + QRadioButton* cmyk_spot_color_option; + QRadioButton* evaluate_rgb_option; + QRadioButton* custom_cmyk_option; + QDoubleSpinBox* c_edit; + QDoubleSpinBox* m_edit; + QDoubleSpinBox* y_edit; + QDoubleSpinBox* k_edit; + + QRadioButton* rgb_spot_color_option; + QRadioButton* evaluate_cmyk_option; + QRadioButton* custom_rgb_option; + QDoubleSpinBox* r_edit; + QDoubleSpinBox* g_edit; + QDoubleSpinBox* b_edit; + QLineEdit* html_edit; + + QTabWidget* properties_widget; + + QAbstractButton* ok_button; + QAbstractButton* reset_button; + + static const int icon_size = 32; + + std::vector< ColorDropDown* > component_colors; + std::vector< QDoubleSpinBox* > component_halftone; + int components_row0; + int components_col0; + QGridLayout* prof_color_layout; + int stretch_row0; + int stretch_col0; + QWidget* stretch; +}; + +#endif diff --git a/src/gui/configure_grid_dialog.cpp b/src/gui/configure_grid_dialog.cpp new file mode 100644 index 0000000..d19b8ae --- /dev/null +++ b/src/gui/configure_grid_dialog.cpp @@ -0,0 +1,265 @@ +/* + * Copyright 2012, 2013 Thomas Schöps + * Copyright 2014, 2015 Kai Pastor + * + * This file is part of OpenOrienteering. + * + * OpenOrienteering is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenOrienteering is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenOrienteering. If not, see . + */ + + +#include "configure_grid_dialog.h" + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../core/georeferencing.h" +#include "../map.h" +#include "../util.h" +#include "../util_gui.h" + + +ConfigureGridDialog::ConfigureGridDialog(QWidget* parent, const Map& map, bool grid_visible) +: QDialog(parent, Qt::WindowSystemMenuHint | Qt::WindowTitleHint) +, map(map) +, grid(map.getGrid()) +, grid_visible(grid_visible) +, current_color(grid.getColor()) +, current_unit(grid.getUnit()) +{ + setWindowTitle(tr("Configure grid")); + + show_grid_check = new QCheckBox(tr("Show grid")); + snap_to_grid_check = new QCheckBox(tr("Snap to grid")); + choose_color_button = new QPushButton(tr("Choose...")); + + display_mode_combo = new QComboBox(); + display_mode_combo->addItem(tr("All lines"), (int)MapGrid::AllLines); + display_mode_combo->addItem(tr("Horizontal lines"), (int)MapGrid::HorizontalLines); + display_mode_combo->addItem(tr("Vertical lines"), (int)MapGrid::VerticalLines); + + mag_north_radio = new QRadioButton(tr("Align with magnetic north")); + grid_north_radio = new QRadioButton(tr("Align with grid north")); + true_north_radio = new QRadioButton(tr("Align with true north")); + + QLabel* rotate_label = new QLabel(tr("Additional rotation (counter-clockwise):")); + additional_rotation_edit = Util::SpinBox::create(Georeferencing::declinationPrecision(), -360, +360, trUtf8("°")); + additional_rotation_edit->setWrapping(true); + + + unit_combo = new QComboBox(); + unit_combo->addItem(tr("meters in terrain"), (int)MapGrid::MetersInTerrain); + unit_combo->addItem(tr("millimeters on map"), (int)MapGrid::MillimetersOnMap); + + QLabel* horz_spacing_label = new QLabel(tr("Horizontal spacing:")); + horz_spacing_edit = Util::SpinBox::create(1, 0.1, Util::InputProperties::max()); + QLabel* vert_spacing_label = new QLabel(tr("Vertical spacing:")); + vert_spacing_edit = Util::SpinBox::create(1, 0.1, Util::InputProperties::max()); + + origin_label = new QLabel(); + QLabel* horz_offset_label = new QLabel(tr("Horizontal offset:")); + horz_offset_edit = Util::SpinBox::create(1, Util::InputProperties::min(), Util::InputProperties::max()); + QLabel* vert_offset_label = new QLabel(tr("Vertical offset:")); + vert_offset_edit = Util::SpinBox::create(1, Util::InputProperties::min(), Util::InputProperties::max()); + + QDialogButtonBox* button_box = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel | QDialogButtonBox::Help, Qt::Horizontal); + + + show_grid_check->setChecked(grid_visible); + snap_to_grid_check->setChecked(grid.isSnappingEnabled()); + display_mode_combo->setCurrentIndex(display_mode_combo->findData((int)grid.getDisplayMode())); + if (grid.getAlignment() == MapGrid::MagneticNorth) + mag_north_radio->setChecked(true); + else if (grid.getAlignment() == MapGrid::GridNorth) + grid_north_radio->setChecked(true); + else // if (grid.getAlignment() == MapGrid::TrueNorth) + true_north_radio->setChecked(true); + additional_rotation_edit->setValue(grid.getAdditionalRotation() * 180 / M_PI); + unit_combo->setCurrentIndex(unit_combo->findData(current_unit)); + horz_spacing_edit->setValue(grid.getHorizontalSpacing()); + vert_spacing_edit->setValue(grid.getVerticalSpacing()); + horz_offset_edit->setValue(grid.getHorizontalOffset()); + vert_offset_edit->setValue(-1 * grid.getVerticalOffset()); + + QFormLayout* layout = new QFormLayout(); + layout->addRow(show_grid_check); + layout->addRow(snap_to_grid_check); + layout->addRow(tr("Line color:"), choose_color_button); + layout->addRow(tr("Display:"), display_mode_combo); + layout->addItem(Util::SpacerItem::create(this)); + + layout->addRow(Util::Headline::create(tr("Alignment"))); + layout->addRow(mag_north_radio); + layout->addRow(grid_north_radio); + layout->addRow(true_north_radio); + layout->addRow(rotate_label, additional_rotation_edit); + layout->addItem(Util::SpacerItem::create(this)); + + layout->addRow(Util::Headline::create(tr("Positioning"))); + layout->addRow(tr("Unit:", "measurement unit"), unit_combo); + layout->addRow(horz_spacing_label, horz_spacing_edit); + layout->addRow(vert_spacing_label, vert_spacing_edit); + layout->addItem(Util::SpacerItem::create(this)); + layout->addRow(origin_label); + layout->addRow(horz_offset_label, horz_offset_edit); + layout->addRow(vert_offset_label, vert_offset_edit); + layout->addItem(Util::SpacerItem::create(this)); + + layout->addRow(button_box); + setLayout(layout); + + updateStates(); + updateColorDisplay(); + + using TakingIntArgument = void (QComboBox::*)(int); + connect(show_grid_check, &QAbstractButton::clicked, this, &ConfigureGridDialog::updateStates); + connect(choose_color_button, &QAbstractButton::clicked, this, &ConfigureGridDialog::chooseColor); + connect(display_mode_combo, (TakingIntArgument)&QComboBox::currentIndexChanged, this, &ConfigureGridDialog::updateStates); + connect(mag_north_radio, &QAbstractButton::clicked, this, &ConfigureGridDialog::updateStates); + connect(grid_north_radio, &QAbstractButton::clicked, this, &ConfigureGridDialog::updateStates); + connect(true_north_radio, &QAbstractButton::clicked, this, &ConfigureGridDialog::updateStates); + connect(unit_combo, (TakingIntArgument)&QComboBox::currentIndexChanged, this, &ConfigureGridDialog::unitChanged); + connect(button_box, &QDialogButtonBox::helpRequested, this, &ConfigureGridDialog::showHelp); + + connect(button_box, &QDialogButtonBox::accepted, this, &ConfigureGridDialog::okClicked); + connect(button_box, &QDialogButtonBox::rejected, this, &QDialog::reject); +} + +ConfigureGridDialog::~ConfigureGridDialog() +{ + // nothing, not inlined +} + +void ConfigureGridDialog::chooseColor() +{ + qDebug() << qAlpha(current_color); + QColor new_color = QColorDialog::getColor(current_color, this, tr("Choose grid line color"), QColorDialog::ShowAlphaChannel); + if (new_color.isValid()) + { + current_color = new_color.rgba(); + updateColorDisplay(); + } +} + +void ConfigureGridDialog::updateColorDisplay() +{ + int icon_size = style()->pixelMetric(QStyle::PM_SmallIconSize); + QPixmap pixmap(icon_size, icon_size); + pixmap.fill(current_color); + QIcon icon(pixmap); + choose_color_button->setIcon(icon); +} + +void ConfigureGridDialog::unitChanged(int index) +{ + auto unit = (MapGrid::Unit)unit_combo->itemData(index).toInt(); + if (unit != current_unit) + { + current_unit = unit; + double factor = 1.0; + switch (current_unit) + { + case MapGrid::MetersInTerrain: + factor = 0.001 * map.getScaleDenominator(); + break; + case MapGrid::MillimetersOnMap: + factor = 1000.0 / map.getScaleDenominator(); + break; + default: + Q_ASSERT(!"Illegal unit"); + } + + for (auto editor : { horz_spacing_edit, vert_spacing_edit, horz_offset_edit, vert_offset_edit }) + { + editor->setValue(editor->value() * factor); + } + } + updateStates(); +} + +void ConfigureGridDialog::okClicked() +{ + grid_visible = show_grid_check->isChecked(); + + grid.setSnappingEnabled(snap_to_grid_check->isChecked()); + grid.setColor(current_color); + grid.setDisplayMode((MapGrid::DisplayMode)display_mode_combo->itemData(display_mode_combo->currentIndex()).toInt()); + + if (mag_north_radio->isChecked()) + grid.setAlignment(MapGrid::MagneticNorth); + else if (grid_north_radio->isChecked()) + grid.setAlignment(MapGrid::GridNorth); + else // if (true_north_radio->isChecked()) + grid.setAlignment(MapGrid::TrueNorth); + grid.setAdditionalRotation(additional_rotation_edit->value() * M_PI / 180); + + grid.setUnit(current_unit); + + grid.setHorizontalSpacing(horz_spacing_edit->value()); + grid.setVerticalSpacing(vert_spacing_edit->value()); + grid.setHorizontalOffset(horz_offset_edit->value()); + grid.setVerticalOffset(-1 * vert_offset_edit->value()); + + accept(); +} + +void ConfigureGridDialog::updateStates() +{ + MapGrid::DisplayMode display_mode = (MapGrid::DisplayMode)display_mode_combo->itemData(display_mode_combo->currentIndex()).toInt(); + choose_color_button->setEnabled(show_grid_check->isChecked()); + display_mode_combo->setEnabled(show_grid_check->isChecked()); + snap_to_grid_check->setEnabled(show_grid_check->isChecked()); + + mag_north_radio->setEnabled(show_grid_check->isChecked()); + grid_north_radio->setEnabled(show_grid_check->isChecked()); + true_north_radio->setEnabled(show_grid_check->isChecked()); + additional_rotation_edit->setEnabled(show_grid_check->isChecked()); + + unit_combo->setEnabled(show_grid_check->isChecked()); + + QString unit_suffix = QLatin1Char(' ') + ((current_unit == MapGrid::MetersInTerrain) ? tr("m", "meters") : tr("mm", "millimeters")); + horz_spacing_edit->setEnabled(show_grid_check->isChecked() && display_mode != MapGrid::HorizontalLines); + horz_spacing_edit->setSuffix(unit_suffix); + vert_spacing_edit->setEnabled(show_grid_check->isChecked() && display_mode != MapGrid::VerticalLines); + vert_spacing_edit->setSuffix(unit_suffix); + + QString origin_text = tr("Origin at: %1"); + if (mag_north_radio->isChecked() || true_north_radio->isChecked()) + origin_text = origin_text.arg(tr("paper coordinates origin")); + else // if (grid_north_radio->isChecked()) + origin_text = origin_text.arg(tr("projected coordinates origin")); + origin_label->setText(origin_text); + + horz_offset_edit->setEnabled(show_grid_check->isChecked() && display_mode != MapGrid::HorizontalLines); + horz_offset_edit->setSuffix(unit_suffix); + vert_offset_edit->setEnabled(show_grid_check->isChecked() && display_mode != MapGrid::VerticalLines); + vert_offset_edit->setSuffix(unit_suffix); +} + +void ConfigureGridDialog::showHelp() +{ + Util::showHelp(this, "grid.html"); +} diff --git a/src/gui/configure_grid_dialog.h b/src/gui/configure_grid_dialog.h new file mode 100644 index 0000000..a013dc5 --- /dev/null +++ b/src/gui/configure_grid_dialog.h @@ -0,0 +1,95 @@ +/* + * Copyright 2012, 2013 Thomas Schöps + * Copyright 2014, 2015 Kai Pastor + * + * This file is part of OpenOrienteering. + * + * OpenOrienteering is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenOrienteering is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenOrienteering. If not, see . + */ + + +#ifndef _OPENORIENTEERING_CONFIGURE_GRID_DIALOG_H_ +#define _OPENORIENTEERING_CONFIGURE_GRID_DIALOG_H_ + +#include + +#include "../core/map_grid.h" + +QT_BEGIN_NAMESPACE +class QCheckBox; +class QComboBox; +class QDoubleSpinBox; +class QLabel; +class QLineEdit; +class QRadioButton; +QT_END_NAMESPACE + +class Map; + +class ConfigureGridDialog : public QDialog +{ +Q_OBJECT +public: + ConfigureGridDialog(QWidget* parent, const Map& map, bool grid_visible); + + ~ConfigureGridDialog() override; + + const MapGrid& resultGrid() const; + + bool gridVisible() const; + +private slots: + void chooseColor(); + void updateColorDisplay(); + void unitChanged(int index); + void okClicked(); + void updateStates(); + void showHelp(); + +private: + QCheckBox* show_grid_check; + QCheckBox* snap_to_grid_check; + QPushButton* choose_color_button; + QComboBox* display_mode_combo; + + QRadioButton* mag_north_radio; + QRadioButton* grid_north_radio; + QRadioButton* true_north_radio; + QDoubleSpinBox* additional_rotation_edit; + + QComboBox* unit_combo; + QDoubleSpinBox* horz_spacing_edit; + QDoubleSpinBox* vert_spacing_edit; + QLabel* origin_label; + QDoubleSpinBox* horz_offset_edit; + QDoubleSpinBox* vert_offset_edit; + + const Map& map; + MapGrid grid; + bool grid_visible; + QRgb current_color; + MapGrid::Unit current_unit; +}; + +inline const MapGrid& ConfigureGridDialog::resultGrid() const +{ + return grid; +} + +inline bool ConfigureGridDialog::gridVisible() const +{ + return grid_visible; +} + +#endif diff --git a/src/gui/georeferencing_dialog.cpp b/src/gui/georeferencing_dialog.cpp new file mode 100644 index 0000000..6282893 --- /dev/null +++ b/src/gui/georeferencing_dialog.cpp @@ -0,0 +1,747 @@ +/* + * Copyright 2012, 2013 Thomas Schöps + * Copyright 2012-2016 Kai Pastor + * + * This file is part of OpenOrienteering. + * + * OpenOrienteering is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenOrienteering is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenOrienteering. If not, see . + */ + + +#include "georeferencing_dialog.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(QT_NETWORK_LIB) +#include +#include +#endif + +#include "../core/crs_template.h" +#include "../core/georeferencing.h" +#include "main_window.h" +#include "../map.h" +#include "../map_editor.h" +#include "../map_dialog_rotate.h" +#include "../util_gui.h" +#include "../util.h" +#include "../util/scoped_signals_blocker.h" +#include "widgets/crs_selector.h" + + +// ### GeoreferencingDialog ### + +GeoreferencingDialog::GeoreferencingDialog(MapEditorController* controller, const Georeferencing* initial, bool allow_no_georeferencing) + : GeoreferencingDialog(controller->getWindow(), controller, controller->getMap(), initial, allow_no_georeferencing) +{ + // nothing else +} + +GeoreferencingDialog::GeoreferencingDialog(QWidget* parent, Map* map, const Georeferencing* initial, bool allow_no_georeferencing) + : GeoreferencingDialog(parent, nullptr, map, initial, allow_no_georeferencing) +{ + // nothing else +} + +GeoreferencingDialog::GeoreferencingDialog( + QWidget* parent, + MapEditorController* controller, + Map* map, + const Georeferencing* initial, + bool allow_no_georeferencing ) + : QDialog(parent, Qt::WindowSystemMenuHint | Qt::WindowTitleHint) + , controller(controller) + , map(map) + , initial_georef(initial ? initial : &map->getGeoreferencing()) + , georef(new Georeferencing(*initial_georef)) + , allow_no_georeferencing(allow_no_georeferencing) + , tool_active(false) + , declination_query_in_progress(false) + , grivation_locked(!initial_georef->isValid() || initial_georef->getState() != Georeferencing::Normal) + , original_declination(0.0) +{ + if (!grivation_locked) + original_declination = initial_georef->getDeclination(); + + setWindowTitle(tr("Map Georeferencing")); + setWindowModality(Qt::WindowModal); + + // Create widgets + QLabel* map_crs_label = Util::Headline::create(tr("Map coordinate reference system")); + + crs_selector = new CRSSelector(*georef, nullptr); + crs_selector->addCustomItem(tr("- local -"), Georeferencing::Local); + + status_label = new QLabel(tr("Status:")); + status_field = new QLabel(); + + /*: The grid scale factor is the ratio between a length in the grid plane + and the corresponding length on the curved earth model. It is applied + as a factor to ground distances to get grid plane distances. */ + auto scale_factor_label = new QLabel(tr("Grid scale factor:")); + scale_factor_edit = Util::SpinBox::create(Georeferencing::scaleFactorPrecision(), 0.001, 1000.0); + + QLabel* reference_point_label = Util::Headline::create(tr("Reference point")); + + ref_point_button = new QPushButton(tr("&Pick on map")); + int ref_point_button_width = ref_point_button->sizeHint().width(); + QLabel* geographic_datum_label = new QLabel(tr("(Datum: WGS84)")); + int geographic_datum_label_width = geographic_datum_label->sizeHint().width(); + + map_x_edit = Util::SpinBox::create(tr("mm")); + map_y_edit = Util::SpinBox::create(tr("mm")); + ref_point_button->setEnabled(controller != nullptr); + QHBoxLayout* map_ref_layout = new QHBoxLayout(); + map_ref_layout->addWidget(map_x_edit, 1); + map_ref_layout->addWidget(new QLabel(tr("X", "x coordinate")), 0); + map_ref_layout->addWidget(map_y_edit, 1); + map_ref_layout->addWidget(new QLabel(tr("Y", "y coordinate")), 0); + if (ref_point_button_width < geographic_datum_label_width) + map_ref_layout->addSpacing(geographic_datum_label_width - ref_point_button_width); + map_ref_layout->addWidget(ref_point_button, 0); + + easting_edit = Util::SpinBox::create(tr("m")); + northing_edit = Util::SpinBox::create(tr("m")); + QHBoxLayout* projected_ref_layout = new QHBoxLayout(); + projected_ref_layout->addWidget(easting_edit, 1); + projected_ref_layout->addWidget(new QLabel(tr("E", "west / east")), 0); + projected_ref_layout->addWidget(northing_edit, 1); + projected_ref_layout->addWidget(new QLabel(tr("N", "north / south")), 0); + projected_ref_layout->addSpacing(qMax(ref_point_button_width, geographic_datum_label_width)); + + projected_ref_label = new QLabel(); + lat_edit = Util::SpinBox::create(8, -90.0, +90.0, trUtf8("°")); + lon_edit = Util::SpinBox::create(8, -180.0, +180.0, trUtf8("°")); + QHBoxLayout* geographic_ref_layout = new QHBoxLayout(); + geographic_ref_layout->addWidget(lat_edit, 1); + geographic_ref_layout->addWidget(new QLabel(tr("N", "north")), 0); + geographic_ref_layout->addWidget(lon_edit, 1); + geographic_ref_layout->addWidget(new QLabel(tr("E", "east")), 0); + if (geographic_datum_label_width < ref_point_button_width) + geographic_ref_layout->addSpacing(ref_point_button_width - geographic_datum_label_width); + geographic_ref_layout->addWidget(geographic_datum_label, 0); + + show_refpoint_label = new QLabel(tr("Show reference point in:")); + link_label = new QLabel(); + link_label->setOpenExternalLinks(true); + + keep_projected_radio = new QRadioButton(tr("Projected coordinates")); + keep_geographic_radio = new QRadioButton(tr("Geographic coordinates")); + if (georef->getState() == Georeferencing::Normal && georef->isValid()) + { + keep_geographic_radio->setChecked(true); + } + else + { + keep_geographic_radio->setEnabled(false); + keep_projected_radio->setCheckable(true); + } + + QLabel* map_north_label = Util::Headline::create(tr("Map north")); + + declination_edit = Util::SpinBox::create(Georeferencing::declinationPrecision(), -180.0, +180.0, trUtf8("°")); + declination_button = new QPushButton(tr("Lookup...")); + QHBoxLayout* declination_layout = new QHBoxLayout(); + declination_layout->addWidget(declination_edit, 1); + declination_layout->addWidget(declination_button, 0); + + grivation_label = new QLabel(); + + buttons_box = new QDialogButtonBox( + QDialogButtonBox::Ok | QDialogButtonBox::Cancel | QDialogButtonBox::Reset | QDialogButtonBox::Help, + Qt::Horizontal); + reset_button = buttons_box->button(QDialogButtonBox::Reset); + reset_button->setEnabled(initial != nullptr); + QPushButton* help_button = buttons_box->button(QDialogButtonBox::Help); + + auto edit_layout = new QFormLayout(); + + edit_layout->addRow(map_crs_label); + edit_layout->addRow(tr("&Coordinate reference system:"), crs_selector); + crs_selector->setDialogLayout(edit_layout); + edit_layout->addRow(status_label, status_field); + edit_layout->addRow(scale_factor_label, scale_factor_edit); + edit_layout->addItem(Util::SpacerItem::create(this)); + + edit_layout->addRow(reference_point_label); + edit_layout->addRow(tr("Map coordinates:"), map_ref_layout); + edit_layout->addRow(projected_ref_label, projected_ref_layout); + edit_layout->addRow(tr("Geographic coordinates:"), geographic_ref_layout); + edit_layout->addRow(show_refpoint_label, link_label); + edit_layout->addRow(show_refpoint_label, link_label); + edit_layout->addRow(tr("On CRS changes, keep:"), keep_projected_radio); + edit_layout->addRow({}, keep_geographic_radio); + edit_layout->addItem(Util::SpacerItem::create(this)); + + edit_layout->addRow(map_north_label); + edit_layout->addRow(tr("Declination:"), declination_layout); + edit_layout->addRow(tr("Grivation:"), grivation_label); + + QVBoxLayout* layout = new QVBoxLayout(); + layout->addLayout(edit_layout); + layout->addStretch(); + layout->addSpacing(16); + layout->addWidget(buttons_box); + + setLayout(layout); + + connect(crs_selector, &CRSSelector::crsChanged, this, &GeoreferencingDialog::crsEdited); + + using TakingDoubleArgument = void (QDoubleSpinBox::*)(double); + connect(scale_factor_edit, (TakingDoubleArgument)&QDoubleSpinBox::valueChanged, this, &GeoreferencingDialog::scaleFactorEdited); + + connect(map_x_edit, (TakingDoubleArgument)&QDoubleSpinBox::valueChanged, this, &GeoreferencingDialog::mapRefChanged); + connect(map_y_edit, (TakingDoubleArgument)&QDoubleSpinBox::valueChanged, this, &GeoreferencingDialog::mapRefChanged); + connect(ref_point_button, &QPushButton::clicked, this, &GeoreferencingDialog::selectMapRefPoint); + + connect(easting_edit, (TakingDoubleArgument)&QDoubleSpinBox::valueChanged, this, &GeoreferencingDialog::eastingNorthingEdited); + connect(northing_edit, (TakingDoubleArgument)&QDoubleSpinBox::valueChanged, this, &GeoreferencingDialog::eastingNorthingEdited); + + connect(lat_edit, (TakingDoubleArgument)&QDoubleSpinBox::valueChanged, this, &GeoreferencingDialog::latLonEdited); + connect(lon_edit, (TakingDoubleArgument)&QDoubleSpinBox::valueChanged, this, &GeoreferencingDialog::latLonEdited); + connect(keep_geographic_radio, &QRadioButton::toggled, this, &GeoreferencingDialog::keepCoordsChanged); + + connect(declination_edit, (TakingDoubleArgument)&QDoubleSpinBox::valueChanged, this, &GeoreferencingDialog::declinationEdited); + connect(declination_button, &QPushButton::clicked, this, &GeoreferencingDialog::requestDeclination); + + connect(buttons_box, &QDialogButtonBox::accepted, this, &GeoreferencingDialog::accept); + connect(buttons_box, &QDialogButtonBox::rejected, this, &GeoreferencingDialog::reject); + connect(reset_button, &QPushButton::clicked, this, &GeoreferencingDialog::reset); + connect(help_button, &QPushButton::clicked, this, &GeoreferencingDialog::showHelp); + + connect(georef.data(), &Georeferencing::stateChanged, this, &GeoreferencingDialog::georefStateChanged); + connect(georef.data(), &Georeferencing::transformationChanged, this, &GeoreferencingDialog::transformationChanged); + connect(georef.data(), &Georeferencing::projectionChanged, this, &GeoreferencingDialog::projectionChanged); + connect(georef.data(), &Georeferencing::declinationChanged, this, &GeoreferencingDialog::declinationChanged); + + transformationChanged(); + georefStateChanged(); + declinationChanged(); +} + +GeoreferencingDialog::~GeoreferencingDialog() +{ + if (tool_active) + controller->setOverrideTool(nullptr); +} + +// slot +void GeoreferencingDialog::georefStateChanged() +{ + const QSignalBlocker block(crs_selector); + + switch (georef->getState()) + { + case Georeferencing::Local: + crs_selector->setCurrentItem(Georeferencing::Local); + keep_geographic_radio->setEnabled(false); + keep_projected_radio->setChecked(true); + break; + default: + qDebug() << "Unhandled georeferencing state:" << georef->getState(); + // fall through + case Georeferencing::Normal: + projectionChanged(); + keep_geographic_radio->setEnabled(true); + } + + updateWidgets(); +} + +// slot +void GeoreferencingDialog::transformationChanged() +{ + ScopedMultiSignalsBlocker block( + map_x_edit, map_y_edit, + easting_edit, northing_edit, + scale_factor_edit + ); + + map_x_edit->setValue(georef->getMapRefPoint().x()); + map_y_edit->setValue(-1 * georef->getMapRefPoint().y()); + + easting_edit->setValue(georef->getProjectedRefPoint().x()); + northing_edit->setValue(georef->getProjectedRefPoint().y()); + + scale_factor_edit->setValue(georef->getGridScaleFactor()); + + updateGrivation(); +} + +// slot +void GeoreferencingDialog::projectionChanged() +{ + ScopedMultiSignalsBlocker block( + crs_selector, + lat_edit, lon_edit + ); + + if (georef->getState() == Georeferencing::Normal) + { + const std::vector< QString >& parameters = georef->getProjectedCRSParameters(); + auto temp = CRSTemplateRegistry().find(georef->getProjectedCRSId()); + if (!temp || temp->parameters().size() != parameters.size()) + { + // The CRS id is not there anymore or the number of parameters has changed. + // Enter as custom spec. + crs_selector->setCurrentCRS(CRSTemplateRegistry().find(QString::fromLatin1("PROJ.4")), { georef->getProjectedCRSSpec() }); + } + else + { + crs_selector->setCurrentCRS(temp, parameters); + } + } + + LatLon latlon = georef->getGeographicRefPoint(); + double latitude = latlon.latitude(); + double longitude = latlon.longitude(); + lat_edit->setValue(latitude); + lon_edit->setValue(longitude); + QString osm_link = + QString::fromLatin1("http://www.openstreetmap.org/?lat=%1&lon=%2&zoom=18&layers=M"). + arg(latitude).arg(longitude); + QString worldofo_link = + QString::fromLatin1("http://maps.worldofo.com/?zoom=15&lat=%1&lng=%2"). + arg(latitude).arg(longitude); + link_label->setText( + tr("OpenStreetMap | World of O Maps"). + arg(osm_link). + arg(worldofo_link) + ); + + QString error = georef->getErrorText(); + if (error.length() == 0) + status_field->setText(tr("valid")); + else + status_field->setText(QLatin1String("") + error + QLatin1String("")); +} + +// slot +void GeoreferencingDialog::declinationChanged() +{ + const QSignalBlocker block(declination_edit); + declination_edit->setValue(georef->getDeclination()); +} + +void GeoreferencingDialog::requestDeclination(bool no_confirm) +{ + if (georef->isLocal()) + return; + + /// \todo Move URL (template) to settings. + QString user_url(QString::fromLatin1("https://www.ngdc.noaa.gov/geomag-web/")); + QUrl service_url(user_url + QLatin1String("calculators/calculateDeclination")); + LatLon latlon(georef->getGeographicRefPoint()); + + if (!no_confirm) + { + int result = QMessageBox::question(this, tr("Online declination lookup"), + trUtf8("The magnetic declination for the reference point %1° %2° will now be retrieved from %3. Do you want to continue?"). + arg(latlon.latitude()).arg(latlon.longitude()).arg(user_url), + QMessageBox::Yes | QMessageBox::No, + QMessageBox::Yes ); + if (result != QMessageBox::Yes) + return; + } + + QUrlQuery query; + QDate today = QDate::currentDate(); + query.addQueryItem(QString::fromLatin1("lat1"), QString::number(latlon.latitude())); + query.addQueryItem(QString::fromLatin1("lon1"), QString::number(latlon.longitude())); + query.addQueryItem(QString::fromLatin1("startYear"), QString::number(today.year())); + query.addQueryItem(QString::fromLatin1("startMonth"), QString::number(today.month())); + query.addQueryItem(QString::fromLatin1("startDay"), QString::number(today.day())); + +#if defined(Q_OS_WIN) || defined(Q_OS_MAC) || defined(Q_OS_ANDROID) || !defined(QT_NETWORK_LIB) + // No QtNetwork or no OpenSSL: open result in system browser. + query.addQueryItem(QString::fromLatin1("resultFormat"), QString::fromLatin1("html")); + service_url.setQuery(query); + QDesktopServices::openUrl(service_url); +#else + // Use result directly + query.addQueryItem(QString::fromLatin1("resultFormat"), QString::fromLatin1("xml")); + service_url.setQuery(query); + + declination_query_in_progress = true; + updateDeclinationButton(); + + QNetworkAccessManager *network = new QNetworkAccessManager(this); + connect(network, &QNetworkAccessManager::finished, this, &GeoreferencingDialog::declinationReplyFinished); + network->get(QNetworkRequest(service_url)); +#endif +} + +void GeoreferencingDialog::setMapRefPoint(MapCoord coords) +{ + georef->setMapRefPoint(coords); + reset_button->setEnabled(true); +} + +void GeoreferencingDialog::setKeepProjectedRefCoords() +{ + keep_projected_radio->setChecked(true); + reset_button->setEnabled(true); +} + +void GeoreferencingDialog::setKeepGeographicRefCoords() +{ + keep_geographic_radio->setChecked(true); + reset_button->setEnabled(true); +} + +void GeoreferencingDialog::toolDeleted() +{ + tool_active = false; +} + +void GeoreferencingDialog::showHelp() +{ + Util::showHelp(parentWidget(), "georeferencing.html"); +} + +void GeoreferencingDialog::reset() +{ + grivation_locked = ( !initial_georef->isValid() || initial_georef->getState() != Georeferencing::Normal ); + if (!grivation_locked) + original_declination = initial_georef->getDeclination(); + *georef.data() = *initial_georef; + reset_button->setEnabled(false); +} + +void GeoreferencingDialog::accept() +{ + float declination_change_degrees = georef->getDeclination() - initial_georef->getDeclination(); + if ( !grivation_locked && + declination_change_degrees != 0 && + (map->getNumObjects() > 0 || map->getNumTemplates() > 0) ) + { + int result = QMessageBox::question(this, tr("Declination change"), tr("The declination has been changed. Do you want to rotate the map content accordingly, too?"), QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel); + if (result == QMessageBox::Cancel) + { + return; + } + else if (result == QMessageBox::Yes) + { + RotateMapDialog dialog(this, map); + dialog.setWindowModality(Qt::WindowModal); + dialog.setRotationDegrees(declination_change_degrees); + dialog.setRotateAroundGeorefRefPoint(); + dialog.setAdjustDeclination(false); + dialog.showAdjustDeclination(false); + int result = dialog.exec(); + if (result == QDialog::Rejected) + return; + } + } + + map->setGeoreferencing(*georef); + QDialog::accept(); +} + +void GeoreferencingDialog::updateWidgets() +{ + ref_point_button->setEnabled(controller != nullptr); + + if (crs_selector->currentCRSTemplate()) + projected_ref_label->setText(crs_selector->currentCRSTemplate()->coordinatesName(crs_selector->parameters()) + QLatin1Char(':')); + else + projected_ref_label->setText(tr("Local coordinates:")); + + bool geographic_coords_enabled = crs_selector->currentCustomItem() != Georeferencing::Local; + status_label->setVisible(geographic_coords_enabled); + status_field->setVisible(geographic_coords_enabled); + lat_edit->setEnabled(geographic_coords_enabled); + lon_edit->setEnabled(geographic_coords_enabled); + link_label->setEnabled(geographic_coords_enabled); + //keep_geographic_radio->setEnabled(geographic_coords_enabled); + + updateDeclinationButton(); + + buttons_box->button(QDialogButtonBox::Ok)->setEnabled(georef->isValid()); +} + +void GeoreferencingDialog::updateDeclinationButton() +{ + /* + bool dialog_enabled = crs_edit->getSelectedCustomItemId() != 0; + bool proj_spec_visible = crs_edit->getSelectedCustomItemId() == 1; + bool geographic_coords_enabled = + dialog_enabled && + (proj_spec_visible || + crs_edit->getSelectedCustomItemId() == -1); + */ + bool enabled = lat_edit->isEnabled() && !declination_query_in_progress; + declination_button->setEnabled(enabled); + declination_button->setText(declination_query_in_progress ? tr("Loading...") : tr("Lookup...")); +} + +void GeoreferencingDialog::updateGrivation() +{ + QString text = trUtf8("%1 °", "degree value").arg(QLocale().toString(georef->getGrivation(), 'f', Georeferencing::declinationPrecision())); + if (grivation_locked) + text.append(QString::fromLatin1(" (%1)").arg(tr("locked"))); + grivation_label->setText(text); +} + +void GeoreferencingDialog::crsEdited() +{ + Georeferencing georef_copy = *georef; + + auto crs_template = crs_selector->currentCRSTemplate(); + auto spec = crs_selector->currentCRSSpec(); + + auto selected_item_id = crs_selector->currentCustomItem(); + switch (selected_item_id) + { + default: + Q_ASSERT(false && "Unsupported CRS item id"); + // fall through + case Georeferencing::Local: + // Local + georef_copy.setState(Georeferencing::Local); + break; + case -1: + // CRS from list + Q_ASSERT(crs_template); + georef_copy.setProjectedCRS(crs_template->id(), spec, crs_selector->parameters()); + georef_copy.setState(Georeferencing::Normal); // Allow invalid spec + if (keep_geographic_radio->isChecked()) + georef_copy.setGeographicRefPoint(georef->getGeographicRefPoint(), !grivation_locked); + else + georef_copy.setProjectedRefPoint(georef->getProjectedRefPoint(), !grivation_locked); + break; + } + + // Apply all changes at once + *georef = georef_copy; + reset_button->setEnabled(true); +} + +void GeoreferencingDialog::scaleFactorEdited() +{ + const QSignalBlocker block{scale_factor_edit}; + georef->setGridScaleFactor(scale_factor_edit->value()); + reset_button->setEnabled(true); +} + +void GeoreferencingDialog::selectMapRefPoint() +{ + if (controller) + { + controller->setOverrideTool(new GeoreferencingTool(this, controller)); + tool_active = true; + hide(); + } +} + +void GeoreferencingDialog::mapRefChanged() +{ + MapCoord coord(map_x_edit->value(), -1 * map_y_edit->value()); + setMapRefPoint(coord); +} + +void GeoreferencingDialog::eastingNorthingEdited() +{ + const QSignalBlocker block1(keep_geographic_radio), block2(keep_projected_radio); + double easting = easting_edit->value(); + double northing = northing_edit->value(); + georef->setProjectedRefPoint(QPointF(easting, northing), !grivation_locked); + keep_projected_radio->setChecked(true); + reset_button->setEnabled(true); +} + +void GeoreferencingDialog::latLonEdited() +{ + const QSignalBlocker block1(keep_geographic_radio), block2(keep_projected_radio); + double latitude = lat_edit->value(); + double longitude = lon_edit->value(); + georef->setGeographicRefPoint(LatLon(latitude, longitude), !grivation_locked); + keep_geographic_radio->setChecked(true); + reset_button->setEnabled(true); +} + +void GeoreferencingDialog::keepCoordsChanged() +{ + if (grivation_locked && keep_geographic_radio->isChecked()) + { + grivation_locked = false; + original_declination = georef->getDeclination(); + updateGrivation(); + } + reset_button->setEnabled(true); +} + +void GeoreferencingDialog::declinationEdited(double value) +{ + if (grivation_locked) + { + grivation_locked = false; + original_declination = georef->getDeclination(); + updateGrivation(); + } + georef->setDeclination(value); + reset_button->setEnabled(true); +} + +void GeoreferencingDialog::declinationReplyFinished(QNetworkReply* reply) +{ +#if defined(QT_NETWORK_LIB) + declination_query_in_progress = false; + updateDeclinationButton(); + + QString error_string; + if (reply->error() != QNetworkReply::NoError) + { + error_string = reply->errorString(); + } + else + { + QXmlStreamReader xml(reply); + while (xml.readNextStartElement()) + { + if (xml.name() == QLatin1String("maggridresult")) + { + while(xml.readNextStartElement()) + { + if (xml.name() == QLatin1String("result")) + { + while (xml.readNextStartElement()) + { + if (xml.name() == QLatin1String("declination")) + { + QString text = xml.readElementText(QXmlStreamReader::IncludeChildElements); + bool ok; + double declination = text.toDouble(&ok); + if (ok) + { + declination_edit->setValue(Georeferencing::roundDeclination(declination)); + return; + } + else + { + error_string = tr("Could not parse data.") + QLatin1Char(' '); + } + } + + xml.skipCurrentElement(); // child of result + } + } + + xml.skipCurrentElement(); // child of mapgridresult + } + } + else if (xml.name() == QLatin1String("errors")) + { + error_string.append(xml.readElementText(QXmlStreamReader::IncludeChildElements) + QLatin1Char(' ')); + } + + xml.skipCurrentElement(); // child of root + } + + if (xml.error() != QXmlStreamReader::NoError) + { + error_string.append(xml.errorString()); + } + else if (error_string.isEmpty()) + { + error_string = tr("Declination value not found."); + } + } + + int result = QMessageBox::critical(this, tr("Online declination lookup"), + tr("The online declination lookup failed:\n%1").arg(error_string), + QMessageBox::Retry | QMessageBox::Close, + QMessageBox::Close ); + if (result == QMessageBox::Retry) + requestDeclination(true); +#else + Q_UNUSED(reply) +#endif +} + + + +// ### GeoreferencingTool ### + +GeoreferencingTool::GeoreferencingTool(GeoreferencingDialog* dialog, MapEditorController* controller, QAction* action) + : MapEditorTool(controller, Other, action) + , dialog(dialog) +{ + // nothing +} + +GeoreferencingTool::~GeoreferencingTool() +{ + dialog->toolDeleted(); +} + +void GeoreferencingTool::init() +{ + setStatusBarText(tr("Click: Set the reference point. Right click: Cancel.")); + MapEditorTool::init(); +} + +bool GeoreferencingTool::mousePressEvent(QMouseEvent* event, MapCoordF, MapWidget*) +{ + bool handled = false; + switch (event->button()) + { + case Qt::LeftButton: + case Qt::RightButton: + handled = true; + break; + default: + ; // nothing + } + + return handled; +} + +bool GeoreferencingTool::mouseReleaseEvent(QMouseEvent* event, MapCoordF map_coord, MapWidget*) +{ + bool handled = false; + switch (event->button()) + { + case Qt::LeftButton: + dialog->setMapRefPoint(MapCoord(map_coord)); + // fall through + case Qt::RightButton: + QTimer::singleShot(0, dialog, SIGNAL(exec())); + handled = true; + break; + default: + ; // nothing + } + + return handled; +} + +const QCursor& GeoreferencingTool::getCursor() const +{ + static auto const cursor = scaledToScreen(QCursor{ QPixmap{ QString::fromLatin1(":/images/cursor-crosshair.png") }, 11, 11 }); + return cursor; +} diff --git a/src/gui/georeferencing_dialog.h b/src/gui/georeferencing_dialog.h new file mode 100644 index 0000000..4992038 --- /dev/null +++ b/src/gui/georeferencing_dialog.h @@ -0,0 +1,332 @@ +/* + * Copyright 2012, 2013 Thomas Schöps + * Copyright 2012-2015 Kai Pastor + * + * This file is part of OpenOrienteering. + * + * OpenOrienteering is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenOrienteering is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenOrienteering. If not, see . + */ + + +#ifndef _OPENORIENTEERING_GEOREFERENCING_DIALOG_H_ +#define _OPENORIENTEERING_GEOREFERENCING_DIALOG_H_ + +#include +#include +#include +#include + +#include "../tool.h" + +QT_BEGIN_NAMESPACE +class QComboBox; +class QDialogButtonBox; +class QDoubleSpinBox; +class QFormLayout; +class QLabel; +class QLineEdit; +class QPushButton; +class QRadioButton; +class QSpinBox; +class QNetworkReply; +QT_END_NAMESPACE + +class CRSSelector; +class Georeferencing; +class GeoreferencingTool; +class Map; +class MapEditorController; + + +/** + * A GeoreferencingDialog allows the user to adjust the georeferencing properties + * of a map. + */ +class GeoreferencingDialog : public QDialog +{ +Q_OBJECT +public: + /** + * Constructs a new georeferencing dialog for the map handled by the given + * controller. The optional parameter initial allows to override the current + * properties of the map's georeferencing. The parameter + * allow_no_georeferencing determines if the okay button can + * be clicked while "- none -" is selected. + */ + GeoreferencingDialog(MapEditorController* controller, const Georeferencing* initial = nullptr, bool allow_no_georeferencing = true); + + /** + * Constructs a new georeferencing dialog for the given map. The optional + * parameter initial allows to override the current properties of the map's + * georeferencing. Since the dialog will not know a MapEditorController, + * it will not allow to select a new reference point from the map. + * The parameter allow_no_georeferencing determines if the okay button can + * be clicked while "- none -" is selected. + */ + GeoreferencingDialog(QWidget* parent, Map* map, const Georeferencing* initial = nullptr, bool allow_no_georeferencing = true); + +protected: + /** + * Constructs a new georeferencing dialog. + * + * The map parameter must not be nullptr, and it must not be a different + * map than the one handled by controller. + * + * @param parent A parent widget. + * @param controller A controller which operates on the map. + * @param map The map. + * @param initial An override of the map's georeferencing + * @param allow_no_georeferencing Determines if the okay button can be + * be clicked while "- none -" is selected. + */ + GeoreferencingDialog( + QWidget* parent, + MapEditorController* controller, + Map* map, + const Georeferencing* initial, + bool allow_no_georeferencing + ); + +public: + /** + * Releases resources. + */ + virtual ~GeoreferencingDialog(); + + + /** + * Updates the dialog from georeferencing state changes. + */ + void georefStateChanged(); + + /** + * Moves transformation properties from the georeferencing to the widgets. + */ + void transformationChanged(); + + /** + * Moves projection properties from the georeferencing to the widgets. + */ + void projectionChanged(); + + /** + * Updates the declination widget from the georeferencing. + */ + void declinationChanged(); + + /** + * Triggers an online request for the magnetic declination. + * + * @param no_confirm If true, the user will not be asked for confirmation. + */ + void requestDeclination(bool no_confirm = false); + + /** + * Sets the map coordinates of the reference point + */ + void setMapRefPoint(MapCoord coords); + + /** + * Activates the "keep projected reference point coordinates on CRS changes" radio button. + */ + void setKeepProjectedRefCoords(); + + /** + * Activates the "keep geographic reference point coordinates on CRS changes" radio button. + */ + void setKeepGeographicRefCoords(); + + /** + * Notifies the dialog that the active GeoreferencingTool was deleted. + */ + void toolDeleted(); + + /** + * Opens this dialog's help page. + */ + void showHelp(); + + /** + * Resets all input fields to the values in the map's Georeferencing. + * + * This will also reset initial values passed to the constructor. + */ + void reset(); + + /** + * Pushes the changes from the dialog to the map's Georeferencing + * and closes the dialog. The dialog's result is set to QDialog::Accepted, + * and the active exec() function will return. + */ + void accept() override; + +protected: + /** + * Updates enabled / disabled states of all widgets. + */ + void updateWidgets(); + + /** + * Updates enabled / disabled state and text of the declination query button. + */ + void updateDeclinationButton(); + + + /** + * Notifies the dialog of a change in the CRS configuration. + */ + void crsEdited(); + + /** + * Notifies the dialog of a change in the grid scale factor. + */ + void scaleFactorEdited(); + + /** + * Hides the dialog and activates a GeoreferencingTool for selecting + * the reference point on the map. + */ + void selectMapRefPoint(); + + /** + * Notifies the dialog of a change in the map reference point fields. + */ + void mapRefChanged(); + + /** + * Notifies the dialog of a change in the easting / northing fields. + */ + void eastingNorthingEdited(); + + /** + * Notifies the dialog of change of the keep-coords buttons. + */ + void keepCoordsChanged(); + + /** + * Notifies the dialog of a change in the latitude / longitude fields. + */ + void latLonEdited(); + + /** + * Notifies the dialog of a change in the declination field. + */ + void declinationEdited(double value); + + /** + * Handles replies from the online declination service. + */ + void declinationReplyFinished(QNetworkReply* reply); + + /** + * Updates the grivation field from the underlying Georeferencing. + */ + void updateGrivation(); + +private: + /* Internal state */ + MapEditorController* const controller; + Map* const map; + const Georeferencing* initial_georef; + QScopedPointer georef; // A working copy of the current or given initial Georeferencing + bool allow_no_georeferencing; + bool tool_active; + bool declination_query_in_progress; + bool grivation_locked; + double original_declination; + + /* GUI elements */ + CRSSelector* crs_selector; + QLabel* status_label; + QLabel* status_field; + QDoubleSpinBox* scale_factor_edit; + + QDoubleSpinBox* map_x_edit; + QDoubleSpinBox* map_y_edit; + QPushButton* ref_point_button; + + QLabel* projected_ref_label; + QDoubleSpinBox* easting_edit; + QDoubleSpinBox* northing_edit; + + QDoubleSpinBox* lat_edit; + QDoubleSpinBox* lon_edit; + QLabel* show_refpoint_label; + QLabel* link_label; + + QRadioButton* keep_projected_radio; + QRadioButton* keep_geographic_radio; + + QDoubleSpinBox* declination_edit; + QPushButton* declination_button; + QLabel* grivation_label; + + QDialogButtonBox* buttons_box; + QPushButton* reset_button; +}; + + + +/** + * GeoreferencingTool is a helper to the GeoreferencingDialog which allows + * the user to select the position of the reference point on the map + * The GeoreferencingDialog hides when it activates this tool. The tool + * takes care of reactivating the dialog. + */ +class GeoreferencingTool : public MapEditorTool +{ +Q_OBJECT +public: + /** + * Constructs a new tool for the given dialog and controller. + */ + GeoreferencingTool( + GeoreferencingDialog* dialog, + MapEditorController* controller, + QAction* toolAction = nullptr + ); + + /** + * Notifies the dialog that the tool is deleted. + */ + virtual ~GeoreferencingTool(); + + /** + * Activates the tool. + */ + void init() override; + + /** + * Consumes left and right clicks. They are handled in mouseReleaseEvent. + */ + bool mousePressEvent(QMouseEvent* event, MapCoordF map_coord, MapWidget* widget) override; + + /** + * Reacts to the user activity by sending the reference point coordinates + * to the dialog (on left click) and reactivating the dialog. + */ + bool mouseReleaseEvent(QMouseEvent* event, MapCoordF map_coord, MapWidget* widget) override; + + /** + * Returns the mouse cursor that will be shown when the tool is active. + */ + const QCursor& getCursor() const override; + +private: + GeoreferencingDialog* const dialog; +}; + + + +#endif diff --git a/src/gui/home_screen_controller.cpp b/src/gui/home_screen_controller.cpp new file mode 100644 index 0000000..ead21f4 --- /dev/null +++ b/src/gui/home_screen_controller.cpp @@ -0,0 +1,157 @@ +/* + * Copyright 2012, 2013 Thomas Schöps, Kai Pastor + * + * This file is part of OpenOrienteering. + * + * OpenOrienteering is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenOrienteering is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenOrienteering. If not, see . + */ + + +#include "home_screen_controller.h" + +#include +#include + +#include "main_window.h" +#include "widgets/home_screen_widget.h" +#include "../settings.h" + + +HomeScreenController::HomeScreenController() +: widget(NULL), + current_tip(-1) +{ + // nothing +} + +HomeScreenController::~HomeScreenController() +{ + // nothing +} + +void HomeScreenController::attach(MainWindow* window) +{ + this->window = window; + + if (MainWindow::mobileMode()) + { + widget = new HomeScreenWidgetMobile(this); + } + else + { + widget = new HomeScreenWidgetDesktop(this); + window->statusBar()->hide(); + window->setStatusBarText(QString{}); + } + + window->setCentralWidget(widget); + + connect(&Settings::getInstance(), SIGNAL(settingsChanged()), this, SLOT(readSettings())); + + readSettings(true); +} + +void HomeScreenController::detach() +{ + if (!MainWindow::mobileMode()) + { + window->statusBar()->show(); + } + window->setCentralWidget(NULL); + widget->deleteLater(); + + Settings::getInstance().setSetting(Settings::HomeScreen_CurrentTip, current_tip); +} + +void HomeScreenController::readSettings(bool init_current_tip) +{ + Settings& settings = Settings::getInstance(); // FIXME: settings should be const + + widget->setRecentFiles(settings.getSettingCached(Settings::General_RecentFilesList).toStringList()); + widget->setOpenMRUFileChecked(settings.getSettingCached(Settings::General_OpenMRUFile).toBool()); + + bool tips_visible = settings.getSettingCached(Settings::HomeScreen_TipsVisible).toBool(); + widget->setTipsVisible(tips_visible); + if (init_current_tip) + { + // The home screen becomes active. + current_tip = settings.getSettingCached(Settings::HomeScreen_CurrentTip).toInt(); + if (tips_visible) + goToNextTip(); + } + else if (tips_visible) + // Settings changed. + goToTip(current_tip); +} + +void HomeScreenController::setOpenMRUFile(bool state) +{ + Settings::getInstance().setSetting(Settings::General_OpenMRUFile, state); +} + +void HomeScreenController::clearRecentFiles() +{ + Settings::getInstance().remove(Settings::General_RecentFilesList); +} + +void HomeScreenController::setTipsVisible(bool state) +{ + Settings::getInstance().setSetting(Settings::HomeScreen_TipsVisible, state); +} + +void HomeScreenController::goToNextTip() +{ + goToTip(current_tip + 1); +} + +void HomeScreenController::goToPreviousTip() +{ + goToTip(current_tip - 1); +} + +void HomeScreenController::goToTip(int index) +{ + static QStringList tips; + if (tips.isEmpty()) + { + // Normally, this will be read only once. + QFile file(QString::fromLatin1(":/help/tip-of-the-day/tips.txt")); + if (file.open(QIODevice::ReadOnly)) + { + while (!file.atEnd()) + { + QString tip(QString::fromUtf8(file.readLine().constData())); + if (tip.endsWith(QLatin1Char('\n'))) + tip.chop(1); + if (!tip.isEmpty()) + tips.push_back(tip); + } + } + } + + if (tips.isEmpty()) + { + // Some error may have occurred during reading the tips file. + // Display a welcome text. + widget->setTipOfTheDay(QString::fromLatin1("

%1

").arg(tr("Welcome to OpenOrienteering Mapper!"))); + } + else + { + Q_ASSERT(tips.count() > 0); + while (index < 0) + index += tips.count(); + current_tip = index % tips.count(); + widget->setTipOfTheDay(tips[current_tip]); + } +} diff --git a/src/gui/home_screen_controller.h b/src/gui/home_screen_controller.h new file mode 100644 index 0000000..63f6ea6 --- /dev/null +++ b/src/gui/home_screen_controller.h @@ -0,0 +1,79 @@ +/* + * Copyright 2012, 2013 Thomas Schöps, Kai Pastor + * + * This file is part of OpenOrienteering. + * + * OpenOrienteering is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenOrienteering is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenOrienteering. If not, see . + */ + + +#ifndef _OPENORIENTEERING_HOME_SCREEN_CONTROLLER_H_ +#define _OPENORIENTEERING_HOME_SCREEN_CONTROLLER_H_ + +#include "main_window_controller.h" + +class AbstractHomeScreenWidget; + +/** + * The controller of the OpenOrienteering Mapper home screen. + * The OpenOrienteering Mapper home screen is shown when no document is open, + * for example after the program is started for the first time. + */ +class HomeScreenController : public MainWindowController +{ +Q_OBJECT +public: + /** Creates a new HomeScreenController. */ + HomeScreenController(); + + /** Destroys the HomeScreenController and its children. */ + ~HomeScreenController(); + + /** Activates the HomeScreenController for the given main window. */ + virtual void attach(MainWindow* window); + + /** Detaches the HomeScreenController from its main window. */ + virtual void detach(); + +public slots: + /** (Re-)reads the settings. */ + void readSettings(bool init_current_tip = false); + + /** Clears the application's list of recently opened files. */ + void clearRecentFiles(); + + /** Sets whether to open the most recently used file on startup. */ + void setOpenMRUFile(bool state); + + /** Sets the visiblity of the tip-of-the-day to state. */ + void setTipsVisible(bool state); + + /** Moves to the tip following the current tip-of-the-day. */ + void goToPreviousTip(); + + /** Moves to the tip preceding the current tip-of-the-day. */ + void goToNextTip(); + + /** Moves to the tip-of-the-day given by index. */ + void goToTip(int index); + +protected: + /** The widget owned and controlled by this HomeScreenController. */ + AbstractHomeScreenWidget* widget; + + /** The index of the tip-of-the-day currently displayed. */ + int current_tip; +}; + +#endif diff --git a/src/gui/main_window.cpp b/src/gui/main_window.cpp new file mode 100644 index 0000000..bdbdd6f --- /dev/null +++ b/src/gui/main_window.cpp @@ -0,0 +1,1189 @@ +/* + * Copyright 2012, 2013, 2014 Thomas Schöps + * Copyright 2012-2016 Kai Pastor + * + * This file is part of OpenOrienteering. + * + * OpenOrienteering is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenOrienteering is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenOrienteering. If not, see . + */ + + +#include "main_window.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(Q_OS_ANDROID) +# include +# include +# include +#endif + +#include + +#include "about_dialog.h" +#include "autosave_dialog.h" +#include "home_screen_controller.h" +#include "settings_dialog.h" +#include "../core/map_view.h" +#include "../file_format_registry.h" +#include "../file_import_export.h" +#include "../map.h" +#include "../map_dialog_new.h" +#include "../map_editor.h" +#include "../mapper_resource.h" +#include "../file_format.h" +#include "../settings.h" +#include "../symbol.h" +#include "../undo_manager.h" +#include "../util.h" +#include "../util/backports.h" + + +constexpr int MainWindow::max_recent_files; + +int MainWindow::num_open_files = 0; + +MainWindow::MainWindow(QWidget* parent, Qt::WindowFlags flags) +: MainWindow { true, parent, flags } +{ + // nothing else +} + +MainWindow::MainWindow(bool as_main_window, QWidget* parent, Qt::WindowFlags flags) +: QMainWindow { parent, flags } +, controller { nullptr } +, create_menu { as_main_window } +, show_menu { create_menu && !mobileMode() } +, shortcuts_blocked { false } +, general_toolbar { nullptr } +, file_menu { nullptr } +, has_opened_file { false } +, has_unsaved_changes { false } +, has_autosave_conflict { false } +, maximized_before_fullscreen { false } +, homescreen_disabled { false } +{ + setWindowIcon(QIcon(QString::fromLatin1(":/images/mapper.png"))); + setAttribute(Qt::WA_DeleteOnClose); + + status_label = new QLabel(); + statusBar()->addWidget(status_label, 1); + statusBar()->setSizeGripEnabled(as_main_window); + if (mobileMode()) + statusBar()->hide(); + + central_widget = new QStackedWidget(this); + QMainWindow::setCentralWidget(central_widget); + + if (as_main_window) + loadWindowSettings(); + +#if defined(Q_OS_ANDROID) + // Needed to catch Qt::Key_Back, cf. MainWindow::eventFilter() + qApp->installEventFilter(this); +#else + installEventFilter(this); +#endif + + connect(&Settings::getInstance(), &Settings::settingsChanged, this, &MainWindow::settingsChanged); + connect(qApp, &QGuiApplication::applicationStateChanged, this, &MainWindow::applicationStateChanged); +} + + + +MainWindow::~MainWindow() +{ + if (controller) + { + controller->detach(); + delete controller; + delete general_toolbar; + } +} + +void MainWindow::settingsChanged() +{ + updateRecentFileActions(); +} + + + +void MainWindow::applicationStateChanged() +{ +#ifdef Q_OS_ANDROID + // The Android app may be started or resumed when the user triggers a suitable "intent". + if (QGuiApplication::applicationState() == Qt::ApplicationActive) + { + auto activity = QtAndroid::androidActivity(); + auto intent_path = activity.callObjectMethod("takeIntentPath").toString(); + if (!intent_path.isEmpty()) + { + const auto local_file = QUrl(intent_path).toLocalFile(); + if (!hasOpenedFile()) + { + openPathLater(local_file); + } + else if (currentPath() != local_file) + { + showStatusBarMessage(tr("You must close the current file before you can open another one.")); + } + return; + } + } +#endif + + // Only on startup, we may need to load the most recently used file. + static bool starting_up = true; + if (starting_up) + { + starting_up = false; + QSettings settings; + if (path_backlog.isEmpty() + && settings.value(QLatin1String("openMRUFile")).toBool()) + { + const auto files = settings.value(QLatin1String("recentFileList")).toStringList(); + if (!files.isEmpty()) + openPathLater(files[0]); + } + } +} + + + +QString MainWindow::appName() const +{ + return APP_NAME; +} + +#ifndef Q_OS_ANDROID +bool MainWindow::mobileMode() +{ + static bool mobile_mode = qEnvironmentVariableIsSet("MAPPER_MOBILE_GUI") + ? (qgetenv("MAPPER_MOBILE_GUI") != "0") + : 0; + return mobile_mode; +} +#endif + +void MainWindow::setCentralWidget(QWidget* widget) +{ + if (widget) + { + // Main window shall not resize to central widget size hint. + widget->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored); + + int index = central_widget->addWidget(widget); + central_widget->setCurrentIndex(index); + } + + if (central_widget->count() > 1) + { + QWidget* w = central_widget->widget(0); + central_widget->removeWidget(w); + w->deleteLater(); + } +} + +void MainWindow::setHomeScreenDisabled(bool disabled) +{ + homescreen_disabled = disabled; +} + +void MainWindow::setController(MainWindowController* new_controller) +{ + setController(new_controller, false); + setCurrentPath({}); +} + +void MainWindow::setController(MainWindowController* new_controller, const QString& path) +{ + setController(new_controller, true); + setCurrentPath(path); +} + +void MainWindow::setController(MainWindowController* new_controller, bool has_file) +{ + if (controller) + { + controller->detach(); + delete controller; + controller = nullptr; + + if (show_menu) + menuBar()->clear(); + delete general_toolbar; + general_toolbar = nullptr; + } + + has_opened_file = has_file; + shortcuts_blocked = false; + + if (create_menu) + createFileMenu(); + + controller = new_controller; + controller->attach(this); + + if (create_menu) + createHelpMenu(); + +#if defined(Q_OS_MAC) + if (isVisible() && qApp->activeWindow() == this) + { + // Force a menu synchronisation, + // QCocoaMenuBar::updateMenuBarImmediately(), + // via QCocoaNativeInterface::onAppFocusWindowChanged(). + qApp->focusWindowChanged(qApp->focusWindow()); + } +#endif + + setHasAutosaveConflict(false); + setHasUnsavedChanges(false); +} + +void MainWindow::createFileMenu() +{ + QAction* new_act = new QAction(QIcon(QString::fromLatin1(":/images/new.png")), tr("&New"), this); + new_act->setShortcuts(QKeySequence::New); + new_act->setStatusTip(tr("Create a new map")); + new_act->setWhatsThis(Util::makeWhatThis("file_menu.html")); + connect(new_act, &QAction::triggered, this, &MainWindow::showNewMapWizard); + + QAction* open_act = new QAction(QIcon(QString::fromLatin1(":/images/open.png")), tr("&Open..."), this); + open_act->setShortcuts(QKeySequence::Open); + open_act->setStatusTip(tr("Open an existing file")); + open_act->setWhatsThis(Util::makeWhatThis("file_menu.html")); + connect(open_act, &QAction::triggered, this, &MainWindow::showOpenDialog); + + open_recent_menu = new QMenu(tr("Open &recent"), this); + open_recent_menu->setWhatsThis(Util::makeWhatThis("file_menu.html")); + for (int i = 0; i < max_recent_files; ++i) + { + recent_file_act[i] = new QAction(this); + connect(recent_file_act[i], &QAction::triggered, this, &MainWindow::openRecentFile); + } + open_recent_menu_inserted = false; + + // NOTE: if you insert something between open_recent_menu and save_act, adjust updateRecentFileActions()! + + save_act = new QAction(QIcon(QString::fromLatin1(":/images/save.png")), tr("&Save"), this); + save_act->setShortcuts(QKeySequence::Save); + save_act->setWhatsThis(Util::makeWhatThis("file_menu.html")); + connect(save_act, &QAction::triggered, this, &MainWindow::save); + + auto save_as_act = new QAction(tr("Save &as..."), this); + if (QKeySequence::keyBindings(QKeySequence::SaveAs).empty()) + save_as_act->setShortcut(tr("Ctrl+Shift+S")); + else + save_as_act->setShortcuts(QKeySequence::SaveAs); + save_as_act->setWhatsThis(Util::makeWhatThis("file_menu.html")); + connect(save_as_act, &QAction::triggered, this, &MainWindow::showSaveAsDialog); + + settings_act = new QAction(tr("Settings..."), this); + settings_act->setShortcut(QKeySequence::Preferences); + settings_act->setMenuRole(QAction::PreferencesRole); + connect(settings_act, &QAction::triggered, this, &MainWindow::showSettings); + + close_act = new QAction(QIcon(QString::fromLatin1(":/images/close.png")), tr("Close"), this); + close_act->setShortcut(QKeySequence::Close); + close_act->setStatusTip(tr("Close this file")); + close_act->setWhatsThis(Util::makeWhatThis("file_menu.html")); + connect(close_act, &QAction::triggered, this, &MainWindow::closeFile); + + QAction* exit_act = new QAction(tr("E&xit"), this); + exit_act->setShortcuts(QKeySequence::Quit); + exit_act->setStatusTip(tr("Exit the application")); + exit_act->setMenuRole(QAction::QuitRole); + exit_act->setWhatsThis(Util::makeWhatThis("file_menu.html")); + connect(exit_act, &QAction::triggered, qApp, &QApplication::closeAllWindows); + + if (show_menu) + { + file_menu = menuBar()->addMenu(tr("&File")); + } + else + { + delete file_menu; + file_menu = new QMenu(this); + } + + file_menu->setWhatsThis(Util::makeWhatThis("file_menu.html")); + file_menu->addAction(new_act); + file_menu->addAction(open_act); + file_menu->addAction(save_act); + file_menu->addAction(save_as_act); + file_menu->addSeparator(); + file_menu->addAction(settings_act); + file_menu->addSeparator(); + file_menu->addAction(close_act); + file_menu->addAction(exit_act); + + general_toolbar = new QToolBar(tr("General")); + general_toolbar->setObjectName(QString::fromLatin1("General toolbar")); + general_toolbar->addAction(new_act); + general_toolbar->addAction(open_act); + general_toolbar->addAction(save_act); + + save_act->setEnabled(has_opened_file); + save_as_act->setEnabled(has_opened_file); + close_act->setEnabled(has_opened_file); + updateRecentFileActions(); +} + +void MainWindow::createHelpMenu() +{ + // Help menu + QAction* manualAct = new QAction(QIcon(QString::fromLatin1(":/images/help.png")), tr("Open &Manual"), this); + manualAct->setStatusTip(tr("Show the help file for this application")); + manualAct->setShortcut(QKeySequence::HelpContents); + connect(manualAct, &QAction::triggered, this, &MainWindow::showHelp); + + QAction* aboutAct = new QAction(tr("&About %1").arg(appName()), this); + aboutAct->setStatusTip(tr("Show information about this application")); + aboutAct->setMenuRole(QAction::AboutRole); + connect(aboutAct, &QAction::triggered, this, &MainWindow::showAbout); + + QAction* aboutQtAct = new QAction(tr("About &Qt"), this); + aboutQtAct->setStatusTip(tr("Show information about Qt")); + aboutQtAct->setMenuRole(QAction::AboutQtRole); + connect(aboutQtAct, &QAction::triggered, qApp, QApplication::aboutQt); + + if (show_menu) + { + QMenu* helpMenu = menuBar()->addMenu(tr("&Help")); + helpMenu->addAction(manualAct); + helpMenu->addAction(QWhatsThis::createAction(this)); + helpMenu->addSeparator(); + helpMenu->addAction(aboutAct); + helpMenu->addAction(aboutQtAct); + } +} + +void MainWindow::setCurrentPath(const QString& path) +{ + Q_ASSERT(has_opened_file || path.isEmpty()); + + QString window_file_path; + current_path.clear(); + if (has_opened_file) + { + window_file_path = QFileInfo(path).canonicalFilePath(); + if (window_file_path.isEmpty()) + window_file_path = tr("Unsaved file"); + else + current_path = window_file_path; + } + setWindowFilePath(window_file_path); +} + +void MainWindow::setMostRecentlyUsedFile(const QString& path) +{ + if (!path.isEmpty()) + { + Settings& settings = Settings::getInstance(); + + // Update least recently used directory + const QString open_directory = QFileInfo(path).canonicalPath(); + QSettings().setValue(QString::fromLatin1("openFileDirectory"), open_directory); + + // Update recent file lists + QStringList files = settings.getSettingCached(Settings::General_RecentFilesList).toStringList(); + files.removeAll(path); + files.prepend(path); + if (files.size() > max_recent_files) + files.erase(files.begin() + max_recent_files, files.end()); + settings.setSetting(Settings::General_RecentFilesList, files); + } +} + +void MainWindow::setHasUnsavedChanges(bool value) +{ + if (hasOpenedFile()) + { + has_unsaved_changes = value; + setAutosaveNeeded(has_unsaved_changes && !has_autosave_conflict); + } + setWindowModified(has_unsaved_changes); +} + +void MainWindow::setStatusBarText(const QString& text) +{ + status_label->setText(text); + status_label->setToolTip(text); +} + +void MainWindow::showStatusBarMessage(const QString& text, int timeout) +{ +#if defined(Q_OS_ANDROID) + Q_UNUSED(timeout); + QAndroidJniObject java_string = QAndroidJniObject::fromString(text); + QAndroidJniObject::callStaticMethod( + "org/openorienteering/mapper/MapperActivity", + "showShortMessage", + "(Ljava/lang/String;)V", + java_string.object()); +#else + statusBar()->showMessage(text, timeout); +#endif +} + +void MainWindow::clearStatusBarMessage() +{ +#if !defined(Q_OS_ANDROID) + statusBar()->clearMessage(); +#endif +} + +void MainWindow::setShortcutsBlocked(bool blocked) +{ + shortcuts_blocked = blocked; +} + +bool MainWindow::closeFile() +{ + bool closed = !has_opened_file || showSaveOnCloseDialog(); + if (closed) + { + if (has_opened_file) + { + num_open_files--; + has_opened_file = false; + } + if (homescreen_disabled || num_open_files > 0) + close(); + else + setController(new HomeScreenController()); + } + return closed; +} + +bool MainWindow::event(QEvent* event) +{ + if (event->type() == QEvent::ShortcutOverride && shortcutsBlocked()) + event->accept(); + + return QMainWindow::event(event); +} + +void MainWindow::closeEvent(QCloseEvent* event) +{ + if (!has_opened_file) + { + saveWindowSettings(); + event->accept(); + } + else if (showSaveOnCloseDialog()) + { + if (has_opened_file) + { + num_open_files--; + has_opened_file = false; + } + saveWindowSettings(); + event->accept(); + } + else + { + event->ignore(); + } +} + +void MainWindow::keyPressEvent(QKeyEvent* event) +{ + if (controller && controller->keyPressEventFilter(event)) + { + // Event filtered, stop handling + return; + } + + QMainWindow::keyPressEvent(event); +} + +void MainWindow::keyReleaseEvent(QKeyEvent* event) +{ + if (controller && controller->keyReleaseEventFilter(event)) + { + // Event filtered, stop handling + return; + } + + QMainWindow::keyReleaseEvent(event); +} + +bool MainWindow::showSaveOnCloseDialog() +{ + if (has_opened_file && (has_unsaved_changes || has_autosave_conflict)) + { + // Show the window in case it is minimized + setWindowState( (windowState() & ~Qt::WindowMinimized) | Qt::WindowActive); + raise(); + activateWindow(); + + QMessageBox::StandardButton ret; + if (!has_unsaved_changes && actual_path != autosavePath(currentPath())) + { + ret = QMessageBox::warning(this, appName(), + tr("Do you want to remove the autosaved version?"), + QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel); + } + else + { + ret = QMessageBox::warning(this, appName(), + tr("The file has been modified.\n" + "Do you want to save your changes?"), + QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel); + } + + switch (ret) + { + case QMessageBox::Cancel: + return false; + + case QMessageBox::Discard: + if (has_autosave_conflict) + setHasAutosaveConflict(false); + else + removeAutosaveFile(); + break; + + case QMessageBox::Save: + if (!save()) + return false; + // fall through + + case QMessageBox::Yes: + setHasAutosaveConflict(false); + removeAutosaveFile(); + break; + + case QMessageBox::No: + setHasAutosaveConflict(false); + break; + + default: + Q_ASSERT(false && "Unsupported return value from message box"); + break; + } + + } + + return true; +} + +void MainWindow::saveWindowSettings() +{ +#if !defined(Q_OS_ANDROID) + QSettings settings; + + settings.beginGroup(QString::fromLatin1("MainWindow")); + settings.setValue(QString::fromLatin1("pos"), pos()); + settings.setValue(QString::fromLatin1("size"), size()); + settings.setValue(QString::fromLatin1("maximized"), isMaximized()); + settings.endGroup(); +#endif +} + +void MainWindow::loadWindowSettings() +{ +#if defined(Q_OS_ANDROID) + // Always show the window on the whole available area on Android + resize(QApplication::desktop()->availableGeometry().size()); +#else + QSettings settings; + + settings.beginGroup(QString::fromLatin1("MainWindow")); + QPoint pos = settings.value(QString::fromLatin1("pos"), QPoint(100, 100)).toPoint(); + QSize size = settings.value(QString::fromLatin1("size"), QSize(800, 600)).toSize(); + bool maximized = settings.value(QString::fromLatin1("maximized"), false).toBool(); + settings.endGroup(); + + move(pos); + resize(size); + if (maximized) + showMaximized(); +#endif +} + +MainWindow* MainWindow::findMainWindow(const QString& file_name) +{ + QString canonical_file_path = QFileInfo(file_name).canonicalFilePath(); + if (canonical_file_path.isEmpty()) + return nullptr; + + const auto top_level_widgets = qApp->topLevelWidgets(); + for (auto widget : top_level_widgets) + { + MainWindow* other = qobject_cast(widget); + if (other && other->currentPath() == canonical_file_path) + return other; + } + + return nullptr; +} + +void MainWindow::showNewMapWizard() +{ + NewMapDialog newMapDialog(this); + newMapDialog.setWindowModality(Qt::WindowModal); + newMapDialog.exec(); + + if (newMapDialog.result() == QDialog::Rejected) + return; + + Map* new_map = new Map(); + MapView tmp_view { nullptr, new_map }; + QString symbol_set_path = newMapDialog.getSelectedSymbolSetPath(); + if (symbol_set_path.isEmpty()) + { + new_map->setScaleDenominator(newMapDialog.getSelectedScale()); + } + else + { + new_map->loadFrom(symbol_set_path, this, &tmp_view, true); + if (new_map->getScaleDenominator() != newMapDialog.getSelectedScale()) + { + if (QMessageBox::question(this, tr("Warning"), tr("The selected map scale is 1:%1, but the chosen symbol set has a nominal scale of 1:%2.\n\nDo you want to scale the symbols to the selected scale?").arg(newMapDialog.getSelectedScale()).arg(new_map->getScaleDenominator()), QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) + { + double factor = double(new_map->getScaleDenominator()) / newMapDialog.getSelectedScale(); + new_map->scaleAllSymbols(factor); + } + + new_map->setScaleDenominator(newMapDialog.getSelectedScale()); + } + + for (int i = new_map->getNumSymbols(); i > 0; i = qMin(i, new_map->getNumSymbols())) + { + --i; + auto symbol = new_map->getSymbol(i); + if (symbol->isHidden() + && !new_map->existsObjectWithSymbol(symbol)) + { + new_map->deleteSymbol(i); + } + } + } + + auto map_view = new MapView { new_map }; + map_view->setGridVisible(tmp_view.isGridVisible()); + + new_map->setHasUnsavedChanges(false); + new_map->undoManager().clear(); + + MainWindow* new_window = hasOpenedFile() ? new MainWindow() : this; + new_window->setController(new MapEditorController(MapEditorController::MapEditor, new_map, map_view), QString()); + + new_window->show(); + new_window->raise(); + new_window->activateWindow(); + num_open_files++; +} + +void MainWindow::showOpenDialog() +{ + QString path = getOpenFileName(this, tr("Open file"), FileFormat::AllFiles); + if (!path.isEmpty()) + openPath(path); +} + +bool MainWindow::openPath(const QString &path) +{ + // Empty path does nothing. This also helps with the single instance application code. + if (path.isEmpty()) + return true; + +#ifdef Q_OS_ANDROID + showStatusBarMessage(tr("Opening %1").arg(QFileInfo(path).fileName())); +#else + MainWindow* const existing = findMainWindow(path); + if (existing) + { + existing->show(); + existing->raise(); + existing->activateWindow(); + return true; + } +#endif + + // Check a blocker that prevents immediate re-opening of crashing files. + // Needed for stopping auto-loading a crashing file on startup. + static const QString reopen_blocker = QString::fromLatin1("open_in_progress"); + QSettings settings; + const QString open_in_progress(settings.value(reopen_blocker).toString()); + if (open_in_progress == path) + { + int result = QMessageBox::warning(this, tr("Crash warning"), + tr("It seems that %1 crashed the last time this file was opened:
%2

Really retry to open it?").arg(appName()).arg(path), + QMessageBox::Yes | QMessageBox::No); + settings.remove(reopen_blocker); + if (result == QMessageBox::No) + return false; + } + + settings.setValue(reopen_blocker, path); + settings.sync(); + + MainWindowController* const new_controller = MainWindowController::controllerForFile(path); + if (!new_controller) + { + QMessageBox::warning(this, tr("Error"), tr("Cannot open file:\n%1\n\nFile format not recognized.").arg(path)); + settings.remove(reopen_blocker); + return false; + } + + QString new_actual_path = path; + QString autosave_path = Autosave::autosavePath(path); + bool new_autosave_conflict = QFileInfo(autosave_path).exists(); + if (new_autosave_conflict) + { +#if defined(Q_OS_ANDROID) + // Assuming small screen, showing dialog before opening the file + AutosaveDialog* autosave_dialog = new AutosaveDialog(path, autosave_path, autosave_path, this); + int result = autosave_dialog->exec(); + new_actual_path = (result == QDialog::Accepted) ? autosave_dialog->selectedPath() : QString(); + delete autosave_dialog; +#else + // Assuming large screen, dialog will be shown while the autosaved file is open + new_actual_path = autosave_path; +#endif + } + + if (new_actual_path.isEmpty() || !new_controller->load(new_actual_path, this)) + { + delete new_controller; + settings.remove(reopen_blocker); + return false; + } + + MainWindow* open_window = this; +#if !defined(Q_OS_ANDROID) + if (has_opened_file) + open_window = new MainWindow(); +#endif + + open_window->setController(new_controller, path); + open_window->actual_path = new_actual_path; + open_window->setHasAutosaveConflict(new_autosave_conflict); + open_window->setHasUnsavedChanges(false); + + open_window->setVisible(true); // Respect the window flags set by new_controller. + open_window->raise(); + num_open_files++; + settings.remove(reopen_blocker); + setMostRecentlyUsedFile(path); + +#if !defined(Q_OS_ANDROID) + // Assuming large screen. Android handled above. + if (new_autosave_conflict) + { + auto autosave_dialog = new AutosaveDialog(path, autosave_path, new_actual_path, open_window, Qt::WindowTitleHint | Qt::CustomizeWindowHint); + autosave_dialog->move(open_window->rect().right() - autosave_dialog->width(), open_window->rect().top()); + autosave_dialog->show(); + autosave_dialog->raise(); + + connect(autosave_dialog, &AutosaveDialog::pathSelected, open_window, &MainWindow::switchActualPath); + connect(open_window, &MainWindow::actualPathChanged, autosave_dialog, &AutosaveDialog::setSelectedPath); + connect(open_window, &MainWindow::autosaveConflictResolved, autosave_dialog, &AutosaveDialog::autosaveConflictResolved); + } +#endif + + open_window->activateWindow(); + + return true; +} + +void MainWindow::switchActualPath(const QString& path) +{ + if (path == actual_path) + { + return; + } + + int ret = QMessageBox::Ok; + if (has_unsaved_changes) + { + ret = QMessageBox::warning(this, appName(), + tr("The file has been modified.\n" + "Do you want to discard your changes?"), + QMessageBox::Discard | QMessageBox::Cancel); + } + + if (ret != QMessageBox::Cancel) + { + const QString& current_path = currentPath(); + MainWindowController* const new_controller = MainWindowController::controllerForFile(current_path); + if (new_controller && new_controller->load(path, this)) + { + setController(new_controller, current_path); + actual_path = path; + setHasUnsavedChanges(false); + } + } + + emit actualPathChanged(actual_path); + activateWindow(); +} + +void MainWindow::openPathLater(const QString& path) +{ + path_backlog.push_back(path); + QTimer::singleShot(10, this, SLOT(openPathBacklog())); +} + +void MainWindow::openPathBacklog() +{ + for (const auto& path : qAsConst(path_backlog)) + openPath(path); + path_backlog.clear(); +} + +void MainWindow::openRecentFile() +{ + if (auto action = qobject_cast(sender())) + openPath(action->data().toString()); +} + +void MainWindow::updateRecentFileActions() +{ + if (! create_menu) + return; + + QStringList files = Settings::getInstance().getSettingCached(Settings::General_RecentFilesList).toStringList(); + + int num_recent_files = qMin(files.size(), max_recent_files); + + open_recent_menu->clear(); + for (int i = 0; i < num_recent_files; ++i) { + QString text = tr("&%1 %2").arg(i + 1).arg(QFileInfo(files[i]).fileName()); + recent_file_act[i]->setText(text); + recent_file_act[i]->setData(files[i]); + open_recent_menu->addAction(recent_file_act[i]); + } + + if (num_recent_files > 0 && !open_recent_menu_inserted) + file_menu->insertMenu(save_act, open_recent_menu); + else if (!(num_recent_files > 0) && open_recent_menu_inserted) + file_menu->removeAction(open_recent_menu->menuAction()); + open_recent_menu_inserted = num_recent_files > 0; +} + +void MainWindow::setHasAutosaveConflict(bool value) +{ + if (has_autosave_conflict != value) + { + has_autosave_conflict = value; + setAutosaveNeeded(has_unsaved_changes && !has_autosave_conflict); + if (!has_autosave_conflict) + emit autosaveConflictResolved(); + } +} + +bool MainWindow::removeAutosaveFile() const +{ + if (!currentPath().isEmpty() && !has_autosave_conflict) + { + QFile autosave_file(autosavePath(currentPath())); + return !autosave_file.exists() || autosave_file.remove(); + } + return false; +} + +Autosave::AutosaveResult MainWindow::autosave() +{ + QString path = currentPath(); + if (path.isEmpty() || !controller) + { + return Autosave::PermanentFailure; + } + else if (controller->isEditingInProgress()) + { + return Autosave::TemporaryFailure; + } + else + { + showStatusBarMessage(tr("Autosaving..."), 0); + if (controller->exportTo(autosavePath(currentPath()))) + { + // Success + clearStatusBarMessage(); + return Autosave::Success; + } + else + { + // Failure + showStatusBarMessage(tr("Autosaving failed!"), 6000); + return Autosave::PermanentFailure; + } + } +} + +bool MainWindow::save() +{ + return savePath(currentPath()); +} + +bool MainWindow::savePath(const QString &path) +{ + if (!controller) + return false; + + if (path.isEmpty()) + return showSaveAsDialog(); + + const FileFormat *format = FileFormats.findFormatForFilename(path); + if (format->isExportLossy()) + { + QString message = tr("This map is being saved as a \"%1\" file. Information may be lost.\n\nPress Yes to save in this format.\nPress No to choose a different format.").arg(format->description()); + int result = QMessageBox::warning(this, tr("Warning"), message, QMessageBox::Yes, QMessageBox::No); + if (result != QMessageBox::Yes) + return showSaveAsDialog(); + } + + if (!controller->save(path)) + return false; + + setMostRecentlyUsedFile(path); + + setHasAutosaveConflict(false); + removeAutosaveFile(); + + if (path != currentPath()) + { + setCurrentPath(path); + removeAutosaveFile(); + } + + setHasUnsavedChanges(false); + + return true; +} + +QString MainWindow::getOpenFileName(QWidget* parent, const QString& title, FileFormat::FileTypes types) +{ + // Get the saved directory to start in, defaulting to the user's home directory. + QSettings settings; + QString open_directory = settings.value(QString::fromLatin1("openFileDirectory"), QDir::homePath()).toString(); + + // Build the list of supported file filters based on the file format registry + QString filters, extensions; + + if (types.testFlag(FileFormat::MapFile)) + { + for (auto format : FileFormats.formats()) + { + if (format->supportsImport()) + { + if (filters.isEmpty()) + { + filters = format->filter(); + extensions = QLatin1String("*.") + format->fileExtensions().join(QString::fromLatin1(" *.")); + } + else + { + filters = filters + QLatin1String(";;") + format->filter(); + extensions = extensions + QLatin1String(" *.") + format->fileExtensions().join(QString::fromLatin1(" *.")); + } + } + } + filters = + tr("All maps") + QLatin1String(" (") + extensions + QLatin1String(");;") + + filters + QLatin1String(";;"); + } + + filters += tr("All files") + QLatin1String(" (*.*)"); + + QString path = QFileDialog::getOpenFileName(parent, title, open_directory, filters); + QFileInfo info(path); + return info.canonicalFilePath(); +} + +bool MainWindow::showSaveAsDialog() +{ + if (!controller) + return false; + + // Try current directory first + QFileInfo current(currentPath()); + QString save_directory = current.canonicalPath(); + if (save_directory.isEmpty()) + { + // revert to least recently used directory or home directory. + QSettings settings; + save_directory = settings.value(QString::fromLatin1("openFileDirectory"), QDir::homePath()).toString(); + } + + // Build the list of supported file filters based on the file format registry + QString filters; + for (auto format : FileFormats.formats()) + { + if (format->supportsExport()) + { + if (filters.isEmpty()) + filters = format->filter(); + else + filters = filters + QLatin1String(";;") + format->filter(); + } + } + + QString filter; // will be set to the selected filter by QFileDialog + QString path = QFileDialog::getSaveFileName(this, tr("Save file"), save_directory, filters, &filter); + + // On Windows, when the user enters "sample", we get "sample.omap *.xmap". + // (Fixed in upstream qtbase/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp + // Wednesday March 20 2013 in commit 426f2cc.) + // This results in an error later, because "*" is not a valid character. + // But it is reasonable to apply the workaround to all platforms, + // due to the special meaning of "*" in shell patterns. + const int extensions_quirk = path.indexOf(QLatin1String(" *.")); + if (extensions_quirk >= 0) + { + path.truncate(extensions_quirk); + } + + if (path.isEmpty()) + return false; + + const FileFormat *format = FileFormats.findFormatByFilter(filter); + if (!format) + { + QMessageBox::information(this, tr("Error"), + tr("File could not be saved:") + QLatin1Char('\n') + + tr("There was a problem in determining the file format.") + QLatin1Char('\n') + QLatin1Char('\n') + + tr("Please report this as a bug.") ); + return false; + } + + // Ensure that the provided filename has a correct file extension. + // Among other things, this will ensure that FileFormats.formatForFilename() + // returns the same thing the user selected in the dialog. +// QString selected_extension = "." + format->primaryExtension(); + QStringList selected_extensions(format->fileExtensions()); + selected_extensions.replaceInStrings(QRegExp(QString::fromLatin1("^")), QString::fromLatin1(".")); + bool has_extension = false; + for (auto selected_extension : qAsConst(selected_extensions)) + { + if (path.endsWith(selected_extension, Qt::CaseInsensitive)) + { + has_extension = true; + break; + } + } + if (!has_extension) + path += QLatin1Char('.') + format->primaryExtension(); + // Ensure that the file name matches the format. + Q_ASSERT(format->fileExtensions().contains(QFileInfo(path).suffix())); + // Fails when using different formats for import and export: + // Q_ASSERT(FileFormats.findFormatForFilename(path) == format); + + return savePath(path); +} + +void MainWindow::toggleFullscreenMode() +{ + if (isFullScreen()) + { + showNormal(); + if (maximized_before_fullscreen) + showMaximized(); + } + else + { + maximized_before_fullscreen = isMaximized(); + showFullScreen(); + } +} + +void MainWindow::showSettings() +{ + SettingsDialog dialog(this); + dialog.exec(); +} + +void MainWindow::showAbout() +{ + AboutDialog about_dialog(this); + about_dialog.exec(); +} + +void MainWindow::showHelp() +{ + Util::showHelp(this); +} + +void MainWindow::linkClicked(const QString &link) +{ + if (link.compare(QLatin1String("settings:"), Qt::CaseInsensitive) == 0) + showSettings(); + else if (link.compare(QLatin1String("help:"), Qt::CaseInsensitive) == 0) + showHelp(); + else if (link.compare(QLatin1String("about:"), Qt::CaseInsensitive) == 0) + showAbout(); + else if (link.startsWith(QLatin1String("examples:"), Qt::CaseInsensitive)) + { + auto example = link.midRef(9); + openPathLater(MapperResource::locate(MapperResource::EXAMPLE) + QLatin1Char('/') + example); + } + else + QDesktopServices::openUrl(link); +} + +bool MainWindow::eventFilter(QObject *object, QEvent *event) +{ + Q_UNUSED(object) + + switch(event->type()) + { + case QEvent::WhatsThisClicked: + { + QWhatsThisClickedEvent* e = static_cast(event); + Util::showHelp(this, e->href()); + }; + break; +#if defined(Q_OS_ANDROID) + case QEvent::KeyRelease: + if (static_cast(event)->key() == Qt::Key_Back && hasOpenedFile()) + { + /* Don't let Qt close the application in + * QGuiApplicationPrivate::processKeyEvent() while a file is opened. + * + * This must be the application-wide event filter in order to + * catch Qt::Key_Back from popup menus (such as template list, + * overflow actions). + * + * Any widgets that want to handle Qt::Key_Back need to watch + * for QEvent::KeyPress. + */ + event->accept(); + return true; + } + break; +#endif + default: + ; // nothing + } + + return false; +} diff --git a/src/gui/main_window.h b/src/gui/main_window.h new file mode 100644 index 0000000..d3877c0 --- /dev/null +++ b/src/gui/main_window.h @@ -0,0 +1,561 @@ +/* + * Copyright 2012, 2013 Thomas Schöps + * Copyright 2013-2016 Kai Pastor + * + * This file is part of OpenOrienteering. + * + * OpenOrienteering is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenOrienteering is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenOrienteering. If not, see . + */ + + +#ifndef OPENORIENTEERING_MAIN_WINDOW_H +#define OPENORIENTEERING_MAIN_WINDOW_H + +#include + +#include "../core/autosave.h" +#include "../file_format.h" + +QT_BEGIN_NAMESPACE +class QLabel; +class QStackedWidget; +class QTimer; +QT_END_NAMESPACE + +class MainWindowController; + +/** + * The MainWindow class provides the generic application window. + * + * It always has an active controller (class MainWindowController) + * which provides the specific window content and behaviours. + * The controller can be exchanged while the window is visible. + */ +class MainWindow : public QMainWindow, private Autosave +{ +Q_OBJECT +public: + /** + * Creates a new main window. + */ + explicit MainWindow(QWidget* parent = nullptr, Qt::WindowFlags flags = Qt::WindowFlags()); + +private: + /** + * Creates a new main window. + * + * The flag as_main_window is a contradiction to the general intent of this + * class. The value fals is used only once, in SymbolSettingDialog. For this + * case, it disables some features such as the main menu. + * + * \todo Refactor to remove the flag as_main_window. + */ + explicit MainWindow(bool as_main_window, QWidget* parent = nullptr, Qt::WindowFlags flags = Qt::WindowFlags()); + + friend class SymbolSettingDialog; + +public: + /** Destroys a main window. */ + ~MainWindow() override; + + /** Returns the application's localized name. */ + QString appName() const; + + + /** + * Returns whether the window is operating in mobile mode. + * + * On the desktop, the default (desktop) mode may be overwritten by + * setting the environment variable MAPPER_MOBILE_GUI to 0 or 1. + * + * For Android, this evaluates to constexpr true so that the compiler + * may optimize away desktop code in conditional blocks. + */ +#ifndef Q_OS_ANDROID + static bool mobileMode(); +#else + static constexpr bool mobileMode() { return true; } +#endif + + + /** + * Changes the controller. + * + * The new controller does not edit a file. + */ + void setController(MainWindowController* new_controller); + + /** + * Changes the controller. + * + * The new controller edits the file with the given path. + * The path may be empty for a new (unnamed) file. + */ + void setController(MainWindowController* new_controller, const QString& path); + +private: + void setController(MainWindowController* new_controller, bool has_file); + +public: + /** Returns the current controller. */ + MainWindowController* getController() const; + + + /** Returns the canonical path of the currently open file or + * an empty string if no file is open. + */ + const QString& currentPath() const; + + /** Registers the given path as most recently used file. + * + * The path is added at (or moved to) the top of the list of most recently + * used files, and the directory is saved as most recently used directory. + */ + static void setMostRecentlyUsedFile(const QString& path); + + /** Returns true if a file is opened in this main window. */ + bool hasOpenedFile() const; + + + /** Returns true if the opened file is marked as having unsaved changes. */ + bool hasUnsavedChanges() const; + + + /** Sets the text in the status bar. */ + void setStatusBarText(const QString& text); + + /** Shows a temporary message in the status bar. */ + void showStatusBarMessage(const QString& text, int timeout = 0); + + /** Clears temporary messages set in the status bar with showStatusBarMessage(). */ + void clearStatusBarMessage(); + + + /** + * Blocks shortcuts. + * + * During text input, it may be neccessary to disable shortcuts. + * + * @param blocked true for blocking shortcuts, false for normal behaviour. + */ + void setShortcutsBlocked(bool blocked); + + /** Returns true if shortcuts are currently disabled. */ + bool shortcutsBlocked() const; + + + /** Returns the main window's file menu so that it can be extended. */ + QMenu* getFileMenu() const; + + /** Returns an QAction which serves as extension point in the file menu. */ + QAction* getFileMenuExtensionAct() const; + + /** Returns the save action. */ + QAction* getSaveAct() const; + + /** Returns the close action. */ + QAction* getCloseAct() const; + + + /** + * Returns a general toolbar with standard file actions (new, open, save). + * + * The MainWindowController is responsible to add it to the main window. + * It will be destroyed (and recreated) when the controller changes. + */ + QToolBar* getGeneralToolBar() const; + + + /** Open the file with the given path after all events have been processed. + * May open a new main window. + * If loading is successful, the selected path will become + * the [new] window's current path. + */ + void openPathLater(const QString &path); + + /** Save the content of the main window. + * @param path the path where to save. + */ + bool savePath(const QString &path); + + /** Shows the open file dialog for the given file type(s) and returns the chosen file + * or an empty string if the dialog is aborted. + */ + static QString getOpenFileName(QWidget* parent, const QString& title, FileFormat::FileTypes types); + + /** + * Sets the MainWindow's effective central widget. + * + * Any previously set widget will be hidden and scheduled for deletion. + * + * Hides an implementation in QMainWindow which causes problems with + * dock widgets when switching from home screen widget to map widget. + * NEVER call QMainWindow::setCentralWidget(...) on a MainWindow. + */ + void setCentralWidget(QWidget* widget); + + + /** + * Indicates whether the home screen is disabled. + * + * Normally the last main window will return to the home screen when a file + * is closed. When the home screen is disabled, the last window will be + * closed instead. + */ + bool homeScreenDisabled() const; + + /** + * Sets whether to show the home screen after closing the last file. + * + * @see homeScreenDisabled() + */ + void setHomeScreenDisabled(bool disabled); + +public slots: + /** + * Reacts to application state changes. + * + * On Android, when the application state becomes Qt::ApplicationActive, + * this method looks for the Android activity's current intent and triggers + * the loading of a given file (if there is not already another file loaded). + * + * In general, when called for the first time after application start, it + * opens the most recently used file, unless this feature is disabled in the + * settings, and unless other files are registered for opening (i.e. files + * given as command line parameters.) + */ + void applicationStateChanged(); + + /** + * Show a wizard for creating new maps. + * + * May open a new main window. + */ + void showNewMapWizard(); + + /** + * Show a file-open dialog and load the select file. + * + * May open a new main window. + * If loading is successful, the selected path will become + * the [new] window's current path. + */ + void showOpenDialog(); + + /** + * Show a file-save dialog. + * + * If saving is successful, the selected path will become + * this window's current path. + * + * @return true if saving was succesful, false otherwise + */ + bool showSaveAsDialog(); + + /** + * Open the file with the given path. + * + * May open a new main window. + * If loading is successful, the selected path will become + * the [new] window's current path. + * + * @return true if loading was succesful, false otherwise + */ + bool openPath(const QString &path); + + /** + * Open the file specified in the sending action's data. + * + * This is intended for opening recent files. + */ + void openRecentFile(); + + /** + * Notify the main window of a change to the list of recent files. + */ + void updateRecentFileActions(); + + /** + * Save the current content to the current path. + * + * This will trigger a file-save dialog if the current path is not set (i.e. empty). + */ + bool save(); + + /** Save the current content to the current path. + */ + Autosave::AutosaveResult autosave() override; + + /** + * Close the file currently opened. + * + * If there are changes to the current file, the user will be asked if he + * wants to save it - the user may even cancel the closing of the file. + * + * This will close the window unless this is the last window. + * + * @return True if the file was actually closed, false otherwise. + */ + bool closeFile(); + + /** Toggle between normal window and fullscreen mode. + */ + void toggleFullscreenMode(); + + /** Show the settings dialog. + */ + void showSettings(); + + /** Show the about dialog. + */ + void showAbout(); + + /** Show the index page of the manual in the help browser. + */ + void showHelp(); + + /** Open a link. + * This is called when the user clicks on a link in the UI, + * e.g. in the tip of the day. + * + * @param link the target URI + */ + void linkClicked(const QString &link); + + /** + * Notifies this window of unsaved changes. + * + * If the controller was set as having an opened file, setting this value to + * true will start the autosave countdown if the previous value was false. + * + * This will update the window title via QWidget::setWindowModified(). + */ + void setHasUnsavedChanges(bool value); + +signals: + /** + * This signal is emitted when the actual path changes. + * + * @see switchActualPath() + */ + void actualPathChanged(const QString &path); + + /** + * This signal is emitted when an autosave conflict gets resolved. + * + * @see setHasAutosaveConflict() + */ + void autosaveConflictResolved(); + +protected slots: + /** + * Switches to a different controller and loads the given path. + * + * This method is meant for switching between an original file and + * autosaved versions. It does not touch current_path. The class of the new + * controller is determined from the current_path (i.e. original file). + * + * If the given path is the current actual_path, no change is made. + * + * If the currently loaded file was modified, the user is asked whether he + * really wants to switch to another file which means loosing the changes + * he had made. + */ + void switchActualPath(const QString &path); + + /** + * Open the files which have been registered by openPathLater(). + */ + void openPathBacklog(); + + /** + * Listens to configuration changes. + */ + void settingsChanged(); + +protected: + /** + * Sets the path of the file edited by this windows' controller. + * + * This will update the window title via QWidget::setWindowFilePath(). + * + * If the controller was not set as having an opened file, + * the path must be empty. + */ + void setCurrentPath(const QString& path); + + /** + * Notifies the windows of autosave conflicts. + * + * An autosave conflict is the situation where a autosaved file exists + * when the original file is opened. This autosaved file indicates that + * the original file was not properly closed, i.e. the software crashed + * before closing. + */ + void setHasAutosaveConflict(bool value); + + /** + * Removes the autosave file if it exists. + * + * Returns true if the file was removed or didn't exist, false otherwise. + */ + bool removeAutosaveFile() const; + + bool event(QEvent* event) override; + void closeEvent(QCloseEvent *event) override; + void keyPressEvent(QKeyEvent* event) override; + void keyReleaseEvent(QKeyEvent* event) override; + + bool eventFilter(QObject* object, QEvent* event) override; + +private: + static constexpr int max_recent_files = 10; + + /** + * Conditionally shows a dialog for saving pending changes. + * + * If this main window has an opened file with unsaved changes, shows + * a dialog which lets the user save the file, discard the changes or + * cancel. + * + * Returns true if the window can be closed, false otherwise. + */ + bool showSaveOnCloseDialog(); + + + /** Saves the window position and state. */ + void saveWindowSettings(); + + /** Loads the window position and state. */ + void loadWindowSettings(); + + + void createFileMenu(); + void createHelpMenu(); + + static MainWindow* findMainWindow(const QString& file_name); + + + /// The active controller + MainWindowController* controller; + const bool create_menu; + bool show_menu; + bool shortcuts_blocked; + + QToolBar* general_toolbar; + QMenu* file_menu; + QAction* save_act; + QMenu* open_recent_menu; + bool open_recent_menu_inserted; + QAction* recent_file_act[max_recent_files]; + QAction* settings_act; + QAction* close_act; + QLabel* status_label; + + /// Canonical path to the currently open file or an empty string if the file was not saved yet ("untitled") + QString current_path; + /// The actual path loaded by the editor. @see switchActualPath() + QString actual_path; + /// Does the main window display a file? If yes, new controllers will be opened in new main windows instead of replacing the active controller of this one + bool has_opened_file; + /// If this window has an opened file: does this file have unsaved changes? + bool has_unsaved_changes; + /// Indicates the presence of an autosave conflict. @see setHasAutosaveConflict() + bool has_autosave_conflict; + + /// Was the window maximized before going into fullscreen mode? In this case, we have to show it maximized again when leaving fullscreen mode. + bool maximized_before_fullscreen; + + bool homescreen_disabled; + + /// Number of active main windows. The last window shall not close on File > Close. + static int num_open_files; + + /// The central widget which never changes during a MainWindow's lifecycle + QStackedWidget* central_widget; + + /// A list of paths to be opened later + QStringList path_backlog; +}; + + +// ### MainWindow inline code ### + +inline +MainWindowController* MainWindow::getController() const +{ + return controller; +} + +inline +const QString& MainWindow::currentPath() const +{ + return current_path; +} + +inline +bool MainWindow::hasOpenedFile() const +{ + return has_opened_file; +} + +inline +bool MainWindow::hasUnsavedChanges() const +{ + return has_unsaved_changes; +} + +inline +bool MainWindow::shortcutsBlocked() const +{ + return shortcuts_blocked; +} + +inline +QMenu* MainWindow::getFileMenu() const +{ + return file_menu; +} + +inline +QAction* MainWindow::getFileMenuExtensionAct() const +{ + return settings_act; +} + +inline +QAction* MainWindow::getSaveAct() const +{ + return save_act; +} + +inline +QAction* MainWindow::getCloseAct() const +{ + return close_act; +} + +inline +QToolBar* MainWindow::getGeneralToolBar() const +{ + return general_toolbar; +} + +inline +bool MainWindow::homeScreenDisabled() const +{ + return homescreen_disabled; +} + +#endif diff --git a/src/gui/main_window_controller.cpp b/src/gui/main_window_controller.cpp new file mode 100644 index 0000000..7720dcf --- /dev/null +++ b/src/gui/main_window_controller.cpp @@ -0,0 +1,85 @@ +/* + * Copyright 2012, 2013 Thomas Schöps + * Copyright 2014 Thomas Schöps, Kai Pastor + * + * This file is part of OpenOrienteering. + * + * OpenOrienteering is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenOrienteering is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenOrienteering. If not, see . + */ + + +#include "main_window_controller.h" + +#include + +#include "../map_editor.h" +#include "../file_format.h" +#include "../file_format_registry.h" + + +MainWindowController::~MainWindowController() +{ + // nothing +} + +bool MainWindowController::save(const QString& path) +{ + Q_UNUSED(path); + return false; +} + +bool MainWindowController::exportTo(const QString& path, const FileFormat* format) +{ + Q_UNUSED(path); + Q_UNUSED(format); + return false; +} + +bool MainWindowController::load(const QString& path, QWidget* dialog_parent) +{ + Q_UNUSED(path); + Q_UNUSED(dialog_parent); + return false; +} + +void MainWindowController::detach() +{ + // nothing +} + +bool MainWindowController::isEditingInProgress() const +{ + return false; +} + +bool MainWindowController::keyPressEventFilter(QKeyEvent* event) +{ + Q_UNUSED(event); + return false; +} + +bool MainWindowController::keyReleaseEventFilter(QKeyEvent* event) +{ + Q_UNUSED(event); + return false; +} + +MainWindowController* MainWindowController::controllerForFile(const QString& filename) +{ + const FileFormat* format = FileFormats.findFormatForFilename(filename); + if (format != NULL && format->supportsImport()) + return new MapEditorController(MapEditorController::MapEditor); + + return NULL; +} diff --git a/src/gui/main_window_controller.h b/src/gui/main_window_controller.h new file mode 100644 index 0000000..bf09f2f --- /dev/null +++ b/src/gui/main_window_controller.h @@ -0,0 +1,130 @@ +/* + * Copyright 2012, 2013 Thomas Schöps + * Copyright 2014 Thomas Schöps, Kai Pastor + * + * This file is part of OpenOrienteering. + * + * OpenOrienteering is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenOrienteering is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenOrienteering. If not, see . + */ + + +#ifndef _OPENORIENTEERING_MAIN_WINDOW_CONTROLLER_H_ +#define _OPENORIENTEERING_MAIN_WINDOW_CONTROLLER_H_ + +#include + +class MainWindow; +class FileFormat; + + +/** A MainWindowController provides the specific content and + * behaviours for a main window, for example map drawing or + * course setting functions. + */ +class MainWindowController : public QObject +{ +Q_OBJECT +public: + + virtual ~MainWindowController(); + + /** Save to a file. + * @param path the path to save to + * @return true if saving was sucessful, false on errors + */ + virtual bool save(const QString& path); + + /** Export to a file, but don't change modified state + * with regard to the original file. + * @param path the path to export to + * @param format the file format (automatically determined if NULL) + * @return true if saving was sucessful, false on errors + */ + virtual bool exportTo(const QString& path, const FileFormat* format = NULL); + + /** Load from a file. + * @param path the path to load from + * @param dialog_parent Alternative parent widget for all dialogs. + * If NULL, implementations should use MainWindowController::window. + * @return true if loading was sucessful, false on errors + */ + virtual bool load(const QString& path, QWidget* dialog_parent = NULL); + + /** Attach the controller to a main window. + * The controller should create its user interface here. + */ + virtual void attach(MainWindow* window) = 0; + + /** Detach the controller from a main window. + * The controller should delete its user interface here. + */ + virtual void detach(); + + /** + * Returns true when editing is in progress. + * + * "Editing in progress" means the file is an "unstable" state where no + * global operations like save, undo, redo shall not be applied. + */ + virtual bool isEditingInProgress() const; + + /** + * @brief Receives key press events from the main window. + * + * QKeyEvent starts with isAccepted() == true, so the return value of this + * function decides if the event shall be stopped from being handled further. + * + * The default implementation simply returns false. + * + * @return True if the event shall be stopped from being handled further, false otherwise. + */ + virtual bool keyPressEventFilter(QKeyEvent* event); + + /** + * @brief Receives key release events from the main window. + * + * QKeyEvent starts with isAccepted() == true, so the return value of this + * function decides if the event shall be stopped from being handled further. + * + * The default implementation simply returns false. + * + * @return True if the event shall be stopped from being handled further, false otherwise. + */ + virtual bool keyReleaseEventFilter(QKeyEvent* event); + + /** Get the main window this controller is attached to. + */ + inline MainWindow* getWindow() const; + + /** Get a controller suitable for a particular file. + * @param filename the name of the file + * @return a MainWindowController that is able to load the file + */ + static MainWindowController* controllerForFile(const QString& filename); + +protected: + MainWindow* window; +}; + + + +//### MainWindowController inline code ### + +inline +MainWindow* MainWindowController::getWindow() const +{ + return window; +} + +#endif diff --git a/src/gui/modifier_key.cpp b/src/gui/modifier_key.cpp new file mode 100644 index 0000000..4e8eacb --- /dev/null +++ b/src/gui/modifier_key.cpp @@ -0,0 +1,97 @@ +/* + * Copyright 2013, 2015 Kai Pastor + * + * This file is part of OpenOrienteering. + * + * OpenOrienteering is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenOrienteering is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenOrienteering. If not, see . + */ + +#include "modifier_key.h" + + +ModifierKey::ModifierKey(int key) + : native_text { QKeySequence((int)key).toString(QKeySequence::NativeText) } +{ + if (native_text.endsWith(QLatin1Char('+'))) + { + native_text.chop(1); + } +} + +ModifierKey::ModifierKey(Qt::KeyboardModifiers keys) + : ModifierKey { (int)keys } +{ + // nothing else +} + +ModifierKey::ModifierKey(Qt::Key key) + : ModifierKey { (int)key } +{ + // nothing else +} + +const ModifierKey& ModifierKey::alt() +{ + static const ModifierKey key(Qt::AltModifier); + return key; +} + +const ModifierKey& ModifierKey::control() +{ + static const ModifierKey key(Qt::ControlModifier); + return key; +} + +const ModifierKey& ModifierKey::controlShift() +{ + static const ModifierKey key(Qt::ControlModifier | Qt::ShiftModifier); + return key; +} + +const ModifierKey& ModifierKey::meta() +{ + static const ModifierKey key(Qt::MetaModifier); + return key; +} + +const ModifierKey& ModifierKey::shift() +{ + static const ModifierKey key(Qt::ShiftModifier); + return key; +} + +const ModifierKey& ModifierKey::space() +{ + static const ModifierKey key(Qt::Key_Space); + return key; +} + +const ModifierKey& ModifierKey::return_key() +{ + static const ModifierKey key(Qt::Key_Return); + return key; +} + +const ModifierKey& ModifierKey::backspace() +{ + static const ModifierKey key(Qt::Key_Backspace); + return key; +} + +const ModifierKey& ModifierKey::escape() +{ + static const ModifierKey key(Qt::Key_Escape); + return key; +} + diff --git a/src/gui/modifier_key.h b/src/gui/modifier_key.h new file mode 100644 index 0000000..77775b4 --- /dev/null +++ b/src/gui/modifier_key.h @@ -0,0 +1,113 @@ +/* + * Copyright 2013, 2015 Kai Pastor + * + * This file is part of OpenOrienteering. + * + * OpenOrienteering is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenOrienteering is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenOrienteering. If not, see . + */ + +#ifndef _OPENORIENTEERING_MODIFIER_KEY_H +#define _OPENORIENTEERING_MODIFIER_KEY_H + +#include +#include + +/** + * A class that helps to deal efficiently with platform and localization issues + * of modifier keys. + * + * It is based on QKeySequence::toString(QKeySequence::NativeText) which provides + * localization and deals with swapping Ctrl and Cmd on Mac OS X. In contrast + * to QKeySequence, ModifierKey has an implicit operator for casting to QString, + * and it removes the trailing '+' from pseudo key sequences which consist of + * modifier keys only. Static methods provide efficient translations of the + * pure modifier keys. + * + * For true QKeySequences, call QKeySequence::toString(QKeySequence::NativeText) + * directly. + * + * On Windows and Linux, the keys will be displayed as word ("Shift" etc.). + * On OS X, the keys will be displayed as graphical symbols ("⇧", i.e. + * Unicode character U+21E7, etc.). + * + * Synopsis: + * + * QString text = tr("%1+Click to add a point.").arg(ModifierKey::control()); + * QString more = tr("%1+Click to select a point.").arg(ModifierKey(Qt::ALT + Qt::ShiftModifier)); + * + * // BUT: + * QString help = help_action.shortcut().toString(QKeySequence::NativeText); + */ +class ModifierKey +{ +protected: + /** Constructs a new ModifierKey for the given key. */ + explicit ModifierKey(int key); + +public: + /** Constructs a new ModifierKey for the given combination of KeyboardModifiers. */ + explicit ModifierKey(Qt::KeyboardModifiers keys); + + /** Constructs a new ModifierKey for the given key. */ + explicit ModifierKey(Qt::Key key); + + /** Returns a string representation for user interface purposes. + * + * This operator is intented to be used for implicit type casts. */ + operator QString() const; + + /** Returns a shared Alt modifier key. */ + static const ModifierKey& alt(); + + /** Returns a shared Control modifier key. */ + static const ModifierKey& control(); + + /** Returns a shared Control+Shift modifier key. */ + static const ModifierKey& controlShift(); + + /** Returns a shared Meta modifier key. */ + static const ModifierKey& meta(); + + /** Returns a shared Shift modifier key. */ + static const ModifierKey& shift(); + + /** Returns a shared Space key. */ + static const ModifierKey& space(); + + /** Returns a shared Return key. */ + static const ModifierKey& return_key(); + + /** Returns a shared Backspace key. */ + static const ModifierKey& backspace(); + + /** Returns a shared Escape modifier key. */ + static const ModifierKey& escape(); + +private: + /** The native text (localized, adapted to the system). */ + QString native_text; +}; + + + +// Inline implementation + +inline +ModifierKey::operator QString() const +{ + return native_text; +} + + +#endif diff --git a/src/gui/point_handles.cpp b/src/gui/point_handles.cpp new file mode 100644 index 0000000..3875532 --- /dev/null +++ b/src/gui/point_handles.cpp @@ -0,0 +1,193 @@ +/* + * Copyright 2012, 2013 Thomas Schöps + * Copyright 2014, 2015 Kai Pastor + * + * This file is part of OpenOrienteering. + * + * OpenOrienteering is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenOrienteering is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenOrienteering. If not, see . + */ + +#include "point_handles.h" + +#include + +#include "../map_widget.h" +#include "../object.h" +#include "../object_text.h" +#include "../settings.h" + +PointHandles::PointHandles(int scale_factor) +: scale_factor(scale_factor) +, handle_image(loadHandleImage(scale_factor)) +{ + ; // nothing +} + +QRgb PointHandles::stateColor(PointHandleState state) const +{ + switch (state) + { + case NormalHandleState: return qRgb( 0, 0, 255); + case ActiveHandleState: return qRgb(255, 150, 0); + case SelectedHandleState: return qRgb(255, 0, 0); + case DisabledHandleState: return qRgb(106, 106, 106); + default: Q_UNREACHABLE(); + return qRgb(255, 0, 0); + } +} + +void PointHandles::draw( + QPainter* painter, + const MapWidget* widget, + const Object* object, + MapCoordVector::size_type hover_point, + bool draw_curve_handles, + PointHandleState base_state ) const +{ + if (object->getType() == Object::Point) + { + const PointObject* point = reinterpret_cast(object); + draw(painter, widget->mapToViewport(point->getCoordF()), NormalHandle, (hover_point == 0) ? ActiveHandleState : base_state); + } + else if (object->getType() == Object::Text) + { + const TextObject* text = reinterpret_cast(object); + std::vector text_handles(text->controlPoints()); + for (std::size_t i = 0; i < text_handles.size(); ++i) + draw(painter, widget->mapToViewport(text_handles[i]), NormalHandle, (hover_point == i) ? ActiveHandleState : base_state); + } + else if (object->getType() == Object::Path) + { + painter->setBrush(Qt::NoBrush); // for handle lines + + const PathObject* path = reinterpret_cast(object); + + for (const auto& part : path->parts()) + { + bool have_curve = part.isClosed() && part.size() > 3 && path->getCoordinate(part.last_index - 3).isCurveStart(); + PointHandleType handle_type = NormalHandle; + + for (auto i = part.first_index; i <= part.last_index; ++i) + { + MapCoord coord = path->getCoordinate(i); + if (coord.isClosePoint()) + continue; + QPointF point = widget->mapToViewport(coord); + bool is_active = hover_point == i; + + if (i == part.first_index && !part.isClosed()) // || (i > part.start_index && path->getCoordinate(i-1).isHolePoint())) + handle_type = StartHandle; + else if (i == part.last_index && !part.isClosed()) // || coord.isHolePoint()) + handle_type = EndHandle; + else + handle_type = coord.isDashPoint() ? DashHandle : NormalHandle; + + // Draw incoming curve handle + QPointF curve_handle; + if (draw_curve_handles && have_curve) + { + auto curve_index = (i == part.first_index) ? (part.last_index - 1) : (i - 1); + curve_handle = widget->mapToViewport(path->getCoordinate(curve_index)); + drawCurveHandleLine(painter, point, curve_handle, handle_type, is_active ? ActiveHandleState : base_state); + draw(painter, curve_handle, CurveHandle, (is_active || hover_point == curve_index) ? ActiveHandleState : base_state); + have_curve = false; + } + + // Draw outgoing curve handle, first part + if (draw_curve_handles && coord.isCurveStart()) + { + curve_handle = widget->mapToViewport(path->getCoordinate(i+1)); + drawCurveHandleLine(painter, point, curve_handle,handle_type, is_active ? ActiveHandleState : base_state); + } + + // Draw point + draw(painter, point, handle_type, is_active ? ActiveHandleState : base_state); + + // Draw outgoing curve handle, second part + if (coord.isCurveStart()) + { + if (draw_curve_handles) + { + draw(painter, curve_handle, CurveHandle, (is_active || hover_point == i + 1) ? ActiveHandleState : base_state); + have_curve = true; + } + i += 2; + } + } + } + } + else + Q_ASSERT(false); +} + +void PointHandles::draw(QPainter* painter, QPointF position, PointHandleType type, PointHandleState state) const +{ + int width = scale_factor * 11; + int offset = (width - 1) / 2; + painter->drawImage(qRound(position.x()) - offset, qRound(position.y()) - offset, image(), (int)type * width, (int)state * width, width, width); +} + +void PointHandles::drawCurveHandleLine(QPainter* painter, QPointF anchor_point, QPointF curve_handle, PointHandleType type, PointHandleState state) const +{ + const float handle_radius = 3 * scale_factor; + if (scale_factor > 1) + painter->setPen(QPen(QBrush(stateColor(state)), scale_factor)); + else + painter->setPen(stateColor(state)); + + QPointF to_handle = curve_handle - anchor_point; + float to_handle_len = to_handle.x()*to_handle.x() + to_handle.y()*to_handle.y(); + if (to_handle_len > 0.00001f) + { + to_handle_len = sqrt(to_handle_len); + if (type == StartHandle) + anchor_point += scale_factor * 5 / qMax(qAbs(to_handle.x()), qAbs(to_handle.y())) * to_handle; + else if (type == DashHandle) + anchor_point += scale_factor * to_handle * (3 / to_handle_len); + else //if (type == NormalHandle) + anchor_point += scale_factor * 3 / qMax(qAbs(to_handle.x()), qAbs(to_handle.y())) * to_handle; + + curve_handle -= to_handle * (handle_radius / to_handle_len); + } + + painter->drawLine(anchor_point, curve_handle); +} + +// static +const QImage PointHandles::loadHandleImage(int factor) +{ + static const QStringList image_names = ( + QStringList() << QString() // not used + << QStringLiteral(":/images/point-handles.png") + << QStringLiteral(":/images/point-handles-2x.png") + << QString() // not used + << QStringLiteral(":/images/point-handles-4x.png") + ); + + Q_ASSERT(factor < image_names.size()); + + // NOTE: If this fails, check MapEditorTool::newScaleFactor()! + Q_ASSERT(!image_names[factor].isEmpty()); + + static int shared_image_factor = factor; + static QImage shared_image = QImage(image_names[shared_image_factor]); + if (shared_image_factor != factor) + { + shared_image_factor = factor; + shared_image = QImage(image_names[shared_image_factor]); + } + + return shared_image; +} + diff --git a/src/gui/point_handles.h b/src/gui/point_handles.h new file mode 100644 index 0000000..3c2d62c --- /dev/null +++ b/src/gui/point_handles.h @@ -0,0 +1,152 @@ +/* + * Copyright 2012, 2013 Thomas Schöps + * Copyright 2014, 2015 Kai Pastor + * + * This file is part of OpenOrienteering. + * + * OpenOrienteering is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenOrienteering is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenOrienteering. If not, see . + */ + +#ifndef _OPENORIENTEERING_POINT_HANDLES_H +#define _OPENORIENTEERING_POINT_HANDLES_H + +#include +#include + +#include "../core/map_coord.h" + +class MapWidget; +class Object; + +/** + * @brief This class deals with anchor and control points for objects. + */ +class PointHandles +{ +public: + /** + * @brief Types of point handle. + * + * The numbers correspond to the columns in point-handles.png + */ + enum PointHandleType + { + StartHandle = 0, + EndHandle = 1, + NormalHandle = 2, + CurveHandle = 3, + DashHandle = 4 + }; + + /** + * @brief States of point handles. + * + * The numbers correspond to the rows in point-handles.png + */ + enum PointHandleState + { + NormalHandleState = 0, + ActiveHandleState = 1, + SelectedHandleState = 2, + DisabledHandleState = 3 + }; + + /** + * @brief Constructs a new point handles utility. + * + * The constructor assures that current settings are used. + */ + PointHandles(int scale_factor); + + /** + * @brief The factor by which all drawing shall be scaled. + * + * The control point handles image matches this factor, too. + * Currently, this value is either 1, 2, or 4. + */ + int scaleFactor() const; + + /** + * @brief The control point handles image. + * + * The control point image matches the current scale factor. + */ + const QImage image() const; + + /** + * @brief Returns the color in which point handles with the given state will be displayed. + */ + QRgb stateColor(PointHandleState state) const; + + /** + * @brief Draws a single handle. + */ + void draw(QPainter* painter, QPointF position, PointHandleType type, PointHandleState state) const; + + /** + * @brief Draws all point handles for the given object. + * + * @param painter QPainter object with correct transformation set. + * @param widget Map widget which provides coordinate transformations. + * @param object Object to draw point handles for. + * @param hover_point Index of a point which should be drawn in 'active' state. Pass a negative number to disable. + * @param draw_curve_handles If false, curve handles for path objects are not drawn. + * @param base_state The state in which all points except hover_point should be drawn. + */ + void draw(QPainter* painter, + const MapWidget* widget, + const Object* object, + MapCoordVector::size_type hover_point = std::numeric_limits::max(), + bool draw_curve_handles = true, + PointHandleState base_state = NormalHandleState + ) const; + + /** + * @brief Draws a point handle line. + * + * The curve handle line connects a curve anchor point and a controlling handle. + */ + void drawCurveHandleLine(QPainter* painter, QPointF anchor_point, QPointF curve_handle, PointHandleType type, PointHandleState state) const; + +private: + /** + * @brief Loads and returns the image for a for a particular scale. + * + * Since scale depends on the pixels-per-inch setting and doesn't change + * very often, the image is loaded only when the scale changes and returned + * from an internal cache otherwise. + */ + static const QImage loadHandleImage(int scale); + + int scale_factor; + QImage handle_image; +}; + + + +//### PointHandles inline code ### + +inline +int PointHandles::scaleFactor() const +{ + return scale_factor; +} + +inline +const QImage PointHandles::image() const +{ + return handle_image; +} + +#endif // _OPENORIENTEERING_POINT_HANDLES_H diff --git a/src/gui/print_progress_dialog.cpp b/src/gui/print_progress_dialog.cpp new file mode 100644 index 0000000..cc72d57 --- /dev/null +++ b/src/gui/print_progress_dialog.cpp @@ -0,0 +1,74 @@ +/* + * Copyright 2013-2015 Kai Pastor + * + * This file is part of OpenOrienteering. + * + * OpenOrienteering is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenOrienteering is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenOrienteering. If not, see . + */ + + +#ifdef QT_PRINTSUPPORT_LIB + +#include "print_progress_dialog.h" + +#include +#include +#include + +#include "../core/map_printer.h" + + +PrintProgressDialog::PrintProgressDialog(MapPrinter* map_printer, QWidget* parent, Qt::WindowFlags f) + : QProgressDialog(parent, f) + , map_printer(map_printer) +{ + setWindowModality(Qt::ApplicationModal); // Required for OSX, cf. QTBUG-40112 + setRange(0, 100); + setMinimumDuration(0); + setValue(0); + + Q_ASSERT(map_printer); + connect(map_printer, &MapPrinter::printProgress, this, &PrintProgressDialog::setProgress); + connect(this, &PrintProgressDialog::canceled, map_printer, &MapPrinter::cancelPrintMap); +} + +PrintProgressDialog::~PrintProgressDialog() +{ + // nothing, not inlined +} + +void PrintProgressDialog::paintRequested(QPrinter* printer) +{ + if (!map_printer->printMap(printer)) + { + QMessageBox::warning( + parentWidget(), tr("Printing", "PrintWidget"), + tr("An error occurred during processing.", "PrintWidget"), + QMessageBox::Ok, QMessageBox::Ok ); + } +} + +void PrintProgressDialog::setProgress(int value, QString status) +{ + setLabelText(status); + setValue(value); + if (!isVisible() && value < maximum()) + { + show(); + } + + QApplication::processEvents(); // Drawing and Cancel events +} + +#endif diff --git a/src/gui/print_progress_dialog.h b/src/gui/print_progress_dialog.h new file mode 100644 index 0000000..23ee696 --- /dev/null +++ b/src/gui/print_progress_dialog.h @@ -0,0 +1,83 @@ +/* + * Copyright 2013-2015 Kai Pastor + * + * This file is part of OpenOrienteering. + * + * OpenOrienteering is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenOrienteering is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenOrienteering. If not, see . + */ + + +#ifdef QT_PRINTSUPPORT_LIB + +#ifndef _OPENORIENTEERING_PRINT_WIDGET_P_H_ +#define _OPENORIENTEERING_PRINT_WIDGET_P_H_ + +#include + +class QPrinter; +class MapPrinter; + +/** + * PrintProgressDialog is a variation of QProgressDialog to be used with MapPrinter. + * + * PrintProgressDialog connects to the MapPrint::printMapProgress() signal. + * It provides a paintRequested slot which is to be connected to the + * corresponding QPrintPreviewDialog signal. + * + * This dialog is modal (for the application) by default. + */ +class PrintProgressDialog : public QProgressDialog +{ +Q_OBJECT +public: + /** + * Constructs a new dialog for the given MapPrinter. + * + * map_printer must not be nullptr. + */ + PrintProgressDialog(MapPrinter* map_printer, QWidget* parent = nullptr, Qt::WindowFlags f = 0); + + /** + * Destructor. + */ + ~PrintProgressDialog(); + +public slots: + /** + * Listens to and forwards paint requests. + * + * Shows an error message if printing fails. + */ + void paintRequested(QPrinter* printer); + +protected slots: + /** + * Listens to printing progress messages. + * + * Shows the dialog if it was hidden, and processes events before returning. + * This makes it possible to react on the dialog's Cancel button, and to + * draw UI updates. + * + * @param value The progress, from 0 (not started) to 100 (finished). + * @param message The text to be shown as a label to the progress. + */ + void setProgress(int value, QString message); + +private: + MapPrinter* const map_printer; +}; + +#endif + +#endif // QT_PRINTSUPPORT_LIB diff --git a/src/gui/print_tool.cpp b/src/gui/print_tool.cpp new file mode 100644 index 0000000..4a23073 --- /dev/null +++ b/src/gui/print_tool.cpp @@ -0,0 +1,377 @@ +/* + * Copyright 2012, 2013 Thomas Schöps + * Copyright 2012-2016 Kai Pastor + * + * This file is part of OpenOrienteering. + * + * OpenOrienteering is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenOrienteering is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenOrienteering. If not, see . + */ + + +#ifdef QT_PRINTSUPPORT_LIB + +#include "print_tool.h" + +#include +#include + +#include "../core/map_printer.h" +#include "../map_editor.h" +#include "../map_widget.h" +#include "print_widget.h" + + +PrintTool::PrintTool(MapEditorController* editor, MapPrinter* map_printer) +: MapEditorTool { editor, Other, nullptr } +, map_printer { map_printer } +, region { Unknown } +, dragging { false } +{ + Q_ASSERT(editor); + Q_ASSERT(map_printer); + + connect(map_printer, &MapPrinter::printAreaChanged, this, &PrintTool::updatePrintArea); + connect(map_printer, &MapPrinter::pageFormatChanged, this, &PrintTool::updatePrintArea); + // Page breaks may change upon scale changes. + connect(map_printer, &MapPrinter::optionsChanged, this, &PrintTool::updatePrintArea); +} + +PrintTool::~PrintTool() +{ + // nothing, not inlined +} + +void PrintTool::init() +{ + setStatusBarText(tr("Drag: Move the map, the print area or the area's borders. ")); + updatePrintArea(); + + MapEditorTool::init(); +} + +const QCursor& PrintTool::getCursor() const +{ + static auto const cursor = QCursor{ Qt::ArrowCursor }; + return cursor; +} + +bool PrintTool::mousePressEvent(QMouseEvent* event, MapCoordF map_coord, MapWidget* widget) +{ + if (event->button() == Qt::LeftButton) + { + mouseMoved(map_coord, widget); + dragging = true; + click_pos = event->pos(); + click_pos_map = map_coord; + if (region == Inside || region == Outside) + widget->setCursor(Qt::ClosedHandCursor); + return true; + } + + if (event->button() == Qt::RightButton) + { + return true; // disable context menu + } + + return false; +} + +bool PrintTool::mouseMoveEvent(QMouseEvent* event, MapCoordF map_coord, MapWidget* widget) +{ + if (dragging && event->buttons() & Qt::LeftButton) + { + if (region == Outside) + { + mapWidget()->getMapView()->setPanOffset(event->pos() - click_pos); + } + else + { + updateDragging(map_coord); + } + return true; + } + + mouseMoved(map_coord, widget); + return false; +} + +bool PrintTool::mouseReleaseEvent(QMouseEvent* event, MapCoordF map_coord, MapWidget* widget) +{ + if (dragging && event->button() == Qt::LeftButton) + { + if (region == Outside) + { + mapWidget()->getMapView()->finishPanning(event->pos() - click_pos); + } + else + { + updateDragging(map_coord); + } + dragging = false; + region = Unknown; // forces mouseMoved() to update cursor and status + mouseMoved(map_coord, widget); + return true; + } + + return false; +} + +void PrintTool::draw(QPainter* painter, MapWidget* widget) +{ + painter->save(); + + QRect view_area = QRect(0, 0, widget->width(), widget->height()); + QRect print_area = widget->mapToViewport(map_printer->getPrintArea()).toRect(); + qreal scale_adjustment = map_printer->getScaleAdjustment(); + QSizeF page_size = widget->mapToViewport(map_printer->getPageFormat().page_rect).size() / scale_adjustment; + + // Strongly darken the region outside the print area + painter->setBrush(QColor(0, 0, 0, 160)); + painter->setPen(Qt::NoPen); + QPainterPath outside_path; + outside_path.addRect(view_area); + outside_path.addRect(view_area.intersected(print_area)); + painter->drawPath(outside_path); + + Q_ASSERT(!map_printer->horizontalPagePositions().empty()); + Q_ASSERT(!map_printer->verticalPagePositions().empty()); + QPointF outer_top_left = widget->mapToViewport( QPointF( + map_printer->horizontalPagePositions().front(), + map_printer->verticalPagePositions().front() ) ); + QPointF outer_bottom_right = widget->mapToViewport( QPointF( + map_printer->horizontalPagePositions().back(), + map_printer->verticalPagePositions().back() ) ); + outer_bottom_right += QPointF(page_size.width(), page_size.height()); + QRectF outer_rect(outer_top_left, outer_bottom_right); + + // Draw red lines for page breaks + QColor top_left_margin_color(255, 0, 0, 160); + QColor bottom_right_margin_color(255, 128, 128, 160); + painter->setBrush(Qt::NoBrush); + + // The relative length of the page dimensions to be actual drawn. + QSizeF drawing_size(page_size * scale_adjustment); + if (map_printer->horizontalPagePositions().size() > 1) + { + drawing_size.setWidth(drawing_size.width() * 0.9 * ( + map_printer->horizontalPagePositions()[1] - + map_printer->horizontalPagePositions()[0] ) / + map_printer->getPageFormat().page_rect.width() ); + } + if (map_printer->verticalPagePositions().size() > 1) + { + drawing_size.setHeight(drawing_size.height() * 0.9 * ( + map_printer->verticalPagePositions()[1] - + map_printer->verticalPagePositions()[0] ) / + map_printer->getPageFormat().page_rect.height() ); + } + + int h = 0; + for (auto hpos : map_printer->horizontalPagePositions()) + { + ++h; + if (h > 100) // Don't visualize too many pages. + break; + + int v = 0; + for (auto vpos : map_printer->verticalPagePositions()) + { + ++v; + if (h+v > 100) // Don't visualize too many pages. + break; + + QPointF pos = widget->mapToViewport(MapCoordF(hpos, vpos)); + painter->setPen(top_left_margin_color); + // Left vertical line + painter->drawLine(QLineF{pos.x(), pos.y(), pos.x(), pos.y()+drawing_size.height()}); + // Top horizontal line + painter->drawLine(QLineF{pos.x(), pos.y(), pos.x()+drawing_size.width(), pos.y()}); + + pos += QPointF(page_size.width(), page_size.height()); + painter->setPen(bottom_right_margin_color); + // Right vertical line + painter->drawLine(QLineF{pos.x(), pos.y()-drawing_size.height(), pos.x(), pos.y()}); + // Bottom horizontal line + painter->drawLine(QLineF{pos.x()-drawing_size.width(), pos.y(), pos.x(), pos.y()}); + } + } + + painter->setPen(top_left_margin_color); + painter->drawLine(QLineF{outer_rect.left(), outer_rect.top(), outer_rect.left(), outer_rect.bottom()}); + painter->drawLine(QLineF{outer_rect.left(), outer_rect.top(), outer_rect.right(), outer_rect.top()}); + painter->setPen(bottom_right_margin_color); + painter->drawLine(QLineF{outer_rect.right(), outer_rect.top(), outer_rect.right(), outer_rect.bottom()}); + painter->drawLine(QLineF{outer_rect.left(), outer_rect.bottom(), outer_rect.right(), outer_rect.bottom()}); + + QRectF print_area_f(print_area); + QPen marker(Qt::red); + marker.setWidth(4); + painter->setPen(marker); + painter->setOpacity(0.5); + if (region == Inside) + { + painter->drawRect(print_area_f); + } + if (region & LeftBorder) + { + painter->drawLine(print_area_f.topLeft(), print_area_f.bottomLeft()); + } + if (region & TopBorder) + { + painter->drawLine(print_area_f.topLeft(), print_area_f.topRight()); + } + if (region & RightBorder) + { + painter->drawLine(print_area_f.topRight(), print_area_f.bottomRight()); + } + if (region & BottomBorder) + { + painter->drawLine(print_area_f.bottomLeft(), print_area_f.bottomRight()); + } + + painter->restore(); +} + +void PrintTool::updatePrintArea() +{ + // The print area visualization is updated by redrawing the whole map. + // TODO: Replace with a more explicit way of marking the whole map area as dirty. + editor->getMap()->setDrawingBoundingBox(QRectF(-1000000, -1000000, 2000000, 2000000), 0); +} + +void PrintTool::updateDragging(MapCoordF mouse_pos_map) +{ + QPointF delta = QPointF(mouse_pos_map - click_pos_map); + QRectF area = map_printer->getPrintArea(); + switch (region) + { + case Inside: + area.moveTopLeft(area.topLeft() + delta); + break; + case LeftBorder: + area.setLeft(area.left() + delta.rx()); + break; + case TopLeftCorner: + area.setTopLeft(area.topLeft() + delta); + break; + case TopBorder: + area.setTop(area.top() + delta.ry()); + break; + case TopRightCorner: + area.setTopRight(area.topRight() + delta); + break; + case RightBorder: + area.setRight(area.right() + delta.rx()); + break; + case BottomRightCorner: + area.setBottomRight(area.bottomRight() + delta); + break; + case BottomBorder: + area.setBottom(area.bottom() + delta.ry()); + break; + case BottomLeftCorner: + area.setBottomLeft(area.bottomLeft() + delta); + break; + case Outside: + Q_ASSERT(false); // Handled outside. + case Unknown: + ; // Nothing + } + + if (area.left() < area.right() && area.top() < area.bottom()) + { + map_printer->setPrintArea(area); + click_pos_map = mouse_pos_map; + } +} + +void PrintTool::mouseMoved(MapCoordF mouse_pos_map, MapWidget* widget) +{ + Q_ASSERT(!dragging); // No change while dragging! + + static const qreal margin_width = 16.0; + static const qreal outer_margin = 8.0; + + QRectF print_area = widget->mapToViewport(map_printer->getPrintArea()); + print_area.adjust(-outer_margin, -outer_margin, outer_margin, outer_margin); + QPointF mouse_pos = widget->mapToViewport(mouse_pos_map); + + int new_region = Outside; + if (print_area.contains(mouse_pos)) + { + new_region = Inside; + + if (mouse_pos.rx() < print_area.left() + margin_width) + { + new_region |= LeftBorder; + } + else if (mouse_pos.rx() > print_area.right() - margin_width) + { + new_region |= RightBorder; + } + + if (mouse_pos.ry() < print_area.top() + margin_width) + { + new_region |= TopBorder; + } + else if (mouse_pos.ry() > print_area.bottom() - margin_width) + { + new_region |= BottomBorder; + } + } + + if (new_region != region) + { + region = InteractionRegion(new_region); + + switch (region) + { + case Inside: + setStatusBarText(tr("Drag: Move the print area. ")); + widget->setCursor(Qt::OpenHandCursor); + break; + case Outside: + setStatusBarText(tr("Drag: Move the map. ")); + widget->setCursor(Qt::ArrowCursor); + break; + case LeftBorder: + case RightBorder: + setStatusBarText(tr("Drag: Move the print area's border. ")); + widget->setCursor(Qt::SizeHorCursor); + break; + case TopBorder: + case BottomBorder: + setStatusBarText(tr("Drag: Move the print area's border. ")); + widget->setCursor(Qt::SizeVerCursor); + break; + case TopLeftCorner: + case BottomRightCorner: + setStatusBarText(tr("Drag: Move the print area's borders. ")); + widget->setCursor(Qt::SizeFDiagCursor); + break; + case TopRightCorner: + case BottomLeftCorner: + setStatusBarText(tr("Drag: Move the print area's borders. ")); + widget->setCursor(Qt::SizeBDiagCursor); + break; + case Unknown: + setStatusBarText(tr("Drag: Move the map, the print area or the area's borders. ")); + widget->setCursor(Qt::ArrowCursor); + } + + updatePrintArea(); + } +} + +#endif // QT_PRINTSUPPORT_LIB diff --git a/src/gui/print_tool.h b/src/gui/print_tool.h new file mode 100644 index 0000000..1f86854 --- /dev/null +++ b/src/gui/print_tool.h @@ -0,0 +1,117 @@ +/* + * Copyright 2012, 2013 Thomas Schöps + * Copyright 2012-2016 Kai Pastor + * + * This file is part of OpenOrienteering. + * + * OpenOrienteering is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenOrienteering is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenOrienteering. If not, see . + */ + + +#ifndef OPENORIENTEERING_PRINT_TOOL_H +#define OPENORIENTEERING_PRINT_TOOL_H + +#ifdef QT_PRINTSUPPORT_LIB + +#include + +#include "../tool.h" + +class MapPrinter; + +/** + * The PrintTool lets the user see and modify the print area on the map + * by dragging + * + * It interacts with a MapEditorController and a PrintWidget which are set in + * the constructor. + */ +class PrintTool : public MapEditorTool +{ +Q_OBJECT +public: + /** Constructs a new PrintTool to configure the given map printer in the + * context of the editor. + * + * The parameters must not be null. */ + PrintTool(MapEditorController* editor, MapPrinter* map_printer); + + ~PrintTool() override; + + /** Notifies the tool that it becomes active. */ + void init() override; + + /** Always returns the tool's default cursor. */ + const QCursor& getCursor() const override; + + /** Starts a dragging interaction. */ + bool mousePressEvent(QMouseEvent* event, MapCoordF map_coord, MapWidget* widget) override; + + /** Updates the state of a running dragging interaction. When not dragging, + * it will update the cursor to indicate a possible interaction. */ + bool mouseMoveEvent(QMouseEvent* event, MapCoordF map_coord, MapWidget* widget) override; + + /** Finishes dragging interactions. */ + bool mouseReleaseEvent(QMouseEvent* event, MapCoordF map_coord, MapWidget* widget) override; + + /** Draws a visualization of the print area the map widget. */ + void draw(QPainter* painter, MapWidget* widget) override; + +public slots: + /** Updates the print area visualization in the map editors. */ + void updatePrintArea(); + +protected: + /** Modifies the print area while dragging. + * This must not be called when the region is Outside. */ + void updateDragging(MapCoordF mouse_pos_map); + + /** Updates the current interaction region. + * This must not be called during dragging. */ + void mouseMoved(MapCoordF mouse_pos_map, MapWidget* widget); + + /** Regions of interaction with the print area. */ + enum InteractionRegion { + Inside = 0x00, + Outside = 0x01, + LeftBorder = 0x02, + TopLeftCorner = 0x06, + TopBorder = 0x04, + TopRightCorner = 0x0c, + RightBorder = 0x08, + BottomRightCorner = 0x18, + BottomBorder = 0x10, + BottomLeftCorner = 0x12, + Unknown = 0xFF + }; + + /** The map printer this tool is operation on. */ + MapPrinter* const map_printer; + + /** The region of the print area where the current interaction takes place. */ + InteractionRegion region; + + /** Indicates whether an interaction is taking place at the moment. */ + bool dragging; + + /** The screen position where the initial click was made. */ + QPoint click_pos; + + /** The map position where the initial click was made. */ + MapCoordF click_pos_map; +}; + +#endif // QT_PRINTSUPPORT_LIB + +#endif // OPENORIENTEERING_PRINT_TOOL_H diff --git a/src/gui/print_widget.cpp b/src/gui/print_widget.cpp new file mode 100644 index 0000000..4ea1d9d --- /dev/null +++ b/src/gui/print_widget.cpp @@ -0,0 +1,1335 @@ +/* + * Copyright 2012, 2013 Thomas Schöps + * Copyright 2012-2016 Kai Pastor + * + * This file is part of OpenOrienteering. + * + * OpenOrienteering is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenOrienteering is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenOrienteering. If not, see . + */ + + +#ifdef QT_PRINTSUPPORT_LIB + +#include "print_widget.h" + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "main_window.h" +#include "print_progress_dialog.h" +#include "print_tool.h" +#include "../core/map_printer.h" +#include "../map.h" +#include "../map_editor.h" +#include "../map_widget.h" +#include "../settings.h" +#include "../template.h" +#include "../util.h" +#include "../util_gui.h" +#include "../util/backports.h" +#include "../util/scoped_signals_blocker.h" + + +namespace +{ + QToolButton* createPrintModeButton(const QIcon& icon, const QString& label, QWidget* parent = nullptr) + { + static const QSize icon_size(48,48); + QToolButton* button = new QToolButton(parent); + button->setAutoRaise(true); + button->setCheckable(true); + button->setIconSize(icon_size); + button->setIcon(icon); + button->setText(label); + button->setToolButtonStyle(Qt::ToolButtonTextUnderIcon); + return button; + } +} + +//### PrintWidget ### + +PrintWidget::PrintWidget(Map* map, MainWindow* main_window, MapView* main_view, MapEditorController* editor, QWidget* parent) +: QWidget { parent } +, task { UNDEFINED_TASK } +, map { map } +, map_printer { new MapPrinter(*map, main_view) } +, main_window { main_window } +, main_view { main_view } +, editor { editor } +, print_tool { nullptr } +, active { false } +{ + Q_ASSERT(main_window); + + layout = new QFormLayout(); + + target_combo = new QComboBox(); + target_combo->setMinimumWidth(1); // Not zero, but not as long as the items + layout->addRow(Util::Headline::create(tr("Printer:")), target_combo); + + if (PlatformPrinterProperties::dialogSupported()) + { + printer_properties_button = new QToolButton(); + printer_properties_button->setText(tr("Properties")); + layout->addRow(nullptr, printer_properties_button); + } + else + { + printer_properties_button = nullptr; + } + + paper_size_combo = new QComboBox(); + layout->addRow(tr("Page format:"), paper_size_combo); + + QWidget* page_size_widget = new QWidget(); + QHBoxLayout* page_size_layout = new QHBoxLayout(); + page_size_widget->setLayout(page_size_layout); + page_size_layout->setMargin(0); + page_width_edit = Util::SpinBox::create(1, 0.1, 1000.0, tr("mm"), 1.0); + page_width_edit->setEnabled(false); + page_size_layout->addWidget(page_width_edit, 1); + page_size_layout->addWidget(new QLabel(QString::fromLatin1("x")), 0); + page_height_edit = Util::SpinBox::create(1, 0.1, 1000.0, tr("mm"), 1.0); + page_height_edit->setEnabled(false); + page_size_layout->addWidget(page_height_edit, 1); + layout->addRow({}, page_size_widget); + + page_orientation_widget = new QWidget(); + QBoxLayout* page_orientation_layout = new QHBoxLayout(); + page_orientation_layout->setContentsMargins(QMargins()); + page_orientation_widget->setLayout(page_orientation_layout); + QRadioButton* portrait_button = new QRadioButton(tr("Portrait")); + page_orientation_layout->addWidget(portrait_button); + QRadioButton* landscape_button = new QRadioButton(tr("Landscape")); + page_orientation_layout->addWidget(landscape_button); + page_orientation_group = new QButtonGroup(this); + page_orientation_group->addButton(portrait_button, QPrinter::Portrait); + page_orientation_group->addButton(landscape_button, QPrinter::Landscape); + layout->addRow(tr("Page orientation:"), page_orientation_widget); + + copies_edit = Util::SpinBox::create(1, 99999); + layout->addRow(tr("Copies:"), copies_edit); + + layout->addItem(Util::SpacerItem::create(this)); + + policy_combo = new QComboBox(); + policy_combo->addItem(tr("Single page"), SinglePage); + policy_combo->addItem(tr("Custom area"), CustomArea); + layout->addRow(Util::Headline::create(tr("Map area:")), policy_combo); // or print/export area + + center_check = new QCheckBox(tr("Center print area")); + layout->addRow(center_check); + + left_edit = Util::SpinBox::create(2, -999999.9, 999999.9, tr("mm"), 1.0); + layout->addRow(tr("Left:"), left_edit); + + top_edit = Util::SpinBox::create(2, -999999.9, 999999.9, tr("mm"), 1.0); + layout->addRow(tr("Top:"), top_edit); + + width_edit = Util::SpinBox::create(2, -999999.9, 999999.9, tr("mm"), 1.0); + layout->addRow(tr("Width:"), width_edit); + + height_edit = Util::SpinBox::create(2, -999999.9, 999999.9, tr("mm"), 1.0); + layout->addRow(tr("Height:"), height_edit); + + overlap_edit = Util::SpinBox::create(2, -999999.9, 999999.9, tr("mm"), 1.0); + layout->addRow(tr("Page overlap:"), overlap_edit); + + layout->addItem(Util::SpacerItem::create(this)); + + layout->addRow(Util::Headline::create(tr("Options"))); + + QWidget* mode_widget = new QWidget(); + QBoxLayout* mode_layout = new QHBoxLayout(); + mode_widget->setLayout(mode_layout); + mode_layout->setMargin(0); + + vector_mode_button = createPrintModeButton(QIcon(QString::fromLatin1(":/images/print-mode-vector.png")), tr("Vector\ngraphics")); + raster_mode_button = createPrintModeButton(QIcon(QString::fromLatin1(":/images/print-mode-raster.png")), tr("Raster\ngraphics")); + separations_mode_button = createPrintModeButton(QIcon(QString::fromLatin1(":/images/print-mode-separations.png")), tr("Color\nseparations")); + vector_mode_button->setChecked(true); + + QButtonGroup* mode_button_group = new QButtonGroup(this); + mode_button_group->addButton(vector_mode_button); + mode_button_group->addButton(raster_mode_button); + mode_button_group->addButton(separations_mode_button); + + mode_layout->addWidget(vector_mode_button); + mode_layout->addWidget(raster_mode_button); + mode_layout->addWidget(separations_mode_button); + mode_layout->addStretch(1); + + layout->addRow(tr("Mode:"), mode_widget); + + dpi_combo = new QComboBox(); + dpi_combo->setEditable(true); + dpi_combo->setValidator(new QRegExpValidator(QRegExp(QLatin1String("^[1-9]\\d{1,4}$|^[1-9]\\d{1,4} ")+tr("dpi")+QLatin1Char('$')), dpi_combo)); + // TODO: Implement spinbox-style " dpi" suffix + layout->addRow(tr("Resolution:"), dpi_combo); + + different_scale_check = new QCheckBox(tr("Print in different scale:")); + // Limit the difference between nominal and printing scale in order to limit the number of page breaks. + int min_scale = qMax(1, int(map->getScaleDenominator() / 10000) * 100); + different_scale_edit = Util::SpinBox::create(min_scale, std::numeric_limits::max(), {}, 500); + different_scale_edit->setPrefix(QString::fromLatin1("1 : ")); + different_scale_edit->setEnabled(false); + int different_scale_height = qMax( + different_scale_edit->minimumSizeHint().height(), + different_scale_check->minimumSizeHint().height() ); + different_scale_check->setMinimumHeight(different_scale_height); + different_scale_edit->setMinimumHeight(different_scale_height); + layout->addRow(different_scale_check, different_scale_edit); + + // this must be created before its value is used to determine the default setting of page_orientation_combo + show_templates_check = new QCheckBox(tr("Show templates")); + QHBoxLayout* templates_warning_layout = new QHBoxLayout(); + QIcon warning_icon = style()->standardIcon(QStyle::SP_MessageBoxWarning); + templates_warning_icon = new QLabel(); + int pixmap_size = qBound(8, style()->pixelMetric(QStyle::PM_IndicatorHeight), 32); + templates_warning_icon->setPixmap(warning_icon.pixmap(QSize(pixmap_size, pixmap_size))); + templates_warning_layout->addWidget(templates_warning_icon); + templates_warning_text = new QLabel(tr("Template appearance may differ.")); + templates_warning_layout->addWidget(templates_warning_text, 1); + layout->addRow(show_templates_check, templates_warning_layout); + + show_grid_check = new QCheckBox(tr("Show grid")); + layout->addRow(show_grid_check); + + overprinting_check = new QCheckBox(tr("Simulate overprinting")); + layout->addRow(overprinting_check); + + color_mode_combo = new QComboBox(); + color_mode_combo->setEditable(false); + color_mode_combo->addItem(tr("Default"), QVariant()); + color_mode_combo->addItem(tr("Device CMYK (experimental)"), QVariant(true)); + layout->addRow(tr("Color mode:"), color_mode_combo); + + scrolling_content = new QWidget(); + scrolling_content->setLayout(layout); + + QBoxLayout* outer_layout = new QVBoxLayout(); + outer_layout->setContentsMargins(QMargins()); + + scroll_area = new QScrollArea(); + scroll_area->setWidget(scrolling_content); + scroll_area->setWidgetResizable(true); + scroll_area->setMinimumWidth((scrolling_content->sizeHint() + scroll_area->verticalScrollBar()->sizeHint()).width()); + outer_layout->addWidget(scroll_area); + + button_box = new QDialogButtonBox(); + QStyleOption style_option(QStyleOption::Version, QStyleOption::SO_DockWidget); + button_box->layout()->setContentsMargins( + style()->pixelMetric(QStyle::PM_LayoutLeftMargin, &style_option), + style()->pixelMetric(QStyle::PM_LayoutTopMargin, &style_option), + style()->pixelMetric(QStyle::PM_LayoutRightMargin, &style_option), + style()->pixelMetric(QStyle::PM_LayoutBottomMargin, &style_option) + ); + preview_button = new QPushButton(tr("Preview...")); + button_box->addButton(preview_button, QDialogButtonBox::ActionRole); + print_button = new QPushButton(tr("Print")); + button_box->addButton(print_button, QDialogButtonBox::ActionRole); + // Use a distinct export button. + // Changing the text at runtime causes distortions on Mac OS X. + export_button = new QPushButton(tr("Export...")); + export_button->hide(); + button_box->addButton(export_button, QDialogButtonBox::ActionRole); + QPushButton* close_button = button_box->addButton(QDialogButtonBox::Close); + outer_layout->addWidget(button_box); + + setLayout(outer_layout); + + connect(target_combo, QOverload::of(&QComboBox::currentIndexChanged), this, &PrintWidget::targetChanged); + if (printer_properties_button) + connect(printer_properties_button, &QAbstractButton::clicked, this, &PrintWidget::propertiesClicked, Qt::QueuedConnection); + connect(paper_size_combo, QOverload::of(&QComboBox::currentIndexChanged), this, &PrintWidget::paperSizeChanged); + connect(page_width_edit, QOverload::of(&QDoubleSpinBox::valueChanged), this, &PrintWidget::paperDimensionsChanged); + connect(page_orientation_group, QOverload::of(&QButtonGroup::buttonClicked), this, &PrintWidget::pageOrientationChanged); + connect(page_height_edit, QOverload::of(&QDoubleSpinBox::valueChanged), this, &PrintWidget::paperDimensionsChanged); + + connect(top_edit, QOverload::of(&QDoubleSpinBox::valueChanged), this, &PrintWidget::printAreaMoved); + connect(left_edit, QOverload::of(&QDoubleSpinBox::valueChanged), this, &PrintWidget::printAreaMoved); + connect(width_edit, QOverload::of(&QDoubleSpinBox::valueChanged), this, &PrintWidget::printAreaResized); + connect(height_edit, QOverload::of(&QDoubleSpinBox::valueChanged), this, &PrintWidget::printAreaResized); + connect(overlap_edit, QOverload::of(&QDoubleSpinBox::valueChanged), this, &PrintWidget::overlapEdited); + + connect(mode_button_group, QOverload::of(&QButtonGroup::buttonClicked), this, &PrintWidget::printModeChanged); + connect(dpi_combo->lineEdit(), &QLineEdit::editingFinished, this, &PrintWidget::resolutionEdited); + connect(different_scale_check, &QAbstractButton::clicked, this, &PrintWidget::differentScaleClicked); + connect(different_scale_edit, QOverload::of(&QSpinBox::valueChanged), this, &PrintWidget::differentScaleEdited); + connect(show_templates_check, &QAbstractButton::clicked, this, &PrintWidget::showTemplatesClicked); + connect(show_grid_check, &QAbstractButton::clicked, this, &PrintWidget::showGridClicked); + connect(overprinting_check, &QAbstractButton::clicked, this, &PrintWidget::overprintingClicked); + connect(color_mode_combo, &QComboBox::currentTextChanged, this, &PrintWidget::colorModeChanged); + + connect(preview_button, &QAbstractButton::clicked, this, &PrintWidget::previewClicked); + connect(print_button, &QAbstractButton::clicked, this, &PrintWidget::printClicked); + connect(export_button, &QAbstractButton::clicked, this, &PrintWidget::printClicked); + connect(close_button, &QAbstractButton::clicked, this, &PrintWidget::closeClicked); + + policy = map_printer->config().single_page_print_area ? SinglePage : CustomArea; + policy_combo->setCurrentIndex(policy_combo->findData(policy)); + connect(policy_combo, QOverload::of(&QComboBox::currentIndexChanged), this, &PrintWidget::printAreaPolicyChanged); + + center_check->setChecked(map_printer->config().center_print_area); + connect(center_check, &QAbstractButton::clicked, this, &PrintWidget::applyCenterPolicy); + + setPageFormat(map_printer->getPageFormat()); + connect(map_printer, &MapPrinter::pageFormatChanged, this, &PrintWidget::setPageFormat); + + connect(map_printer, &MapPrinter::optionsChanged, this, &PrintWidget::setOptions); + spotColorPresenceChanged(map->hasSpotColors()); + connect(map, &Map::spotColorPresenceChanged, this, &PrintWidget::spotColorPresenceChanged); + + setPrintArea(map_printer->getPrintArea()); + connect(map_printer, &MapPrinter::printAreaChanged, this, &PrintWidget::setPrintArea); + + connect(map_printer, &MapPrinter::targetChanged, this, &PrintWidget::setTarget); + + connect(this, &PrintWidget::finished, this, &PrintWidget::savePrinterConfig); +} + +PrintWidget::~PrintWidget() +{ + delete map_printer; +} + +QSize PrintWidget::sizeHint() const +{ + QSize size = QWidget::sizeHint(); + size.setHeight(scrolling_content->sizeHint().height() + + 2 * scroll_area->frameWidth() + + button_box->sizeHint().height() + + layout->horizontalSpacing() ); + return size; +} + +// slot +void PrintWidget::setTask(PrintWidget::TaskFlags type) +{ + if (task != type) + { + task = type; + bool is_print_task = type==PRINT_TASK; + bool is_multipage = type.testFlag(MULTIPAGE_FLAG); + layout->labelForField(target_combo)->setVisible(is_print_task); + target_combo->setVisible(is_print_task); + layout->labelForField(copies_edit)->setVisible(is_multipage); + copies_edit->setVisible(is_multipage); + policy_combo->setVisible(is_multipage); + updateTargets(); + switch (type) + { + case PRINT_TASK: + // Reset values which are typically modified for exporting + if (policy == SinglePage && !map->printerConfig().single_page_print_area) + { + policy = CustomArea; + policy_combo->setCurrentIndex(policy_combo->findData(policy)); + } + if (map_printer->getPageFormat().paper_size == QPrinter::Custom) + { + map_printer->setPaperSize(map->printerConfig().page_format.paper_size); + } + // TODO: Set target to most recently used printer + emit taskChanged(tr("Print")); + break; + + case EXPORT_PDF_TASK: + map_printer->setTarget(MapPrinter::pdfTarget()); + emit taskChanged(tr("PDF export")); + break; + + case EXPORT_IMAGE_TASK: + map_printer->setTarget(MapPrinter::imageTarget()); + policy = SinglePage; + if (policy_combo->itemData(policy_combo->currentIndex()) != policy) + { + map_printer->setCustomPaperSize(map_printer->getPrintAreaPaperSize()); + policy_combo->setCurrentIndex(policy_combo->findData(policy)); + } + emit taskChanged(tr("Image export")); + break; + + default: + emit taskChanged(QString{}); + } + } +} + +// slot +void PrintWidget::savePrinterConfig() const +{ + MapPrinterConfig printer_config(map_printer->config()); + printer_config.center_print_area = center_check->isChecked(); + if (task.testFlag(MULTIPAGE_FLAG)) + { + printer_config.single_page_print_area = policy == SinglePage; + } + if (task.testFlag(EXPORT_IMAGE_TASK)) + { + // Don't override the printer page format from the custom image format. + printer_config.page_format = map->printerConfig().page_format; + } + map->setPrinterConfig(printer_config); +} + +// slot +void PrintWidget::setActive(bool active) +{ + if (this->active != active) + { + this->active = active; + + if (active) + { + // Save the current state of the map view. + saved_view_state.clear(); + QXmlStreamWriter writer(&saved_view_state); + main_view->save(writer, QLatin1String("saved_view"), false); + + editor->setViewOptionsEnabled(false); + + // Printers may have been added or removed. + updateTargets(); + + // Update the map view from the current options + setOptions(map_printer->getOptions()); + connect(main_view, &MapView::visibilityChanged, this, &PrintWidget::onVisibilityChanged); + + // Set reasonable zoom. + bool zoom_to_map = true; + if (zoom_to_map) + { + // Ensure the visibility of the whole map. + QRectF map_extent = map->calculateExtent(true, !main_view->areAllTemplatesHidden(), main_view); + editor->getMainWidget()->ensureVisibilityOfRect(map_extent, MapWidget::ContinuousZoom); + } + else + { + // Ensure the visibility of the print area. + QRectF print_area(map_printer->getPrintArea()); + editor->getMainWidget()->ensureVisibilityOfRect(print_area, MapWidget::ContinuousZoom); + } + + // Activate PrintTool. + if (!print_tool) + { + print_tool = new PrintTool(editor, map_printer); + } + editor->setOverrideTool(print_tool); + editor->setEditingInProgress(true); + } + else + { + disconnect(main_view, &MapView::visibilityChanged, this, &PrintWidget::onVisibilityChanged); + + editor->setEditingInProgress(false); + editor->setOverrideTool(nullptr); + print_tool = nullptr; + + // Restore view + QXmlStreamReader reader(saved_view_state); + reader.readNextStartElement(); + main_view->load(reader); + + editor->setViewOptionsEnabled(true); + } + } +} + + + +void PrintWidget::updateTargets() +{ + QVariant current_target = target_combo->itemData(target_combo->currentIndex()); + const QPrinterInfo* saved_printer = map_printer->getTarget(); + const QString saved_printer_name = saved_printer ? saved_printer->printerName() : QString{}; + int saved_target_index = -1; + int default_printer_index = -1; + { + const QSignalBlocker block(target_combo); + target_combo->clear(); + + if (task == PRINT_TASK) + { + // Exporters + target_combo->addItem(tr("Save to PDF"), QVariant(int(PdfExporter))); + target_combo->insertSeparator(target_combo->count()); + target_combo->setCurrentIndex(0); + + // Printers +#if QT_VERSION < 0x050300 + printers = QPrinterInfo::availablePrinters(); + for (int i = 0; i < printers.size(); ++i) + { + if (printers[i].printerName() == saved_printer_name) + saved_target_index = target_combo->count(); + if (printers[i].isDefault()) + default_printer_index = target_combo->count(); + target_combo->addItem(printers[i].printerName(), i); + } +#else + auto default_printer_name = QPrinterInfo::defaultPrinterName(); + printers = QPrinterInfo::availablePrinterNames(); + for (int i = 0; i < printers.size(); ++i) + { + const QString& name = printers[i]; + if (name == saved_printer_name) + saved_target_index = target_combo->count(); + if (name == default_printer_name) + default_printer_index = target_combo->count(); + target_combo->addItem(name, i); + } +#endif + } + + // Restore selected target if possible and exit on success + if (current_target.isValid()) + { + int index = target_combo->findData(current_target); + if (index >= 0) + { + target_combo->setCurrentIndex(index); + return; + } + } + + if (saved_target_index >= 0) + // Restore saved target if possible + target_combo->setCurrentIndex(saved_target_index); + else if (default_printer_index >= 0) + // Set default printer as current target + target_combo->setCurrentIndex(default_printer_index); + + // Explicitly invoke signal handler + targetChanged(target_combo->currentIndex()); + } +} + +// slot +void PrintWidget::setTarget(const QPrinterInfo* target) +{ + int target_index = printers.size()-1; + if (target == MapPrinter::pdfTarget()) + target_index = PdfExporter; + else if (target == MapPrinter::imageTarget()) + target_index = ImageExporter; + else + { + for (; target_index >= 0; target_index--) + { +#if QT_VERSION < 0x050300 + if (target && printers[target_index].printerName() == target->printerName()) +#else + if (target && printers[target_index] == target->printerName()) +#endif + break; + else if (!target) + break; + } + } + target_combo->setCurrentIndex(target_combo->findData(QVariant(target_index))); + + updatePaperSizes(target); + updateResolutions(target); + + bool supports_pages = (target != MapPrinter::imageTarget()); + bool supports_copies = (supports_pages && target && QPrinter(*target).supportsMultipleCopies()); + copies_edit->setEnabled(supports_copies); + layout->labelForField(copies_edit)->setEnabled(supports_copies); + + bool is_printer = map_printer->isPrinter(); + print_button->setVisible(is_printer); + print_button->setDefault(is_printer); + export_button->setVisible(!is_printer); + export_button->setDefault(!is_printer); + if (printer_properties_button) + printer_properties_button->setEnabled(is_printer); + + bool is_image_target = target == MapPrinter::imageTarget(); + vector_mode_button->setEnabled(!is_image_target); + separations_mode_button->setEnabled(!is_image_target && map->hasSpotColors()); + if (is_image_target) + { + raster_mode_button->setChecked(true); + printModeChanged(raster_mode_button); + } + + updateColorMode(); +} + +// slot +void PrintWidget::targetChanged(int index) const +{ + if (index < 0) + return; + + int target_index = target_combo->itemData(index).toInt(); + Q_ASSERT(target_index >= -2); + Q_ASSERT(target_index < printers.size()); + + if (target_index == PdfExporter) + map_printer->setTarget(MapPrinter::pdfTarget()); + else if (target_index == ImageExporter) + map_printer->setTarget(MapPrinter::imageTarget()); + else +#if QT_VERSION < 0x050300 + map_printer->setTarget(&printers[target_index]); +#else + { + auto info = QPrinterInfo::printerInfo(printers[target_index]); + map_printer->setTarget(&info); + } +#endif +} + +// slot +void PrintWidget::propertiesClicked() +{ + if (map_printer && map_printer->isPrinter()) + { + std::shared_ptr buffer; // must not be destroyed before printer. + auto printer = map_printer->makePrinter(); + Q_ASSERT(printer->outputFormat() == QPrinter::NativeFormat); + if (PlatformPrinterProperties::execDialog(printer.get(), buffer, this) == QDialog::Accepted) + map_printer->takePrinterSettings(printer.get()); + } +} + +void PrintWidget::updatePaperSizes(const QPrinterInfo* target) const +{ + QString prev_paper_size_name = paper_size_combo->currentText(); + bool have_custom_size = false; + + { + const QSignalBlocker block(paper_size_combo); + + paper_size_combo->clear(); + QList size_list; + if (target) + size_list = target->supportedPaperSizes(); + if (size_list.isEmpty()) + size_list = defaultPaperSizes(); + + for (auto size : qAsConst(size_list)) + { + if (size == QPrinter::Custom) + have_custom_size = true; // add it once after all other entires + else + paper_size_combo->addItem(toString(size), size); + } + + if (have_custom_size) + paper_size_combo->addItem(toString(QPrinter::Custom), QPrinter::Custom); + + int paper_size_index = paper_size_combo->findData(map_printer->getPageFormat().paper_size); + if (!prev_paper_size_name.isEmpty()) + { + paper_size_index = paper_size_combo->findText(prev_paper_size_name); + } + paper_size_combo->setCurrentIndex(qMax(0, paper_size_index)); + paperSizeChanged(paper_size_combo->currentIndex()); + } +} + +// slot +void PrintWidget::setPageFormat(const MapPrinterPageFormat& format) +{ + ScopedMultiSignalsBlocker block( + paper_size_combo, page_orientation_group, + page_width_edit, page_height_edit, + overlap_edit + ); + paper_size_combo->setCurrentIndex(paper_size_combo->findData(format.paper_size)); + page_orientation_group->button(format.orientation)->setChecked(true); + page_width_edit->setValue(format.paper_dimensions.width()); + page_width_edit->setEnabled(format.paper_size == QPrinter::Custom); + page_height_edit->setValue(format.paper_dimensions.height()); + page_height_edit->setEnabled(format.paper_size == QPrinter::Custom); + // We only have a single overlap edit field, but MapPrinter supports + // distinct horizontal and vertical overlap. Choose the minimum. + overlap_edit->setValue(qMin(format.h_overlap, format.v_overlap)); + applyPrintAreaPolicy(); +} + +// slot +void PrintWidget::paperSizeChanged(int index) const +{ + if (index >= 0) + { + QPrinter::PaperSize paper_size = QPrinter::PaperSize(paper_size_combo->itemData(index).toInt()); + map_printer->setPaperSize(paper_size); + } +} + +// slot +void PrintWidget::paperDimensionsChanged() const +{ + const QSizeF dimensions(page_width_edit->value(), page_height_edit->value()); + map_printer->setCustomPaperSize(dimensions); +} + +// slot +void PrintWidget::pageOrientationChanged(int id) const +{ + if (id == QPrinter::Portrait || id == QPrinter::Landscape) + { + map_printer->setPageOrientation((id == QPrinter::Portrait) ? MapPrinterPageFormat::Portrait : MapPrinterPageFormat::Landscape); + } +} + + +// slot +void PrintWidget::printAreaPolicyChanged(int index) +{ + policy = PrintAreaPolicy(policy_combo->itemData(index).toInt()); + applyPrintAreaPolicy(); +} + + +// slot +void PrintWidget::applyPrintAreaPolicy() const +{ + if (policy == SinglePage) + { + setOverlapEditEnabled(false); + QRectF print_area = map_printer->getPrintArea(); + print_area.setSize(map_printer->getPageRectPrintAreaSize()); + if (center_check->isChecked()) + centerOnMap(print_area); + map_printer->setPrintArea(print_area); + } + else + { + setOverlapEditEnabled(true); + } +} + +// slot +void PrintWidget::applyCenterPolicy() const +{ + if (center_check->isChecked()) + { + QRectF print_area = map_printer->getPrintArea(); + centerOnMap(print_area); + map_printer->setPrintArea(print_area); + } +} + +void PrintWidget::centerOnMap(QRectF& area) const +{ + QRectF map_extent = map->calculateExtent(false, show_templates_check->isChecked(), main_view); + area.moveLeft(map_extent.center().x() - 0.5f * area.width()); + area.moveTop(map_extent.center().y() - 0.5f * area.height()); +} + + + +// slot +void PrintWidget::setPrintArea(const QRectF& area) +{ + ScopedMultiSignalsBlocker block( + left_edit, top_edit, + width_edit, height_edit + ); + + left_edit->setValue(area.left()); + top_edit->setValue(-area.top()); // Flip sign! + width_edit->setValue(area.width()); + height_edit->setValue(area.height()); + + if (center_check->isChecked()) + { + QRectF centered_area = map_printer->getPrintArea(); + centerOnMap(centered_area); + if ( qAbs(centered_area.left() - area.left()) > 0.005 || + qAbs(centered_area.top() - area.top()) > 0.005 ) + { + // No longer centered. + center_check->setChecked(false); + } + } + + if (policy == SinglePage) + { + if (map_printer->getPageFormat().paper_size == QPrinter::Custom || !task.testFlag(MULTIPAGE_FLAG)) + { + // Update custom paper size from print area size + QSizeF area_dimensions = area.size() * map_printer->getScaleAdjustment(); + if (map_printer->getPageFormat().page_rect.size() != area_dimensions) + { + // Don't force a custom paper size unless necessary + map_printer->setCustomPaperSize(area_dimensions); + } + } + else + { + QSizeF page_dimensions = map_printer->getPageRectPrintAreaSize(); + if ( qAbs(area.width() - page_dimensions.width()) > 0.005 || + qAbs(area.height() - page_dimensions.height()) > 0.005 ) + { + // No longer single page. + block << policy_combo; + policy_combo->setCurrentIndex(policy_combo->findData(CustomArea)); + center_check->setChecked(false); + setOverlapEditEnabled(true); + } + } + } +} + +// slot +void PrintWidget::printAreaMoved() +{ + QRectF area = map_printer->getPrintArea(); + area.moveLeft(left_edit->value()); + area.moveTop(-top_edit->value()); // Flip sign! + map_printer->setPrintArea(area); +} + +// slot +void PrintWidget::printAreaResized() +{ + QRectF area = map_printer->getPrintArea(); + area.setWidth(width_edit->value()); + area.setHeight(height_edit->value()); + map_printer->setPrintArea(area); +} + +// slot +void PrintWidget::overlapEdited(double overlap) +{ + map_printer->setOverlap(overlap, overlap); +} + +void PrintWidget::setOverlapEditEnabled(bool state) const +{ + overlap_edit->setEnabled(state); + layout->labelForField(overlap_edit)->setEnabled(state); +} + + +// slot +void PrintWidget::setOptions(const MapPrinterOptions& options) +{ + using namespace Util::TristateCheckbox; + + ScopedMultiSignalsBlocker block( + dpi_combo->lineEdit(), + show_templates_check, + show_grid_check, + overprinting_check, + color_mode_combo, + vector_mode_button, + raster_mode_button, + separations_mode_button, + different_scale_check, + different_scale_edit + ); + + switch (options.mode) + { + default: + Q_ASSERT(false && "Unhandled MapPrinterOptions::MapPrinterMode"); + // fall through in release build + case MapPrinterOptions::Vector: + vector_mode_button->setChecked(true); + setEnabledAndChecked(show_templates_check, options.show_templates); + setEnabledAndChecked(show_grid_check, options.show_grid); + setDisabledAndChecked(overprinting_check, options.simulate_overprinting); + main_view->setAllTemplatesHidden(!options.show_templates); + main_view->setGridVisible(options.show_grid); + main_view->setOverprintingSimulationEnabled(false); + break; + case MapPrinterOptions::Raster: + raster_mode_button->setChecked(true); + setEnabledAndChecked(show_templates_check, options.show_templates); + setEnabledAndChecked(show_grid_check, options.show_grid); + setEnabledAndChecked(overprinting_check, options.simulate_overprinting); + main_view->setAllTemplatesHidden(!options.show_templates); + main_view->setGridVisible(options.show_grid); + main_view->setOverprintingSimulationEnabled(options.simulate_overprinting); + break; + case MapPrinterOptions::Separations: + separations_mode_button->setChecked(true); + setDisabledAndChecked(show_templates_check, options.show_templates); + setDisabledAndChecked(show_grid_check, options.show_grid); + setDisabledAndChecked(overprinting_check, options.simulate_overprinting); + main_view->setAllTemplatesHidden(true); + main_view->setGridVisible(false); + main_view->setOverprintingSimulationEnabled(true); + break; + } + + switch (options.color_mode) + { + default: + Q_ASSERT(false && "Unhandled MapPrinterOptions::ColorMode"); + // fall through in release build + case MapPrinterOptions::DefaultColorMode: + color_mode_combo->setCurrentIndex(0); + break; + case MapPrinterOptions::DeviceCmyk: + color_mode_combo->setCurrentIndex(1); + break; + } + + checkTemplateConfiguration(); + updateColorMode(); + + static QString dpi_template(QLatin1String("%1 ") + tr("dpi")); + dpi_combo->setEditText(dpi_template.arg(options.resolution)); + + if (options.scale != map->getScaleDenominator()) + { + different_scale_check->setChecked(true); + different_scale_edit->setEnabled(true); + } + + auto scale = int(options.scale); + different_scale_edit->setValue(scale); + differentScaleEdited(scale); +} + +void PrintWidget::onVisibilityChanged() +{ + map_printer->setPrintTemplates(!main_view->areAllTemplatesHidden()); + map_printer->setPrintGrid(main_view->isGridVisible()); + map_printer->setSimulateOverprinting(main_view->isOverprintingSimulationEnabled()); +} + +void PrintWidget::updateResolutions(const QPrinterInfo* target) const +{ + static const QList default_resolutions(QList() << 150 << 300 << 600 << 1200); + + // Numeric resolution list + QList supported_resolutions; + if (target) + { + QPrinter pr(*target, QPrinter::HighResolution); + supported_resolutions = pr.supportedResolutions(); + if (supported_resolutions.size() == 1 && supported_resolutions[0] == 72) + { + // X11/CUPS + supported_resolutions.clear(); + } + } + if (supported_resolutions.isEmpty()) + supported_resolutions = default_resolutions; + + // Resolution list item with unit "dpi" + static QString dpi_template(QLatin1String("%1 ") + tr("dpi")); + QStringList resolutions; + for (auto resolution : qAsConst(supported_resolutions)) + resolutions << dpi_template.arg(resolution); + + QString dpi_text = dpi_combo->currentText(); + { + const QSignalBlocker block(dpi_combo); + dpi_combo->clear(); + dpi_combo->addItems(resolutions); + } + dpi_combo->lineEdit()->setText(dpi_text.isEmpty() ? dpi_template.arg(600) : dpi_text); +} + +void PrintWidget::updateColorMode() +{ + bool enable = map_printer->getTarget() == MapPrinter::pdfTarget() + && !raster_mode_button->isChecked(); + color_mode_combo->setEnabled(enable); + layout->labelForField(color_mode_combo)->setEnabled(enable); + if (!enable) + color_mode_combo->setCurrentIndex(0); +} + +// slot +void PrintWidget::resolutionEdited() +{ + auto resolution_text = dpi_combo->currentText(); + auto index_of_space = resolution_text.indexOf(QLatin1Char(' ')); + auto dpi_value = resolution_text.leftRef(index_of_space).toInt(); + if (dpi_value > 0) + map_printer->setResolution(dpi_value); +} + +// slot +void PrintWidget::differentScaleClicked(bool checked) +{ + if (!checked) + different_scale_edit->setValue(int(map->getScaleDenominator())); + + different_scale_edit->setEnabled(checked); +} + +// slot +void PrintWidget::differentScaleEdited(int value) +{ + map_printer->setScale(static_cast(value)); + applyPrintAreaPolicy(); + + if (different_scale_edit->value() < 500) + { + different_scale_edit->setSingleStep(500 - different_scale_edit->value()); + } + else + { + different_scale_edit->setSingleStep(500); + } +} + +// slot +void PrintWidget::spotColorPresenceChanged(bool has_spot_colors) +{ + separations_mode_button->setEnabled(has_spot_colors); + if (!has_spot_colors && separations_mode_button->isChecked()) + { + map_printer->setMode(MapPrinterOptions::Vector); + } +} + +// slot +void PrintWidget::printModeChanged(QAbstractButton* button) +{ + if (button == vector_mode_button) + { + map_printer->setMode(MapPrinterOptions::Vector); + } + else if (button == raster_mode_button) + { + map_printer->setMode(MapPrinterOptions::Raster); + } + else + { + map_printer->setMode(MapPrinterOptions::Separations); + } +} + +// slot +void PrintWidget::showTemplatesClicked(bool checked) +{ + map_printer->setPrintTemplates(checked); + checkTemplateConfiguration(); +} + +void PrintWidget::checkTemplateConfiguration() +{ + bool visibility = vector_mode_button->isChecked() && show_templates_check->isChecked(); + templates_warning_icon->setVisible(visibility); + templates_warning_text->setVisible(visibility); +} + +// slot +void PrintWidget::showGridClicked(bool checked) +{ + map_printer->setPrintGrid(checked); +} + +// slot +void PrintWidget::overprintingClicked(bool checked) +{ + map_printer->setSimulateOverprinting(checked); +} + +void PrintWidget::colorModeChanged() +{ + if (color_mode_combo->currentData().toBool()) + map_printer->setColorMode(MapPrinterOptions::DeviceCmyk); + else + map_printer->setColorMode(MapPrinterOptions::DefaultColorMode); +} + +// slot +void PrintWidget::previewClicked() +{ +#if defined(Q_OS_ANDROID) + // Qt for Android has no QPrintPreviewDialog + QMessageBox::warning(this, tr("Error"), tr("Not supported on Android.")); +#else + if (checkForEmptyMap()) + return; + + auto printer = map_printer->makePrinter(); + if (!printer) + { + QMessageBox::warning(this, tr("Error"), tr("Failed to prepare the preview.")); + return; + } + + printer->setCreator(main_window->appName()); + printer->setDocName(QFileInfo(main_window->currentPath()).baseName()); + + QPrintPreviewDialog preview(printer.get(), editor->getWindow()); + preview.setWindowModality(Qt::ApplicationModal); // Required for OSX, cf. QTBUG-40112 + + PrintProgressDialog progress(map_printer, editor->getWindow()); + progress.setWindowTitle(tr("Print Preview Progress")); + connect(&preview, &QPrintPreviewDialog::paintRequested, &progress, &PrintProgressDialog::paintRequested); + // Doesn't work as expected, on OSX at least. + //connect(&progress, &QProgressDialog::canceled, &preview, &QPrintPreviewDialog::reject); + + preview.exec(); +#endif +} + +// slot +void PrintWidget::printClicked() +{ + if (checkForEmptyMap()) + return; + + if (map->isAreaHatchingEnabled() || map->isBaselineViewEnabled()) + { + if (QMessageBox::question(this, tr("Warning"), + tr("A non-standard view mode is activated. " + "Are you sure to print / export the map like this?"), + QMessageBox::Ok | QMessageBox::Cancel) == QMessageBox::Cancel) + return; + } + + if (map_printer->getTarget() == MapPrinter::imageTarget()) + exportToImage(); + else if (map_printer->getTarget() == MapPrinter::pdfTarget()) + exportToPdf(); + else + print(); +} + +void PrintWidget::exportToImage() +{ + static const QString filter_template(QString::fromLatin1("%1 (%2)")); + QStringList filters = { filter_template.arg(tr("PNG"), QString::fromLatin1("*.png")), + filter_template.arg(tr("BMP"), QString::fromLatin1("*.bmp")), + filter_template.arg(tr("TIFF"), QString::fromLatin1("*.tif *.tiff")), + filter_template.arg(tr("JPEG"), QString::fromLatin1("*.jpg *.jpeg")), + tr("All files (*.*)") }; + QString path = QFileDialog::getSaveFileName(this, tr("Export map ..."), {}, filters.join(QString::fromLatin1(";;"))); + if (path.isEmpty()) + return; + + if (!path.endsWith(QLatin1String(".png"), Qt::CaseInsensitive) + && !path.endsWith(QLatin1String(".bmp"), Qt::CaseInsensitive) + && !path.endsWith(QLatin1String(".tif"), Qt::CaseInsensitive) && !path.endsWith(QLatin1String(".tiff"), Qt::CaseInsensitive) + && !path.endsWith(QLatin1String(".jpg"), Qt::CaseInsensitive) && !path.endsWith(QLatin1String(".jpeg"), Qt::CaseInsensitive) ) + { + path.append(QString::fromLatin1(".png")); + } + + qreal pixel_per_mm = map_printer->getOptions().resolution / 25.4; + int print_width = qRound(map_printer->getPrintAreaPaperSize().width() * pixel_per_mm); + int print_height = qRound(map_printer->getPrintAreaPaperSize().height() * pixel_per_mm); + QImage image(print_width, print_height, QImage::Format_ARGB32_Premultiplied); + if (image.isNull()) + { + QMessageBox::warning(this, tr("Error"), tr("Failed to prepare the image. Not enough memory.")); + return; + } + + int dots_per_meter = qRound(pixel_per_mm * 1000); + image.setDotsPerMeterX(dots_per_meter); + image.setDotsPerMeterY(dots_per_meter); + +#if 0 // Pointless unless drawPage drives the event loop and sends progress + PrintProgressDialog progress(map_printer, main_window); + progress.setWindowTitle(tr("Export map ...")); +#endif + + // Export the map + QPainter p(&image); + map_printer->drawPage(&p, map_printer->getOptions().resolution, map_printer->getPrintArea(), true, &image); + p.end(); + if (!image.save(path)) + { + QMessageBox::warning(this, tr("Error"), tr("Failed to save the image. Does the path exist? Do you have sufficient rights?")); + } + else + { + main_window->showStatusBarMessage(tr("Exported successfully to %1").arg(path), 4000); + emit finished(0); + } + return; +} + +void PrintWidget::exportToPdf() +{ + auto printer = map_printer->makePrinter(); + if (!printer) + { + QMessageBox::warning(this, tr("Error"), tr("Failed to prepare the PDF export.")); + return; + } + + printer->setOutputFormat(QPrinter::PdfFormat); + printer->setNumCopies(copies_edit->value()); + printer->setCreator(main_window->appName()); + printer->setDocName(QFileInfo(main_window->currentPath()).baseName()); + + static const QString filter_template(QString::fromLatin1("%1 (%2)")); + QStringList filters = { filter_template.arg(tr("PDF"), QString::fromLatin1("*.pdf")), + tr("All files (*.*)") }; + QString path = QFileDialog::getSaveFileName(this, tr("Export map ..."), {}, filters.join(QString::fromLatin1(";;"))); + if (path.isEmpty()) + { + return; + } + else if (!path.endsWith(QLatin1String(".pdf"), Qt::CaseInsensitive)) + { + path.append(QLatin1String(".pdf")); + } + printer->setOutputFileName(path); + + PrintProgressDialog progress(map_printer, main_window); + progress.setWindowTitle(tr("Export map ...")); + + // Export the map + if (!map_printer->printMap(printer.get())) + { + QFile(path).remove(); + QMessageBox::warning(this, tr("Error"), tr("Failed to finish the PDF export.")); + } + else if (!progress.wasCanceled()) + { + main_window->showStatusBarMessage(tr("Exported successfully to %1").arg(path), 4000); + emit finished(0); + } + else + { + QFile(path).remove(); + main_window->showStatusBarMessage(tr("Canceled."), 4000); + } +} + +void PrintWidget::print() +{ + auto printer = map_printer->makePrinter(); + if (!printer) + { + QMessageBox::warning(this, tr("Error"), tr("Failed to prepare the printing.")); + return; + } + + printer->setNumCopies(copies_edit->value()); + printer->setCreator(main_window->appName()); + printer->setDocName(QFileInfo(main_window->currentPath()).baseName()); + + PrintProgressDialog progress(map_printer, main_window); + progress.setWindowTitle(tr("Printing Progress")); + + // Print the map + if (!map_printer->printMap(printer.get())) + { + QMessageBox::warning(main_window, tr("Error"), tr("An error occurred during printing.")); + } + else if (!progress.wasCanceled()) + { + main_window->showStatusBarMessage(tr("Successfully created print job"), 4000); + emit finished(0); + } + else if (printer->abort()) + { + main_window->showStatusBarMessage(tr("Canceled."), 4000); + } + else + { + QMessageBox::warning(main_window, tr("Error"), tr("The print job could not be stopped.")); + } +} + +QList PrintWidget::defaultPaperSizes() const +{ + // TODO: Learn from user's past choices, present reduced list unless asked for more. + static QList default_paper_sizes(QList() + << QPrinter::A4 + << QPrinter::Letter + << QPrinter::Legal + << QPrinter::Executive + << QPrinter::A0 + << QPrinter::A1 + << QPrinter::A2 + << QPrinter::A3 + << QPrinter::A5 + << QPrinter::A6 + << QPrinter::A7 + << QPrinter::A8 + << QPrinter::A9 + << QPrinter::B0 + << QPrinter::B1 + << QPrinter::B10 + << QPrinter::B2 + << QPrinter::B3 + << QPrinter::B4 + << QPrinter::B5 + << QPrinter::B6 + << QPrinter::B7 + << QPrinter::B8 + << QPrinter::B9 + << QPrinter::C5E + << QPrinter::Comm10E + << QPrinter::DLE + << QPrinter::Folio + << QPrinter::Ledger + << QPrinter::Tabloid + << QPrinter::Custom + ); + return default_paper_sizes; +} + +QString PrintWidget::toString(QPrinter::PaperSize size) +{ +#if defined(Q_OS_ANDROID) + // Qt for Android has no QPrintDialog + Q_UNUSED(size); + return tr("Unknown", "Paper size"); +#else + const QHash< int, const char*>& paper_size_names = MapPrinter::paperSizeNames(); + if (paper_size_names.contains(size)) + // These translations are not used in QPrintDialog, + // but in Qt's qpagesetupdialog_unix.cpp. + return QPrintDialog::tr(paper_size_names[size]); + else + return tr("Unknown", "Paper size"); +#endif +} + +bool PrintWidget::checkForEmptyMap() +{ + if (map_printer->isOutputEmpty()) + { + QMessageBox::warning(this, tr("Error"), tr("The map area is empty. Output canceled.")); + return true; + } + return false; +} + +#endif diff --git a/src/gui/print_widget.h b/src/gui/print_widget.h new file mode 100644 index 0000000..0b92f6f --- /dev/null +++ b/src/gui/print_widget.h @@ -0,0 +1,326 @@ +/* + * Copyright 2012, 2013 Thomas Schöps + * Copyright 2012-2016 Kai Pastor + * + * This file is part of OpenOrienteering. + * + * OpenOrienteering is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenOrienteering is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenOrienteering. If not, see . + */ + + +#ifdef QT_PRINTSUPPORT_LIB + +#ifndef OPENORIENTEERING_PRINT_WIDGET_H +#define OPENORIENTEERING_PRINT_WIDGET_H + +#include +#include + +class QAbstractButton; +class QButtonGroup; +class QCheckBox; +class QComboBox; +class QDialogButtonBox; +class QDoubleSpinBox; +class QFormLayout; +class QLabel; +class QPushButton; +class QScrollArea; +class QSpinBox; +class QToolButton; + +class Map; +class MapEditorController; +class MapPrinter; +class MapPrinterOptions; +class MapPrinterPageFormat; +class MapView; +class MainWindow; +class PrintTool; + +/** + * The print widget lets the user adjust targets and parameters + * for printing and export. + */ +class PrintWidget : public QWidget +{ +Q_OBJECT +public: + enum TaskFlag + { + EXPORT_FLAG = 0x02, + MULTIPAGE_FLAG = 0x04, + + UNDEFINED_TASK = 0x00, + PRINT_TASK = 0x14, // 0x10 | 0x04 + EXPORT_PDF_TASK = 0x26, // 0x20 | 0x04 | 0x02 + EXPORT_IMAGE_TASK = 0x42, // 0x40 | 0x02 + + END_JOB_TYPE + }; + Q_DECLARE_FLAGS(TaskFlags, TaskFlag) + + /** Constructs a new print widget. */ + PrintWidget(Map* map, MainWindow* main_window, MapView* main_view, MapEditorController* editor, QWidget* parent = nullptr); + + /** Destroys the widget. */ + ~PrintWidget() override; + + /** Indicates the default widget size. */ + QSize sizeHint() const override; + + /** Returns a translated name for the given paper size. */ + static QString toString(QPrinter::PaperSize size); + +public slots: + /** Changes the type of the print or export task. */ + void setTask(TaskFlags type); + + /** Saves the print or export settings. */ + void savePrinterConfig() const; + + /** + * Sets the active state of the print widget. + * + * When the widget becomes active, it saves the map view state and + * activates a tool on the map editor which allows to move the print area. + * When the widget becomes inactive, the tool is removed, and the map view + * state is restored. + */ + void setActive(bool active); + + /** Sets the widget's (print/export) target. */ + void setTarget(const QPrinterInfo* target); + + /** Sets the format of a single page. */ + void setPageFormat(const MapPrinterPageFormat& format); + + /** Sets the exported area. */ + void setPrintArea(const QRectF& area); + + /** Sets output options: resolution, overprinting. */ + void setOptions(const MapPrinterOptions& parameters); + + /** Listens to view feature changes. */ + void onVisibilityChanged(); + +signals: + /** + * This signal is emitted when the type of task changes. + * It may be used to set a window title. + */ + void taskChanged(QString name); + + /** + * This signal is emitted when a print or export job has been started + * and finished. + * + * The signal is not emitted when the widget is hidden + * (cf. QDialog::finished(int result) ). + */ + void finished(int result); + + /** + * This signal is emitted when the dialog's close button is clicked. + */ + void closeClicked(); + +protected slots: + /** This slot reacts to changes of the target combobox. */ + void targetChanged(int index) const; + + /** Opens a dialog to change printer properties. */ + void propertiesClicked(); + + /** This slot reacts to changes of the paper size combobox. */ + void paperSizeChanged(int index) const; + + /** This slot reacts to changes of the paper dimension widgets. */ + void paperDimensionsChanged() const; + + /** This slot reacts to changes of the page orientation widget. */ + void pageOrientationChanged(int id) const; + + /** This slot reacts to changes of the print area policy combobox. */ + void printAreaPolicyChanged(int index); + + /** This slot applies the map area policy to the current area. */ + void applyPrintAreaPolicy() const; + + /** This slot applies the center map area policy to the current area. */ + void applyCenterPolicy() const; + + /** This slot reacts to changes of print area position widgets. */ + void printAreaMoved(); + + /** This slot reacts to changes of print area size widget. */ + void printAreaResized(); + + /** This slot reacts to changes to the page overlap widget. */ + void overlapEdited(double overlap); + + /** This slot is called when the resolution widget signals that editing finished. */ + void resolutionEdited(); + + /** This slot enables the alternative scale widget, or resets it. */ + void differentScaleClicked(bool checked); + + /** This slot reacts to changes in the alternative scale widget. */ + void differentScaleEdited(int value); + + /** This slot reacts to changes in the presence of spot colors in the map. + * The following features are enabled only when spot colors are present: + * - spot color separations + * - overprinting simulation + */ + void spotColorPresenceChanged(bool has_spot_colors); + + /** This slot reacts to changes in the print mode buttons. */ + void printModeChanged(QAbstractButton* button); + + /** This slot reacts to changes of the "Show template" option. */ + void showTemplatesClicked(bool checked); + + /** This slot reacts to changes of the "Show grid" option. */ + void showGridClicked(bool checked); + + /** This slot reacts to changes of the "Simulate overprinting" option. */ + void overprintingClicked(bool checked); + + /** This slot reacts to changes of the "Color mode" option. */ + void colorModeChanged(); + + /** Opens a preview window. */ + void previewClicked(); + + /** Starts printing and terminates this dialog. */ + void printClicked(); + +protected: + /** Alternative policies of handling the print area. */ + enum PrintAreaPolicy + { + SinglePage = 2, + CustomArea = 4 + }; + + /** Re-initializes the list of print/export targets. */ + void updateTargets(); + + /** Updates the list of paper sizes from the given target. */ + void updatePaperSizes(const QPrinterInfo* target) const; + + /** Updates the list of resolutions from the given target. */ + void updateResolutions(const QPrinterInfo* target) const; + + /** Updates the color mode combobox from target and mode settings. */ + void updateColorMode(); + + /** A list of paper sizes which is used when the target does not specify + * supported paper sizes. */ + QList defaultPaperSizes() const; + + /** Moves the given rectangle to a position where it is centered on the + * map for the current output options. */ + void centerOnMap(QRectF& area) const; + + /** Shows a warning and returns true if the output would be empty. */ + bool checkForEmptyMap(); + + /** Sets the enabled state of the page overlap field. */ + void setOverlapEditEnabled(bool state = true) const; + + /** Checks whether the template order warning needs to be displayed. */ + void checkTemplateConfiguration(); + + /** Exports to an image file. */ + void exportToImage(); + + /** Exports to a PDF file. */ + void exportToPdf(); + + /** Print to a printer. */ + void print(); + +private: + enum Exporters + { + PdfExporter = -1, + ImageExporter = -2 + }; + TaskFlags task; + + QFormLayout* layout; + QWidget* scrolling_content; + QScrollArea* scroll_area; + QDialogButtonBox* button_box; + + QComboBox* target_combo; + QToolButton* printer_properties_button; + QComboBox* paper_size_combo; + QWidget* page_orientation_widget; + QButtonGroup* page_orientation_group; + QSpinBox* copies_edit; + QDoubleSpinBox* page_width_edit; + QDoubleSpinBox* page_height_edit; + + QComboBox* dpi_combo; + QCheckBox* show_templates_check; + QLabel* templates_warning_icon; + QLabel* templates_warning_text; + QCheckBox* show_grid_check; + QCheckBox* overprinting_check; + QCheckBox* different_scale_check; + QSpinBox* different_scale_edit; + QComboBox* color_mode_combo; + + QComboBox* policy_combo; + QCheckBox* center_check; + QDoubleSpinBox* left_edit; + QDoubleSpinBox* top_edit; + QDoubleSpinBox* width_edit; + QDoubleSpinBox* height_edit; + QDoubleSpinBox* overlap_edit; + + QToolButton* vector_mode_button; + QToolButton* raster_mode_button; + QToolButton* separations_mode_button; + + QPushButton* preview_button; + QPushButton* print_button; + QPushButton* export_button; + +#if QT_VERSION < 0x050300 + QList printers; +#else + QStringList printers; +#endif + + PrintAreaPolicy policy; + + Map* map; + MapPrinter* map_printer; + MainWindow* main_window; + MapView* main_view; + MapEditorController* editor; + PrintTool* print_tool; + QString saved_view_state; + bool active; +}; + +Q_DECLARE_OPERATORS_FOR_FLAGS(PrintWidget::TaskFlags) + +#endif + +#endif diff --git a/src/gui/select_crs_dialog.cpp b/src/gui/select_crs_dialog.cpp new file mode 100644 index 0000000..bac8dea --- /dev/null +++ b/src/gui/select_crs_dialog.cpp @@ -0,0 +1,133 @@ +/* + * Copyright 2012, 2013 Thomas Schöps + * Copyright 2012-2015 Kai Pastor + * + * This file is part of OpenOrienteering. + * + * OpenOrienteering is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenOrienteering is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenOrienteering. If not, see . + */ + + +#include "select_crs_dialog.h" + +#include +#include +#include +#include +#include + +#include "../core/georeferencing.h" +#include "../util_gui.h" +#include "widgets/crs_selector.h" + + +namespace { + +enum SpecialCRS { + SameAsMap = 1, + Local = 2, + Geographic = 3 +}; + +} + +SelectCRSDialog::SelectCRSDialog( + const Georeferencing& georef, + QWidget* parent, + GeorefAlternatives alternatives, + const QString& description ) + : QDialog(parent, Qt::WindowSystemMenuHint | Qt::WindowTitleHint) + , georef(georef) +{ + setWindowModality(Qt::WindowModal); + setWindowTitle(tr("Select coordinate reference system")); + + crs_selector = new CRSSelector(georef, nullptr); + if (georef.isLocal()) + crs_selector->clear(); + + if (alternatives.testFlag(TakeFromMap) && !georef.isLocal()) + { + crs_selector->addCustomItem(tr("Same as map"), SpecialCRS::SameAsMap); + crs_selector->setCurrentIndex(0); // TakeFromMap + } + + if (alternatives.testFlag(Local) || georef.isLocal()) + { + crs_selector->addCustomItem(tr("Local"), SpecialCRS::Local); + crs_selector->setCurrentIndex(0); // TakeFromMap or Local, both is fine. + } + + if (alternatives.testFlag(Geographic) && !georef.isLocal()) + crs_selector->addCustomItem(tr("Geographic coordinates (WGS84)"), SpecialCRS::Geographic); + + status_label = new QLabel(); + button_box = new QDialogButtonBox(QDialogButtonBox::Cancel | QDialogButtonBox::Ok); + + auto form_layout = new QFormLayout(); + if (!description.isEmpty()) + { + form_layout->addRow(new QLabel(description)); + form_layout->addItem(Util::SpacerItem::create(this)); + } + form_layout->addRow(QCoreApplication::translate("GeoreferencingDialog", "&Coordinate reference system:"), crs_selector); + form_layout->addRow(tr("Status:"), status_label); + form_layout->addItem(Util::SpacerItem::create(this)); + crs_selector->setDialogLayout(form_layout); + + auto layout = new QVBoxLayout(); + layout->addLayout(form_layout, 1); + layout->addWidget(button_box, 0); + setLayout(layout); + + connect(crs_selector, &CRSSelector::crsChanged, this, &SelectCRSDialog::updateWidgets); + connect(button_box, &QDialogButtonBox::accepted, this, &SelectCRSDialog::accept); + connect(button_box, &QDialogButtonBox::rejected, this, &SelectCRSDialog::reject); + + updateWidgets(); +} + +QString SelectCRSDialog::currentCRSSpec() const +{ + QString spec; + switch (crs_selector->currentCustomItem()) + { + case SpecialCRS::SameAsMap: + spec = georef.getProjectedCRSSpec(); + break; + case SpecialCRS::Local: + // nothing + break; + case SpecialCRS::Geographic: + spec = QLatin1String("+proj=latlong +datum=WGS84"); + break; + default: + spec = crs_selector->currentCRSSpec(); + } + + return spec; +} + +void SelectCRSDialog::updateWidgets() +{ + Georeferencing georef; + auto spec = currentCRSSpec(); + auto valid = spec.isEmpty() || georef.setProjectedCRS({}, spec); + + button_box->button(QDialogButtonBox::Ok)->setEnabled(valid); + if (valid) + status_label->setText(tr("valid")); + else + status_label->setText(QLatin1String("") + georef.getErrorText() + QLatin1String("")); +} diff --git a/src/gui/select_crs_dialog.h b/src/gui/select_crs_dialog.h new file mode 100644 index 0000000..2d94e78 --- /dev/null +++ b/src/gui/select_crs_dialog.h @@ -0,0 +1,91 @@ +/* + * Copyright 2012, 2013 Thomas Schöps + * Copyright 2012-2015 Kai Pastor + * + * This file is part of OpenOrienteering. + * + * OpenOrienteering is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenOrienteering is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenOrienteering. If not, see . + */ + + +#ifndef _OPENORIENTEERING_SELECT_CRS_DIALOG_H_ +#define _OPENORIENTEERING_SELECT_CRS_DIALOG_H_ + +#include +#include + +QT_BEGIN_NAMESPACE +class QDialogButtonBox; +class QLabel; +QT_END_NAMESPACE + +class CRSSelector; +class Georeferencing; + + +/** Dialog to select a coordinate reference system (CRS) */ +class SelectCRSDialog : public QDialog +{ +Q_OBJECT +public: + + /** + * Georeferencing alternatives + */ + enum GeorefAlternative + { + TakeFromMap = 1 << 0, + Local = 1 << 1, + Geographic = 1 << 2, + None = 0 + }; + Q_DECLARE_FLAGS(GeorefAlternatives, GeorefAlternative) + + /** + * Creates a SelectCRSDialog. + * + * @param georef A default georeferencing (usually the map's one). + * @param parent The parent widget. + * @param alternatives The georeferencing alternatives to be offered. + * @param description Optional description text for the dialog. + * Should explain what the selected CRS will be used for. + */ + SelectCRSDialog( + const Georeferencing& georef, + QWidget* parent, + GeorefAlternatives alternatives, + const QString& description = QString() + ); + + /** + * Returns the current CRS specification string. + */ + QString currentCRSSpec() const; + +protected: + /** + * Update the status field and enables/disables the OK button. + */ + void updateWidgets(); + +private: + const Georeferencing& georef; + CRSSelector* crs_selector; + QLabel* status_label; + QDialogButtonBox* button_box; +}; + +Q_DECLARE_OPERATORS_FOR_FLAGS(SelectCRSDialog::GeorefAlternatives) + +#endif diff --git a/src/gui/settings_dialog.cpp b/src/gui/settings_dialog.cpp new file mode 100644 index 0000000..bc9de89 --- /dev/null +++ b/src/gui/settings_dialog.cpp @@ -0,0 +1,220 @@ +/* + * Copyright 2012, 2013 Jan Dalheimer + * Copyright 2012-2016 Kai Pastor + * + * This file is part of OpenOrienteering. + * + * OpenOrienteering is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenOrienteering is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenOrienteering. If not, see . + */ + +#include "settings_dialog.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../util.h" +#include "../util/backports.h" + +#include "main_window.h" +#include "widgets/editor_settings_page.h" +#include "widgets/general_settings_page.h" +#ifdef MAPPER_USE_GDAL +# include "../gdal/gdal_settings_page.h" +#endif + + +SettingsDialog::SettingsDialog(QWidget* parent) + : QDialog { parent } + , tab_widget { nullptr } + , stack_widget { nullptr } +{ + setWindowTitle(tr("Settings")); + + QVBoxLayout* layout = new QVBoxLayout(this); + + auto buttons = QDialogButtonBox::StandardButtons{ QDialogButtonBox::Ok }; + if (MainWindow::mobileMode()) + { + if (parent) + setGeometry(parent->geometry()); + + stack_widget = new QStackedWidget(); + layout->addWidget(stack_widget, 1); + + auto menu_widget = new QToolBar(); + menu_widget->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); + menu_widget->setOrientation(Qt::Vertical); + stack_widget->addWidget(menu_widget); + } + else + { + buttons |= QDialogButtonBox::Reset | QDialogButtonBox::Cancel | QDialogButtonBox::Help; + + tab_widget = new QTabWidget(); +#ifndef Q_OS_OSX + tab_widget->setDocumentMode(true); +#endif + layout->addWidget(tab_widget, 1); + } + + button_box = new QDialogButtonBox(buttons, Qt::Horizontal); + connect(button_box, &QDialogButtonBox::clicked, this, &SettingsDialog::buttonPressed); + if (MainWindow::mobileMode()) + { + int left, top, right, bottom; + layout->getContentsMargins(&left, &top, &right, &bottom); + layout->setContentsMargins(0, 0, 0, 0); + layout->setSpacing(0); + + QVBoxLayout* l = new QVBoxLayout(); + l->setContentsMargins(left, top, right, bottom); + l->addWidget(button_box); + layout->addLayout(l); + } + else + { + layout->addWidget(button_box); + } + + addPages(); +} + +SettingsDialog::~SettingsDialog() +{ + // Nothing, not inlined. +} + +void SettingsDialog::closeEvent(QCloseEvent* e) +{ + if (MainWindow::mobileMode()) + callOnAllPages(&SettingsPage::apply); + QDialog::closeEvent(e); +} + +void SettingsDialog::keyPressEvent(QKeyEvent* event) +{ + switch (event->key()) + { + case Qt::Key_Back: + case Qt::Key_Escape: + if (MainWindow::mobileMode() && stack_widget->currentIndex() > 0) + { + stack_widget->setCurrentIndex(0); + auto buttons = button_box->standardButtons(); + button_box->setStandardButtons((buttons & ~QDialogButtonBox::Reset) | QDialogButtonBox::Help); + return; + } + break; + default: + ; // nothing + } + QDialog::keyPressEvent(event); +} + +void SettingsDialog::addPages() +{ + addPage(new GeneralSettingsPage(this)); + addPage(new EditorSettingsPage(this)); +#ifdef MAPPER_USE_GDAL + addPage(new GdalSettingsPage(this)); +#endif +} + +void SettingsDialog::addPage(SettingsPage* page) +{ + if (MainWindow::mobileMode()) + { + if (auto form_layout = qobject_cast(page->layout())) + { + form_layout->setRowWrapPolicy(QFormLayout::WrapAllRows); + auto labels = page->findChildren(); + for (auto label : qAsConst(labels)) + label->setWordWrap(true); + } + page->setMaximumWidth(width()); + + auto scrollarea = new QScrollArea(); + scrollarea->setFrameShape(QFrame::NoFrame); + QScroller::grabGesture(scrollarea, QScroller::TouchGesture); + scrollarea->setWidget(page); + stack_widget->addWidget(scrollarea); + + auto menu_widget = qobject_cast(stack_widget->widget(0)); + auto action = menu_widget->addAction(page->title()); + connect(action, &QAction::triggered, [this, scrollarea]() + { + stack_widget->setCurrentWidget(scrollarea); + scrollarea->ensureVisible(0, 0); + button_box->setStandardButtons(button_box->standardButtons() | QDialogButtonBox::Reset); + } ); + } + else + { + tab_widget->addTab(page, page->title()); + } +} + +void SettingsDialog::callOnAllPages(void (SettingsPage::*member)()) +{ + auto pages = MainWindow::mobileMode() ? stack_widget->findChildren() + : tab_widget->findChildren(); + for (auto page : qAsConst(pages)) + (page->*member)(); +} + +void SettingsDialog::buttonPressed(QAbstractButton* button) +{ + QDialogButtonBox::StandardButton id = button_box->standardButton(button); + switch (id) + { + case QDialogButtonBox::Ok: + callOnAllPages(&SettingsPage::apply); + if (MainWindow::mobileMode() && stack_widget->currentIndex() > 0) + { + stack_widget->setCurrentIndex(0); + button_box->setStandardButtons(button_box->standardButtons() & ~QDialogButtonBox::Reset); + } + else + { + this->accept(); + } + break; + + case QDialogButtonBox::Reset: + callOnAllPages(&SettingsPage::reset); + break; + + case QDialogButtonBox::Cancel: + this->reject(); + break; + + case QDialogButtonBox::Help: + Util::showHelp(this, QLatin1String("settings.html")); + break; + + default: + qDebug("%s: Unexpected button '0x%x'", Q_FUNC_INFO, id); + } +} diff --git a/src/gui/settings_dialog.h b/src/gui/settings_dialog.h new file mode 100644 index 0000000..8372080 --- /dev/null +++ b/src/gui/settings_dialog.h @@ -0,0 +1,99 @@ +/* + * Copyright 2012, 2013 Jan Dalheimer + * Copyright 2013-2016 Kai Pastor + * + * This file is part of OpenOrienteering. + * + * OpenOrienteering is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenOrienteering is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenOrienteering. If not, see . + */ + +#ifndef OPENORIENTEERING_SETTINGS_DIALOG_H +#define OPENORIENTEERING_SETTINGS_DIALOG_H + +#include + +QT_BEGIN_NAMESPACE +class QAbstractButton; +class QDialogButtonBox; +class QStackedWidget; +class QTabWidget; +QT_END_NAMESPACE + +class SettingsPage; + +/** + * A dialog for editing Mapper's settings. + */ +class SettingsDialog : public QDialog +{ +Q_OBJECT +public: + /** + * Constructs a new settings dialog. + */ + explicit SettingsDialog(QWidget* parent = nullptr); + + /** + * Destroys the settings dialog. + */ + ~SettingsDialog() override; + +protected: + /** + * Adds all known pages to the dialog. + * + * This function is called from the constructor. It may be overridden to + * provide dialogs with different pages. + */ + virtual void addPages(); + + /** + * Adds a single page to the dialog. + */ + void addPage(SettingsPage* page); + + /** + * Calls a SettingsPage member function on all pages. + */ + void callOnAllPages(void (SettingsPage::*member)()); + + + void closeEvent(QCloseEvent* event) override; + + void keyPressEvent(QKeyEvent* event) override; + +private slots: + /** + * Reacts to dialog buttons (OK, Cancel, Rest). + */ + void buttonPressed(QAbstractButton* button); + +private: + /** + * A tab widget which holds all pages in desktop mode. + */ + QTabWidget* tab_widget; + + /** + * A stack widget which holds all pages in mobile mode. + */ + QStackedWidget* stack_widget; + + /** + * The box of standard dialog buttons. + */ + QDialogButtonBox* button_box; +}; + +#endif diff --git a/src/gui/text_browser_dialog.cpp b/src/gui/text_browser_dialog.cpp new file mode 100644 index 0000000..5ee5325 --- /dev/null +++ b/src/gui/text_browser_dialog.cpp @@ -0,0 +1,132 @@ +/* + * Copyright 2012, 2013, 2014 Thomas Schöps + * Copyright 2012-2015 Kai Pastor + * + * This file is part of OpenOrienteering. + * + * OpenOrienteering is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenOrienteering is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenOrienteering. If not, see . + */ + +#include "text_browser_dialog.h" + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include + + +TextBrowserDialog::TextBrowserDialog(const QUrl& initial_url, QWidget* parent) + : QDialog(parent) + , text_browser(new QTextBrowser()) +{ + if (parent) + { + setWindowModality(Qt::WindowModal); + } + + QVBoxLayout* layout = new QVBoxLayout(); + setLayout(layout); + + int left, top, right, bottom; + layout->getContentsMargins(&left, &top, &right, &bottom); + layout->setContentsMargins(0, 0, 0, 0); + layout->setSpacing(0); + + text_browser->setOpenExternalLinks(true); + layout->addWidget(text_browser); + + QHBoxLayout* buttons_layout = new QHBoxLayout(); + buttons_layout->setContentsMargins(left, top, right, bottom); + + QPushButton* back_button = new QPushButton(QIcon(QStringLiteral(":/images/arrow-left.png")), QApplication::translate("QFileDialog", "Back")); + buttons_layout->addWidget(back_button); + + buttons_layout->addStretch(1); + + QPushButton* close_button = new QPushButton(QApplication::translate("QPlatformTheme", "Close")); + close_button->setDefault(true); + buttons_layout->addWidget(close_button); + + layout->addLayout(buttons_layout); + + connect(text_browser, &QTextBrowser::sourceChanged, this, &TextBrowserDialog::sourceChanged); + connect(text_browser, &QTextBrowser::textChanged, this, &TextBrowserDialog::updateWindowTitle); + connect(text_browser, &QTextBrowser::backwardAvailable, back_button, &TextBrowserDialog::setEnabled); + connect(text_browser, (void (QTextBrowser::*)(const QString &))&QTextBrowser::highlighted, this, &TextBrowserDialog::highlighted); + connect(back_button, &QPushButton::clicked, text_browser, &QTextBrowser::backward); + connect(close_button, &QPushButton::clicked, this, &TextBrowserDialog::accept); + + text_browser->setSource(initial_url); + text_browser->document()->adjustSize(); // needed for sizeHint() + +#if defined(Q_OS_ANDROID) + QScroller::grabGesture(text_browser->viewport(), QScroller::TouchGesture); + // Disable selection, so that it doesn't interfere with scrolling + text_browser->setTextInteractionFlags(Qt::TextInteractionFlags(Qt::TextBrowserInteraction) & ~Qt::TextSelectableByMouse); + // Note: Only the above combination of QScroller::LeftMouseButtonGesture + // and ~Qt::TextSelectableByMouse seems to achieve the desired behaviour + // (touch-scrolling without selecting text.) + + setWindowState((windowState() & ~(Qt::WindowMinimized | Qt::WindowFullScreen)) + | Qt::WindowMaximized); +#endif +} + +QSize TextBrowserDialog::sizeHint() const +{ + QSize size = text_browser->document()->size().toSize(); + if (text_browser->verticalScrollBar()) + size.rwidth() += text_browser->verticalScrollBar()->width(); + return size; +} + +void TextBrowserDialog::sourceChanged(const QUrl&) +{ + ; // Nothing, to be overriden in subclasses +} + +void TextBrowserDialog::updateWindowTitle() +{ + setWindowTitle(text_browser->documentTitle()); +} + +void TextBrowserDialog::highlighted(const QString& link) +{ + if (link.isEmpty()) + { + QToolTip::hideText(); + return; + } + + QString tooltip_text; + if (link.contains(QLatin1String("://"))) + { + tooltip_text = tr("External link: %1").arg(link); + } + else + { + tooltip_text = tr("Click to view"); + } + /// @todo: Position near mouse pointer + QPoint tooltip_pos = pos() + text_browser->pos(); + tooltip_pos.ry() += text_browser->height(); + QToolTip::showText(tooltip_pos, tooltip_text, this, QRect()); +} diff --git a/src/gui/text_browser_dialog.h b/src/gui/text_browser_dialog.h new file mode 100644 index 0000000..0055f72 --- /dev/null +++ b/src/gui/text_browser_dialog.h @@ -0,0 +1,69 @@ +/* + * Copyright 2012, 2013, 2014 Thomas Schöps + * Copyright 2012-2015 Kai Pastor + * + * This file is part of OpenOrienteering. + * + * OpenOrienteering is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenOrienteering is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenOrienteering. If not, see . + */ + +#ifndef _OPENORIENTEERING_TEXT_BROWSER_DIALOG_H_ +#define _OPENORIENTEERING_TEXT_BROWSER_DIALOG_H_ + +#include + +class QTextBrowser; +class QUrl; + +/** + * @brief A dialog for basic browsing of HTML pages. + */ +class TextBrowserDialog : public QDialog +{ +Q_OBJECT +public: + /** + * @brief Construct a new dialog. + */ + TextBrowserDialog(const QUrl& initial_url, QWidget* parent = nullptr); + +protected slots: + /** + * @brief Sets custom HTML content when the URL identifies the first page. + */ + virtual void sourceChanged(const QUrl& url); + + /** + * @brief Updates the window title from the current document title. + */ + virtual void updateWindowTitle(); + + /** + * @brief Displays a tooltip showing the link if is an external document. + */ + void highlighted(const QString& link); + +protected: + /** + * @brief Returns a size hint based on the text browser's content. + */ + virtual QSize sizeHint() const override; + + /** + * @brief The TextBrowser is the main widget of this dialog. + */ + QTextBrowser* const text_browser; +}; + +#endif diff --git a/src/gui/widgets/action_grid_bar.cpp b/src/gui/widgets/action_grid_bar.cpp new file mode 100644 index 0000000..100c1f5 --- /dev/null +++ b/src/gui/widgets/action_grid_bar.cpp @@ -0,0 +1,274 @@ +/* + * Copyright 2013 Thomas Schöps + * + * This file is part of OpenOrienteering. + * + * OpenOrienteering is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenOrienteering is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenOrienteering. If not, see . + */ + + +#include "action_grid_bar.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../../util.h" +#include "../../settings.h" + +ActionGridBar::ActionGridBar(Direction direction, int rows, QWidget* parent) +: QWidget(parent) +{ + this->direction = direction; + this->rows = rows; + next_id = 0; + + // Will be calculated in resizeEvent() + cols = 1; + + if (direction == Horizontal) + setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); + else + setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Expanding); + + // Create overflow action + overflow_action = new QAction(QIcon(QString::fromLatin1(":/images/three-dots.png")), tr("Show remaining items"), this); + connect(overflow_action, SIGNAL(triggered()), this, SLOT(overflowActionClicked())); + overflow_button = NULL; + overflow_menu = new QMenu(this); + include_overflow_from_list.push_back(this); +} + +int ActionGridBar::getRows() const +{ + return rows; +} + +int ActionGridBar::getCols() const +{ + return cols; +} + +void ActionGridBar::addAction(QAction* action, int row, int col, int row_span, int col_span, bool at_end) +{ + // Determine icon size (important for high-dpi screens). + // Use a somewhat smaller size than what would cover the whole icon to + // account for the (assumed) button border. + QSize icon_size = getIconSize(row_span, col_span); + + // Ensure that the icon of the given action is big enough. If not, scale it up. + // NOTE: Here, row_span == col_span is assumed. + QIcon icon = action->icon(); + QPixmap pixmap = icon.pixmap(icon_size, QIcon::Normal, QIcon::Off); + if (! pixmap.isNull() && pixmap.width() < icon_size.width()) + { + pixmap = pixmap.scaled(icon_size, Qt::IgnoreAspectRatio, Qt::SmoothTransformation); + icon.addPixmap(pixmap); + action->setIcon(icon); + } + + // Add the item + GridItem newItem; + newItem.id = next_id ++; + newItem.action = action; + newItem.button = new QToolButton(); + newItem.button->setDefaultAction(action); + newItem.button->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + newItem.button->setAutoRaise(true); + newItem.button->setIconSize(icon_size); + newItem.button_hidden = false; + newItem.row = row; + newItem.col = col; + newItem.row_span = row_span; + newItem.col_span = col_span; + newItem.at_end = at_end; + items.push_back(newItem); + + // If this is the overflow action, remember the button. + if (action == overflow_action) + overflow_button = newItem.button; +} + +void ActionGridBar::addActionAtEnd(QAction* action, int row, int col, int row_span, int col_span) +{ + addAction(action, row, col, row_span, col_span, true); +} + +QSize ActionGridBar::getIconSize(int row_span, int col_span) const +{ + int icon_size_pixel_row = qRound(row_span * Util::mmToPixelLogical(Settings::getInstance().getSettingCached(Settings::ActionGridBar_ButtonSizeMM).toFloat())); + int icon_size_pixel_col = qRound(col_span * Util::mmToPixelLogical(Settings::getInstance().getSettingCached(Settings::ActionGridBar_ButtonSizeMM).toFloat())); + const int button_icon_size_row = icon_size_pixel_row - 12; + const int button_icon_size_col = icon_size_pixel_col - 12; + if (direction == Horizontal) + return QSize(button_icon_size_row, button_icon_size_col); + else + return QSize(button_icon_size_col, button_icon_size_row); +} + +QAction* ActionGridBar::getOverflowAction() const +{ + return overflow_action; +} + +void ActionGridBar::setToUseOverflowActionFrom(ActionGridBar* other_bar) +{ + other_bar->include_overflow_from_list.push_back(this); +} + +QToolButton* ActionGridBar::getButtonForAction(QAction* action) +{ + for (size_t i = 0, end = items.size(); i < end; ++ i) + { + GridItem& item = items[i]; + if (item.action == action) + return item.button_hidden ? NULL : item.button; + } + return NULL; +} + +QSize ActionGridBar::sizeHint() const +{ + int height_px = Util::mmToPixelLogical(rows * Settings::getInstance().getSettingCached(Settings::ActionGridBar_ButtonSizeMM).toFloat()); + if (direction == Horizontal) + return QSize(100, height_px); + else + return QSize(height_px, 100); +} + +bool ActionGridBar::compareItemPtrId(ActionGridBar::GridItem* a, ActionGridBar::GridItem* b) +{ + return a->id < b->id; +} + +void ActionGridBar::overflowActionClicked() +{ + overflow_menu->clear(); + for (size_t k = 0; k < include_overflow_from_list.size(); ++ k) + { + ActionGridBar* source_bar = include_overflow_from_list[k]; + for (size_t i = 0, end = source_bar->hidden_items.size(); i < end; ++ i) + overflow_menu->addAction(source_bar->hidden_items[i]->action); + } + if (overflow_button) + overflow_menu->popup(overflow_button->mapToGlobal(QPoint(0, overflow_button->height()))); + else + overflow_menu->popup(mapToGlobal(QPoint(0, height()))); +} + +void ActionGridBar::resizeEvent(QResizeEvent* event) +{ + hidden_items.clear(); + + int length_px = (direction == Horizontal) ? width() : height(); + float length_millimeters = Util::pixelToMMLogical(length_px); + cols = qMax(1, qFloor(length_millimeters / Settings::getInstance().getSettingCached(Settings::ActionGridBar_ButtonSizeMM).toFloat())); + + delete layout(); + QGridLayout* new_layout = new QGridLayout(this); + new_layout->setContentsMargins(0, 0, 0, 0); + new_layout->setSpacing(0); + for (size_t i = 0, end = items.size(); i < end; ++ i) + { + GridItem& item = items[i]; + int resulting_col = item.at_end ? (cols - 1 - item.col) : item.col; + bool hidden = item.row >= rows || item.col >= cols; + if (! hidden) + { + // Check for collisions with other items + for (size_t k = 0; k < items.size(); ++ k) + { + if (i == k) + continue; + GridItem& other = items[k]; + int resulting_col_other = other.at_end ? (cols - 1 - other.col) : other.col; + if (item.row == other.row && resulting_col == resulting_col_other) + { + // Check which item "wins" this spot and which will be hidden + if (item.at_end == other.at_end) + qDebug() << "Warning: two items set to same position in ActionGridBar, this case is not handled!"; + if ((item.at_end && resulting_col <= cols / 2) + || (! item.at_end && resulting_col > cols / 2)) + { + hidden = true; + break; + } + } + } + } + if (hidden) + { + item.button->hide(); + item.button_hidden = true; + hidden_items.push_back(&item); + continue; + } + + if (direction == Horizontal) + { + new_layout->addWidget( + item.button, + item.row, + resulting_col, + qMin(item.row_span, rows - item.row), + qMin(item.col_span, cols - resulting_col) + ); + } + else + { + new_layout->addWidget( + item.button, + resulting_col, + item.row, + qMin(item.col_span, cols - resulting_col), + qMin(item.row_span, rows - item.row) + ); + } + if (item.button_hidden) + { + item.button->setVisible(true); + item.button_hidden = false; + } + item.button->updateGeometry(); + } + + // Set row/col strech. The first and last row/col acts as margin in case + // the available area is not a multiple of the button size. + if (direction == Horizontal) + { + for (int i = 0; i < cols; ++ i) + new_layout->setColumnStretch(i, 1); + for (int i = 0; i < rows; ++ i) + new_layout->setRowStretch(i, 1); + } + else + { + for (int i = 0; i < cols; ++ i) + new_layout->setRowStretch(i, 1); + for (int i = 0; i < rows; ++ i) + new_layout->setColumnStretch(i, 1); + } + + overflow_action->setEnabled(! hidden_items.empty()); + std::sort(hidden_items.begin(), hidden_items.end(), compareItemPtrId); + + event->accept(); +} diff --git a/src/gui/widgets/action_grid_bar.h b/src/gui/widgets/action_grid_bar.h new file mode 100644 index 0000000..9719ace --- /dev/null +++ b/src/gui/widgets/action_grid_bar.h @@ -0,0 +1,119 @@ +/* + * Copyright 2013 Thomas Schöps + * + * This file is part of OpenOrienteering. + * + * OpenOrienteering is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenOrienteering is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenOrienteering. If not, see . + */ + + +#ifndef _OPENORIENTEERING_ACTION_GRID_BAR_H_ +#define _OPENORIENTEERING_ACTION_GRID_BAR_H_ + +#include + +QT_BEGIN_NAMESPACE +class QToolButton; +class QMenu; +QT_END_NAMESPACE + +/** + * A toolbar with a grid layout, whose button size depends on the ppi. + */ +class ActionGridBar : public QWidget +{ +Q_OBJECT +public: + enum Direction + { + Horizontal = 0, + Vertical + }; + + /** + * Constructs a new ActionGridBar. + * + * After constructions, add items and either insert the overflow action + * with addAction(getOverflowAction(), ...) or set another ActionGridBar + * to include the overflow items. + * + * @param direction Direction of the toolbar. + * @param height_items Number of rows in the direction opposite to the main + * toolbar direction. + */ + ActionGridBar(Direction direction, int height_items, QWidget* parent = NULL); + + /** Returns the number of grid rows. */ + int getRows() const; + + /** Returns the number of grid columns. */ + int getCols() const; + + /** Adds an action to the grid. */ + void addAction(QAction* action, int row, int col, int row_span = 1, int col_span = 1, bool at_end = false); + + /** Adds an action to the grid, starting from the opposite direction. */ + void addActionAtEnd(QAction* action, int row, int col, int row_span = 1, int col_span = 1); + + /** Returns the size of the button icons. */ + QSize getIconSize(int row_span = 1, int col_span = 1) const; + + /** Returns the overflow action (to be inserted into the action bar with addAction()). + * The overflow action is enabled if there are items which do not fit into + * the action bar. On click, it shows a list of those actions. */ + QAction* getOverflowAction() const; + + /** Configures this bar to put its overflow actions into another bar. */ + void setToUseOverflowActionFrom(ActionGridBar* other_bar); + + /** Finds and returns the button corresponding to the given action or NULL + * if either the action has not been inserted into the action bar, + * or the button is hidden because of a collision. */ + QToolButton* getButtonForAction(QAction* action); + + virtual QSize sizeHint() const; + +protected slots: + void overflowActionClicked(); + +protected: + struct GridItem + { + int id; // sequential id for sorting in overflow item chooser + int row; + int col; + int row_span; + int col_span; + bool at_end; + QAction* action; + QToolButton* button; + bool button_hidden; + }; + + static bool compareItemPtrId(GridItem* a, GridItem* b); + virtual void resizeEvent(QResizeEvent* event); + + Direction direction; + int rows; + int cols; + std::vector< GridItem > items; + int next_id; + QAction* overflow_action; + QToolButton* overflow_button; + QMenu* overflow_menu; + std::vector< GridItem* > hidden_items; + std::vector< ActionGridBar* > include_overflow_from_list; +}; + +#endif diff --git a/src/gui/widgets/color_dropdown.cpp b/src/gui/widgets/color_dropdown.cpp new file mode 100644 index 0000000..798afb2 --- /dev/null +++ b/src/gui/widgets/color_dropdown.cpp @@ -0,0 +1,161 @@ +/* + * Copyright 2012, 2013 Thomas Schöps + * Copyright 2015 Kai Pastor + * + * This file is part of OpenOrienteering. + * + * OpenOrienteering is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenOrienteering is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenOrienteering. If not, see . + */ + + +#include "color_dropdown.h" + +#include "../../map.h" +#include "../../core/map_color.h" + + +ColorDropDown::ColorDropDown(const Map* map, const MapColor* initial_color, bool spot_colors_only, QWidget* parent) +: QComboBox(parent) +, spot_colors_only(spot_colors_only) +{ + addItem(tr("- none -"), QVariant::fromValue(NULL)); + + int icon_size = style()->pixelMetric(QStyle::PM_SmallIconSize); + QPixmap pixmap(icon_size, icon_size); + + int initial_index = 0; + int num_colors = map->getNumColors(); + for (int i = 0; i < num_colors; ++i) + { + const MapColor* color = map->getColor(i); + if (spot_colors_only && color->getSpotColorMethod() != MapColor::SpotColor) + continue; + + if (initial_color == color) + initial_index = count(); + + pixmap.fill(colorWithOpacity(*color)); + QString name = spot_colors_only ? color->getSpotColorName() : color->getName(); + addItem(QIcon(pixmap), name, QVariant::fromValue(color)); + } + if (!spot_colors_only) + { + const int count = this->count(); + if (count > 0) + { + insertSeparator(count); + } + const MapColor* color = Map::getRegistrationColor(); + pixmap.fill(*color); + addItem(QIcon(pixmap), color->getName(), QVariant::fromValue(color)); + } + setCurrentIndex(initial_index); + + connect(map, &Map::colorAdded, this, &ColorDropDown::onColorAdded); + connect(map, &Map::colorChanged, this, &ColorDropDown::onColorChanged); + connect(map, &Map::colorDeleted, this, &ColorDropDown::onColorDeleted); +} + +ColorDropDown::~ColorDropDown() +{ + // Nothing, not inlined. +} + +const MapColor* ColorDropDown::color() const +{ + return itemData(currentIndex()).value(); +} + +void ColorDropDown::setColor(const MapColor* color) +{ + setCurrentIndex(findData(QVariant::fromValue(color))); +} + +void ColorDropDown::addColor(const MapColor* color) +{ + if (!spot_colors_only || color->getSpotColorMethod() == MapColor::SpotColor) + { + int pos = 0; + for (; pos < count(); ++pos) + { + const MapColor* c = itemData(pos).value(); + if (c && c->getPriority() > color->getPriority()) + break; + } + int icon_size = style()->pixelMetric(QStyle::PM_SmallIconSize); + QPixmap pixmap(icon_size, icon_size); + pixmap.fill(*color); + insertItem(pos, color->getName(), QVariant::fromValue(color)); + setItemData(pos, pixmap, Qt::DecorationRole); + } +} + +void ColorDropDown::updateColor(const MapColor* color) +{ + if (!spot_colors_only || color->getSpotColorMethod() == MapColor::SpotColor) + { + int pos = 0; + for (; pos < count(); ++pos) + { + if (itemData(pos).value() == color) + break; + } + + if (pos < count()) + { + int icon_size = style()->pixelMetric(QStyle::PM_SmallIconSize); + QPixmap pixmap(icon_size, icon_size); + pixmap.fill(*color); + setItemText(pos, color->getName()); + setItemData(pos, pixmap, Qt::DecorationRole); + } + else + { + addColor(color); + } + } + else + { + removeColor(color); + } +} + +void ColorDropDown::removeColor(const MapColor* color) +{ + for (int pos = 0; pos < count(); ++pos) + { + if (itemData(pos).value() == color) + { + if (currentIndex() == pos) + setCurrentIndex(0); + removeItem(pos); + break; + } + } +} + +void ColorDropDown::onColorAdded(int, const MapColor* color) +{ + addColor(color); +} + +void ColorDropDown::onColorChanged(int, const MapColor* color) +{ + updateColor(color); +} + +void ColorDropDown::onColorDeleted(int, const MapColor* color) +{ + removeColor(color); +} diff --git a/src/gui/widgets/color_dropdown.h b/src/gui/widgets/color_dropdown.h new file mode 100644 index 0000000..2d629b7 --- /dev/null +++ b/src/gui/widgets/color_dropdown.h @@ -0,0 +1,69 @@ +/* + * Copyright 2012, 2013 Thomas Schöps + * Copyright 2015 Kai Pastor + * + * This file is part of OpenOrienteering. + * + * OpenOrienteering is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenOrienteering is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenOrienteering. If not, see . + */ + + +#ifndef _OPENORIENTEERING_COLOR_DROPDOWN_H_ +#define _OPENORIENTEERING_COLOR_DROPDOWN_H_ + +#include + +class Map; +class MapColor; + +/** + * A combobox which lets the user select a map color. + */ +class ColorDropDown : public QComboBox +{ +Q_OBJECT +public: + /** + * Constructs a new ColorDropDown for the colors of the given map. + * If spot_colors_only is true, it will only display fulltone spot colors. + */ + ColorDropDown(const Map* map, const MapColor* initial_color = nullptr, bool spot_colors_only = false, QWidget* parent = nullptr); + + /** Destructor. */ + ~ColorDropDown(); + + /** Returns the selected color or NULL if no color selected. */ + const MapColor* color() const; + + /** Sets the selection to the given color. */ + void setColor(const MapColor* color); + + /** Adds a color to the list. */ + void addColor(const MapColor* color); + + /** Updates a color in the list. */ + void updateColor(const MapColor* color); + + /** Removes a color from the list. */ + void removeColor(const MapColor* color); + +protected: + void onColorAdded(int, const MapColor* color); + void onColorChanged(int, const MapColor* color); + void onColorDeleted(int, const MapColor* color); + + const bool spot_colors_only; +}; + +#endif diff --git a/src/gui/widgets/compass_display.cpp b/src/gui/widgets/compass_display.cpp new file mode 100644 index 0000000..1b96257 --- /dev/null +++ b/src/gui/widgets/compass_display.cpp @@ -0,0 +1,116 @@ +/* + * Copyright 2013 Thomas Schöps + * Copyright 2015 Kai Pastor + * + * This file is part of OpenOrienteering. + * + * OpenOrienteering is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenOrienteering is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenOrienteering. If not, see . + */ + +#include "compass_display.h" + +#include +#include + +#include "../../util.h" + + +CompassDisplay::CompassDisplay(QWidget* parent) + : QWidget(parent) + , azimuth(qSNaN()) + , last_update_time(QTime::currentTime()) +{ + setAttribute(Qt::WA_NoSystemBackground, true); +} + +CompassDisplay::~CompassDisplay() +{ + // nothing, not inlined +} + +void CompassDisplay::setAzimuth(float azimuth_deg) +{ + constexpr int update_interval = 200; + QTime current_time = QTime::currentTime(); + if (qAbs(last_update_time.msecsTo(current_time)) >= update_interval + && azimuth != azimuth_deg) + { + last_update_time = current_time; + azimuth = azimuth_deg; + update(); + if (auto parent = parentWidget()) + parent->update(geometry()); + } +} + +QSize CompassDisplay::sizeHint() const +{ + auto width = qRound(Util::mmToPixelLogical(20.0)); + return QSize(width, width); +} + +void CompassDisplay::showEvent(QShowEvent*) +{ + azimuth = qSNaN(); +} + +void CompassDisplay::hideEvent(QHideEvent*) +{ + // nothing +} + +void CompassDisplay::paintEvent(QPaintEvent*) +{ + QPainter painter(this); + painter.setRenderHint(QPainter::Antialiasing); + + auto margin = Util::mmToPixelLogical(1.0f); + QRectF bounding_box = { {0,0}, size() }; + bounding_box.adjust(margin, margin, -margin, -margin); + QPointF midpoint = bounding_box.center(); + QPointF endpoint = QPointF(midpoint.x(), bounding_box.top()); + QLineF line(midpoint, endpoint); + + auto have_value = !qIsNaN(azimuth); + + // Draw alignment cue + constexpr qreal max_alignment_angle = 10; + if (have_value && qAbs(azimuth) < max_alignment_angle) + { + float alignment_factor = (max_alignment_angle - qAbs(azimuth)) / max_alignment_angle; + float radius = alignment_factor * 0.25f * bounding_box.height(); + painter.setPen(Qt::NoPen); + painter.setBrush(Qt::green); + painter.drawEllipse(line.pointAt(0.5f), radius, radius); + } + + // Draw up marker + float line_width = Util::mmToPixelLogical(0.3f); + + painter.setPen(QPen(Qt::white, line_width)); + painter.setBrush(Qt::NoBrush); + painter.drawLine(line); + + painter.setPen(QPen(Qt::black, line_width)); + painter.drawLine(midpoint + QPointF(line_width, 0), endpoint + QPointF(line_width, 0)); + painter.drawLine(midpoint + QPointF(-1 * line_width, 0), endpoint + QPointF(-1 * line_width, 0)); + + // Draw needle + if (have_value) + { + painter.setPen(QPen(Qt::red, line_width)); + line.setAngle(90 + azimuth); + painter.drawLine(line); + } +} diff --git a/src/gui/widgets/compass_display.h b/src/gui/widgets/compass_display.h new file mode 100644 index 0000000..c3c8d68 --- /dev/null +++ b/src/gui/widgets/compass_display.h @@ -0,0 +1,69 @@ +/* + * Copyright 2013 Thomas Schöps + * Copyright 2015 Kai Pastor + * + * This file is part of OpenOrienteering. + * + * OpenOrienteering is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenOrienteering is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenOrienteering. If not, see . + */ + + +#ifndef _OPENORIENTEERING_COMPASS_DISPLAY_H_ +#define _OPENORIENTEERING_COMPASS_DISPLAY_H_ + +#include +#include + +/** + * A widget which displays a compass. + * + * By default, this widget is transparent (Qt::WA_NoSystemBackground), i.e. it + * it does not draw a background. For proper background drawing, it shall not be + * a child but a sibling of the background widget. + */ +class CompassDisplay : public QWidget +{ +Q_OBJECT +public: + /** + * Creates a compass display. + */ + CompassDisplay(QWidget* parent = nullptr); + + /** + * Destructor. + */ + ~CompassDisplay() override; + + /** + * Sets the compass direction, and updates the widget. + * + * This does nothing unless at least 200 ms elapsed since the last change. + */ + void setAzimuth(float azimuth_deg); + + QSize sizeHint() const override; + +protected: + void showEvent(QShowEvent* event) override; + + void hideEvent(QHideEvent* event) override; + + void paintEvent(QPaintEvent* event) override; + + qreal azimuth; + QTime last_update_time; +}; + +#endif diff --git a/src/gui/widgets/crs_param_widgets.cpp b/src/gui/widgets/crs_param_widgets.cpp new file mode 100644 index 0000000..dca1634 --- /dev/null +++ b/src/gui/widgets/crs_param_widgets.cpp @@ -0,0 +1,97 @@ +/* + * Copyright 2015 Kai Pastor + * + * This file is part of OpenOrienteering. + * + * OpenOrienteering is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenOrienteering is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenOrienteering. If not, see . + */ + +#include "crs_param_widgets.h" + +#include +#include +#include +#include +#include + +#include "../../core/crs_template.h" +#include "../../core/crs_template_implementation.h" +#include "../../core/georeferencing.h" +#include "../../core/latlon.h" +#include "../georeferencing_dialog.h" + + + +UTMZoneEdit::UTMZoneEdit(CRSParameterWidgetObserver& observer, QWidget* parent) + : QWidget(parent) + , observer(observer) +{ + static const QRegExp zone_regexp(QString::fromLatin1("(?:[0-5]?[1-9]|[1-6]0)(?: [NS])?")); + static QStringList zone_list; + if (zone_list.isEmpty()) + { + for (int i = 1; i <= 60; ++i) + { + QString zone = QString::number(i); + zone_list << QString::fromLatin1("%1 N").arg(zone) << QString::fromLatin1("%1 S").arg(zone); + if (i < 10) + zone_list << QString::fromLatin1("0%1 N").arg(zone) << QString::fromLatin1("0%1 S").arg(zone); + } + } + + line_edit = new QLineEdit(); + line_edit->setValidator(new QRegExpValidator(zone_regexp, line_edit)); + QCompleter* completer = new QCompleter(zone_list, line_edit); + completer->setMaxVisibleItems(4); + line_edit->setCompleter(completer); + connect(line_edit, &QLineEdit::textChanged, this, &UTMZoneEdit::textEdited); + + QPushButton* button = new QPushButton(tr("Calculate")); + connect(button, &QPushButton::clicked, this, &UTMZoneEdit::calculateValue); + + QHBoxLayout* layout = new QHBoxLayout(); + layout->setMargin(0); + layout->addWidget(line_edit, 1); + layout->addWidget(button, 0); + setLayout(layout); + + calculateValue(); +} + +UTMZoneEdit::~UTMZoneEdit() +{ + // nothing, not inlined +} + +QString UTMZoneEdit::text() const +{ + return line_edit->text(); +} + +void UTMZoneEdit::setText(const QString& value) +{ + line_edit->setText(value); +} + +bool UTMZoneEdit::calculateValue() +{ + auto georef = observer.georeferencing(); + auto zone = CRSTemplates::UTMZoneParameter::calculateUTMZone(georef.getGeographicRefPoint()); + if (!zone.isNull()) + { + setText(zone.toString()); + } + + return !zone.isNull(); +} diff --git a/src/gui/widgets/crs_param_widgets.h b/src/gui/widgets/crs_param_widgets.h new file mode 100644 index 0000000..8b4c94c --- /dev/null +++ b/src/gui/widgets/crs_param_widgets.h @@ -0,0 +1,54 @@ +/* + * Copyright 2015 Kai Pastor + * + * This file is part of OpenOrienteering. + * + * OpenOrienteering is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenOrienteering is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenOrienteering. If not, see . + */ + + +#ifndef OPENORIENTEERING_CRS_PARAM_WIDGETS_H +#define OPENORIENTEERING_CRS_PARAM_WIDGETS_H + +#include + +class QLineEdit; + +class BaseGeoreferencingDialog; +class CRSParameterWidgetObserver; +class LatLon; + + +class UTMZoneEdit : public QWidget +{ + Q_OBJECT +public: + UTMZoneEdit(CRSParameterWidgetObserver& observer, QWidget* parent = nullptr); + virtual ~UTMZoneEdit(); + + QString text() const; + void setText(const QString& text); + bool calculateValue(); + +signals: + void textEdited(const QString& text); // TODO: rename to textChanged, see QLineEdit + +private: + CRSParameterWidgetObserver& observer; + QLineEdit* line_edit; +}; + + + +#endif diff --git a/src/gui/widgets/crs_selector.cpp b/src/gui/widgets/crs_selector.cpp new file mode 100644 index 0000000..7078c5f --- /dev/null +++ b/src/gui/widgets/crs_selector.cpp @@ -0,0 +1,382 @@ +/* + * Copyright 2012, 2013 Thomas Schöps + * Copyright 2012-2015 Kai Pastor + * + * This file is part of OpenOrienteering. + * + * OpenOrienteering is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenOrienteering is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenOrienteering. If not, see . + */ + + +#include "crs_selector.h" + +#include +#include +#include + +#include "../georeferencing_dialog.h" +#include "../../core/crs_template.h" +#include "../../core/georeferencing.h" +#include "../../util/scoped_signals_blocker.h" + + +// Helper functions for parameter widgets +namespace +{ +static const char* crsParameterWidgetProperty = "CRS parameter widget"; +static const char* crsParameterKeyProperty = "CRS parameter key"; + +inline +void setParameterWidget(QWidget* w, bool value = true) +{ + w->setProperty(crsParameterWidgetProperty, QVariant(value)); +} + +inline +bool isParameterWidget(const QWidget* w) +{ + return w->property(crsParameterWidgetProperty).toBool(); +} + +inline +void setParameterKey(QWidget* w, const QString& value) +{ + w->setProperty(crsParameterKeyProperty, QVariant(value)); +} + +inline +QString ParameterKey(const QWidget* w) +{ + return w->property(crsParameterKeyProperty).toString(); +} + +} // namespace + + + +CRSSelector::CRSSelector(const Georeferencing& georef, QWidget* parent) + : QComboBox(parent) + , georef(georef) + , dialog_layout(nullptr) + , num_custom_items(0) + , configured_crs(nullptr) +{ + for (auto&& crs : CRSTemplateRegistry().list()) + { + addItem(crs->name(), QVariant(crs->id())); + } +} + +CRSSelector::~CRSSelector() +{ + // nothing, not inlined +} + + +void CRSSelector::setDialogLayout(QFormLayout* dialog_layout) +{ + Q_ASSERT(dialog_layout && !this->dialog_layout); + + this->dialog_layout = dialog_layout; + + using TakingIntArgument = void (QComboBox::*)(int); + connect(this, (TakingIntArgument)&QComboBox::currentIndexChanged, + this, &CRSSelector::crsSelectionChanged); +} + + +void CRSSelector::addCustomItem(const QString& text, unsigned short id) +{ + insertItem(num_custom_items, text, QVariant(int(id))); + if (num_custom_items == 0) + insertSeparator(1); + ++num_custom_items; +} + + +const CRSTemplate* CRSSelector::currentCRSTemplate() const +{ + const CRSTemplate* crs = nullptr; + auto item_data = itemData(currentIndex()); + if (item_data.type() == QVariant::String) + crs = CRSTemplateRegistry().find(item_data.toString()); + return crs; +} + +QString CRSSelector::currentCRSSpec() const +{ + QString spec; + if (auto crs = currentCRSTemplate()) + { + spec = crs->specificationTemplate(); + auto field_values = parameters(); + Q_ASSERT(field_values.size() == crs->parameters().size()); + + auto field_value = begin(field_values); + for (auto&& param : crs->parameters()) + { + for (auto&& value : param->specValues(*field_value)) + spec = spec.arg(value); + ++field_value; + } + } + return spec; +} + +int CRSSelector::currentCustomItem() const +{ + int id = -1; + QVariant item_data = itemData(currentIndex()); + if (item_data.type() == QVariant::Int) + id = item_data.toInt(); + return id; +} + +void CRSSelector::setCurrentCRS(const CRSTemplate* crs, const std::vector& values) +{ + Q_ASSERT(crs); + if (crs) + { + Q_ASSERT(crs->parameters().size() == values.size()); + + int index = findData(QVariant(crs->id())); + setCurrentIndex(index); + + // Explicit call because signals may be blocked. + if (crs == currentCRSTemplate()) + { + configureParameterFields(crs, values); + } + } +} + +void CRSSelector::setCurrentItem(unsigned short id) +{ + QSignalBlocker block(this); + int index = findData(QVariant(id)); + setCurrentIndex(index); + + // Explicit call because signals may be blocked. + if (currentCustomItem() == int(id)) + { + configureParameterFields(nullptr, {}); + } +} + + +std::vector CRSSelector::parameters() const + +{ + std::vector values; + auto crs = currentCRSTemplate(); + if (crs && configured_crs == crs) + { + values.reserve(crs->parameters().size()); + + int row; + QFormLayout::ItemRole role; + dialog_layout->getWidgetPosition(const_cast(this), &row, &role); + + for (auto&& param : crs->parameters()) + { + ++row; + auto field = dialog_layout->itemAt(row, QFormLayout::FieldRole)->widget(); + Q_ASSERT(isParameterWidget(field)); + values.push_back(param->value(field)); + } + } + else if (crs) + { + values.resize(crs->parameters().size()); + } + + return values; +} + +const Georeferencing& CRSSelector::georeferencing() const +{ + return georef; +} + +void CRSSelector::crsSelectionChanged() +{ + configureParameterFields(); + emit crsChanged(); +} + +void CRSSelector::crsParameterEdited() +{ + emit crsChanged(); +} + + +void CRSSelector::configureParameterFields() +{ + if (dialog_layout) + { + auto crs = currentCRSTemplate(); + if (!crs) + configureParameterFields(crs, {}); + else if (crs->id() == georef.getProjectedCRSId()) + configureParameterFields(crs, georef.getProjectedCRSParameters()); + else + configureParameterFields(crs, std::vector(crs->parameters().size())); + } +} + +void CRSSelector::configureParameterFields(const CRSTemplate* crs, const std::vector& values) +{ + if (crs != configured_crs && dialog_layout) + { + removeParameterFields(); + addParameterFields(crs); + } + + if (crs && configured_crs == crs && !values.empty()) + { + int row; + QFormLayout::ItemRole role; + dialog_layout->getWidgetPosition(this, &row, &role); + + // Set the new parameter values. + auto parameters = crs->parameters(); + Q_ASSERT(parameters.size() == values.size()); + + auto parameter = begin(parameters); + auto value = begin(values); + for (++row; dialog_layout->rowCount() > row && value != end(values); ++row) + { + auto field_item = dialog_layout->itemAt(row, QFormLayout::FieldRole); + if (!field_item) + continue; + + auto field = field_item->widget(); + if (!field || !isParameterWidget(field)) + continue; + + QSignalBlocker block(field); + (*parameter)->setValue(field, *value); + ++value; + ++parameter; + } + } +} + +void CRSSelector::addParameterFields(const CRSTemplate* crs) +{ + Q_ASSERT(!configured_crs); + + if (dialog_layout && crs && crs != configured_crs) + { + int row; + QFormLayout::ItemRole role; + dialog_layout->getWidgetPosition(this, &row, &role); + + // Add the labels and fields of the new parameters. + for (auto&& parameter : crs->parameters()) + { + ++row; + auto field = parameter->createEditor(*this); + setParameterWidget(field, true); + setParameterKey(field, parameter->id()); + auto label = new QLabel(parameter->name() + QLatin1Char(':')); + if (dialog_layout->itemAt(row, QFormLayout::FieldRole)) + { + dialog_layout->insertRow(row, label, field); + } + else + { + dialog_layout->setWidget(row, QFormLayout::LabelRole, label); + dialog_layout->setWidget(row, QFormLayout::FieldRole, field); + } + } + + configured_crs = crs; + } +} + +void CRSSelector::removeParameterFields() +{ + if (dialog_layout) + { + int crs_row; + QFormLayout::ItemRole role; + dialog_layout->getWidgetPosition(this, &crs_row, &role); + + // Remove the labels and fields of the old parameters. + for (int row = dialog_layout->rowCount()-1; row > crs_row; --row) + { + auto field_item = dialog_layout->itemAt(row, QFormLayout::FieldRole); + if (!field_item) + continue; + + auto field = field_item->widget(); + if (!field || !isParameterWidget(field)) + continue; + + auto label_item = dialog_layout->itemAt(row, QFormLayout::LabelRole); + if (auto label = label_item->widget()) + { + delete dialog_layout->takeAt(dialog_layout->indexOf(label)); + delete label; + } + + delete dialog_layout->takeAt(dialog_layout->indexOf(field)); + delete field; + } + + configured_crs = nullptr; + } +} + +void CRSSelector::changeEvent(QEvent* event) +{ + switch (event->type()) + { + case QEvent::EnabledChange: + if (dialog_layout) + { + bool enabled = isEnabled(); + if (auto label = dialog_layout->labelForField(this)) + label->setEnabled(enabled); + + int row; + QFormLayout::ItemRole role; + dialog_layout->getWidgetPosition(this, &row, &role); + + // Remove the labels and fields of the old parameters. + for (++row; dialog_layout->rowCount() > row; ++row) + { + auto field_item = dialog_layout->itemAt(row, QFormLayout::FieldRole); + if (!field_item) + continue; + + auto field = field_item->widget(); + if (!field || !isParameterWidget(field)) + continue; + + auto label_item = dialog_layout->itemAt(row, QFormLayout::LabelRole); + if (auto label = label_item->widget()) + label->setEnabled(enabled); + + field->setEnabled(enabled); + } + + configured_crs = nullptr; + } + break; + default: + ; // nothing + } +} diff --git a/src/gui/widgets/crs_selector.h b/src/gui/widgets/crs_selector.h new file mode 100644 index 0000000..0d160e2 --- /dev/null +++ b/src/gui/widgets/crs_selector.h @@ -0,0 +1,186 @@ +/* + * Copyright 2012, 2013 Thomas Schöps + * Copyright 2012-2015 Kai Pastor + * + * This file is part of OpenOrienteering. + * + * OpenOrienteering is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenOrienteering is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenOrienteering. If not, see . + */ + + +#ifndef OPENORIENTEERING_CRS_SELECTOR_H +#define OPENORIENTEERING_CRS_SELECTOR_H + +#include + +#include "../../core/crs_template.h" + +QT_BEGIN_NAMESPACE +class QFormLayout; +QT_END_NAMESPACE + +class BaseGeoreferencingDialog; +class CRSTemplate; + + +/** + * Combobox for selecting projected coordinate reference system (CRS). + * + * It operates on the list of CRS templates in the CRSTemplateRegistry. + * However, it accepts custom items which are prepended to and separated from + * the default items. + * + * This is more than just a simple widget. CRSSelector is meant to be inserted + * into a QFormLayout. Upon CRS selection changes it will add and remove extra + * lines below itself, for editing CRS parameters. + * + * \todo Consider making this a QWidget which has got a QCombobox - the public + * QComboBox API should better not be exposed. The combobox' signals could + * no longer be block from clients. + */ +class CRSSelector : public QComboBox, public CRSParameterWidgetObserver +{ +Q_OBJECT +public: + /** + * Constructor. + * + * The dialog parameter must not be nullptr. It is passed to parameter widgets. + * Ownership is taken only by the parent widget if given. + */ + CRSSelector(const Georeferencing& georef, QWidget* parent = nullptr); + + /** + * Destructor. + */ + virtual ~CRSSelector(); + + + /** + * Sets the QFormLayout which this field is part of. + * + * When the selected CRS is changed, or when configureParameterFields() + * is called explicitly, CRSSelector will add extra lines below its own row + * for editing CRS parameters. + * + * This is to be called once. However, it will not create the parameter + * fields for the current selection. + */ + void setDialogLayout(QFormLayout* dialog_layout); + + + /** + * Adds a custom item with the given text and id at the top of the list. + */ + void addCustomItem(const QString& text, unsigned short id); + + + /** + * Returns the selected CRS template, or nullptr if a custom item is selected. + */ + const CRSTemplate* currentCRSTemplate() const; + + /** + * Returns the selected CRS specification string, + * or an empty string if a custom item is selected. + */ + QString currentCRSSpec() const; + + /** + * Returns the id of the selected custom item, + * or -1 if a normal item is selected. + */ + int currentCustomItem() const; + + + /** + * Selects the given standard item, and sets the parameters. + */ + void setCurrentCRS(const CRSTemplate* crs, const std::vector& values); + + /** + * Selects the given custom item. + */ + void setCurrentItem(unsigned short id); + + + /** + * Returns the list of CRS configuration parameter values. + */ + std::vector parameters() const; + + + /** + * Provides the current georeferencing. + */ + const Georeferencing& georeferencing() const override; + + +signals: + /** + * Emitted when the user changes the CRS or its parameters. + */ + void crsChanged(); + + +protected: + /** + * Listens to changes of the selected CRS. + */ + void crsSelectionChanged(); + + /** + * Listens to changes of CRS parameters. + */ + void crsParameterEdited() override; + + /** + * Updates the parameter fields in the dialog_layout, + * according to the selected CRS. + */ + void configureParameterFields(); + + /** + * Updates the parameter fields in the dialog_layout, + * according to the given CRS and values. + */ + void configureParameterFields(const CRSTemplate* crs, const std::vector& values); + + /** + * Adds parameter fields to the dialog_layout, + * according to the given crs. + * + * There must be no other parameter fields in the dialog, + * i.e. removeParameterFields() needs to be called before. + */ + void addParameterFields(const CRSTemplate* crs); + + /** + * Removes all parameter fields from the dialog_layout. + */ + void removeParameterFields(); + + /** + * Propagates enabling/disabling to the parameter widgets. + */ + void changeEvent(QEvent* event) override; + +private: + const Georeferencing& georef; + QFormLayout* dialog_layout; + int num_custom_items; + const CRSTemplate* configured_crs; +}; + +#endif diff --git a/src/gui/widgets/editor_settings_page.cpp b/src/gui/widgets/editor_settings_page.cpp new file mode 100644 index 0000000..f499a5a --- /dev/null +++ b/src/gui/widgets/editor_settings_page.cpp @@ -0,0 +1,147 @@ +/* + * Copyright 2012, 2013 Jan Dalheimer + * Copyright 2012-2016 Kai Pastor + * + * This file is part of OpenOrienteering. + * + * OpenOrienteering is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenOrienteering is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenOrienteering. If not, see . + */ + +#include "editor_settings_page.h" + +#include +#include +#include + +#include "../modifier_key.h" +#include "../../util_gui.h" + + +EditorSettingsPage::EditorSettingsPage(QWidget* parent) + : SettingsPage(parent) +{ + auto layout = new QFormLayout(this); + + antialiasing = new QCheckBox(tr("High quality map display (antialiasing)"), this); + antialiasing->setToolTip(tr("Antialiasing makes the map look much better, but also slows down the map display")); + layout->addRow(antialiasing); + + text_antialiasing = new QCheckBox(tr("High quality text display in map (antialiasing), slow"), this); + text_antialiasing->setToolTip(tr("Antialiasing makes the map look much better, but also slows down the map display")); + layout->addRow(text_antialiasing); + + tolerance = Util::SpinBox::create(0, 50, tr("mm", "millimeters")); + layout->addRow(tr("Click tolerance:"), tolerance); + + snap_distance = Util::SpinBox::create(0, 100, tr("mm", "millimeters")); + layout->addRow(tr("Snap distance (%1):").arg(ModifierKey::shift()), snap_distance); + + fixed_angle_stepping = Util::SpinBox::create(1, 180, trUtf8("°", "Degree sign for angles")); + layout->addRow(tr("Stepping of fixed angle mode (%1):").arg(ModifierKey::control()), fixed_angle_stepping); + + select_symbol_of_objects = new QCheckBox(tr("When selecting an object, automatically select its symbol, too")); + layout->addRow(select_symbol_of_objects); + + zoom_out_away_from_cursor = new QCheckBox(tr("Zoom away from cursor when zooming out")); + layout->addRow(zoom_out_away_from_cursor); + + draw_last_point_on_right_click = new QCheckBox(tr("Drawing tools: set last point on finishing with right click")); + layout->addRow(draw_last_point_on_right_click); + + keep_settings_of_closed_templates = new QCheckBox(tr("Templates: keep settings of closed templates")); + layout->addRow(keep_settings_of_closed_templates); + + + layout->addItem(Util::SpacerItem::create(this)); + layout->addRow(Util::Headline::create(tr("Edit tool:"))); + + edit_tool_delete_bezier_point_action = new QComboBox(); + edit_tool_delete_bezier_point_action->addItem(tr("Retain old shape"), (int)Settings::DeleteBezierPoint_RetainExistingShape); + edit_tool_delete_bezier_point_action->addItem(tr("Reset outer curve handles"), (int)Settings::DeleteBezierPoint_ResetHandles); + edit_tool_delete_bezier_point_action->addItem(tr("Keep outer curve handles"), (int)Settings::DeleteBezierPoint_KeepHandles); + layout->addRow(tr("Action on deleting a curve point with %1:").arg(ModifierKey::control()), edit_tool_delete_bezier_point_action); + + edit_tool_delete_bezier_point_action_alternative = new QComboBox(); + edit_tool_delete_bezier_point_action_alternative->addItem(tr("Retain old shape"), (int)Settings::DeleteBezierPoint_RetainExistingShape); + edit_tool_delete_bezier_point_action_alternative->addItem(tr("Reset outer curve handles"), (int)Settings::DeleteBezierPoint_ResetHandles); + edit_tool_delete_bezier_point_action_alternative->addItem(tr("Keep outer curve handles"), (int)Settings::DeleteBezierPoint_KeepHandles); + layout->addRow(tr("Action on deleting a curve point with %1:").arg(ModifierKey::controlShift()), edit_tool_delete_bezier_point_action_alternative); + + layout->addItem(Util::SpacerItem::create(this)); + layout->addRow(Util::Headline::create(tr("Rectangle tool:"))); + + rectangle_helper_cross_radius = Util::SpinBox::create(0, 999999, tr("mm", "millimeters")); + layout->addRow(tr("Radius of helper cross:"), rectangle_helper_cross_radius); + + rectangle_preview_line_width = new QCheckBox(tr("Preview the width of lines with helper cross")); + layout->addRow(rectangle_preview_line_width); + + + connect(antialiasing, &QAbstractButton::toggled, text_antialiasing, &QCheckBox::setEnabled); + + updateWidgets(); +} + +EditorSettingsPage::~EditorSettingsPage() +{ + // nothing, not inlined +} + +QString EditorSettingsPage::title() const +{ + return tr("Editor"); +} + +void EditorSettingsPage::apply() +{ + setSetting(Settings::MapDisplay_Antialiasing, antialiasing->isChecked()); + setSetting(Settings::MapDisplay_TextAntialiasing, text_antialiasing->isChecked()); + setSetting(Settings::MapEditor_ClickToleranceMM, tolerance->value()); + setSetting(Settings::MapEditor_SnapDistanceMM, snap_distance->value()); + setSetting(Settings::MapEditor_FixedAngleStepping, fixed_angle_stepping->value()); + setSetting(Settings::MapEditor_ChangeSymbolWhenSelecting, select_symbol_of_objects->isChecked()); + setSetting(Settings::MapEditor_ZoomOutAwayFromCursor, zoom_out_away_from_cursor->isChecked()); + setSetting(Settings::MapEditor_DrawLastPointOnRightClick, draw_last_point_on_right_click->isChecked()); + setSetting(Settings::Templates_KeepSettingsOfClosed, keep_settings_of_closed_templates->isChecked()); + setSetting(Settings::EditTool_DeleteBezierPointAction, edit_tool_delete_bezier_point_action->currentData()); + setSetting(Settings::EditTool_DeleteBezierPointActionAlternative, edit_tool_delete_bezier_point_action_alternative->currentData()); + setSetting(Settings::RectangleTool_HelperCrossRadiusMM, rectangle_helper_cross_radius->value()); + setSetting(Settings::RectangleTool_PreviewLineWidth, rectangle_preview_line_width->isChecked()); +} + +void EditorSettingsPage::reset() +{ + updateWidgets(); +} + +void EditorSettingsPage::updateWidgets() +{ + antialiasing->setChecked(getSetting(Settings::MapDisplay_Antialiasing).toBool()); + text_antialiasing->setEnabled(antialiasing->isChecked()); + text_antialiasing->setChecked(getSetting(Settings::MapDisplay_TextAntialiasing).toBool()); + tolerance->setValue(getSetting(Settings::MapEditor_ClickToleranceMM).toInt()); + snap_distance->setValue(getSetting(Settings::MapEditor_SnapDistanceMM).toInt()); + fixed_angle_stepping->setValue(getSetting(Settings::MapEditor_FixedAngleStepping).toInt()); + select_symbol_of_objects->setChecked(getSetting(Settings::MapEditor_ChangeSymbolWhenSelecting).toBool()); + zoom_out_away_from_cursor->setChecked(getSetting(Settings::MapEditor_ZoomOutAwayFromCursor).toBool()); + draw_last_point_on_right_click->setChecked(getSetting(Settings::MapEditor_DrawLastPointOnRightClick).toBool()); + keep_settings_of_closed_templates->setChecked(getSetting(Settings::Templates_KeepSettingsOfClosed).toBool()); + + edit_tool_delete_bezier_point_action->setCurrentIndex(edit_tool_delete_bezier_point_action->findData(getSetting(Settings::EditTool_DeleteBezierPointAction).toInt())); + edit_tool_delete_bezier_point_action_alternative->setCurrentIndex(edit_tool_delete_bezier_point_action_alternative->findData(getSetting(Settings::EditTool_DeleteBezierPointActionAlternative).toInt())); + + rectangle_helper_cross_radius->setValue(getSetting(Settings::RectangleTool_HelperCrossRadiusMM).toInt()); + rectangle_preview_line_width->setChecked(getSetting(Settings::RectangleTool_PreviewLineWidth).toBool()); +} + diff --git a/src/gui/widgets/editor_settings_page.h b/src/gui/widgets/editor_settings_page.h new file mode 100644 index 0000000..f1279e6 --- /dev/null +++ b/src/gui/widgets/editor_settings_page.h @@ -0,0 +1,69 @@ +/* + * Copyright 2012, 2013 Jan Dalheimer + * Copyright 2013-2016 Kai Pastor + * + * This file is part of OpenOrienteering. + * + * OpenOrienteering is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenOrienteering is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenOrienteering. If not, see . + */ + +#ifndef OPENORIENTEERING_EDITOR_SETTINGS_PAGE_H +#define OPENORIENTEERING_EDITOR_SETTINGS_PAGE_H + +#include "settings_page.h" + +class QCheckBox; +class QComboBox; +class QSpinBox; + +class MainWindow; + + +class EditorSettingsPage : public SettingsPage +{ +Q_OBJECT +public: + explicit EditorSettingsPage(QWidget* parent = nullptr); + + ~EditorSettingsPage() override; + + QString title() const override; + + void apply() override; + + void reset() override; + +protected: + void updateWidgets(); + +private: + QCheckBox* antialiasing; + QCheckBox* text_antialiasing; + QSpinBox* tolerance; + QSpinBox* snap_distance; + QSpinBox* fixed_angle_stepping; + QCheckBox* select_symbol_of_objects; + QCheckBox* zoom_out_away_from_cursor; + QCheckBox* draw_last_point_on_right_click; + QCheckBox* keep_settings_of_closed_templates; + + QComboBox* edit_tool_delete_bezier_point_action; + QComboBox* edit_tool_delete_bezier_point_action_alternative; + + QSpinBox* rectangle_helper_cross_radius; + QCheckBox* rectangle_preview_line_width; +}; + + +#endif diff --git a/src/gui/widgets/general_settings_page.cpp b/src/gui/widgets/general_settings_page.cpp new file mode 100644 index 0000000..74525d9 --- /dev/null +++ b/src/gui/widgets/general_settings_page.cpp @@ -0,0 +1,391 @@ +/* + * Copyright 2012, 2013 Jan Dalheimer + * Copyright 2012-2016 Kai Pastor + * + * This file is part of OpenOrienteering. + * + * OpenOrienteering is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenOrienteering is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenOrienteering. If not, see . + */ + +#include "general_settings_page.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "home_screen_widget.h" +#include "../main_window.h" +#include "../../util_gui.h" +#include "../../util_translation.h" +#include "../../util/backports.h" +#include "../../util/encoding.h" +#include "../../util/scoped_signals_blocker.h" + + +GeneralSettingsPage::GeneralSettingsPage(QWidget* parent) +: SettingsPage(parent) +, translation_file(getSetting(Settings::General_TranslationFile).toString()) +{ + auto layout = new QFormLayout(this); + + layout->addRow(Util::Headline::create(tr("Appearance"))); + + auto language_widget = new QWidget(); + auto language_layout = new QHBoxLayout(language_widget); + language_layout->setContentsMargins({}); + layout->addRow(tr("Language:"), language_widget); + + language_box = new QComboBox(this); + language_layout->addWidget(language_box); + + QAbstractButton* language_file_button = new QToolButton(); + if (MainWindow::mobileMode()) + { + language_file_button->setVisible(false); + } + else + { + language_file_button->setIcon(QIcon(QLatin1String(":/images/open.png"))); + } + language_layout->addWidget(language_file_button); + + layout->addItem(Util::SpacerItem::create(this)); + layout->addRow(Util::Headline::create(tr("Screen"))); + + auto ppi_widget = new QWidget(); + auto ppi_layout = new QHBoxLayout(ppi_widget); + ppi_layout->setContentsMargins({}); + layout->addRow(tr("Pixels per inch:"), ppi_widget); + + ppi_edit = Util::SpinBox::create(2, 0.01, 9999); + ppi_layout->addWidget(ppi_edit); + + QAbstractButton* ppi_calculate_button = new QToolButton(); + ppi_calculate_button->setIcon(QIcon(QLatin1String(":/images/settings.png"))); + ppi_layout->addWidget(ppi_calculate_button); + + layout->addItem(Util::SpacerItem::create(this)); + layout->addRow(Util::Headline::create(tr("Program start"))); + + open_mru_check = new QCheckBox(AbstractHomeScreenWidget::tr("Open most recently used file")); + layout->addRow(open_mru_check); + + tips_visible_check = new QCheckBox(AbstractHomeScreenWidget::tr("Show tip of the day")); + layout->addRow(tips_visible_check); + + layout->addItem(Util::SpacerItem::create(this)); + layout->addRow(Util::Headline::create(tr("Saving files"))); + + compatibility_check = new QCheckBox(tr("Retain compatibility with Mapper %1").arg(QLatin1String("0.5"))); + layout->addRow(compatibility_check); + + // Possible point: limit size of undo/redo journal + + autosave_check = new QCheckBox(tr("Save information for automatic recovery")); + layout->addRow(autosave_check); + + autosave_interval_edit = Util::SpinBox::create(1, 120, tr("min", "unit minutes"), 1); + layout->addRow(tr("Recovery information saving interval:"), autosave_interval_edit); + + layout->addItem(Util::SpacerItem::create(this)); + layout->addRow(Util::Headline::create(tr("File import and export"))); + + QStringList available_codecs; + available_codecs.append(tr("Default")); + encoding_box = new QComboBox(); + encoding_box->setEditable(true); + encoding_box->addItem(available_codecs.first()); + encoding_box->addItem(QString::fromLatin1("Windows-1252")); // Serves as an example, not translated. + const auto available_codecs_raw = QTextCodec::availableCodecs(); + for (const QByteArray& item : available_codecs_raw) + { + available_codecs.append(QString::fromUtf8(item)); + } + if (available_codecs.size() > 1) + { + available_codecs.sort(Qt::CaseInsensitive); + available_codecs.removeDuplicates(); + encoding_box->addItem(tr("More...")); + } + QCompleter* completer = new QCompleter(available_codecs, this); + completer->setModelSorting(QCompleter::CaseInsensitivelySortedModel); + completer->setCaseSensitivity(Qt::CaseInsensitive); + completer->setCompletionMode(QCompleter::UnfilteredPopupCompletion); + encoding_box->setCompleter(completer); + layout->addRow(tr("8-bit encoding:"), encoding_box); + + ocd_importer_check = new QCheckBox(tr("Use the new OCD importer also for version 8 files").replace(QLatin1Char('8'), QString::fromLatin1("6-8"))); + layout->addRow(ocd_importer_check); + + updateWidgets(); + + connect(language_file_button, &QAbstractButton::clicked, this, &GeneralSettingsPage::openTranslationFileDialog); + connect(ppi_calculate_button, &QAbstractButton::clicked, this, &GeneralSettingsPage::openPPICalculationDialog); + connect(encoding_box, &QComboBox::currentTextChanged, this, &GeneralSettingsPage::encodingChanged); + connect(autosave_check, &QAbstractButton::toggled, autosave_interval_edit, &QWidget::setEnabled); + connect(autosave_check, &QAbstractButton::toggled, layout->labelForField(autosave_interval_edit), &QWidget::setEnabled); + +} + +GeneralSettingsPage::~GeneralSettingsPage() +{ + // nothing, not inlined +} + +QString GeneralSettingsPage::title() const +{ + return tr("General"); +} + +void GeneralSettingsPage::apply() +{ + auto language = language_box->currentData().toString(); + if (language != getSetting(Settings::General_Language).toString() + || translation_file != getSetting(Settings::General_TranslationFile).toString()) + { + // Show an message box in the new language. + TranslationUtil translation(language, translation_file); + auto new_language = QLocale(translation.code()).language(); + switch (new_language) + { + case QLocale::AnyLanguage: + case QLocale::C: + case QLocale::English: + QMessageBox::information(window(), QLatin1String("Notice"), QLatin1String("The program must be restarted for the language change to take effect!")); + break; + + default: + qApp->installEventFilter(this); + qApp->installTranslator(&translation.getQtTranslator()); + qApp->installTranslator(&translation.getAppTranslator()); + QMessageBox::information(window(), tr("Notice"), tr("The program must be restarted for the language change to take effect!")); + qApp->removeTranslator(&translation.getAppTranslator()); + qApp->removeTranslator(&translation.getQtTranslator()); + qApp->removeEventFilter(this); + } + + setSetting(Settings::General_Language, translation.code()); + setSetting(Settings::General_TranslationFile, translation_file); +#if defined(Q_OS_MAC) + // The native [file] dialogs will use the first element of the + // AppleLanguages array in the application's .plist file - + // and this file is also the one used by QSettings. + QSettings().setValue(QString::fromLatin1("AppleLanguages"), QStringList{ translation.code() }); +#endif + } + + setSetting(Settings::General_OpenMRUFile, open_mru_check->isChecked()); + setSetting(Settings::HomeScreen_TipsVisible, tips_visible_check->isChecked()); + setSetting(Settings::General_NewOcd8Implementation, ocd_importer_check->isChecked()); + setSetting(Settings::General_RetainCompatiblity, compatibility_check->isChecked()); + setSetting(Settings::General_PixelsPerInch, ppi_edit->value()); + + auto encoding = encoding_box->currentText().toLatin1(); + if (QLatin1String(encoding) == encoding_box->itemText(0) + || !QTextCodec::codecForName(encoding)) + { + encoding = "Default"; + } + setSetting(Settings::General_Local8BitEncoding, encoding); + + int interval = autosave_interval_edit->value(); + if (!autosave_check->isChecked()) + interval = -interval; + setSetting(Settings::General_AutosaveInterval, interval); +} + +void GeneralSettingsPage::reset() +{ + translation_file = getSetting(Settings::General_TranslationFile).toString(); + updateWidgets(); +} + +void GeneralSettingsPage::updateLanguageBox(QVariant code) +{ + auto languages = TranslationUtil::availableLanguages(); + std::sort(begin(languages), end(languages)); + + const QSignalBlocker block(language_box); + language_box->clear(); + for (const auto& language : languages) + language_box->addItem(language.displayName, language.code); + + // If there is an explicit translation file, make sure it is in the box. + auto language = TranslationUtil::languageFromFilename(translation_file); + if (language.isValid()) + { + auto index = language_box->findData(language.code); + if (index < 0) + language_box->addItem(language.displayName, language.code); + } + + // Select current language + auto index = language_box->findData(code); + if (index < 0) + { + code = QString::fromLatin1("en"); + index = language_box->findData(code); + } + language_box->setCurrentIndex(index); +} + +void GeneralSettingsPage::updateWidgets() +{ + updateLanguageBox(getSetting(Settings::General_Language)); + + ppi_edit->setValue(getSetting(Settings::General_PixelsPerInch).toDouble()); + open_mru_check->setChecked(getSetting(Settings::General_OpenMRUFile).toBool()); + tips_visible_check->setChecked(getSetting(Settings::HomeScreen_TipsVisible).toBool()); + compatibility_check->setChecked(getSetting(Settings::General_RetainCompatiblity).toBool()); + + int autosave_interval = getSetting(Settings::General_AutosaveInterval).toInt(); + autosave_check->setChecked(autosave_interval > 0); + autosave_interval_edit->setEnabled(autosave_interval > 0); + autosave_interval_edit->setValue(qAbs(autosave_interval)); + + auto encoding = getSetting(Settings::General_Local8BitEncoding).toByteArray(); + if (encoding != "Default" + && QTextCodec::codecForName(encoding)) + { + encoding_box->setCurrentText(QString::fromLatin1(encoding)); + } + + ocd_importer_check->setChecked(getSetting(Settings::General_NewOcd8Implementation).toBool()); +} + +// slot +void GeneralSettingsPage::encodingChanged(const QString& input) +{ + if (input == tr("More...")) + { + const QSignalBlocker block(encoding_box); + encoding_box->setCurrentText(last_encoding_input); + encoding_box->completer()->setCompletionPrefix(last_encoding_input); + encoding_box->completer()->complete(); + } + else + { + // Inline completition, in addition to UnfilteredPopupCompletition + // Don't complete after pressing Backspace or Del + if (!last_encoding_input.startsWith(input)) + { + if (last_matching_completition.startsWith(input)) + encoding_box->completer()->setCompletionPrefix(last_matching_completition); + + auto text = encoding_box->completer()->currentCompletion(); + auto line_edit = encoding_box->lineEdit(); + if (text.startsWith(input) + && line_edit) + { + const QSignalBlocker block(encoding_box); + auto pos = line_edit->cursorPosition(); + line_edit->setText(text); + line_edit->setSelection(text.length(), pos - text.length()); + last_encoding_input = input.left(pos); + last_matching_completition = text; + return; + } + } + last_encoding_input = input; + } +} + +// slot +void GeneralSettingsPage::openTranslationFileDialog() +{ + QString filename = translation_file; + if (filename.isEmpty()) + filename = getSetting(Settings::General_TranslationFile).toString(); + + filename = QFileDialog::getOpenFileName(this, + tr("Open translation"), filename, tr("Translation files (*.qm)")); + if (!filename.isNull()) + { + auto language = TranslationUtil::languageFromFilename(filename); + if (!language.isValid()) + { + QMessageBox::critical(this, tr("Open translation"), + tr("The selected file is not a valid translation.") ); + } + else + { + translation_file = filename; + updateLanguageBox(language.code); + } + } +} + +// slot +void GeneralSettingsPage::openPPICalculationDialog() +{ + int primary_screen_width = QApplication::primaryScreen()->size().width(); + int primary_screen_height = QApplication::primaryScreen()->size().height(); + double screen_diagonal_pixels = double(qSqrt(primary_screen_width*primary_screen_width + primary_screen_height*primary_screen_height)); + + double old_ppi = ppi_edit->value(); + double old_screen_diagonal_inches = screen_diagonal_pixels / old_ppi; + + QDialog* dialog = new QDialog(window(), Qt::WindowSystemMenuHint | Qt::WindowTitleHint); + if (MainWindow::mobileMode()) + { + dialog->setGeometry(window()->geometry()); + } + + auto layout = new QVBoxLayout(dialog); + + auto form_layout = new QFormLayout(); + + QLabel* resolution_display = new QLabel(tr("%1 x %2").arg(primary_screen_width).arg(primary_screen_height)); + form_layout->addRow(tr("Primary screen resolution in pixels:"), resolution_display); + + QDoubleSpinBox* size_edit = Util::SpinBox::create(2, 0.01, 9999); + size_edit->setValue(old_screen_diagonal_inches); + form_layout->addRow(tr("Primary screen size in inches (diagonal):"), size_edit); + + layout->addLayout(form_layout); + + layout->addItem(Util::SpacerItem::create(this)); + + QDialogButtonBox* button_box = new QDialogButtonBox(QDialogButtonBox::Cancel | QDialogButtonBox::Ok); + layout->addWidget(button_box); + + connect(button_box, &QDialogButtonBox::accepted, dialog, &QDialog::accept); + connect(button_box, &QDialogButtonBox::rejected, dialog, &QDialog::reject); + dialog->exec(); + + if (dialog->result() == QDialog::Accepted) + { + ppi_edit->setValue(screen_diagonal_pixels / size_edit->value()); + } +} + +bool GeneralSettingsPage::eventFilter(QObject* /* watched */, QEvent* event) +{ + if (event->type() == QEvent::LanguageChange) + return true; + + return false; +} + diff --git a/src/gui/widgets/general_settings_page.h b/src/gui/widgets/general_settings_page.h new file mode 100644 index 0000000..5b95949 --- /dev/null +++ b/src/gui/widgets/general_settings_page.h @@ -0,0 +1,86 @@ +/* + * Copyright 2012, 2013 Jan Dalheimer + * Copyright 2013-2016 Kai Pastor + * + * This file is part of OpenOrienteering. + * + * OpenOrienteering is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenOrienteering is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenOrienteering. If not, see . + */ + +#ifndef OPENORIENTEERING_GENERAL_SETTINGS_PAGE_H +#define OPENORIENTEERING_GENERAL_SETTINGS_PAGE_H + +#include "settings_page.h" + +class QCheckBox; +class QComboBox; +class QDoubleSpinBox; +class QSpinBox; + + +class GeneralSettingsPage : public SettingsPage +{ +Q_OBJECT +public: + explicit GeneralSettingsPage(QWidget* parent = nullptr); + + ~GeneralSettingsPage() override; + + QString title() const override; + + void apply() override; + + void reset() override; + +protected: + /** + * Adds the available languages to the language combo box, + * and sets the current element. + */ + void updateLanguageBox(QVariant code); + + void updateWidgets(); + + /** + * This event filter stops LanguageChange events. + */ + bool eventFilter(QObject* watched, QEvent* event) override; + +private slots: + void openTranslationFileDialog(); + + void openPPICalculationDialog(); + + void encodingChanged(const QString& input); + +private: + QString translation_file; + QString last_encoding_input; + QString last_matching_completition; + + QComboBox* language_box; + + QDoubleSpinBox* ppi_edit; + QCheckBox* open_mru_check; + QCheckBox* tips_visible_check; + + QCheckBox* compatibility_check; + QCheckBox* autosave_check; + QSpinBox* autosave_interval_edit; + + QComboBox* encoding_box; + QCheckBox* ocd_importer_check; +}; + +#endif diff --git a/src/gui/widgets/home_screen_widget.cpp b/src/gui/widgets/home_screen_widget.cpp new file mode 100644 index 0000000..3db9686 --- /dev/null +++ b/src/gui/widgets/home_screen_widget.cpp @@ -0,0 +1,570 @@ +/* + * Copyright 2012, 2013 Thomas Schöps + * Copyright 2012-2015 Kai Pastor + * + * This file is part of OpenOrienteering. + * + * OpenOrienteering is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenOrienteering is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenOrienteering. If not, see . + */ + + +#include "home_screen_widget.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../home_screen_controller.h" +#include "../main_window.h" +#include "../settings_dialog.h" +#include "../../core/storage_location.h" +#include "../../file_format_registry.h" +#include "../../mapper_resource.h" + + +//### AbstractHomeScreenWidget ### + +AbstractHomeScreenWidget::AbstractHomeScreenWidget(HomeScreenController* controller, QWidget* parent) +: QWidget(parent), + controller(controller) +{ + Q_ASSERT(controller->getWindow() != NULL); +} + +AbstractHomeScreenWidget::~AbstractHomeScreenWidget() +{ + // nothing +} + +QLabel* AbstractHomeScreenWidget::makeHeadline(const QString& text, QWidget* parent) const +{ + QLabel* title_label = new QLabel(text, parent); + QFont title_font = title_label->font(); + int pixel_size = title_font.pixelSize(); + if (pixel_size > 0) + { + title_font.setPixelSize(pixel_size * 2); + } + else + { + pixel_size = title_font.pointSize(); + title_font.setPointSize(pixel_size * 2); + } + title_font.setBold(true); + title_label->setFont(title_font); + title_label->setAlignment(Qt::AlignLeft | Qt::AlignTop); + return title_label; +} + +QAbstractButton* AbstractHomeScreenWidget::makeButton(const QString& text, QWidget* parent) const +{ + QAbstractButton* button = new QCommandLinkButton(text, parent); + QFont button_font = button->font(); + int pixel_size = button_font.pixelSize(); + if (pixel_size > 0) + { + button_font.setPixelSize(pixel_size * 3 / 2); + } + else + { + pixel_size = button_font.pointSize(); + button_font.setPointSize(pixel_size * 3 / 2); + } + button->setFont(button_font); + return button; +} + +QAbstractButton* AbstractHomeScreenWidget::makeButton(const QString& text, const QIcon& icon, QWidget* parent) const +{ + QAbstractButton* button = makeButton(text, parent); + button->setIcon(icon); + return button; +} + + + +//### HomeScreenWidgetDesktop ### + +HomeScreenWidgetDesktop::HomeScreenWidgetDesktop(HomeScreenController* controller, QWidget* parent) +: AbstractHomeScreenWidget(controller, parent) +{ + QLabel* title_label = new QLabel(QString::fromLatin1("")); + title_label->setAlignment(Qt::AlignCenter); + QWidget* menu_widget = makeMenuWidget(controller, parent); + QWidget* recent_files_widget = makeRecentFilesWidget(controller, parent); + QWidget* tips_widget = makeTipsWidget(controller, parent); + + QGridLayout* layout = new QGridLayout(); + layout->setSpacing(2 * layout->spacing()); + layout->addWidget(title_label, 0, 0, 1, 2); + layout->addWidget(menu_widget, 1, 0, 2, 1); + layout->addWidget(recent_files_widget, 1, 1); + layout->setRowStretch(1, 4); + layout->addWidget(tips_widget, 2, 1); + layout->setRowStretch(2, 3); + setLayout(layout); + + setAutoFillBackground(false); +} + +HomeScreenWidgetDesktop::~HomeScreenWidgetDesktop() +{ + // nothing +} + +QWidget* HomeScreenWidgetDesktop::makeMenuWidget(HomeScreenController* controller, QWidget* parent) +{ + MainWindow* window = controller->getWindow(); + + QVBoxLayout* menu_layout = new QVBoxLayout(); + + QLabel* menu_headline = makeHeadline(tr("Activities")); + menu_layout->addWidget(menu_headline); + QAbstractButton* button_new_map = makeButton( + tr("Create a new map ..."), QIcon(QString::fromLatin1(":/images/new.png"))); + menu_layout->addWidget(button_new_map); + QAbstractButton* button_open_map = makeButton( + tr("Open map ..."), QIcon(QString::fromLatin1(":/images/open.png"))); + menu_layout->addWidget(button_open_map); + + menu_layout->addStretch(1); + + QAbstractButton* button_settings = makeButton( + tr("Settings"), QIcon(QString::fromLatin1(":/images/settings.png"))); + menu_layout->addWidget(button_settings); + QAbstractButton* button_about = makeButton( + tr("About %1", "As in 'About OpenOrienteering Mapper'").arg(window->appName()), QIcon(QString::fromLatin1(":/images/about.png"))); + menu_layout->addWidget(button_about); + QAbstractButton* button_help = makeButton( + tr("Help"), QIcon(QString::fromLatin1(":/images/help.png"))); + menu_layout->addWidget(button_help); + QAbstractButton* button_exit = makeButton( + tr("Exit"), QIcon(QString::fromLatin1(":/qt-project.org/styles/commonstyle/images/standardbutton-close-32.png"))); // From Qt5 + menu_layout->addWidget(button_exit); + + connect(button_new_map, SIGNAL(clicked(bool)), window, SLOT(showNewMapWizard())); + connect(button_open_map, SIGNAL(clicked(bool)), window, SLOT(showOpenDialog())); + connect(button_settings, SIGNAL(clicked(bool)), window, SLOT(showSettings())); + connect(button_about, SIGNAL(clicked(bool)), window, SLOT(showAbout())); + connect(button_help, SIGNAL(clicked(bool)), window, SLOT(showHelp())); + connect(button_exit, SIGNAL(clicked(bool)), qApp, SLOT(closeAllWindows())); + + QWidget* menu_widget = new QWidget(parent); + menu_widget->setLayout(menu_layout); + menu_widget->setAutoFillBackground(true); + return menu_widget; +} + +QWidget* HomeScreenWidgetDesktop::makeRecentFilesWidget(HomeScreenController* controller, QWidget* parent) +{ + QGridLayout* recent_files_layout = new QGridLayout(); + + QLabel* recent_files_headline = makeHeadline(tr("Recent maps")); + recent_files_layout->addWidget(recent_files_headline, 0, 0, 1, 2); + + recent_files_list = new QListWidget(); + QFont list_font = recent_files_list->font(); + int pixel_size = list_font.pixelSize(); + if (pixel_size > 0) + { + list_font.setPixelSize(pixel_size * 3 / 2); + } + else + { + pixel_size = list_font.pointSize(); + list_font.setPointSize(pixel_size * 3 / 2); + } + recent_files_list->setFont(list_font); + recent_files_list->setSpacing(pixel_size/2); + recent_files_list->setCursor(Qt::PointingHandCursor); + recent_files_list->setStyleSheet(QString::fromLatin1(" \ + QListWidget::item:hover { \ + color: palette(highlighted-text); \ + background: palette(highlight); \ + } ")); + recent_files_layout->addWidget(recent_files_list, 1, 0, 1, 2); + + open_mru_file_check = new QCheckBox(tr("Open most recently used file on start")); + recent_files_layout->addWidget(open_mru_file_check, 2, 0, 1, 1); + + QPushButton* clear_list_button = new QPushButton(tr("Clear list")); + recent_files_layout->addWidget(clear_list_button, 2, 1, 1, 1); + + recent_files_layout->setRowStretch(1, 1); + recent_files_layout->setColumnStretch(0, 1); + + connect(recent_files_list, SIGNAL(itemClicked(QListWidgetItem*)), this, SLOT(recentFileClicked(QListWidgetItem*))); + connect(open_mru_file_check, SIGNAL(clicked(bool)), controller, SLOT(setOpenMRUFile(bool))); + connect(clear_list_button, SIGNAL(clicked(bool)), controller, SLOT(clearRecentFiles())); + + QWidget* recent_files_widget = new QWidget(parent); + recent_files_widget->setLayout(recent_files_layout); + recent_files_widget->setAutoFillBackground(true); + return recent_files_widget; +} + +QWidget* HomeScreenWidgetDesktop::makeTipsWidget(HomeScreenController* controller, QWidget* parent) +{ + QGridLayout* tips_layout = new QGridLayout(); + QWidget* tips_headline = makeHeadline(tr("Tip of the day")); + tips_layout->addWidget(tips_headline, 0, 0, 1, 3); + tips_label = new QLabel(); + tips_label->setWordWrap(true); + tips_label->setAlignment(Qt::AlignLeft | Qt::AlignVCenter); + tips_check = new QCheckBox(tr("Show tip of the day")); + tips_check->setChecked(true); + tips_layout->addWidget(tips_check, 2, 0, 1, 1); + tips_layout->addWidget(tips_label, 1, 0, 1, 3); + QPushButton* prev_button = new QPushButton(QIcon(QString::fromLatin1(":/images/arrow-left.png")), tr("Previous")); + tips_layout->addWidget(prev_button, 2, 1, 1, 1); + QPushButton* next_button = new QPushButton(QIcon(QString::fromLatin1(":/images/arrow-right.png")), tr("Next")); + tips_layout->addWidget(next_button, 2, 2, 1, 1); + + tips_layout->setRowStretch(1, 1); + tips_layout->setColumnStretch(0, 1); + + tips_children.reserve(4); + tips_children.push_back(tips_headline); + tips_children.push_back(tips_label); + tips_children.push_back(prev_button); + tips_children.push_back(next_button); + + MainWindow* window = controller->getWindow(); + connect(tips_label, SIGNAL(linkActivated(QString)), window, SLOT(linkClicked(QString))); + connect(tips_check, SIGNAL(clicked(bool)), controller, SLOT(setTipsVisible(bool))); + connect(prev_button, SIGNAL(clicked(bool)), controller, SLOT(goToPreviousTip())); + connect(next_button, SIGNAL(clicked(bool)), controller, SLOT(goToNextTip())); + + QWidget* tips_widget = new QWidget(parent); + tips_widget->setLayout(tips_layout); + tips_widget->setAutoFillBackground(true); + return tips_widget; +} + +void HomeScreenWidgetDesktop::setRecentFiles(const QStringList& files) +{ + recent_files_list->clear(); + for (auto&& file : files) + { + QListWidgetItem* new_item = new QListWidgetItem(QFileInfo(file).fileName()); + new_item->setData(Qt::UserRole, file); + new_item->setToolTip(file); + recent_files_list->addItem(new_item); + } +} + +void HomeScreenWidgetDesktop::recentFileClicked(QListWidgetItem* item) +{ + QString path = item->data(Qt::UserRole).toString(); + controller->getWindow()->openPath(path); +} + +void HomeScreenWidgetDesktop::paintEvent(QPaintEvent*) +{ + // Background + QPainter p(this); + p.setPen(Qt::NoPen); + p.setBrush(Qt::gray); + p.drawRect(rect()); +} + +void HomeScreenWidgetDesktop::setOpenMRUFileChecked(bool state) +{ + open_mru_file_check->setChecked(state); +} + +void HomeScreenWidgetDesktop::setTipOfTheDay(const QString& text) +{ + tips_label->setText(text); +} + +void HomeScreenWidgetDesktop::setTipsVisible(bool state) +{ + QGridLayout* layout = qobject_cast(this->layout()); + for (auto widget : tips_children) + { + widget->setVisible(state); + } + if (layout != NULL) + layout->setRowStretch(2, state ? 3 : 0); + + tips_check->setChecked(state); +} + + + +//### HomeScreenWidgetMobile ### + +HomeScreenWidgetMobile::HomeScreenWidgetMobile(HomeScreenController* controller, QWidget* parent) +: AbstractHomeScreenWidget(controller, parent) +{ + title_pixmap = QPixmap::fromImage(QImage(QString::fromLatin1(":/images/title.png"))); + + title_label = new QLabel(); + title_label->setPixmap(title_pixmap); + title_label->setAlignment(Qt::AlignCenter); + + QWidget* file_list_widget = makeFileListWidget(controller, parent); + + examples_button = new QPushButton(tr("Examples")); + connect(examples_button, &QPushButton::clicked, this, &HomeScreenWidgetMobile::showExamples); + auto settings_button = new QPushButton(HomeScreenWidgetDesktop::tr("Settings")); + connect(settings_button, &QPushButton::clicked, controller->getWindow(), &MainWindow::showSettings); + QPushButton* help_button = new QPushButton(HomeScreenWidgetDesktop::tr("Help")); + connect(help_button, &QPushButton::clicked, controller->getWindow(), &MainWindow::showHelp); + QPushButton* about_button = new QPushButton(tr("About Mapper")); + connect(about_button, &QPushButton::clicked, controller->getWindow(), &MainWindow::showAbout); + QHBoxLayout* buttons_layout = new QHBoxLayout(); + buttons_layout->setContentsMargins(0, 0, 0, 0); + buttons_layout->addWidget(examples_button); + buttons_layout->addStretch(1); + buttons_layout->addWidget(settings_button); + buttons_layout->addWidget(help_button); + buttons_layout->addWidget(about_button); + + QGridLayout* layout = new QGridLayout(); + layout->setSpacing(2 * layout->spacing()); + layout->addWidget(title_label, 0, 0); + layout->addWidget(file_list_widget, 1, 0); + layout->addLayout(buttons_layout, 2, 0); + setLayout(layout); + + setAutoFillBackground(false); +} + +HomeScreenWidgetMobile::~HomeScreenWidgetMobile() +{ + // nothing +} + +void HomeScreenWidgetMobile::resizeEvent(QResizeEvent* event) +{ + Q_UNUSED(event); + adjustTitlePixmapSize(); +} + +void HomeScreenWidgetMobile::adjustTitlePixmapSize() +{ + QSize label_size = title_label->size(); + int scaled_width = qRound(title_pixmap.devicePixelRatio() * label_size.width()); + if (title_pixmap.width() > scaled_width) + { + if (title_label->pixmap()->width() != scaled_width) + { + label_size.setHeight(title_pixmap.height()); + title_label->setPixmap(title_pixmap.scaled(label_size, Qt::KeepAspectRatio, Qt::SmoothTransformation)); + } + } + else if (title_label->pixmap()->width() != title_pixmap.width()) + { + title_label->setPixmap(title_pixmap); + } +} + +void HomeScreenWidgetMobile::setRecentFiles(const QStringList& files) +{ + Q_UNUSED(files); + // nothing +} + +void HomeScreenWidgetMobile::setOpenMRUFileChecked(bool state) +{ + Q_UNUSED(state); + // nothing +} + +void HomeScreenWidgetMobile::setTipOfTheDay(const QString& text) +{ + Q_UNUSED(text); + // nothing +} + +void HomeScreenWidgetMobile::setTipsVisible(bool state) +{ + Q_UNUSED(state); + // nothing +} + +// slot +void HomeScreenWidgetMobile::showExamples() +{ + int old_size = file_list->count(); + + QStringList paths = MapperResource::getLocations(MapperResource::EXAMPLE); + while (!paths.isEmpty()) + { + addFilesToFileList(file_list, paths.takeFirst()); + } + + if (file_list->count() > old_size) + { + file_list_stack->setCurrentIndex(0); + file_list->setCurrentRow(old_size, QItemSelectionModel::ClearAndSelect); + examples_button->setEnabled(false); + } +} + +void HomeScreenWidgetMobile::showSettings() +{ + auto window = this->window(); + + SettingsDialog dialog(window); + dialog.setGeometry(window->geometry()); + dialog.exec(); +} + +void HomeScreenWidgetMobile::fileClicked(QListWidgetItem* item) +{ + QString hint_text = item->data(Qt::UserRole+1).toString(); + if (!hint_text.isEmpty()) + QMessageBox::warning(this, MainWindow::tr("Warning"), hint_text.arg(item->data(Qt::DisplayRole).toString())); + + QString path = item->data(Qt::UserRole).toString(); + controller->getWindow()->openPath(path); +} + +QWidget* HomeScreenWidgetMobile::makeFileListWidget(HomeScreenController* controller, QWidget* parent) +{ + Q_UNUSED(controller); + Q_UNUSED(parent); + + QGridLayout* file_list_layout = new QGridLayout(); + + QLabel* file_list_headline = makeHeadline(tr("File list")); + file_list_layout->addWidget(file_list_headline, 0, 0, 1, 2); + + file_list_stack = new QStackedLayout(); + file_list_layout->addLayout(file_list_stack, 1, 0, 1, 2); + file_list_layout->setRowStretch(1, 1); + + file_list = new QListWidget(); + QScroller::grabGesture(file_list->viewport(), QScroller::TouchGesture); + QFont list_font = file_list->font(); + int pixel_size = list_font.pixelSize(); + if (pixel_size > 0) + { + list_font.setPixelSize(pixel_size * 3 / 2); + } + else + { + pixel_size = list_font.pointSize(); + list_font.setPointSize(pixel_size * 3 / 2); + } + file_list->setFont(list_font); + file_list->setSpacing(pixel_size/2); + file_list->setCursor(Qt::PointingHandCursor); + file_list->setStyleSheet(QString::fromLatin1(" \ + QListWidget::item:hover { \ + color: palette(highlighted-text); \ + background: palette(highlight); \ + } ")); + file_list_stack->addWidget(file_list); + + // Look for map files at device-specific locations +#ifdef Q_OS_ANDROID + const auto style = file_list->style(); + StorageLocation::refresh(); + const auto locations = StorageLocation::knownLocations(); + for (const auto& location : *locations) + { + QIcon icon; + QString hint_text; + switch (location.hint()) + { + case StorageLocation::HintApplication: + icon = style->standardIcon(QStyle::SP_MessageBoxInformation); + hint_text = StorageLocation::fileHintTextTemplate(location.hint()); + break; + case StorageLocation::HintReadOnly: + icon = style->standardIcon(QStyle::SP_MessageBoxWarning); + hint_text = StorageLocation::fileHintTextTemplate(location.hint()); + break; + default: + break; + } + + QDirIterator it(location.path(), QDir::Files | QDir::NoDotAndDotDot, QDirIterator::Subdirectories); + while (it.hasNext()) { + it.next(); + if (!FileFormats.findFormatForFilename(it.filePath())) + continue; + + QListWidgetItem* new_item = new QListWidgetItem(it.fileInfo().fileName()); + new_item->setData(Qt::UserRole, it.filePath()); + new_item->setToolTip(it.filePath()); + if (Q_LIKELY( + location.hint() == StorageLocation::HintReadOnly + || it.fileInfo().isWritable() )) + { + new_item->setIcon(icon); + new_item->setData(Qt::UserRole+1, hint_text); + } + else + { + new_item->setIcon(style->standardIcon(QStyle::SP_MessageBoxWarning)); + new_item->setData(Qt::UserRole+1, StorageLocation::fileHintTextTemplate(StorageLocation::HintReadOnly)); + } + file_list->addItem(new_item); + } + } +#endif + + if (file_list->count() == 0) + { + // Remove the incorrect part from the existing translated text. + /// \todo Review the text for placing the first maps + auto label_text = tr("No map files found!

Copy map files to a top-level folder named 'OOMapper' on the device or a memory card."); + label_text.truncate(label_text.indexOf(QLatin1String("
"))); + QLabel* message_label = new QLabel(label_text); + message_label->setWordWrap(true); + file_list_stack->addWidget(message_label); + file_list_stack->setCurrentWidget(message_label); + } + + connect(file_list, SIGNAL(itemClicked(QListWidgetItem*)), this, SLOT(fileClicked(QListWidgetItem*))); + + QWidget* file_list_widget = new QWidget(); + file_list_widget->setLayout(file_list_layout); + file_list_widget->setAutoFillBackground(true); + return file_list_widget; +} + +void HomeScreenWidgetMobile::addFilesToFileList(QListWidget* file_list, const QString& path) +{ + QDirIterator it(path, QDir::Files | QDir::NoDotAndDotDot, QDirIterator::Subdirectories); + while (it.hasNext()) { + it.next(); + if (FileFormats.findFormatForFilename(it.filePath()) == NULL) + continue; + + QListWidgetItem* new_item = new QListWidgetItem(it.fileInfo().fileName()); + new_item->setData(Qt::UserRole, it.filePath()); + new_item->setToolTip(it.filePath()); + file_list->addItem(new_item); + } +} diff --git a/src/gui/widgets/home_screen_widget.h b/src/gui/widgets/home_screen_widget.h new file mode 100644 index 0000000..99b3be1 --- /dev/null +++ b/src/gui/widgets/home_screen_widget.h @@ -0,0 +1,204 @@ +/* + * Copyright 2012, 2013, 2014 Thomas Schöps, Kai Pastor + * + * This file is part of OpenOrienteering. + * + * OpenOrienteering is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenOrienteering is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenOrienteering. If not, see . + */ + + +#ifndef _OPENORIENTEERING_HOME_SCREEN_WIDGET_H_ +#define _OPENORIENTEERING_HOME_SCREEN_WIDGET_H_ + +#include + +#include + +QT_BEGIN_NAMESPACE +class QAbstractButton; +class QCheckBox; +class QLabel; +class QListWidget; +class QListWidgetItem; +class QMouseEvent; +class QPaintEvent; +class QPushButton; +class QStackedLayout; +QT_END_NAMESPACE + +class HomeScreenController; + +/** + * The user interface of the OpenOrienteering Mapper home screen. + * The OpenOrienteering Mapper home screen is shown when no document is open, + * for example after the program is started for the first time. + */ +class AbstractHomeScreenWidget : public QWidget +{ +Q_OBJECT +public: + /** Creates a new AbstractHomeScreenWidget for the given controller. */ + AbstractHomeScreenWidget(HomeScreenController* controller, QWidget* parent = NULL); + + /** Destroys the AbstractHomeScreenWidget. */ + virtual ~AbstractHomeScreenWidget(); + +public slots: + /** Sets the list of recent files. */ + virtual void setRecentFiles(const QStringList& files) = 0; + + /** Sets the "checked" state of the control for opening + * the most recently used file on startup. */ + virtual void setOpenMRUFileChecked(bool state) = 0; + + /** Sets the text of the the tip-of-the-day. */ + virtual void setTipOfTheDay(const QString& text) = 0; + + /** Sets the visiblity of the tip-of-the-day, and + * sets the "checked" state of the control for displaying the tip. */ + virtual void setTipsVisible(bool state) = 0; + +protected: + /** Returns a QLabel for displaying a headline in the home screen. */ + QLabel* makeHeadline(const QString& text, QWidget* parent = NULL) const; + + /** Returns a button with the given text + * for triggering a top level activity in the home screen. + * There will be no icon or a default icon. */ + QAbstractButton* makeButton(const QString& text, QWidget* parent = NULL) const; + + /** Returns a button with the given text and icon + * for triggering a top level activity in the home screen. */ + QAbstractButton* makeButton(const QString& text, const QIcon& icon, QWidget* parent = NULL) const; + + + HomeScreenController* controller; +}; + + +/** + * Implementation of AbstractHomeScreenWidget for desktop PCs. + */ +class HomeScreenWidgetDesktop : public AbstractHomeScreenWidget +{ +Q_OBJECT +public: + /** Creates a new HomeScreenWidgetDesktop for the given controller. */ + HomeScreenWidgetDesktop(HomeScreenController* controller, QWidget* parent = NULL); + + /** Destroys the HomeScreenWidgetDesktop. */ + virtual ~HomeScreenWidgetDesktop(); + +public slots: + /** Sets the list of recent files. */ + virtual void setRecentFiles(const QStringList& files); + + /** Sets the "checked" state of the control for opening + * the most recently used file on startup. */ + virtual void setOpenMRUFileChecked(bool state); + + /** Sets the text of the the tip-of-the-day. */ + virtual void setTipOfTheDay(const QString& text); + + /** Sets the visiblity of the tip-of-the-day, and + * sets the "checked" state of the control for displaying the tip. */ + virtual void setTipsVisible(bool state); + +protected slots: + /** Opens a file when its is list item is clicked. */ + void recentFileClicked(QListWidgetItem* item); + +protected: + /** Draws the home screen background when a paint event occurs. */ + virtual void paintEvent(QPaintEvent* event); + + /** Creates the activities widget. */ + QWidget* makeMenuWidget(HomeScreenController* controller, QWidget* parent = NULL); + + /** Creates the recent files widget. */ + QWidget* makeRecentFilesWidget(HomeScreenController* controller, QWidget* parent = NULL); + + /** Creates the tip-of-the-day widget. */ + QWidget* makeTipsWidget(HomeScreenController* controller, QWidget* parent = NULL); + + + QListWidget* recent_files_list; + QCheckBox* open_mru_file_check; + QLabel* tips_label; + QCheckBox* tips_check; + std::vector tips_children; +}; + + +/** + * Implementation of AbstractHomeScreenWidget for mobile devices. + */ +class HomeScreenWidgetMobile : public AbstractHomeScreenWidget +{ +Q_OBJECT +public: + /** Creates a new HomeScreenWidgetMobile for the given controller. */ + HomeScreenWidgetMobile(HomeScreenController* controller, QWidget* parent = NULL); + + /** Destroys the HomeScreenWidgetMobile. */ + virtual ~HomeScreenWidgetMobile(); + +public slots: + /** Sets the list of recent files. */ + virtual void setRecentFiles(const QStringList& files); + + /** Sets the "checked" state of the control for opening + * the most recently used file on startup. */ + virtual void setOpenMRUFileChecked(bool state); + + /** Sets the text of the the tip-of-the-day. */ + virtual void setTipOfTheDay(const QString& text); + + /** Sets the visiblity of the tip-of-the-day, and + * sets the "checked" state of the control for displaying the tip. */ + virtual void setTipsVisible(bool state); + + /** Adds the examples to the list of files + * if they are not already there. */ + void showExamples(); + + /** Shows the settings dialog, adjusted for small screens. */ + void showSettings(); + +protected slots: + /** Opens a file when its is list item is clicked. */ + void fileClicked(QListWidgetItem* item); + +protected: + /** Triggers title image adjustment on resize events. */ + virtual void resizeEvent(QResizeEvent* event); + + /** Resizes the title image to fit both the labels width and height */ + void adjustTitlePixmapSize(); + + /** Creates the file list widget. */ + QWidget* makeFileListWidget(HomeScreenController* controller, QWidget* parent = NULL); + + /** Iterates over all files at the given path and adds all map files to the list */ + void addFilesToFileList(QListWidget* file_list, const QString& path); + +private: + QPixmap title_pixmap; + QLabel* title_label; + QStackedLayout* file_list_stack; + QListWidget* file_list; + QPushButton* examples_button; +}; + +#endif diff --git a/src/gui/widgets/key_button_bar.cpp b/src/gui/widgets/key_button_bar.cpp new file mode 100644 index 0000000..6246a45 --- /dev/null +++ b/src/gui/widgets/key_button_bar.cpp @@ -0,0 +1,122 @@ +/* + * Copyright 2014 Thomas Schöps + * + * This file is part of OpenOrienteering. + * + * OpenOrienteering is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenOrienteering is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenOrienteering. If not, see . + */ + +#include "key_button_bar.h" + +#include +#include +#include +#include +#include + +#include "../../tool.h" +#include "../../map_editor.h" +#include "../../map_widget.h" + + +KeyButtonBar::KeyButtonBar(MapEditorTool* tool, MapWidget* map_widget, QWidget* parent) + : QWidget(parent) + , map_widget(map_widget) + , tool(tool) +{ + active_modifiers = 0; + + layout = new QHBoxLayout(this); + layout->setContentsMargins(0, 0, 0, 0); + layout->setSpacing(layout->spacing() / 2); + setLayout(layout); +} + +void KeyButtonBar::addPressKey(int key_code, QString text, QIcon icon) +{ + createButton(key_code, text, icon, false, 0); +} + +void KeyButtonBar::addPressKeyWithModifier(int key_code, int modifier_code, QString text, QIcon icon) +{ + createButton(key_code, text, icon, false, modifier_code); +} + +void KeyButtonBar::addModifierKey(int key_code, int modifier_code, QString text, QIcon icon) +{ + createButton(key_code, text, icon, true, modifier_code); +} + +int KeyButtonBar::activeModifiers() const +{ + return active_modifiers; +} + +void KeyButtonBar::buttonClicked(bool checked) +{ + QToolButton* button = reinterpret_cast(sender()); + ButtonInfo info = button_info.value(button); + + if (info.is_checkable) + { + if (checked) + sendKeyPressEvent(info.key_code, info.modifier_code); + else + sendKeyReleaseEvent(info.key_code, info.modifier_code); + } + else + { + active_modifiers |= info.modifier_code; + sendKeyPressEvent(info.key_code, 0); + active_modifiers &= ~info.modifier_code; + } +} + +void KeyButtonBar::sendKeyPressEvent(int key_code, int modifier_code) +{ + QKeyEvent* event = new QKeyEvent(QEvent::KeyPress, key_code, Qt::KeyboardModifiers(active_modifiers)); + QCoreApplication::postEvent(map_widget, event); + //tool->keyPressEvent(&event); + active_modifiers |= modifier_code; +} + +void KeyButtonBar::sendKeyReleaseEvent(int key_code, int modifier_code) +{ + active_modifiers &= ~modifier_code; + QKeyEvent* event = new QKeyEvent(QEvent::KeyRelease, key_code, Qt::KeyboardModifiers(active_modifiers)); + QCoreApplication::postEvent(map_widget, event); + //tool->keyReleaseEvent(&event); +} + +QToolButton* KeyButtonBar::createButton(int key_code, QString text, QIcon icon, bool is_checkable, int modifier_code) +{ + QToolButton* button = new QToolButton(); + button->setText(text); + if (! icon.isNull()) + button->setIcon(icon); + if (is_checkable) + button->setCheckable(true); + + connect(button, SIGNAL(clicked(bool)), this, SLOT(buttonClicked(bool))); + + layout->addWidget(button); + + ButtonInfo info; + info.key_code = key_code; + info.modifier_code = modifier_code; + info.is_checkable = is_checkable; + button_info.insert(button, info); + + return button; +} diff --git a/src/gui/widgets/key_button_bar.h b/src/gui/widgets/key_button_bar.h new file mode 100644 index 0000000..5218e03 --- /dev/null +++ b/src/gui/widgets/key_button_bar.h @@ -0,0 +1,80 @@ +/* + * Copyright 2014 Thomas Schöps + * + * This file is part of OpenOrienteering. + * + * OpenOrienteering is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenOrienteering is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenOrienteering. If not, see . + */ + + +#ifndef _OPENORIENTEERING_KEY_BUTTON_BAR_H_ +#define _OPENORIENTEERING_KEY_BUTTON_BAR_H_ + +#include +#include + +QT_BEGIN_NAMESPACE +class QHBoxLayout; +class QToolButton; +QT_END_NAMESPACE + +class MapEditorController; +class MapEditorTool; +class MapWidget; + + +/** Shows a set of buttons for simulating key presses. + * This is used to simulate keys in Mapper's mobile GUI. */ +class KeyButtonBar : public QWidget +{ +Q_OBJECT +public: + KeyButtonBar(MapEditorTool* tool, MapWidget* map_widget, QWidget* parent = 0); + + /** Adds a non-checkable button. */ + void addPressKey(int key_code, QString text, QIcon icon = QIcon()); + + /** Adds a non-checkable button for which in addition a modifier key is pressed while the key is pressed. */ + void addPressKeyWithModifier(int key_code, int modifier_code, QString text, QIcon icon = QIcon()); + + /** Adds a checkable button which may add a modifier code while checked. */ + void addModifierKey(int key_code, int modifier_code, QString text, QIcon icon = QIcon()); + + /** Returns the active modifier flags. Is intended to be combined with the modifier flags returned by mouse events, + * because the key simulation cannot insert modifiers there. */ + int activeModifiers() const; + +public slots: + void buttonClicked(bool checked); + +private: + struct ButtonInfo + { + int key_code; + int modifier_code; + bool is_checkable; + }; + + QToolButton* createButton(int key_code, QString text, QIcon icon, bool is_checkable, int modifier_code); + void sendKeyPressEvent(int key_code, int modifier_code); + void sendKeyReleaseEvent(int key_code, int modifier_code); + + int active_modifiers; + QHash button_info; + QHBoxLayout* layout; + MapWidget* map_widget; + MapEditorTool* tool; +}; + +#endif // _OPENORIENTEERING_KEY_BUTTON_BAR_H_ diff --git a/src/gui/widgets/mapper_proxystyle.cpp b/src/gui/widgets/mapper_proxystyle.cpp new file mode 100644 index 0000000..971db8c --- /dev/null +++ b/src/gui/widgets/mapper_proxystyle.cpp @@ -0,0 +1,177 @@ +/* + * Copyright 2013-2016 Kai Pastor + * + * This file is part of OpenOrienteering. + * + * OpenOrienteering is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenOrienteering is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenOrienteering. If not, see . + */ + + +#include "mapper_proxystyle.h" + +#include +#include +#include +#include + +#include "segmented_button_layout.h" + + +MapperProxyStyle::MapperProxyStyle(QStyle* base_style) + : QProxyStyle(base_style) +{ + ; // Nothing +} + +MapperProxyStyle::~MapperProxyStyle() +{ + ; // Nothing, not inlined +} + +void MapperProxyStyle::drawPrimitive(QStyle::PrimitiveElement element, const QStyleOption* option, QPainter* painter, const QWidget* widget) const +{ + auto overridden_element = element; + switch (element) + { + case PE_IndicatorButtonDropDown: + overridden_element = PE_PanelButtonTool; // Enforce same appearence. Workaround QWindowsStyle quirk. + // fall through + case PE_PanelButtonCommand: + case PE_PanelButtonBevel: + case PE_PanelButtonTool: + if (int segment = widget ? widget->property("segment").toInt() : 0) + { + drawSegmentedButton(segment, overridden_element, option, painter, widget); + return; + } + break; + +#ifdef Q_OS_ANDROID + case QStyle::PE_IndicatorItemViewItemCheck: + if (option->state.testFlag(QStyle::State_NoChange) + || !option->state.testFlag(QStyle::State_Enabled)) + { + auto item = qstyleoption_cast(option); + auto o = QStyleOptionViewItem{ *item }; + o.state |= QStyle::State_Enabled; + if (option->state.testFlag(QStyle::State_NoChange)) + { + o.state &= ~QStyle::State_NoChange; + o.state |= QStyle::State_On; + } + auto opacity = painter->opacity(); + painter->setOpacity(0.4); + QProxyStyle::drawPrimitive(element, &o, painter, widget); + painter->setOpacity(opacity); + return; + } + break; +#endif + + default: + ; // Nothing + } + + QProxyStyle::drawPrimitive(element, option, painter, widget); +} + +void MapperProxyStyle::drawSegmentedButton(int segment, QStyle::PrimitiveElement element, const QStyleOption* option, QPainter* painter, const QWidget* widget) const +{ + painter->save(); + + // Background (to be clipped by the widget) + int left_adj = (segment & SegmentedButtonLayout::LeftNeighbor) ? 4 : 0; + int right_adj = (segment & SegmentedButtonLayout::RightNeighbor) ? 4 : 0; + + if (option->rect.left()) + { + // Subcomponent clipping + painter->setClipRect(option->rect, Qt::IntersectClip); + left_adj = 4; + } + + QStyleOption mod_option(*option); + mod_option.rect.adjust(-left_adj, 0, right_adj, 0); + QProxyStyle::drawPrimitive(element, &mod_option, painter, widget); + + // Segment separators + painter->setOpacity((option->state & QStyle::State_Enabled) ? 0.5 : 0.2); + int frame_width = proxy()->pixelMetric(PM_DefaultFrameWidth, option, widget); + mod_option.rect = option->rect.adjusted(0, frame_width, 0, -frame_width); + + if (left_adj) + { + if (option->state & QStyle::State_Sunken) + painter->setPen(option->palette.dark().color()); + else + painter->setPen(option->palette.light().color()); + painter->drawLine(option->rect.left(), option->rect.top(), option->rect.left(), option->rect.bottom()); + } + + if (right_adj) + { + if (option->state & QStyle::State_Sunken) + painter->setPen(option->palette.light().color()); + else + painter->setPen(option->palette.dark().color()); + painter->drawLine(option->rect.right(), option->rect.top(), option->rect.right(), option->rect.bottom()); + } + + painter->restore(); +} + +int MapperProxyStyle::pixelMetric(PixelMetric metric, const QStyleOption* option, const QWidget* widget) const +{ + switch (metric) + { +#ifdef Q_OS_ANDROID + case QStyle::PM_ButtonIconSize: + { + static int s = qMax(QProxyStyle::pixelMetric(metric), QProxyStyle::pixelMetric(QStyle::PM_IndicatorWidth)); + return s; + } + case QStyle::PM_SplitterWidth: + { + static int s = (QProxyStyle::pixelMetric(metric), QProxyStyle::pixelMetric(QStyle::PM_IndicatorWidth)) / 2; + return s; + } +#endif +#ifdef Q_OS_MAC + case QStyle::PM_ToolBarIconSize: + { + static int s = (QProxyStyle::pixelMetric(metric) + QProxyStyle::pixelMetric(QStyle::PM_SmallIconSize)) / 2; + return s; + } +#endif + default: + break; + } + + return QProxyStyle::pixelMetric(metric, option, widget); +} + +int MapperProxyStyle::styleHint(QStyle::StyleHint hint, const QStyleOption* option, const QWidget* widget, QStyleHintReturn* return_data) const +{ + switch (hint) + { +#ifdef Q_OS_ANDROID + case QStyle::SH_FormLayoutWrapPolicy: + return QFormLayout::WrapLongRows; +#endif + default: + break; + } + + return QProxyStyle::styleHint(hint, option, widget, return_data); +} diff --git a/src/gui/widgets/mapper_proxystyle.h b/src/gui/widgets/mapper_proxystyle.h new file mode 100644 index 0000000..67c57a5 --- /dev/null +++ b/src/gui/widgets/mapper_proxystyle.h @@ -0,0 +1,85 @@ +/* + * Copyright 2013, 2016 Kai Pastor + * + * This file is part of OpenOrienteering. + * + * OpenOrienteering is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenOrienteering is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenOrienteering. If not, see . + */ + + +#ifndef OPENORIENTEERING_MAPPER_PROXYSTYLE_H_ +#define OPENORIENTEERING_MAPPER_PROXYSTYLE_H_ + +#include + +/** + * MapperProxyStyle customizes the platform's base style. + * + * It supports the implementation of missing UI elements, and + * it adjustes the size of some elements to more practical values. + */ +class MapperProxyStyle : public QProxyStyle +{ +Q_OBJECT +public: + /** + * Constructs a new MapperProxyStyle. + * + * Being a QProxyStyle, MapperProxyStyle takes ownership of the base style, + * if given. + */ + MapperProxyStyle(QStyle* base_style = nullptr); + + /** + * Destroys the object. + */ + ~MapperProxyStyle() override; + + /** + * Draws the given primitive element. + * + * Implements rendering of segmented buttons for all platforms. + * + * On Android: + * - QStyle::PE_IndicatorItemViewItemCheck is modified for disabled and tristate checkboxes. + */ + void drawPrimitive(PrimitiveElement element, const QStyleOption* option, QPainter* painter, const QWidget* widget = nullptr) const override; + + /** + * Returns some adjusted pixel metrics. + * + * On OS X: + * - QStyle::PM_ToolBarIconSize is adjusted (reduced) towards QStyle::PM_SmallIconSize. + * + * On Android: + * - QStyle::PM_ButtonIconSize is enlarged to QStyle::PM_IndicatorWidth (checkbox size), + * - QStyle::PM_ToolBarIconSize is adjusted (enlarged) towards QStyle::PM_SmallIconSize. + */ + int pixelMetric(PixelMetric metric, const QStyleOption* option = nullptr, const QWidget* widget = nullptr) const override; + + /** + * Returns adjusted style hints. + * + * On Android: + * - QStyle::SH_FormLayoutWrapPolicy is QFormLayout::QFormLayout::WrapLongRows. + */ + int styleHint(StyleHint hint, const QStyleOption* option = nullptr, const QWidget* widget = nullptr, QStyleHintReturn* return_data = nullptr) const override; + +private: + void drawSegmentedButton(int segment, PrimitiveElement element, const QStyleOption* option, QPainter* painter, const QWidget* widget) const; + + Q_DISABLE_COPY(MapperProxyStyle) +}; + +#endif // OPENORIENTEERING_MAPPER_PROXYSTYLE_H_ diff --git a/src/gui/widgets/measure_widget.cpp b/src/gui/widgets/measure_widget.cpp new file mode 100644 index 0000000..5a8a196 --- /dev/null +++ b/src/gui/widgets/measure_widget.cpp @@ -0,0 +1,162 @@ +/* + * Copyright 2012, 2013 Thomas Schöps + * Copyright 2012-2015 Kai Pastor + * + * This file is part of OpenOrienteering. + * + * OpenOrienteering is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenOrienteering is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenOrienteering. If not, see . + */ + + +#include "measure_widget.h" + +#include +#include + +#include "../../map.h" +#include "../../object.h" +#include "../../symbol.h" +#include "../../symbol_area.h" +#include "../../symbol_line.h" + + +MeasureWidget::MeasureWidget(Map* map, QWidget* parent) +: QTextBrowser(parent) +, map(map) +{ + QScroller::grabGesture(viewport(), QScroller::TouchGesture); + + connect(map, &Map::objectSelectionChanged, this, &MeasureWidget::objectSelectionChanged); + connect(map, &Map::selectedObjectEdited, this, &MeasureWidget::objectSelectionChanged); + connect(map, &Map::symbolChanged, this, &MeasureWidget::objectSelectionChanged); + + objectSelectionChanged(); +} + +MeasureWidget::~MeasureWidget() +{ + // nothing +} + +void MeasureWidget::objectSelectionChanged() +{ + QString headline; // inline HTML + QString body; // HTML blocks + QString extra_text; // inline HTML + + auto& selected_objects = map->selectedObjects(); + if (selected_objects.empty()) + { + extra_text = tr("No object selected."); + } + else if (selected_objects.size() > 1) + { + extra_text = tr("%1 objects selected.").arg(locale().toString(map->getNumSelectedObjects())); + } + else + { + const Object* object = *begin(selected_objects); + const Symbol* symbol = object->getSymbol(); + headline = symbol->getNumberAsString() + QLatin1Char(' ') + symbol->getName(); + + if (object->getType() != Object::Path) + { + extra_text = tr("The selected object is not a path."); + } + else + { + body = QLatin1String{ "" }; + static const QString table_row{ QLatin1String{ + "" + } }; + + double paper_to_real = 0.001 * map->getScaleDenominator(); + + object->update(); + const PathPartVector& parts = static_cast(object)->parts(); + Q_ASSERT(!parts.empty()); + + auto paper_length = parts.front().length(); + auto real_length = paper_length * paper_to_real; + + auto paper_length_text = locale().toString(paper_length, 'f', 2); + auto real_length_text = locale().toString(real_length, 'f', 0); + + if (symbol->getContainedTypes() & Symbol::Area) + { + body.append(table_row.arg(tr("Boundary length:"), + paper_length_text, tr("mm", "millimeters"), + real_length_text, tr("m", "meters"))); + + auto paper_area = parts.front().calculateArea(); + if (parts.size() > 1) + { + paper_area *= 2; + for (const auto& part : parts) + paper_area -= part.calculateArea(); + } + double real_area = paper_area * paper_to_real * paper_to_real; + + auto paper_area_text = locale().toString(paper_area, 'f', 2); + auto real_area_text = locale().toString(real_area, 'f', 0); + + body.append(table_row.arg(tr("Area:"), + paper_area_text, trUtf8("mm²", "square millimeters"), + real_area_text , trUtf8("m²", "square meters"))); + + auto minimum_area = 0.0; + auto minimum_area_text = QString{ }; + if (symbol->getType() == Symbol::Area) + { + minimum_area = 0.001 * static_cast(symbol)->getMinimumArea(); + minimum_area_text = locale().toString(minimum_area, 'f', 2); + } + + if (paper_area < minimum_area && paper_area_text != minimum_area_text) + { + extra_text = QLatin1String("") + tr("This object is too small.") + QLatin1String("
") + + tr("The minimimum area is %1 %2.").arg(minimum_area_text, trUtf8("mm²")) + + QLatin1String("
"); + } + extra_text.append(tr("Note: Boundary length and area are correct only if there are no self-intersections and holes are used as such.")); + } + else + { + body.append(table_row.arg(tr("Length:"), + paper_length_text, tr("mm", "millimeters"), + real_length_text, tr("m", "meters"))); + + auto minimum_length = 0.0; + auto minimum_length_text = QString{ }; + if (symbol->getType() == Symbol::Line) + { + minimum_length = 0.001 * static_cast(symbol)->getMinimumLength(); + minimum_length_text = locale().toString(minimum_length, 'f', 2); + } + + if (paper_length < minimum_length && paper_length_text != minimum_length_text) + { + extra_text = QLatin1String("") + tr("This line is too short.") + QLatin1String("
") + + tr("The minimum length is %1 %2.").arg(minimum_length_text).arg(tr("mm")); + } + } + + body.append(QLatin1String("
%1%2 %3(%4 %5)
")); + } + } + + if (!extra_text.isEmpty()) + body.append(QLatin1String("

") + extra_text + QLatin1String("

")); + setHtml(QLatin1String("

") + headline + QLatin1String("

") + body); +} diff --git a/src/gui/widgets/measure_widget.h b/src/gui/widgets/measure_widget.h new file mode 100644 index 0000000..787527b --- /dev/null +++ b/src/gui/widgets/measure_widget.h @@ -0,0 +1,54 @@ +/* + * Copyright 2012, 2013 Thomas Schöps + * Copyright 2015 Kai Pastor + * + * This file is part of OpenOrienteering. + * + * OpenOrienteering is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenOrienteering is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenOrienteering. If not, see . + */ + + +#ifndef OPENORIENTEERING_MEASURE_WIDGET_H +#define OPENORIENTEERING_MEASURE_WIDGET_H + +#include + +class Map; + +/** + * The widget which is shown in a dock widget when the measure tool is active. + * Displays information about the currently selected objects. + */ +class MeasureWidget : public QTextBrowser +{ +Q_OBJECT +public: + /** Creates a new MeasureWidget for a given map. */ + MeasureWidget(Map* map, QWidget* parent = nullptr); + + /** Destroys the MeasureWidget. */ + ~MeasureWidget() override; + +protected slots: + /** + * Is called when the object selection in the map changes. + * Updates the widget content. + */ + void objectSelectionChanged(); + +private: + Map* map; +}; + +#endif diff --git a/src/gui/widgets/pie_menu.cpp b/src/gui/widgets/pie_menu.cpp new file mode 100644 index 0000000..eecaf8a --- /dev/null +++ b/src/gui/widgets/pie_menu.cpp @@ -0,0 +1,398 @@ +/* + * Copyright 2012, 2013 Thomas Schöps + * Copyright 2014 Thomas Schöps, Kai Pastor + * + * This file is part of OpenOrienteering. + * + * OpenOrienteering is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenOrienteering is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenOrienteering. If not, see . + */ + + +#include "pie_menu.h" + +#include +#include +#include +#include +#include +#include +#include + +#include "../../settings.h" + +PieMenu::PieMenu(QWidget* parent) +: QWidget(parent, Qt::Popup | Qt::FramelessWindowHint), // NOTE: use Qt::Window for debugging to avoid mouse grab + minimum_action_count(3), + icon_size(24), + active_action(NULL), + actions_changed(true), + clicked(false) +{ + setCursor(QCursor(Qt::ArrowCursor)); + setAttribute(Qt::WA_OpaquePaintEvent); + setAttribute(Qt::WA_ShowWithoutActivating); + setAutoFillBackground(false); + setMouseTracking(true); + + auto scale = Settings::getInstance().getSetting(Settings::General_PixelsPerInch).toReal() / 96.0; + if (scale > 1.5) + { + icon_size = qRound(icon_size * scale); + } + + updateCachedState(); +} + +int PieMenu::minimumActionCount() const +{ + return minimum_action_count; +} + +void PieMenu::setMinimumActionCount(int count) +{ + if (count >= 3 && count != minimum_action_count) + { + minimum_action_count = count; + actions_changed = true; + update(); + } +} + +int PieMenu::visibleActionCount() const +{ + int count = 0; + for (int i = 0, end = actions().size(); i < end; ++i) + { + const QAction* action = actions()[i]; + if (action->isVisible() && !action->isSeparator()) + ++count; + } + return count; +} + +bool PieMenu::isEmpty() const +{ + for (int i = 0, end = actions().size(); i < end; ++i) + { + const QAction* action = actions()[i]; + if (action->isVisible() && !action->isSeparator()) + return false; + } + return true; +} + +void PieMenu::clear() +{ + while (!actions().isEmpty()) + { + removeAction(actions().last()); + } +} + +int PieMenu::iconSize() const +{ + return icon_size; +} + +void PieMenu::setIconSize(int icon_size) +{ + if (icon_size > 0) + { + this->icon_size = icon_size; + actions_changed = true; + update(); + } +} + +QAction* PieMenu::actionAt(const QPoint& pos) const +{ + for (size_t i = 0, end = actions().size(); i < end; ++i) + { + QAction* action = actions()[i]; + if (geometries.contains(action) && + geometries[action].area.containsPoint(pos, Qt::WindingFill)) + { + return action; + } + } + return NULL; +} + +PieMenu::ItemGeometry PieMenu::actionGeometry(QAction* action) const +{ + ItemGeometry geometry; + if (geometries.contains(action)) + geometry = geometries[action]; + + return geometry; +} + +QAction* PieMenu::activeAction() const +{ + return active_action; +} + +void PieMenu::setActiveAction(QAction* action) +{ + QAction* const prev_action = active_action; + active_action = (action && action->isEnabled() && action->isVisible() && !action->isSeparator()) ? action : NULL; + if (isVisible()) + { + if (active_action && active_action != prev_action) + { + active_action->activate(QAction::Hover); + emit hovered(active_action); + active_action->showStatusText(0); + } + else if (prev_action && !active_action) + { + QString empty_string; + QStatusTipEvent e(empty_string); + QApplication::sendEvent(parent(), &e); + } + update(); + } +} + +void PieMenu::popup(const QPoint pos) +{ + updateCachedState(); // We need the current total_radius. + + QPoint cursor_pos = QCursor::pos(); + QRect screen_rect = qApp->desktop()->availableGeometry(cursor_pos); + + if (cursor_pos.x() > screen_rect.right() - total_radius) + cursor_pos.setX(screen_rect.right() - total_radius); + else if (cursor_pos.x() < total_radius) + cursor_pos.setX(total_radius); + + if (cursor_pos.y() > screen_rect.bottom() - total_radius) + cursor_pos.setY(screen_rect.bottom() - total_radius); + else if (cursor_pos.y() < total_radius) + cursor_pos.setY(total_radius); + + setGeometry(pos.x() - total_radius, pos.y() - total_radius, 2 * total_radius, 2 * total_radius); + + clicked = false; + active_action = NULL; + + emit aboutToShow(); + show(); +} + +void PieMenu::actionEvent(QActionEvent* event) +{ + if (event->type() == QEvent::ActionRemoved) + { + QAction* const action = event->action(); + geometries.remove(action); + if (action == active_action) + setActiveAction(NULL); + } + + actions_changed = true; + update(); + QWidget::actionEvent(event); +} + +void PieMenu::hideEvent(QHideEvent* event) +{ + if (!event->spontaneous()) + { + emit aboutToHide(); + setActiveAction(NULL); + QString empty_string; + QStatusTipEvent e(empty_string); + QApplication::sendEvent(parent(), &e); + } + QWidget::hideEvent(event); +} + +void PieMenu::mouseMoveEvent(QMouseEvent* event) +{ + setActiveAction(actionAt(event->pos())); + event->accept(); +} + +void PieMenu::mousePressEvent(QMouseEvent* event) +{ + if (event->button() == Qt::LeftButton || event->button() == Qt::RightButton) + { + if (mask().contains(event->pos())) + { + clicked = true; + setActiveAction(actionAt(event->pos())); + } + else + { + hide(); + } + event->accept(); + return; + } + + QWidget::mousePressEvent(event); +} + +void PieMenu::mouseReleaseEvent(QMouseEvent* event) +{ + if (event->button() == Qt::LeftButton || event->button() == Qt::RightButton) + { + if (active_action) + { + Q_ASSERT(active_action->isEnabled()); + Q_ASSERT(active_action->isVisible()); + Q_ASSERT(!active_action->isSeparator()); + active_action->activate(QAction::Trigger); + emit triggered(active_action); + hide(); + } + else if (clicked && !mask().contains(event->pos())) + { + hide(); + } + + clicked = false; + event->accept(); + return; + } + + QWidget::mouseReleaseEvent(event); +} + +void PieMenu::paintEvent(QPaintEvent* event) +{ + updateCachedState(); + + QStyleOptionMenuItem option; + option.initFrom(this); + QPalette& palette = option.palette; + palette.setCurrentColorGroup(QPalette::Active); + + // Draw on the widget + QPainter painter(this); + painter.setClipRect(event->rect()); + painter.setRenderHint(QPainter::Antialiasing, true); + + // Background + QPen pen(palette.color(QPalette::Dark)); + pen.setWidth(1); + painter.setPen(pen); + painter.setBrush(palette.brush(QPalette::Button)); + painter.drawConvexPolygon(outer_border); + painter.setBrush(Qt::NoBrush); + painter.drawConvexPolygon(inner_border); + + // Items + for (int i = 0, end = actions().size(); i < end; ++i) + { + QAction* const action = actions()[i]; + if (!geometries.contains(action)) + continue; + + QPolygon area = geometries[action].area; + QIcon::Mode mode = QIcon::Normal; + if (action->isChecked()) + { + mode = QIcon::Selected; + QPen pen(palette.color(QPalette::Dark)); + pen.setWidth(1); + painter.setPen(pen); + painter.setBrush(palette.color(QPalette::Button).darker(120)); + painter.setOpacity(1.0); + painter.drawConvexPolygon(area); + } + else if (action->isEnabled() && action == active_action) + { + mode = QIcon::Active; + QPen pen(palette.color(QPalette::Dark)); + pen.setWidth(1); + painter.setPen(pen); + painter.setBrush(clicked ? palette.color(QPalette::Button).darker(120) : palette.color(QPalette::Button).lighter(120)); + painter.setOpacity(1.0); + painter.drawConvexPolygon(area); + } + else if (!action->isEnabled()) + { + mode = QIcon::Disabled; + painter.setOpacity(0.4); + } + else + { + painter.setOpacity(1.0); + } + + // Draw icon + QPixmap pixmap = action->icon().pixmap(icon_size, mode); + QPoint midpoint = geometries[action].icon_pos; + painter.drawPixmap(QPoint(midpoint.x() - pixmap.width() / 2, midpoint.y() - pixmap.height() / 2), pixmap); + } +} + +void PieMenu::updateCachedState() +{ + if (actions_changed) + { + int action_count = qMax(minimum_action_count, visibleActionCount()); + outer_border.resize(action_count); + inner_border.resize(action_count); + + double half_angle = M_PI / action_count; + double inner_radius = 0.5 * icon_size; + double inner_corner_radius = inner_radius / cos(half_angle); + + double icon_padding_inner = 0.7 * icon_size; + double icon_radius = inner_radius + icon_padding_inner + 0.5 * icon_size; + + double icon_padding_outer = 0.2 * icon_size; + double outer_corner_radius = (inner_radius + icon_padding_inner + icon_size + icon_padding_outer) / cos(half_angle); + + total_radius = qCeil(outer_corner_radius); + + // The total shape + for (int i = 0; i < action_count; ++i) + { + double angle = (2*i + 1) * half_angle; + inner_border.setPoint(i, getPoint(inner_corner_radius, angle)); + outer_border.setPoint(i, getPoint(outer_corner_radius, angle)); + } + + setMask(outer_border.subtracted(inner_border)); + + // The items + for (int i = 0, j = 0, end = actions().size(); j < end; ++j) + { + QAction* const action = actions()[j]; + if (action->isVisible() && !action->isSeparator()) + { + ItemGeometry geometry; + + geometry.area.resize(4); + double angle = (2*i - 1) * half_angle; + geometry.area.setPoint(0, getPoint(inner_corner_radius, angle)); + geometry.area.setPoint(1, inner_border.point(i)); + geometry.area.setPoint(2, outer_border.point(i)); + geometry.area.setPoint(3, getPoint(outer_corner_radius, angle)); + + angle = 2*i * half_angle; + geometry.icon_pos = getPoint(icon_radius, angle); + + geometries[action] = geometry; + ++i; + } + } + + actions_changed = false; + } +} diff --git a/src/gui/widgets/pie_menu.h b/src/gui/widgets/pie_menu.h new file mode 100644 index 0000000..4d9b61d --- /dev/null +++ b/src/gui/widgets/pie_menu.h @@ -0,0 +1,156 @@ +/* + * Copyright 2012, 2013 Thomas Schöps + * Copyright 2014 Thomas Schöps, Kai Pastor + * + * This file is part of OpenOrienteering. + * + * OpenOrienteering is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenOrienteering is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenOrienteering. If not, see . + */ + + +#ifndef _OPENORIENTEERING_PIE_MENU_H_ +#define _OPENORIENTEERING_PIE_MENU_H_ + +#include + +#include + +/** + * Displays a pie menu. + * + * This class has an API and behavior similar to QMenu, + * but is neither a subclass nor a full replacement. + */ +class PieMenu : public QWidget +{ +Q_OBJECT +public: + /** Stores the geometry of a particular item in the PieMenu. */ + struct ItemGeometry + { + /** The area covered by the item. */ + QPolygon area; + + /** The position of the center of the item. */ + QPoint icon_pos; + }; + + /** Constructs a pie menu with default settings. */ + PieMenu(QWidget* parent = NULL); + + /** Returns the minimum number of actions in the menu. */ + int minimumActionCount() const; + + /** Sets the minimum number of actions in the menu (must be at least three). */ + void setMinimumActionCount(int count); + + /** Returns the current number of visible actions. */ + int visibleActionCount() const; + + /** Removes all actions from the menu. + * Other than QMenu::clear(), this will not immediately delete any action, + * even if owned by this object. (Actions owned by this object will be + * deleted when this objected is deleted.) + * @see QMenu::clear() */ + void clear(); + + /** Returns true if there are no visible actions in the menu, + * false otherwise. + * @see QMenu::isEmpty */ + bool isEmpty() const; + + /** Returns the icon size (single dimension). */ + int iconSize() const; + + /** Sets the icon size (single dimension). + * @param icon_size the new size (at least 1) */ + void setIconSize(int icon_size); + + /** Returns the action at pos. + * Returns NULL if there is no action at this place. */ + QAction* actionAt(const QPoint& pos) const; + + /** Returns the geometry of the given action. + * The action must be enabled and visible. + * Otherwise the geometry will be empty. + * @see QMenu::actionGeometry */ + ItemGeometry actionGeometry(QAction* action) const; + + /** Returns the currently highlighted action. + * Returns NULL if no action is highlighted. + * @see QMenu::activeAction */ + QAction* activeAction() const; + + /** Sets the currently highlighted action. + * The action must be enabled and visible. + * Otherwise there will be no highlighted action. + * @see QMenu::setActiveAction */ + void setActiveAction(QAction* action); + + /** Shows the menu at the given absolute position. + * @see QMenu::popup */ + void popup(const QPoint pos); + +signals: + /** This signal is emitted just before the menu is shown. + * @see QMenu::aboutToShow */ + void aboutToShow(); + + /** This signal is emitted just before the menu is hidden. + * @see QMenu::aboutToHide */ + void aboutToHide(); + + /** This signal is emitted when a menu item is highlighted. + * @see QMenu::hovered */ + void hovered(QAction* action); + + /** This signal is emitted when a menu item's action is triggered. + * @see QMenu::triggered */ + void triggered(QAction* action); + +protected: + virtual void actionEvent(QActionEvent* event); + virtual void hideEvent(QHideEvent* event); + virtual void mouseMoveEvent(QMouseEvent* event); + virtual void mousePressEvent(QMouseEvent* event); + virtual void mouseReleaseEvent(QMouseEvent* event); + virtual void paintEvent(QPaintEvent* event); + + void updateCachedState(); + + QPoint getPoint(double radius, double angle) const; + + int minimum_action_count; + int icon_size; + QAction* active_action; + + bool actions_changed; + bool clicked; + int total_radius; + QPolygon outer_border; + QPolygon inner_border; + QHash< QAction*, ItemGeometry > geometries; +}; + + +// ### PieMenu inline code ### + +inline +QPoint PieMenu::getPoint(double radius, double angle) const +{ + return QPoint(total_radius + qRound(radius * -sin(angle)), total_radius + qRound(radius * -cos(angle))); +} + + +#endif diff --git a/src/gui/widgets/segmented_button_layout.cpp b/src/gui/widgets/segmented_button_layout.cpp new file mode 100644 index 0000000..6736470 --- /dev/null +++ b/src/gui/widgets/segmented_button_layout.cpp @@ -0,0 +1,75 @@ +/* + * Copyright 2013 Kai Pastor + * + * This file is part of OpenOrienteering. + * + * OpenOrienteering is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenOrienteering is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenOrienteering. If not, see . + */ + +#include "segmented_button_layout.h" + +#include +#include + +#include "mapper_proxystyle.h" + + +SegmentedButtonLayout::SegmentedButtonLayout() + : QHBoxLayout() +{ + setContentsMargins(0, 0, 0, 0); + setSpacing(0); +} + +SegmentedButtonLayout::SegmentedButtonLayout(QWidget* parent) + : QHBoxLayout(parent) +{ + setContentsMargins(0, 0, 0, 0); + setSpacing(0); +} + +SegmentedButtonLayout::~SegmentedButtonLayout() +{ + ; // Nothing, not inlined +} + +void SegmentedButtonLayout::invalidate() +{ + int num_items = count(); + QWidget* first_widget = NULL; + QWidget* widget = NULL; + for (int i = 0; i < num_items; ++i) + { + widget = itemAt(i)->widget(); + if (!widget) + continue; + +// widget->setStyle(segmented_style); + + if (!first_widget) + { + first_widget = widget; + widget->setProperty("segment", RightNeighbor); + } + else + { + widget->setProperty("segment", BothNeighbors); + } + } + + if (widget) + widget->setProperty("segment", (widget == first_widget) ? NoNeighbors : LeftNeighbor); + + QHBoxLayout::invalidate(); +} diff --git a/src/gui/widgets/segmented_button_layout.h b/src/gui/widgets/segmented_button_layout.h new file mode 100644 index 0000000..e50f1cb --- /dev/null +++ b/src/gui/widgets/segmented_button_layout.h @@ -0,0 +1,74 @@ +/* + * Copyright 2013 Kai Pastor + * + * This file is part of OpenOrienteering. + * + * OpenOrienteering is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenOrienteering is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenOrienteering. If not, see . + */ + + +#ifndef _OPENORIENTEERING_SEGMENTED_BUTTON_LAYOUT_H_ +#define _OPENORIENTEERING_SEGMENTED_BUTTON_LAYOUT_H_ + +#include + +/** + * SegmentedButtonLayout is a horizontal box layout with no margin and no + * spacing which will mark the contained widgets as being segments having a + * left and/or right neighbor. + * + * MapperProxyStyle uses this information to make buttons from a single + * SegmentedButtonLayout appear as a single segmented button. + */ +class SegmentedButtonLayout : public QHBoxLayout +{ +Q_OBJECT +public: + /** + * Constructs a new SegmentedButtonLayout. + */ + SegmentedButtonLayout(); + + /** + * Constructs a new SegmentedButtonLayout for the given parent. + */ + explicit SegmentedButtonLayout(QWidget* parent); + + /** + * Destroys the object. + */ + virtual ~SegmentedButtonLayout(); + + /** + * Resets the information about neighboring segments and any other cached + * information about the layout. + */ + virtual void invalidate(); + + /** + * Types of segment neighborhood. + */ + enum Segment + { + NoNeighbors = 0x00, + RightNeighbor = 0x01, + LeftNeighbor = 0x02, + BothNeighbors = RightNeighbor | LeftNeighbor + }; + +private: + Q_DISABLE_COPY(SegmentedButtonLayout) +}; + +#endif // _OPENORIENTEERING_SEGMENTED_BUTTON_LAYOUT_H_ diff --git a/src/gui/widgets/settings_page.cpp b/src/gui/widgets/settings_page.cpp new file mode 100644 index 0000000..ee9468f --- /dev/null +++ b/src/gui/widgets/settings_page.cpp @@ -0,0 +1,33 @@ +/* + * Copyright 2012 Jan Dalheimer + * Copyright 2012-2016 Kai Pastor + * + * This file is part of OpenOrienteering. + * + * OpenOrienteering is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenOrienteering is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenOrienteering. If not, see . + */ + +#include "settings_page.h" + + +SettingsPage::SettingsPage(QWidget* parent) +: QWidget(parent) +{ + // nothing +} + +SettingsPage::~SettingsPage() +{ + // nothing, not inlined +} diff --git a/src/gui/widgets/settings_page.h b/src/gui/widgets/settings_page.h new file mode 100644 index 0000000..a46f289 --- /dev/null +++ b/src/gui/widgets/settings_page.h @@ -0,0 +1,92 @@ +/* + * Copyright 2012 Jan Dalheimer + * Copyright 2013-2016 Kai Pastor + * + * This file is part of OpenOrienteering. + * + * OpenOrienteering is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenOrienteering is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenOrienteering. If not, see . + */ + +#ifndef OPENORIENTEERING_SETTINGS_PAGE_H +#define OPENORIENTEERING_SETTINGS_PAGE_H + +#include +#include + +#include "../../settings.h" + + +/** + * A widget which serves as a page in the SettingsDialog. + */ +class SettingsPage : public QWidget +{ +Q_OBJECT +public: + /** + * Constructs a new settings page. + */ + explicit SettingsPage(QWidget* parent = nullptr); + + /** + * Destructor. + */ + ~SettingsPage() override; + + /** + * Returns the title of this page. + */ + virtual QString title() const = 0; + +public slots: + /** + * This slot is to transfer the input fields to the settings. + */ + virtual void apply() = 0; + + /** + * This slot is to reset all input widgets to the state of the settings. + */ + virtual void reset() = 0; + +protected: + /** + * Convenience function for retrieving a setting. + */ + static QVariant getSetting(Settings::SettingsEnum setting); + + /** + * Convenience function for changing a setting. + */ + template + static void setSetting(Settings::SettingsEnum setting, T value); + +}; + + + +inline +QVariant SettingsPage::getSetting(Settings::SettingsEnum setting) +{ + return Settings::getInstance().getSetting(setting); +} + +template +void SettingsPage::setSetting(Settings::SettingsEnum setting, T value) +{ + Settings::getInstance().setSetting(setting, QVariant{ value }); +} + + +#endif diff --git a/src/gui/widgets/symbol_dropdown.cpp b/src/gui/widgets/symbol_dropdown.cpp new file mode 100644 index 0000000..864824e --- /dev/null +++ b/src/gui/widgets/symbol_dropdown.cpp @@ -0,0 +1,157 @@ +/* + * Copyright 2012, 2013 Thomas Schöps + * Copyright 2012, 2013, 2014 Kai Pastor + * + * This file is part of OpenOrienteering. + * + * OpenOrienteering is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenOrienteering is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenOrienteering. If not, see . + */ + + +#include "symbol_dropdown.h" + +#include +#include +#include +#include +#include +#include +#include + +#include "../../symbol_combined.h" +#include "../../map.h" + +// ### SymbolDropDown ### + +// allow explicit use of Symbol pointers in QVariant +Q_DECLARE_METATYPE(Symbol*) + +SymbolDropDown::SymbolDropDown(const Map* map, int filter, const Symbol* initial_symbol, const Symbol* excluded_symbol, QWidget* parent) + : QComboBox(parent) +{ + num_custom_items = 0; + addItem(tr("- none -"), QVariant::fromValue(NULL)); + + int size = map->getNumSymbols(); + for (int i = 0; i < size; ++i) + { + const Symbol* symbol = map->getSymbol(i); + if (!(symbol->getType() & filter)) + continue; + if (symbol == excluded_symbol) + continue; + if (symbol->getType() == Symbol::Combined) // TODO: if point objects start to be able to contain objects of other ordinary symbols, add a check for these here, too, to prevent circular references + { + const CombinedSymbol* combined_symbol = reinterpret_cast(symbol); + if (combined_symbol->containsSymbol(excluded_symbol)) + continue; + } + + QString symbol_name = symbol->getNumberAsString() + QLatin1Char(' ') + symbol->getPlainTextName(); + addItem(QPixmap::fromImage(symbol->getIcon(map)), symbol_name, QVariant::fromValue(symbol)); + } + setSymbol(initial_symbol); +} + +const Symbol* SymbolDropDown::symbol() const +{ + QVariant data = itemData(currentIndex()); + if (data.canConvert()) + return data.value(); + else + return NULL; +} + +void SymbolDropDown::setSymbol(const Symbol* symbol) +{ + setCurrentIndex(findData(QVariant::fromValue(symbol))); +} + +void SymbolDropDown::addCustomItem(const QString& text, int id) +{ + insertItem(1 + num_custom_items, text, QVariant(id)); + ++num_custom_items; +} + +int SymbolDropDown::customID() const +{ + QVariant data = itemData(currentIndex()); + if (data.canConvert()) + return data.value(); + else + return -1; +} + +void SymbolDropDown::setCustomItem(int id) +{ + setCurrentIndex(findData(QVariant(id))); +} + + +// ### SymbolDropDownDelegate ### + +SymbolDropDownDelegate::SymbolDropDownDelegate(int symbol_type_filter, QObject* parent) + : QItemDelegate(parent), symbol_type_filter(symbol_type_filter) +{ +} + +QWidget* SymbolDropDownDelegate::createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const +{ + Q_UNUSED(option); + QVariantList list = index.data(Qt::UserRole).toList(); + SymbolDropDown* widget + = new SymbolDropDown(list.at(0).value(), symbol_type_filter, + list.at(1).value(), NULL, parent); + + connect(widget, SIGNAL(currentIndexChanged(int)), this, SLOT(emitCommitData())); + return widget; +} + +void SymbolDropDownDelegate::setEditorData(QWidget* editor, const QModelIndex& index) const +{ + SymbolDropDown* widget = static_cast(editor); + const Symbol* symbol = index.data(Qt::UserRole).toList().at(1).value(); + widget->setSymbol(symbol); +} + +void SymbolDropDownDelegate::setModelData(QWidget* editor, QAbstractItemModel* model, const QModelIndex& index) const +{ + SymbolDropDown* widget = static_cast(editor); + const Symbol* symbol = widget->symbol(); + QVariantList list = index.data(Qt::UserRole).toList(); + list[1] = qVariantFromValue(symbol); + model->setData(index, list, Qt::UserRole); + + if (symbol) + { + model->setData(index, QVariant(symbol->getNumberAsString() + QLatin1Char(' ') + symbol->getPlainTextName()), Qt::EditRole); + model->setData(index, symbol->getIcon(list[0].value()), Qt::DecorationRole); + } + else + { + model->setData(index, tr("- None -"), Qt::EditRole); + model->setData(index, QVariant(), Qt::DecorationRole); + } +} + +void SymbolDropDownDelegate::updateEditorGeometry(QWidget* editor, const QStyleOptionViewItem& option, const QModelIndex& index) const +{ + Q_UNUSED(index); + editor->setGeometry(option.rect); +} + +void SymbolDropDownDelegate::emitCommitData() +{ + emit commitData(qobject_cast(sender())); +} diff --git a/src/gui/widgets/symbol_dropdown.h b/src/gui/widgets/symbol_dropdown.h new file mode 100644 index 0000000..589550a --- /dev/null +++ b/src/gui/widgets/symbol_dropdown.h @@ -0,0 +1,96 @@ +/* + * Copyright 2012, 2013 Thomas Schöps + * Copyright 2012, 2013, 2014 Kai Pastor + * + * This file is part of OpenOrienteering. + * + * OpenOrienteering is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenOrienteering is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenOrienteering. If not, see . + */ + + +#ifndef _OPENORIENTEERING_SYMBOL_DROPDOWN_H_ +#define _OPENORIENTEERING_SYMBOL_DROPDOWN_H_ + +#include +#include + +#include "../../symbol.h" + + +/** + * Drop down combobox for selecting a symbol. + */ +class SymbolDropDown : public QComboBox +{ +Q_OBJECT +public: + /** + * Creates a SymbolDropDown. + * @param map Map in which to choose a symbol. + * @param filter Bitwise-or combination of the allowed Symbol::Type types. + * @param initial_symbol Initial choice or NULL for "- none -". + * @param excluded_symbol Symbol to exclude from the list or NULL. + * @param parent QWidget parent. + */ + SymbolDropDown(const Map* map, int filter, const Symbol* initial_symbol = NULL, const Symbol* excluded_symbol = NULL, QWidget* parent = NULL); + + /** Returns the selected symbol or NULL if no symbol selected */ + const Symbol* symbol() const; + + /** Sets the selection to the given symbol */ + void setSymbol(const Symbol* symbol); + + /** Adds a custom text item below the topmost "- none -" which + * can be identified by the given id. */ + void addCustomItem(const QString& text, int id); + + /** Returns the id of the current item if it is a custom item, + * or -1 otherwise */ + int customID() const; + + /** Sets the selection to the custom item with the given id */ + void setCustomItem(int id); + +protected slots: + // TODO: react to changes in the map (not important as long as that cannot + // happen as long as a SymbolDropDown is shown, which is the case currently) + +private: + int num_custom_items; +}; + + + +/** + * Qt item delegate for SymbolDropDown. + */ +class SymbolDropDownDelegate : public QItemDelegate +{ +Q_OBJECT +public: + SymbolDropDownDelegate(int symbol_type_filter, QObject* parent = 0); + + virtual QWidget* createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const; + virtual void setEditorData(QWidget* editor, const QModelIndex& index) const; + virtual void setModelData(QWidget* editor, QAbstractItemModel* model, const QModelIndex& index) const; + virtual void updateEditorGeometry(QWidget* editor, const QStyleOptionViewItem& option, const QModelIndex& index) const; + +private slots: + void emitCommitData(); + +private: + int symbol_type_filter; +}; + +#endif diff --git a/src/gui/widgets/symbol_render_widget.cpp b/src/gui/widgets/symbol_render_widget.cpp new file mode 100644 index 0000000..2e73327 --- /dev/null +++ b/src/gui/widgets/symbol_render_widget.cpp @@ -0,0 +1,1216 @@ +/* + * Copyright 2012, 2013 Thomas Schöps + * Copyright 2014 Kai Pastor + * + * This file is part of OpenOrienteering. + * + * OpenOrienteering is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenOrienteering is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenOrienteering. If not, see . + */ + + +#include "symbol_render_widget.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../../core/map_color.h" +#include "../../map.h" +#include "../../object.h" +#include "../../settings.h" +#include "../../symbol.h" +#include "../../symbol_area.h" +#include "../../symbol_combined.h" +#include "../../symbol_line.h" +#include "../../symbol_point.h" +#include "../../symbol_setting_dialog.h" +#include "../../symbol_text.h" +#include "../../util/overriding_shortcut.h" +#include "symbol_tooltip.h" + + +namespace MimeType { + +/// The index of a symbol during drag-and-drop +static const QString oo_symbol_index { QStringLiteral("openorienteering/symbol_index") }; + +/// Symbol definitions +static const QString oo_symbols { QStringLiteral("openorienteering/symbols") }; + +} + +//### SymbolIconDecorator ### + +/** + * @brief Abstract interface for classes which draws icon decorations. + * + * The icon is expected to be at (0, 0) in the painter's coordinates. + */ +class SymbolIconDecorator +{ +public: + virtual ~SymbolIconDecorator(); + virtual void draw(QPainter& p) const = 0; +}; + +SymbolIconDecorator::~SymbolIconDecorator() +{ + ; // nothing +} + + + +//### ProtectedSymbolDecorator ### + +/** + * @brief Draws the decoration for a protected symbol. + * + * A small gray lock is drawn in the top-right corner of the icon. + */ +class ProtectedSymbolDecorator : public SymbolIconDecorator +{ +public: + explicit ProtectedSymbolDecorator(int icon_size); + virtual ~ProtectedSymbolDecorator(); + virtual void draw(QPainter& p) const; + +private: + int arc_size; + int pen_width; + int box_width; + int box_height; + QPoint offset; +}; + +ProtectedSymbolDecorator::ProtectedSymbolDecorator(int icon_size) +: arc_size(qFloor(qMax(3.0, 0.15*icon_size))) +, pen_width(qMax(1, qCeil(0.4*arc_size))) +, box_width(arc_size + pen_width + qMax(1, qFloor(0.1*icon_size))) +, box_height(qMax(arc_size, qCeil(0.6*box_width))) +, offset(icon_size - 3 - box_width, 1 + pen_width) +{ + ; // nothing else +} + +ProtectedSymbolDecorator::~ProtectedSymbolDecorator() +{ + ; // nothing +} + +void ProtectedSymbolDecorator::draw(QPainter& painter) const +{ + // Draw a lock symbol + painter.save(); + painter.setRenderHint(QPainter::Antialiasing, true); + painter.translate(offset); + + painter.setOpacity(0.5); + QPen arc_background_pen(Qt::white); + arc_background_pen.setWidth(pen_width+2); + painter.setPen(arc_background_pen); + painter.drawRoundedRect(0.5*(box_width-arc_size), 0.0, qreal(arc_size), qreal(arc_size+pen_width), qreal(pen_width), qreal(pen_width)); + painter.fillRect(-1, arc_size-1, box_width+2, box_height+2, QBrush(Qt::white)); + + painter.setOpacity(1.0); + QPen arc_pen(Qt::darkGray); + arc_pen.setWidth(pen_width); + painter.setPen(arc_pen); + painter.drawRoundedRect(0.5*(box_width-arc_size), 0.0, qreal(arc_size), qreal(arc_size+pen_width), qreal(pen_width), qreal(pen_width)); + painter.fillRect(0, arc_size, box_width, box_height, QBrush(Qt::darkGray)); + + painter.restore(); +} + + + +//### HiddenSymbolDecorator ### + +/** + * @brief Draws the decoration for a hidden symbol. + * + * A small red x is drawn in the top-left corner of the icon. + */ +class HiddenSymbolDecorator : public SymbolIconDecorator +{ +public: + explicit HiddenSymbolDecorator(int icon_size); + virtual ~HiddenSymbolDecorator(); + virtual void draw(QPainter& p) const; + +private: + int icon_size; + int pen_width; + int x_width; + QPoint offset; +}; + +HiddenSymbolDecorator::HiddenSymbolDecorator(int icon_size) +: icon_size(icon_size) +, pen_width(qMax(1, qCeil(0.06*icon_size))) +, x_width(icon_size/3) +, offset(1 + pen_width, 1 + pen_width) +{ + ; // nothing else +} + +HiddenSymbolDecorator::~HiddenSymbolDecorator() +{ + ; // nothing +} + +void HiddenSymbolDecorator::draw(QPainter& painter) const +{ + // Draw a lock symbol + painter.save(); + painter.setRenderHint(QPainter::Antialiasing, true); + + painter.setOpacity(0.6); + painter.fillRect(0, 0, icon_size, icon_size, QBrush(Qt::white)); + + painter.translate(offset); + painter.setOpacity(1.0); + QPen pen(Qt::red); + pen.setWidth(pen_width); + painter.setPen(pen); + painter.drawLine(QPoint(0, 0), QPoint(x_width, x_width)); + painter.drawLine(QPoint(x_width, 0), QPoint(0, x_width)); + + painter.restore(); +} + + + +//### SymbolRenderWidget ### + +SymbolRenderWidget::SymbolRenderWidget(Map* map, bool mobile_mode, QWidget* parent) +: QWidget(parent) +, map(map) +, mobile_mode(mobile_mode) +, selection_locked(false) +, dragging(false) +, current_symbol_index(-1) +, hover_symbol_index(-1) +, last_drop_pos(-1) +, last_drop_row(-1) +, icon_size(Settings::getInstance().getSymbolWidgetIconSizePx()) +, icons_per_row(6) +, num_rows(5) +, preferred_size(icons_per_row * icon_size, num_rows * icon_size) +, hidden_symbol_decoration(new HiddenSymbolDecorator(icon_size)) +, protected_symbol_decoration(new ProtectedSymbolDecorator(icon_size)) +{ + setBackgroundRole(QPalette::Base); + setMouseTracking(true); + setFocusPolicy(Qt::ClickFocus); + setAcceptDrops(true); + + QShortcut* description_shortcut = new OverridingShortcut( + QKeySequence(tr("F1", "Shortcut for displaying the symbol's description")), + window() + ); + tooltip = new SymbolToolTip(this, description_shortcut); + // TODO: Use a placeholder in the literal and pass the actual shortcut's string representation. + setStatusTip(tr("For symbols with description, press F1 while the tooltip is visible to show it")); + + context_menu = new QMenu(this); + + QMenu* new_menu = new QMenu(tr("New symbol"), context_menu); + new_menu->setIcon(QIcon(QStringLiteral(":/images/plus.png"))); + /*QAction* new_point_action =*/ new_menu->addAction(tr("Point"), this, SLOT(newPointSymbol())); + /*QAction* new_line_action =*/ new_menu->addAction(tr("Line"), this, SLOT(newLineSymbol())); + /*QAction* new_area_action =*/ new_menu->addAction(tr("Area"), this, SLOT(newAreaSymbol())); + /*QAction* new_text_action =*/ new_menu->addAction(tr("Text"), this, SLOT(newTextSymbol())); + /*QAction* new_combined_action =*/ new_menu->addAction(tr("Combined"), this, SLOT(newCombinedSymbol())); + context_menu->addMenu(new_menu); + + edit_action = context_menu->addAction(tr("Edit"), this, SLOT(editSymbol())); + duplicate_action = context_menu->addAction(QIcon(QStringLiteral(":/images/tool-duplicate.png")), tr("Duplicate"), this, SLOT(duplicateSymbol())); + delete_action = context_menu->addAction(QIcon(QStringLiteral(":/images/minus.png")), tr("Delete"), this, SLOT(deleteSymbols())); + scale_action = context_menu->addAction(QIcon(QStringLiteral(":/images/tool-scale.png")), tr("Scale..."), this, SLOT(scaleSymbol())); + context_menu->addSeparator(); + copy_action = context_menu->addAction(QIcon(QStringLiteral(":/images/copy.png")), tr("Copy"), this, SLOT(copySymbols())); + paste_action = context_menu->addAction(QIcon(QStringLiteral(":/images/paste.png")), tr("Paste"), this, SLOT(pasteSymbols())); + context_menu->addSeparator(); + switch_symbol_action = context_menu->addAction(QIcon(QStringLiteral(":/images/tool-switch-symbol.png")), tr("Switch symbol of selected object(s)"), this, SIGNAL(switchSymbolClicked())); + fill_border_action = context_menu->addAction(QIcon(QStringLiteral(":/images/tool-fill-border.png")), tr("Fill / Create border for selected object(s)"), this, SIGNAL(fillBorderClicked())); + // text will be filled in by updateContextMenuState() + select_objects_action = context_menu->addAction(QIcon(QStringLiteral(":/images/tool-edit.png")), {}, this, SLOT(selectObjectsExclusively())); + select_objects_additionally_action = context_menu->addAction(QIcon(QStringLiteral(":/images/tool-edit.png")), {}, this, SLOT(selectObjectsAdditionally())); + deselect_objects_action = context_menu->addAction(QIcon(QStringLiteral(":/images/tool-edit.png")), {}, this, SLOT(deselectObjects())); + context_menu->addSeparator(); + hide_action = context_menu->addAction({}, this, SLOT(setSelectedSymbolVisibility(bool))); + hide_action->setCheckable(true); + protect_action = context_menu->addAction({}, this, SLOT(setSelectedSymbolProtection(bool))); + protect_action->setCheckable(true); + context_menu->addSeparator(); + + QMenu* select_menu = new QMenu(tr("Select symbols"), context_menu); + select_menu->addAction(tr("Select all"), this, SLOT(selectAll())); + select_menu->addAction(tr("Select unused"), this, SLOT(selectUnused())); + select_menu->addSeparator(); + select_menu->addAction(tr("Invert selection"), this, SLOT(invertSelection())); + context_menu->addMenu(select_menu); + + QMenu* sort_menu = new QMenu(tr("Sort symbols"), context_menu); + sort_menu->addAction(tr("Sort by number"), this, SLOT(sortByNumber())); + sort_menu->addAction(tr("Sort by primary color"), this, SLOT(sortByColor())); + sort_menu->addAction(tr("Sort by primary color priority"), this, SLOT(sortByColorPriority())); + sort_manual_action = sort_menu->addAction(tr("Enable drag and drop")); + sort_manual_action->setCheckable(true); + context_menu->addMenu(sort_menu); + + connect(map, SIGNAL(colorDeleted(int, const MapColor*)), this, SLOT(update())); + connect(map, SIGNAL(symbolAdded(int, const Symbol*)), this, SLOT(updateAll())); + connect(map, SIGNAL(symbolDeleted(int, const Symbol*)), this, SLOT(symbolDeleted(int, const Symbol*))); + connect(map, SIGNAL(symbolChanged(int, const Symbol*, const Symbol*)), this, SLOT(symbolChanged(int, const Symbol*, const Symbol*))); + connect(map, SIGNAL(symbolIconChanged(int)), this, SLOT(updateSingleIcon(int))); +} + +SymbolRenderWidget::~SymbolRenderWidget() +{ + ; // nothing +} + +void SymbolRenderWidget::symbolDeleted(int pos, const Symbol *old_symbol) +{ + Q_UNUSED(old_symbol); + + std::set::iterator it = selected_symbols.find(pos); + if (it != selected_symbols.end()) + { + // Remove pos + std::set::iterator new_it = it; + ++new_it; + selected_symbols.erase(it); + // Renumber successors + for (it = new_it; it != selected_symbols.end(); it = ++new_it) + { + new_it = selected_symbols.insert(*it - 1).first; + selected_symbols.erase(it); + } + emitGuarded_selectedSymbolsChanged(); + } + + adjustLayout(); + update(); +} + +void SymbolRenderWidget::symbolChanged(int pos, const Symbol* new_symbol, const Symbol* old_symbol) +{ + Q_UNUSED(new_symbol); + Q_UNUSED(old_symbol); + + updateSingleIcon(pos); + + if (isSymbolSelected(pos)) + emitGuarded_selectedSymbolsChanged(); +} + +void SymbolRenderWidget::updateAll() +{ + adjustLayout(); + update(); +} + +void SymbolRenderWidget::updateSingleIcon(int i) +{ + if (i >= 0) + { + QPoint pos = iconPosition(i); + update(pos.x(), pos.y(), icon_size, icon_size); + } +} + +QSize SymbolRenderWidget::sizeHint() const +{ + return preferred_size; +} + +void SymbolRenderWidget::adjustLayout() +{ + icon_size = Settings::getInstance().getSymbolWidgetIconSizePx(); + // Allow symbol widget to be that much wider than the viewport + int overflow = icon_size / 3; + icons_per_row = qMax(1, (width() + overflow) / icon_size); + num_rows = qMax(1, (map->getNumSymbols() + icons_per_row -1) / icons_per_row); + setFixedHeight(num_rows * icon_size); + + hidden_symbol_decoration.reset(new HiddenSymbolDecorator(icon_size)); + protected_symbol_decoration.reset(new ProtectedSymbolDecorator(icon_size)); +} + +void SymbolRenderWidget::emitGuarded_selectedSymbolsChanged() +{ + QScopedValueRollback save(selection_locked); + selection_locked = true; + emit selectedSymbolsChanged(); +} + +const Symbol* SymbolRenderWidget::singleSelectedSymbol() const +{ + if (selected_symbols.size() != 1) + return NULL; + return static_cast(map)->getSymbol(*(selected_symbols.begin())); +} + +Symbol* SymbolRenderWidget::singleSelectedSymbol() +{ + if (selected_symbols.size() != 1) + return NULL; + return map->getSymbol(*(selected_symbols.begin())); +} + +bool SymbolRenderWidget::isSymbolSelected(const Symbol* symbol) const +{ + return isSymbolSelected(map->findSymbolIndex(symbol)); +} + +bool SymbolRenderWidget::isSymbolSelected(int i) const +{ + return selected_symbols.find(i) != selected_symbols.end(); +} + +void SymbolRenderWidget::selectSingleSymbol(const Symbol *symbol) +{ + int index = map->findSymbolIndex(symbol); + if (index >= 0) + selectSingleSymbol(index); +} + +void SymbolRenderWidget::selectSingleSymbol(int i) +{ + if (selection_locked) + return; + + if (selected_symbols.size() == 1 && *selected_symbols.begin() == i) + return; // Symbol already selected as only selection + + updateSelectedIcons(); + selected_symbols.clear(); + if (i >= 0) + { + selected_symbols.insert(i); + updateSingleIcon(i); + } + current_symbol_index = i; + + emitGuarded_selectedSymbolsChanged(); +} + +void SymbolRenderWidget::hover(QPoint pos) +{ + int i = symbolIndexAt(pos); + + if (i != hover_symbol_index) + { + updateSingleIcon(hover_symbol_index); + hover_symbol_index = i; + updateSingleIcon(hover_symbol_index); + + if (hover_symbol_index >= 0) + { + Symbol* symbol = map->getSymbol(hover_symbol_index); + if (tooltip->getSymbol() != symbol) + { + const QRect icon_rect(mapToGlobal(iconPosition(hover_symbol_index)), QSize(icon_size, icon_size)); + tooltip->scheduleShow(symbol, icon_rect); + } + } + else + { + tooltip->reset(); + } + } +} + +QPoint SymbolRenderWidget::iconPosition(int i) const +{ + return QPoint((i % icons_per_row) * icon_size, (i / icons_per_row) * icon_size); +} + +int SymbolRenderWidget::symbolIndexAt(QPoint pos) const +{ + int i = -1; + + int icon_in_row = pos.x() / icon_size; + if (icon_in_row < icons_per_row) + { + i = icon_in_row + icons_per_row * (pos.y() / icon_size); + if (i >= map->getNumSymbols()) + i = -1; + } + + return i; +} + +void SymbolRenderWidget::updateSelectedIcons() +{ + for (std::set::const_iterator it = selected_symbols.begin(); it != selected_symbols.end(); ++it) + updateSingleIcon(*it); +} + +bool SymbolRenderWidget::dropPosition(QPoint pos, int& row, int& pos_in_row) +{ + row = pos.y() / icon_size; + if (row >= num_rows) + { + row = -1; + pos_in_row = -1; + return false; + } + + pos_in_row = (pos.x() + icon_size / 2) / icon_size; + if (pos_in_row > icons_per_row) + { + pos_in_row = icons_per_row; + } + + int global_pos = row * icons_per_row + pos_in_row; + if (global_pos > map->getNumSymbols()) + { + row = -1; + pos_in_row = -1; + return false; + } + + return true; +} + +QRect SymbolRenderWidget::dropIndicatorRect(int row, int pos_in_row) +{ + const int rect_width = 3; + return QRect(pos_in_row * icon_size - rect_width / 2 - 1, row * icon_size - 1, rect_width, icon_size + 2); +} + +void SymbolRenderWidget::drawIcon(QPainter &painter, int i) const +{ + painter.save(); + + Symbol* symbol = map->getSymbol(i); + painter.drawImage(0, 0, symbol->getIcon(map)); + + if (isSymbolSelected(i) || i == current_symbol_index) + { + painter.setOpacity(0.5); + QPen pen(Qt::white); + pen.setWidth(2); + pen.setJoinStyle(Qt::MiterJoin); + painter.setPen(pen); + painter.drawRect(QRectF(1.5f, 1.5f, icon_size - 5, icon_size - 5)); + + painter.setOpacity(1.0); + } + + if (symbol->isProtected()) + protected_symbol_decoration->draw(painter); + + if (symbol->isHidden()) + hidden_symbol_decoration->draw(painter); + + if (isSymbolSelected(i)) + { + QPen pen(qRgb(12, 0, 255)); + pen.setWidth(2); + pen.setJoinStyle(Qt::MiterJoin); + painter.setPen(pen); + painter.drawRect(QRectF(0.5f, 0.5f, icon_size - 3, icon_size - 3)); + + if (i == hover_symbol_index) + { + QPen pen(qRgb(255, 150, 0)); + pen.setWidth(2); + pen.setDashPattern(QVector() << 1 << 2); + pen.setJoinStyle(Qt::MiterJoin); + painter.setPen(pen); + painter.drawRect(QRectF(0.5f, 0.5f, icon_size - 3, icon_size - 3)); + } + else if (i == current_symbol_index) + { + QPen pen(Qt::white); + pen.setDashPattern(QVector() << 2 << 2); + painter.setPen(pen); + painter.drawRect(1, 1, icon_size - 4, icon_size - 4); + } + } + else if (i == hover_symbol_index) + { + QPen pen(qRgb(255, 150, 0)); + pen.setWidth(2); + pen.setJoinStyle(Qt::MiterJoin); + painter.setPen(pen); + painter.drawRect(QRectF(0.5f, 0.5f, icon_size - 3, icon_size - 3)); + } + + painter.setPen(Qt::gray); + painter.drawLine(QPoint(0, icon_size - 1), QPoint(icon_size - 1, icon_size - 1)); + painter.drawLine(QPoint(icon_size - 1, 0), QPoint(icon_size - 1, icon_size - 2)); + + painter.restore(); +} + +void SymbolRenderWidget::paintEvent(QPaintEvent* event) +{ + QRect event_rect = event->rect().adjusted(-icon_size, -icon_size, 0, 0); + + QPainter painter(this); + painter.setPen(Qt::gray); + + int x = 0; + int y = 0; + for (int i = 0; i < map->getNumSymbols(); ++i) + { + if (event_rect.contains(x,y)) + { + painter.save(); + painter.translate(x, y); + drawIcon(painter, i); + painter.restore(); + } + + x += icon_size; + if (x >= icons_per_row * icon_size) + { + x = 0; + y += icon_size; + } + } + + // Drop indicator? + if (last_drop_pos >= 0 && last_drop_row >= 0) + { + QRect drop_rect = dropIndicatorRect(last_drop_row, last_drop_pos); + painter.setPen(qRgb(255, 150, 0)); + painter.setBrush(Qt::NoBrush); + painter.drawRect(drop_rect.left(), drop_rect.top(), drop_rect.width() - 1, drop_rect.height() - 1); + } + + painter.end(); +} + +void SymbolRenderWidget::resizeEvent(QResizeEvent* event) +{ + if (width() != event->oldSize().width()) + { + adjustLayout(); + } +} + +void SymbolRenderWidget::mouseMoveEvent(QMouseEvent* event) +{ + if (mobile_mode) + { + if (event->buttons() & Qt::LeftButton) + { + if ((event->pos() - last_click_pos).manhattanLength() < Settings::getInstance().getStartDragDistancePx()) + return; + dragging = sort_manual_action->isChecked(); + } + } + else + { + if (event->buttons() & Qt::LeftButton + && current_symbol_index >= 0 + && sort_manual_action->isChecked()) + { + if ((event->pos() - last_click_pos).manhattanLength() < Settings::getInstance().getStartDragDistancePx()) + return; + + tooltip->hide(); + + QDrag* drag = new QDrag(this); + QMimeData* mime_data = new QMimeData(); + + QByteArray data; + data.append((const char*)¤t_symbol_index, sizeof(int)); + mime_data->setData(MimeType::oo_symbol_index, data); + drag->setMimeData(mime_data); + + drag->exec(Qt::MoveAction); + } + else if (event->button() == Qt::NoButton) + { + hover(event->pos()); + } + } + event->accept(); +} + +void SymbolRenderWidget::mousePressEvent(QMouseEvent* event) +{ + dragging = false; + + if (mobile_mode) + { + last_click_pos = event->pos(); + return; + } + + updateSingleIcon(current_symbol_index); + int old_symbol_index = current_symbol_index; + current_symbol_index = symbolIndexAt(event->pos()); + updateSingleIcon(current_symbol_index); + + if (event->button() == Qt::LeftButton || event->button() == Qt::RightButton) + { + if (event->modifiers() & Qt::ControlModifier) + { + if (current_symbol_index >= 0) + { + if (!isSymbolSelected(current_symbol_index)) + selected_symbols.insert(current_symbol_index); + else + selected_symbols.erase(current_symbol_index); + emitGuarded_selectedSymbolsChanged(); + } + } + else if (event->modifiers() & Qt::ShiftModifier) + { + if (current_symbol_index >= 0) + { + bool insert = !isSymbolSelected(current_symbol_index); + int i = (old_symbol_index >= 0) ? old_symbol_index : current_symbol_index; + while (true) + { + if (insert) + selected_symbols.insert(i); + else + selected_symbols.erase(i); + updateSingleIcon(i); + + if (current_symbol_index > i) + ++i; + else if (current_symbol_index < i) + --i; + else + break; + } + emitGuarded_selectedSymbolsChanged(); + } + } + else + { + if (event->button() == Qt::LeftButton || + (event->button() == Qt::RightButton && + current_symbol_index >= 0 && !isSymbolSelected(current_symbol_index))) + selectSingleSymbol(current_symbol_index); + } + } + + else if (event->button() == Qt::LeftButton && current_symbol_index >= 0 && !(event->modifiers() & Qt::ShiftModifier)) + { + last_click_pos = event->pos(); + last_drop_pos = -1; + last_drop_row = -1; + } +} + +void SymbolRenderWidget::mouseReleaseEvent(QMouseEvent* event) +{ + if (mobile_mode) + { + if (dragging) + { + dragging = false; + return; + } + + updateSingleIcon(current_symbol_index); + current_symbol_index = symbolIndexAt(event->pos()); + updateSingleIcon(current_symbol_index); + + if (current_symbol_index >= 0 && !isSymbolSelected(current_symbol_index)) + selectSingleSymbol(current_symbol_index); + else + emitGuarded_selectedSymbolsChanged(); // HACK, will close the symbol selection screen + } +} + +void SymbolRenderWidget::mouseDoubleClickEvent(QMouseEvent* event) +{ + if (mobile_mode) + return; + + int i = symbolIndexAt(event->pos()); + if (i < 0) + return; + + updateSingleIcon(current_symbol_index); + current_symbol_index = i; + updateSingleIcon(current_symbol_index); + editSymbol(); +} + +void SymbolRenderWidget::leaveEvent(QEvent* event) +{ + Q_UNUSED(event); + updateSingleIcon(hover_symbol_index); + hover_symbol_index = -1; + + tooltip->reset(); +} + +void SymbolRenderWidget::dragEnterEvent(QDragEnterEvent* event) +{ + if (event->mimeData()->hasFormat(MimeType::oo_symbol_index)) + event->acceptProposedAction(); +} + +void SymbolRenderWidget::dragMoveEvent(QDragMoveEvent* event) +{ + if (event->mimeData()->hasFormat(MimeType::oo_symbol_index)) + { + int row, pos_in_row; + if (!dropPosition(event->pos(), row, pos_in_row)) + { + if (last_drop_pos >= 0 && last_drop_row >= 0) + { + update(dropIndicatorRect(last_drop_row, last_drop_pos)); + last_drop_pos = -1; + last_drop_row = -1; + } + return; + } + + if (row != last_drop_row || pos_in_row != last_drop_pos) + { + if (last_drop_row >= 0 && last_drop_pos >= 0) + update(dropIndicatorRect(last_drop_row, last_drop_pos)); + + last_drop_row = row; + last_drop_pos = pos_in_row; + + if (last_drop_row >= 0 && last_drop_pos >= 0) + update(dropIndicatorRect(last_drop_row, last_drop_pos)); + } + + event->acceptProposedAction(); + } +} + +void SymbolRenderWidget::dropEvent(QDropEvent* event) +{ + last_drop_row = -1; + last_drop_pos = -1; + + if (event->source() != this || current_symbol_index < 0) + return; + + if (event->proposedAction() == Qt::MoveAction) + { + int row, pos_in_row; + if (!dropPosition(event->pos(), row, pos_in_row)) + return; + + int pos = row * icons_per_row + pos_in_row; + if (pos == current_symbol_index) + return; + + event->acceptProposedAction(); + + // save selection + std::set sel; + for (std::set::const_iterator it = selected_symbols.begin(); it != selected_symbols.end(); ++it) { + sel.insert(map->getSymbol(*it)); + } + + map->moveSymbol(current_symbol_index, pos); + update(); + + + if (pos > current_symbol_index) + --pos; + current_symbol_index = pos; + selectSingleSymbol(pos); + } +} + +void SymbolRenderWidget::selectObjectsExclusively() +{ + emit selectObjectsClicked(true); +} + +void SymbolRenderWidget::selectObjectsAdditionally() +{ + emit selectObjectsClicked(false); +} + +void SymbolRenderWidget::deselectObjects() +{ + emit deselectObjectsClicked(); +} + +void SymbolRenderWidget::newPointSymbol() +{ + newSymbol(new PointSymbol()); +} + +void SymbolRenderWidget::newLineSymbol() +{ + newSymbol(new LineSymbol()); +} + +void SymbolRenderWidget::newAreaSymbol() +{ + newSymbol(new AreaSymbol()); +} + +void SymbolRenderWidget::newTextSymbol() +{ + newSymbol(new TextSymbol()); +} + +void SymbolRenderWidget::newCombinedSymbol() +{ + newSymbol(new CombinedSymbol()); +} + +void SymbolRenderWidget::editSymbol() +{ + Q_ASSERT(current_symbol_index >= 0); + + Symbol* symbol = map->getSymbol(current_symbol_index); + SymbolSettingDialog dialog(symbol, map, this); + dialog.setWindowModality(Qt::WindowModal); + if (dialog.exec() == QDialog::Accepted) + { + symbol = dialog.getNewSymbol(); + map->setSymbol(symbol, current_symbol_index); + } +} + +void SymbolRenderWidget::scaleSymbol() +{ + Q_ASSERT(!selected_symbols.empty()); + + bool ok; + double percent = QInputDialog::getDouble(this, tr("Scale symbol(s)"), tr("Scale to percentage:"), 100, 0, 999999, 6, &ok); + if (!ok || percent == 100) + return; + + for (std::set::const_iterator it = selected_symbols.begin(); it != selected_symbols.end(); ++it) + { + Symbol* symbol = map->getSymbol(*it); + + symbol->scale(percent / 100.0); + updateSingleIcon(current_symbol_index); + map->changeSymbolForAllObjects(symbol, symbol); // update the objects + } + + map->setSymbolsDirty(); +} + +void SymbolRenderWidget::deleteSymbols() +{ + // save selected symbols + std::vector saved_selection; + saved_selection.reserve(selected_symbols.size()); + for (std::set::const_iterator it = selected_symbols.begin(); it != selected_symbols.end(); ++it) + { + saved_selection.push_back(map->getSymbol(*it)); + } + + // delete symbols in order + for (std::vector::iterator it = saved_selection.begin(); it != saved_selection.end(); ++it) + { + if (map->existsObjectWithSymbol(*it)) + { + if (QMessageBox::warning(this, tr("Confirmation"), tr("The map contains objects with the symbol \"%1\". Deleting it will delete those objects and clear the undo history! Do you really want to do that?").arg((*it)->getName()), QMessageBox::Yes | QMessageBox::No) == QMessageBox::No) + continue; + } + map->deleteSymbol(map->findSymbolIndex(*it)); + } + + if (selected_symbols.empty() && map->getFirstSelectedObject()) + selectSingleSymbol(map->getFirstSelectedObject()->getSymbol()); +} + +void SymbolRenderWidget::duplicateSymbol() +{ + Q_ASSERT(current_symbol_index >= 0); + + map->addSymbol(map->getSymbol(current_symbol_index)->duplicate(), current_symbol_index + 1); + selectSingleSymbol(current_symbol_index + 1); +} + +void SymbolRenderWidget::copySymbols() +{ + // Create map containing all colors and the selected symbols. + // Copying all colors improves preservation of relative order during paste. + Map* copy_map = new Map(); + copy_map->setScaleDenominator(map->getScaleDenominator()); + + copy_map->importMap(map, Map::ColorImport, this); + + std::vector selection(map->getNumSymbols(), false); + for (std::set::const_iterator it = selected_symbols.begin(); it != selected_symbols.end(); ++it) + selection[*it] = true; + + copy_map->importMap(map, Map::MinimalSymbolImport, this, &selection); + + // Save map to memory + QBuffer buffer; + if (!copy_map->exportToIODevice(&buffer)) + { + delete copy_map; + QMessageBox::warning(NULL, tr("Error"), tr("An internal error occurred, sorry!")); + return; + } + delete copy_map; + + // Put buffer into clipboard + QMimeData* mime_data = new QMimeData(); + mime_data->setData(MimeType::oo_symbols, buffer.data()); + QApplication::clipboard()->setMimeData(mime_data); +} + +void SymbolRenderWidget::pasteSymbols() +{ + if (!QApplication::clipboard()->mimeData()->hasFormat(MimeType::oo_symbols)) + { + QMessageBox::warning(NULL, tr("Error"), tr("There are no symbols in clipboard which could be pasted!")); + return; + } + + // Get buffer from clipboard + QByteArray byte_array = QApplication::clipboard()->mimeData()->data(MimeType::oo_symbols); + QBuffer buffer(&byte_array); + buffer.open(QIODevice::ReadOnly); + + // Create map from buffer + Map* paste_map = new Map(); + if (!paste_map->importFromIODevice(&buffer)) + { + QMessageBox::warning(NULL, tr("Error"), tr("An internal error occurred, sorry!")); + return; + } + + // Ensure that a change in selection is detected + selectSingleSymbol(-1); + + // Import pasted map + map->importMap(paste_map, Map::MinimalSymbolImport, this, NULL, current_symbol_index, false); + delete paste_map; + + selectSingleSymbol(current_symbol_index); +} + +void SymbolRenderWidget::setSelectedSymbolVisibility(bool checked) +{ + bool selection_changed = false; + for (std::set::const_iterator it = selected_symbols.begin(); it != selected_symbols.end(); ++it) + { + Symbol* symbol = map->getSymbol(*it); + if (symbol->isHidden() != checked) + { + symbol->setHidden(checked); + updateSingleIcon(*it); + if (checked) + selection_changed |= map->removeSymbolFromSelection(symbol, false); + } + } + if (selection_changed) + map->emitSelectionChanged(); + map->updateAllMapWidgets(); + map->setSymbolsDirty(); + emitGuarded_selectedSymbolsChanged(); +} +void SymbolRenderWidget::setSelectedSymbolProtection(bool checked) +{ + bool selection_changed = false; + for (std::set::const_iterator it = selected_symbols.begin(); it != selected_symbols.end(); ++it) + { + Symbol* symbol = map->getSymbol(*it); + if (symbol->isProtected() != checked) + { + symbol->setProtected(checked); + updateSingleIcon(*it); + if (checked) + selection_changed |= map->removeSymbolFromSelection(symbol, false); + } + } + if (selection_changed) + map->emitSelectionChanged(); + map->setSymbolsDirty(); + emitGuarded_selectedSymbolsChanged(); +} + +void SymbolRenderWidget::selectAll() +{ + for (int i = 0; i < map->getNumSymbols(); ++i) + selected_symbols.insert(i); + emitGuarded_selectedSymbolsChanged(); + update(); +} + +void SymbolRenderWidget::selectUnused() +{ + std::vector symbols_in_use; + map->determineSymbolsInUse(symbols_in_use); + + updateSelectedIcons(); + selected_symbols.clear(); + for (size_t i = 0, end = symbols_in_use.size(); i < end; ++i) + { + if (!symbols_in_use[i]) + { + selected_symbols.insert(i); + updateSingleIcon(i); + } + } + emitGuarded_selectedSymbolsChanged(); +} + +void SymbolRenderWidget::invertSelection() +{ + std::set new_set; + for (int i = 0; i < map->getNumSymbols(); ++i) + { + if (!isSymbolSelected(i)) + new_set.insert(i); + } + swap(selected_symbols, new_set); + emitGuarded_selectedSymbolsChanged(); + update(); +} + +void SymbolRenderWidget::sortByNumber() +{ + sort(Symbol::compareByNumber); +} + +void SymbolRenderWidget::sortByColor() +{ + sort(Symbol::compareByColor(map)); +} + +void SymbolRenderWidget::sortByColorPriority() +{ + sort(Symbol::compareByColorPriority); +} + +void SymbolRenderWidget::showContextMenu(QPoint global_pos) +{ + updateContextMenuState(); + context_menu->popup(global_pos); +} + +void SymbolRenderWidget::contextMenuEvent(QContextMenuEvent* event) +{ + showContextMenu(event->globalPos()); + event->accept(); +} + +void SymbolRenderWidget::updateContextMenuState() +{ + bool have_selection = selectedSymbolsCount() > 0; + bool single_selection = selectedSymbolsCount() == 1 && current_symbol_index >= 0; + const Symbol* single_symbol = singleSelectedSymbol(); + bool all_symbols_hidden = have_selection; + bool all_symbols_protected = have_selection; + for (std::set::const_iterator it = selected_symbols.begin(); it != selected_symbols.end(); ++it) + { + if (!map->getSymbol(*it)->isHidden()) + all_symbols_hidden = false; + if (!map->getSymbol(*it)->isProtected()) + all_symbols_protected = false; + if (!all_symbols_hidden && !all_symbols_protected) + break; + } + + bool single_symbol_compatible; + bool single_symbol_different; + map->getSelectionToSymbolCompatibility(single_symbol, single_symbol_compatible, single_symbol_different); + + edit_action->setEnabled(single_selection); + scale_action->setEnabled(have_selection); + copy_action->setEnabled(have_selection); + paste_action->setEnabled(QApplication::clipboard()->mimeData()->hasFormat(MimeType::oo_symbols)); + switch_symbol_action->setEnabled(single_symbol_compatible && single_symbol_different); + fill_border_action->setEnabled(single_symbol_compatible && single_symbol_different); + hide_action->setEnabled(have_selection); + hide_action->setChecked(all_symbols_hidden); + protect_action->setEnabled(have_selection); + protect_action->setChecked(all_symbols_protected); + duplicate_action->setEnabled(single_selection); + delete_action->setEnabled(have_selection); + + if (single_selection) + { + select_objects_action->setText(tr("Select all objects with this symbol")); + select_objects_additionally_action->setText(tr("Add all objects with this symbol to selection")); + deselect_objects_action->setText(tr("Remove all objects with this symbol from selection")); + hide_action->setText(tr("Hide objects with this symbol")); + protect_action->setText(tr("Protect objects with this symbol")); + } + else + { + select_objects_action->setText(tr("Select all objects with selected symbols")); + select_objects_additionally_action->setText(tr("Add all objects with selected symbols to selection")); + deselect_objects_action->setText(tr("Remove all objects with selected symbols from selection")); + hide_action->setText(tr("Hide objects with selected symbols")); + protect_action->setText(tr("Protect objects with selected symbols")); + } + select_objects_action->setEnabled(have_selection); + select_objects_additionally_action->setEnabled(have_selection); + deselect_objects_action->setEnabled(have_selection); +} + +bool SymbolRenderWidget::newSymbol(Symbol* prototype) +{ + SymbolSettingDialog dialog(prototype, map, this); + dialog.setWindowModality(Qt::WindowModal); + delete prototype; + if (dialog.exec() == QDialog::Rejected) + return false; + + Symbol* new_symbol = dialog.getNewSymbol(); + int pos = (current_symbol_index >= 0) ? current_symbol_index : map->getNumSymbols(); + map->addSymbol(new_symbol, pos); + // Ensure that a change in selection is detected + selectSingleSymbol(-1); + selectSingleSymbol(pos); + return true; +} + +template +void SymbolRenderWidget::sort(T compare) +{ + // save selection + std::set saved_selection; + for (std::set::const_iterator it = selected_symbols.begin(); it != selected_symbols.end(); ++it) + { + saved_selection.insert(map->getSymbol(*it)); + } + + map->sortSymbols(compare); + + // restore selection + selected_symbols.clear(); + for (int i = 0; i < map->getNumSymbols(); ++i) + { + if (saved_selection.find(map->getSymbol(i)) != saved_selection.end()) + selected_symbols.insert(i); + } + + update(); +} diff --git a/src/gui/widgets/symbol_render_widget.h b/src/gui/widgets/symbol_render_widget.h new file mode 100644 index 0000000..4f85759 --- /dev/null +++ b/src/gui/widgets/symbol_render_widget.h @@ -0,0 +1,359 @@ +/* + * Copyright 2012, 2013 Thomas Schöps + * Copyright 2014 Kai Pastor + * + * This file is part of OpenOrienteering. + * + * OpenOrienteering is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenOrienteering is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenOrienteering. If not, see . + */ + + +#ifndef _OPENORIENTEERING_SYMBOL_RENDER_WIDGET_H_ +#define _OPENORIENTEERING_SYMBOL_RENDER_WIDGET_H_ + +#include + +#include +#include + +QT_BEGIN_NAMESPACE +class QMenu; +QT_END_NAMESPACE + +class Map; +class Symbol; +class SymbolToolTip; +class SymbolIconDecorator; + +/** + * @brief Shows all symbols from a map in a size-constrained widget. + * + * SymbolRenderWidget lets the user select symbols and perform actions on them. + * It is a plain widget which does not implement scrolling but takes as much + * height as neccessary for given width and number of symbols. Scrolling is + * realized by SymbolWidget. + */ +class SymbolRenderWidget : public QWidget +{ +Q_OBJECT +public: + /** + * @brief Constructs a new SymbolRenderWidget. + * @param map The map which provides the symbols. Must not be NULL. + * @param mobile_mode If true, enables a special mode for mobile devices. + * @param parent The parent QWidget. + */ + SymbolRenderWidget(Map* map, bool mobile_mode, QWidget* parent = NULL); + + /** + * @brief Destroys the SymbolRenderWidget. + */ + virtual ~SymbolRenderWidget(); + + /** + * @brief Returns the number of selected symbols. + */ + int selectedSymbolsCount() const; + + /** + * @brief Checks if the symbol is selected. + */ + bool isSymbolSelected(const Symbol* symbol) const; + + /** + * @brief Checks if the symbol with given index is selected. + */ + bool isSymbolSelected(int i) const; + + /** + * @brief If exactly one symbol is selected, returns this symbol. + * + * Otherwise returns NULL. + */ + const Symbol* singleSelectedSymbol() const; + + /** + * @brief If exactly one symbol is selected, returns this symbol. + * + * Otherwise returns NULL. + */ + Symbol* singleSelectedSymbol(); + + /** + * @brief Selects the given symbol exclusively. + * + * Deselects other symbols, if there was a different selection before. + */ + void selectSingleSymbol(const Symbol* symbol); + + /** + * @brief Selects the given symbol exclusively. + * + * Selects the symbol with the given number. + * Deselects other symbols, if there was a different selection before. + */ + void selectSingleSymbol(int i); + + /** + * @brief Returns the recommended size for the widget. + * + * Reimplemented from QWidget::sizeHint(). + */ + virtual QSize sizeHint() const; + + /** + * @brief Opens the context menu at the given global position. + */ + void showContextMenu(QPoint global_pos); + +public slots: + /** + * @brief Updates the layout and marks all icons for repainting. + */ + void updateAll(); + + /** + * @brief Marks the icon with the given index for repainting. + */ + void updateSingleIcon(int i); + +signals: + /** + * @brief The collection of selected symbols changed. + */ + void selectedSymbolsChanged(); + + /** + * @brief The user triggered "Switch symbol". + * @todo Merge with/Reuse corresponding action in MapEditorController. + */ + void switchSymbolClicked(); + + /** + * @brief The user triggered "Fill/Create border". + * @todo Merge with/Reuse corresponding action in MapEditorController. + */ + void fillBorderClicked(); + + /** + * @brief The user triggered selecting objects with the active symbol. + * @param exclusively If true, an existing selection is replaced, + * otherwise it is extend. + */ + void selectObjectsClicked(bool exclusively); + + /** + * @brief The user triggered deselecting objects with the active symbol. + */ + void deselectObjectsClicked(); + +protected slots: + /** + * @brief Updates icon and selection when a symbol changes. + * + * @see Map::symbolChanged() + */ + void symbolChanged(int pos, const Symbol* new_symbol, const Symbol* old_symbol); + + /** + * @brief Updates the widget and the current selection. + * + * @see Map::symbolDeleted() + */ + void symbolDeleted(int pos, const Symbol* old_symbol); + + void newPointSymbol(); + void newLineSymbol(); + void newAreaSymbol(); + void newTextSymbol(); + void newCombinedSymbol(); + void editSymbol(); + void scaleSymbol(); + void deleteSymbols(); + void duplicateSymbol(); + void copySymbols(); + void pasteSymbols(); + void setSelectedSymbolVisibility(bool checked); + void setSelectedSymbolProtection(bool checked); + void selectObjectsExclusively(); + void selectObjectsAdditionally(); + void deselectObjects(); + void selectAll(); + void selectUnused(); + void invertSelection(); + void sortByNumber(); + void sortByColor(); + void sortByColorPriority(); + +protected: + virtual void resizeEvent(QResizeEvent* event); + + /** + * @brief Recalculates the layout and size. + * + * This function reads the icon size from the settings and the widget's + * current width and adjusts the number of icons per row, the number of + * rows and the widget's height to fit the current number of symbols. + */ + void adjustLayout(); + + /** + * @brief Returns the top-left coordinates of a symbol's icon. + * @param i The index of the symbol. + */ + QPoint iconPosition(int i) const; + + /** + * @brief Returns the index of the symbol represented at a particular location + * @param pos The location + */ + int symbolIndexAt(QPoint pos) const; + + + virtual void paintEvent(QPaintEvent* event); + + /** + * @brief Draws the icon and its decoration (hidden, protected). + * + * The icon is drawn at (0, 0) with the current icon size. + * @param painter The QPainter to be used (must be active). + * @param i The index of the symbol. + */ + void drawIcon(QPainter& painter, int i) const; + + + virtual void mouseMoveEvent(QMouseEvent* event); + virtual void mousePressEvent(QMouseEvent* event); + virtual void mouseReleaseEvent(QMouseEvent* event); + virtual void mouseDoubleClickEvent(QMouseEvent* event); + virtual void leaveEvent(QEvent* event); + + /** + * @brief Handles hovering over the icons, i.e. controlling the tool tip. + * @param pos The current location of the pointing device. + */ + void hover(QPoint pos); + + + virtual void dragEnterEvent(QDragEnterEvent* event); + virtual void dragMoveEvent(QDragMoveEvent* event); + virtual void dropEvent(QDropEvent* event); + + /** + * @brief Determines the drop location for a given pointing device position. + * @param pos The pointing device position. + * @param row The icon row where to insert the dropped symbol. + * @param pos_in_row The position in the row where to insert the dropped symbol. + * @return If there is a valid drop position, returns true, otherwise false. + */ + bool dropPosition(QPoint pos, int& row, int& pos_in_row); + + /** + * @brief Determines a drop indicator rectangle for a given location in the icons. + * @param row The icon row where to insert the dropped symbol. + * @param pos_in_row The position in the row where to insert the dropped symbol. + */ + QRect dropIndicatorRect(int row, int pos_in_row); + + + /** + * @brief Takes care of editing and inserting a newly created symbol. + * @param prototype The symbol which will be edited and inserted in the map. + * @return If editing is cancelled, returns false. Otherwise returns true. + */ + bool newSymbol(Symbol* prototype); + + /** + * @brief Sorts the map's symbol set by arbitrary criteria. + */ + template void sort(T compare); + + /** + * @brief Marks the icons of the selected symbols for repainting. + */ + void updateSelectedIcons(); + + /** + * @brief Emits selectedSymbolsChanged() while temporarily locking the symbol selection against changes. + * + * An active tool could catch the selectedSymbolsChanged() signal and + * finish its editing for that reason. It would than insert a new object to + * the map and so trigger another change of selection. Emitting + * selectedSymbolsChanged() via this method supresses behavior by setting + * the selection_locked flag before emitting the actual signal and resetting + * the flag on return. + */ + void emitGuarded_selectedSymbolsChanged(); + + /** + * @brief Receives context menu events and opens the context menu. + */ + virtual void contextMenuEvent(QContextMenuEvent* event); + + /** + * @brief Updates the state of the actions in the context menu. + */ + void updateContextMenuState(); + +private: + Map* map; + bool mobile_mode; + + bool selection_locked; + bool dragging; + + int current_symbol_index; + int hover_symbol_index; + std::set selected_symbols; + + QPoint last_click_pos; + int last_drop_pos; + int last_drop_row; + + int icon_size; + int icons_per_row; + int num_rows; + QSize preferred_size; + + QMenu* context_menu; + QAction* edit_action; + QAction* scale_action; + QAction* copy_action; + QAction* paste_action; + QAction* switch_symbol_action; + QAction* fill_border_action; + QAction* hide_action; + QAction* protect_action; + QAction* duplicate_action; + QAction* delete_action; + QAction* select_objects_action; + QAction* select_objects_additionally_action; + QAction* deselect_objects_action; + QAction* sort_manual_action; + + SymbolToolTip* tooltip; + + QScopedPointer hidden_symbol_decoration; + QScopedPointer protected_symbol_decoration; +}; + +//### SymbolRenderWidget inline code ### + +inline +int SymbolRenderWidget::selectedSymbolsCount() const +{ + return (int)selected_symbols.size(); +} + +#endif diff --git a/src/gui/widgets/symbol_tooltip.cpp b/src/gui/widgets/symbol_tooltip.cpp new file mode 100644 index 0000000..7c44dc1 --- /dev/null +++ b/src/gui/widgets/symbol_tooltip.cpp @@ -0,0 +1,202 @@ +/* + * Copyright 2012, 2013 Thomas Schöps + * + * This file is part of OpenOrienteering. + * + * OpenOrienteering is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenOrienteering is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenOrienteering. If not, see . + */ + + +#include "symbol_tooltip.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../../symbol.h" + + +SymbolToolTip::SymbolToolTip(QWidget* parent, QShortcut* shortcut) + : QWidget(parent), + shortcut(shortcut), + symbol(NULL), + description_shown(false) +{ + setWindowFlags(Qt::ToolTip | Qt::FramelessWindowHint); + setAttribute(Qt::WA_OpaquePaintEvent); + + QPalette text_palette; + text_palette.setColor(QPalette::Window, text_palette.color(QPalette::Base)); + text_palette.setColor(QPalette::WindowText, text_palette.color(QPalette::Text)); + setPalette(text_palette); + + name_label = new QLabel(); + description_label = new QLabel(); + description_label->setWordWrap(true); + description_label->hide(); + + QVBoxLayout* layout = new QVBoxLayout(); + QStyleOption style_option; + layout->setContentsMargins( + style()->pixelMetric(QStyle::PM_LayoutLeftMargin, &style_option) / 2, + style()->pixelMetric(QStyle::PM_LayoutTopMargin, &style_option) / 2, + style()->pixelMetric(QStyle::PM_LayoutRightMargin, &style_option) / 2, + style()->pixelMetric(QStyle::PM_LayoutBottomMargin, &style_option) / 2 + ); + layout->addWidget(name_label); + layout->addWidget(description_label); + setLayout(layout); + + tooltip_timer.setSingleShot(true); + connect(&tooltip_timer, SIGNAL(timeout()), this, SLOT(show())); + + if (shortcut) + { + shortcut->setEnabled(false); + connect(shortcut, SIGNAL(activated()), this, SLOT(showDescription())); + } +} + +void SymbolToolTip::showDescription() +{ + if (symbol && !description_shown && isVisible()) + { + description_label->show(); + adjustSize(); + adjustPosition(); + description_shown = true; + } + + if (shortcut) + shortcut->setEnabled(false); +} + +void SymbolToolTip::reset() +{ + symbol = NULL; + tooltip_timer.stop(); + hide(); + description_label->hide(); + description_shown = false; + + if (shortcut) + shortcut->setEnabled(false); +} + +void SymbolToolTip::enterEvent(QEvent* event) +{ + Q_UNUSED(event); + hide(); +} + +void SymbolToolTip::paintEvent(QPaintEvent* event) +{ + Q_UNUSED(event); + + QPainter painter(this); + + painter.setBrush(palette().color(QPalette::Window)); + painter.setPen(palette().color(QPalette::WindowText)); + + QRect rect(0, 0, width() - 1, height() - 1); + painter.drawRect(rect); + + painter.end(); +} + +void SymbolToolTip::adjustPosition() +{ + QSize size = this->size(); + QRect desktop = QApplication::desktop()->screenGeometry(QCursor::pos()); + + const int margin = 3; + const bool hasRoomToLeft = (icon_rect.left() - size.width() - margin >= desktop.left()); + const bool hasRoomToRight = (icon_rect.right() + size.width() + margin <= desktop.right()); + const bool hasRoomAbove = (icon_rect.top() - size.height() - margin >= desktop.top()); + const bool hasRoomBelow = (icon_rect.bottom() + size.height() + margin <= desktop.bottom()); + if (!hasRoomAbove && !hasRoomBelow && !hasRoomToLeft && !hasRoomToRight) { + return; + } + + int x = 0; + int y = 0; + + if (hasRoomBelow || hasRoomAbove) { + y = hasRoomBelow ? icon_rect.bottom() + margin : icon_rect.top() - size.height() - margin; + x = qMin(qMax(desktop.left() + margin, icon_rect.center().x() - size.width() / 2), desktop.right() - size.width() - margin); + } else { + Q_ASSERT(hasRoomToLeft || hasRoomToRight); + x = hasRoomToRight ? icon_rect.right() + margin : icon_rect.left() - size.width() - margin; + y = qMin(qMax(desktop.top() + margin, icon_rect.center().y() - size.height() / 2), desktop.bottom() - size.height() - margin); + } + + move(QPoint(x, y)); +} + +void SymbolToolTip::scheduleShow(const Symbol* symbol, QRect icon_rect) +{ + this->icon_rect = icon_rect; + this->symbol = symbol; + + name_label->setText(symbol->getNumberAsString() + QLatin1String(" ") + symbol->getName() + QLatin1String("")); + + QString help_text(symbol->getDescription()); + if (help_text.isEmpty()) + { + help_text = tr("No description!"); + } + else + { + help_text.replace(QLatin1Char('\n'), QStringLiteral("
")); + help_text.remove(QLatin1Char('\r')); + } + description_label->setText(help_text); + description_label->hide(); + description_shown = false; + shortcut->setEnabled(isVisible()); + + adjustSize(); + adjustPosition(); + + static const int delay = 150; + tooltip_timer.start(delay); +} + +void SymbolToolTip::showEvent(QShowEvent* event) +{ + if (shortcut && !description_shown && !event->spontaneous()) + shortcut->setEnabled(true); + + QWidget::showEvent(event); +} + +void SymbolToolTip::hideEvent(QHideEvent* event) +{ + if (!event->spontaneous()) + reset(); + + QWidget::hideEvent(event); +} + +const Symbol* SymbolToolTip::getSymbol() const +{ + return symbol; +} diff --git a/src/gui/widgets/symbol_tooltip.h b/src/gui/widgets/symbol_tooltip.h new file mode 100644 index 0000000..034892d --- /dev/null +++ b/src/gui/widgets/symbol_tooltip.h @@ -0,0 +1,131 @@ +/* + * Copyright 2012, 2013 Thomas Schöps + * + * This file is part of OpenOrienteering. + * + * OpenOrienteering is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenOrienteering is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenOrienteering. If not, see . + */ + + +#ifndef _OPENORIENTEERING_SYMBOL_TOOLTIP_H_ +#define _OPENORIENTEERING_SYMBOL_TOOLTIP_H_ + +#include +#include + +QT_BEGIN_NAMESPACE +class QLabel; +class QShortcut; +QT_END_NAMESPACE + +class Symbol; + + +/** + * @brief A SymbolToolTip displays the name and description of a symbol. + * + * The tooltip is normally not displayed immediately but scheduled to be + * displayed after a short delay, by a call to scheduleShow(). Initially, the + * tooltip displays the symbol's number and name only. The description can be + * made visible by a call to showDescription(). + * + * A QShortcut may be set which will trigger the display of the description + * while the tooltip is already visible. The shortcut does not need to be + * unique: SymbolToolTip enables the shortcut only when the tooltip is visible + * and the description is not yet shown. SymbolToolTip does not take ownership + * of the shortcut. + * + * To permanently hide a SymbolToolTip it is not enough to call hide() because + * the widget may be hidden but scheduled to show up. Call reset() to hide the + * widget and stop the timer if scheduled. + * + * SymbolToolTip does not use the standard tooltip colors but the text editor + * colors. + */ +class SymbolToolTip : public QWidget +{ +Q_OBJECT +public: + /** + * Constructs a new SymbolToolTip. + * The optional shortcut will trigger the description to be shown. + */ + SymbolToolTip(QWidget* parent = NULL, QShortcut* shortcut = NULL); + + /** + * Schedules the tooltip for the symbol to be shown close to + * but not covering the region given by rect. + */ + void scheduleShow(const Symbol* symbol, QRect rect); + + /** + * Resets the tooltip. + * It hides the widget, stops the timer and disables the shortcut. + */ + void reset(); + + /** + * Returns the symbol for which the tooltip is currently shown or + * scheduled to be shown, or NULL. + */ + const Symbol* getSymbol() const; + +public slots: + /** + * Expands the symbol's description in the tooltip. + * Disables the shortcut. + */ + void showDescription(); + +protected: + /** + * Hides the tooltip when the mouse enters it. + * This is neccessary to let the user select another symbol. + */ + virtual void enterEvent(QEvent* event); + + /** + * Enables the shortcut when the tooltip is shown. + */ + virtual void showEvent(QShowEvent* event); + + /** + * Resets the tooltip's state on hiding the tooltip. + * Disables the shortcut. + */ + virtual void hideEvent(QHideEvent* event); + + /** + * Draws the tooltip's background. + */ + virtual void paintEvent(QPaintEvent* event); + +private: + /** + * Moves the tooltip so that it is nicely placed close the region given + * to scheduleShow(). + */ + void adjustPosition(); + + QShortcut* shortcut; /// An optional shortcut for showing the description. + const Symbol* symbol; /// The current symbol, or NULL. + QRect icon_rect; /// The region to be considered when determining position. + bool description_shown; /// If true, the full description is visible. + QLabel* name_label; /// The label displaying the symbol's name. + QLabel* description_label; /// The label displaying the symbol's description. + QTimer tooltip_timer; /// The timer which triggers the delayed showing. + +}; + +#endif diff --git a/src/gui/widgets/symbol_widget.cpp b/src/gui/widgets/symbol_widget.cpp new file mode 100644 index 0000000..0d323f4 --- /dev/null +++ b/src/gui/widgets/symbol_widget.cpp @@ -0,0 +1,82 @@ +/* + * Copyright 2012, 2013 Thomas Schöps + * Copyright 2014 Kai Pastor + * + * This file is part of OpenOrienteering. + * + * OpenOrienteering is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenOrienteering is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenOrienteering. If not, see . + */ + + +#include "symbol_widget.h" + +#include + +#include "symbol_render_widget.h" + + +SymbolWidget::SymbolWidget(Map* map, bool mobile_mode, QWidget* parent) +: QScrollArea(parent) +{ + render_widget = new SymbolRenderWidget(map, mobile_mode, this); + setWidget(render_widget); + + setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded); + setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + setWidgetResizable(true); + setBackgroundRole(QPalette::Base); + + // Relay render_widget signals + connect(render_widget, SIGNAL(selectedSymbolsChanged()), this, SIGNAL(selectedSymbolsChanged())); + connect(render_widget, SIGNAL(fillBorderClicked()), this, SIGNAL(fillBorderClicked())); + connect(render_widget, SIGNAL(switchSymbolClicked()), this, SIGNAL(switchSymbolClicked())); + connect(render_widget, SIGNAL(selectObjectsClicked(bool)), this, SIGNAL(selectObjectsClicked(bool))); + connect(render_widget, SIGNAL(deselectObjectsClicked()), this, SIGNAL(deselectObjectsClicked())); +} + +SymbolWidget::~SymbolWidget() +{ + ; // nothing +} + +const Symbol* SymbolWidget::getSingleSelectedSymbol() const +{ + return static_cast(render_widget)->singleSelectedSymbol(); +} + +Symbol* SymbolWidget::getSingleSelectedSymbol() +{ + return render_widget->singleSelectedSymbol(); +} + +int SymbolWidget::selectedSymbolsCount() const +{ + return render_widget->selectedSymbolsCount(); +} + +bool SymbolWidget::isSymbolSelected(const Symbol* symbol) const +{ + return render_widget->isSymbolSelected(symbol); +} + +void SymbolWidget::selectSingleSymbol(const Symbol* symbol) +{ + render_widget->selectSingleSymbol(symbol); +} + +void SymbolWidget::contextMenuEvent(QContextMenuEvent* event) +{ + render_widget->showContextMenu(event->globalPos()); + event->accept(); +} diff --git a/src/gui/widgets/symbol_widget.h b/src/gui/widgets/symbol_widget.h new file mode 100644 index 0000000..58eaeba --- /dev/null +++ b/src/gui/widgets/symbol_widget.h @@ -0,0 +1,126 @@ +/* + * Copyright 2012, 2013 Thomas Schöps + * Copyright 2014 Kai Pastor + * + * This file is part of OpenOrienteering. + * + * OpenOrienteering is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenOrienteering is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenOrienteering. If not, see . + */ + + +#ifndef _OPENORIENTEERING_SYMBOL_WIDGET_H_ +#define _OPENORIENTEERING_SYMBOL_WIDGET_H_ + +#include + +class Map; +class Symbol; +class SymbolRenderWidget; + +/** + * @brief Shows all symbols from a map in a scrollable widget. + * + * SymbolWidget shows all symbols from a map's symbol set. + * It lets the user select symbols and perform actions on symbols. + * + * The implementation is based on SymbolRenderWidget and QScrollArea. + * Normally it is used inside a dock widget. + */ +class SymbolWidget : public QScrollArea +{ +Q_OBJECT +public: + /** + * @brief Constructs a new SymbolWidget. + * @param map The map which provides the symbols. Must not be NULL. + * @param mobile_mode If true, enables a special mode for mobile devices. + * @param parent The parent QWidget. + */ + SymbolWidget(Map* map, bool mobile_mode, QWidget* parent = NULL); + + /** + * @brief Destroys the SymbolWidget. + */ + virtual ~SymbolWidget(); + + /** + * @brief If exactly one symbol is selected, returns this symbol. + * + * Otherwise returns NULL. + */ + const Symbol* getSingleSelectedSymbol() const; + + /** + * @brief If exactly one symbol is selected, returns this symbol. + * + * Otherwise returns NULL. + */ + Symbol* getSingleSelectedSymbol(); + + /** + * @brief Returns the number of selected symbols. + */ + int selectedSymbolsCount() const; + + /** + * @brief Checks if the symbol is selected. + */ + bool isSymbolSelected(const Symbol* symbol) const; + + /** + * @brief Selects the symbol exclusively, deselecting all other symbols. + */ + void selectSingleSymbol(const Symbol* symbol); + +signals: + /** + * @brief The collection of selected symbols changed. + */ + void selectedSymbolsChanged(); + + /** + * @brief The user triggered "Switch symbol". + * @todo Merge with/Reuse corresponding action in MapEditorController. + */ + void switchSymbolClicked(); + + /** + * @brief The user triggered "Fill/Create border". + * @todo Merge with/Reuse corresponding action in MapEditorController. + */ + void fillBorderClicked(); + + /** + * @brief The user triggered selecting objects with the active symbol. + * @param select_exclusively If true, an existing selection is replaced, + * otherwise it is extend. + */ + void selectObjectsClicked(bool select_exclusively); + + /** + * @brief The user triggered deselecting objects with the active symbol. + */ + void deselectObjectsClicked(); + +protected: + /** + * @brief Receives context menu events and opens the context menu. + */ + virtual void contextMenuEvent(QContextMenuEvent* event); + +private: + SymbolRenderWidget* render_widget; +}; + +#endif diff --git a/src/gui/widgets/tag_select_widget.cpp b/src/gui/widgets/tag_select_widget.cpp new file mode 100644 index 0000000..bdf2380 --- /dev/null +++ b/src/gui/widgets/tag_select_widget.cpp @@ -0,0 +1,419 @@ +/* + * Copyright 2016 Mitchell Krome + * + * This file is part of OpenOrienteering. + * + * OpenOrienteering is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenOrienteering is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenOrienteering. If not, see . + */ + + +#include "tag_select_widget.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "segmented_button_layout.h" +#include "../main_window.h" +#include "../../map.h" +#include "../../map_editor.h" +#include "../../map_part.h" +#include "../../object.h" +#include "../../object_query.h" +#include "../../tool.h" +#include "../../util.h" + + +// ### TagSelectWidget ### + +TagSelectWidget::TagSelectWidget(Map* map, MapView* main_view, MapEditorController* controller, QWidget* parent) +: QWidget { parent } +, map { map } +, main_view { main_view } +, controller { controller } +{ + Q_ASSERT(main_view); + Q_ASSERT(controller); + + setWhatsThis(Util::makeWhatThis("tag_selector.html")); + + query_table = new QTableWidget(1, 4); + query_table->setEditTriggers(QAbstractItemView::AllEditTriggers); + query_table->setSelectionBehavior(QAbstractItemView::SelectRows); + query_table->setSelectionMode(QAbstractItemView::SingleSelection); + query_table->setHorizontalHeaderLabels(QStringList() << tr("Relation") << tr("Key") << tr("Comparison") << tr("Value")); + query_table->verticalHeader()->setVisible(false); + + QHeaderView* header_view = query_table->horizontalHeader(); + header_view->setSectionResizeMode(0, QHeaderView::Fixed); + header_view->setSectionResizeMode(1, QHeaderView::Stretch); + header_view->setSectionResizeMode(2, QHeaderView::Fixed); + header_view->setSectionResizeMode(3, QHeaderView::Stretch); + header_view->setSectionsClickable(false); + + all_query_layout = new QVBoxLayout(); + all_query_layout->setMargin(0); + all_query_layout->addWidget(query_table, 1); + + addRowItems(0); + + add_button = newToolButton(QIcon(QString::fromLatin1(":/images/plus.png")), tr("Add Row")); + delete_button = newToolButton(QIcon(QString::fromLatin1(":/images/minus.png")), tr("Remove Row")); + + SegmentedButtonLayout* add_remove_layout = new SegmentedButtonLayout(); + add_remove_layout->addWidget(add_button); + add_remove_layout->addWidget(delete_button); + + move_up_button = newToolButton(QIcon(QString::fromLatin1(":/images/arrow-up.png")), tr("Move Up")); + move_up_button->setAutoRepeat(true); + move_down_button = newToolButton(QIcon(QString::fromLatin1(":/images/arrow-down.png")), tr("Move Down")); + move_down_button->setAutoRepeat(true); + + SegmentedButtonLayout* up_down_layout = new SegmentedButtonLayout(); + up_down_layout->addWidget(move_up_button); + up_down_layout->addWidget(move_down_button); + + select_button = newToolButton(QIcon(QString::fromLatin1(":/images/tool-edit.png")), tr("Select")); + select_button->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); + + selection_info = new QLabel(); + + QToolButton* help_button = newToolButton(QIcon(QString::fromLatin1(":/images/help.png")), tr("Help")); + help_button->setAutoRaise(true); + + QBoxLayout* list_buttons_layout = new QHBoxLayout(); + list_buttons_layout->setContentsMargins(0,0,0,0); + list_buttons_layout->addLayout(add_remove_layout); + list_buttons_layout->addLayout(up_down_layout); + list_buttons_layout->addWidget(select_button); + list_buttons_layout->addWidget(selection_info); + + list_buttons_group = new QWidget(); + list_buttons_group->setLayout(list_buttons_layout); + + QBoxLayout* all_buttons_layout = new QHBoxLayout(); + QStyleOption style_option(QStyleOption::Version, QStyleOption::SO_DockWidget); + all_buttons_layout->setContentsMargins( + style()->pixelMetric(QStyle::PM_LayoutLeftMargin, &style_option) / 2, + 0, // Covered by the main layout's spacing. + style()->pixelMetric(QStyle::PM_LayoutRightMargin, &style_option) / 2, + style()->pixelMetric(QStyle::PM_LayoutBottomMargin, &style_option) / 2 + ); + all_buttons_layout->addWidget(list_buttons_group); + all_buttons_layout->addWidget(new QLabel(QString::fromLatin1(" ")), 1); + all_buttons_layout->addWidget(help_button); + + all_query_layout->addLayout(all_buttons_layout); + + setLayout(all_query_layout); + + // Connections + connect(add_button, &QAbstractButton::clicked, this, &TagSelectWidget::addRow); + connect(delete_button, &QAbstractButton::clicked, this, &TagSelectWidget::deleteRow); + connect(move_up_button, &QAbstractButton::clicked, this, [this]{ moveRow(true); }); + connect(move_down_button, &QAbstractButton::clicked, this, [this]{ moveRow(false); }); + connect(select_button, &QAbstractButton::clicked, this, &TagSelectWidget::makeSelection); + connect(help_button, &QAbstractButton::clicked, this, &TagSelectWidget::showHelp); + + connect(query_table, &QTableWidget::cellChanged, this, &TagSelectWidget::cellChanged); + connect(map, &Map::objectSelectionChanged, this, &TagSelectWidget::resetSelectionInfo); +} + + +TagSelectWidget::~TagSelectWidget() +{ + ; // Nothing +} + + + +void TagSelectWidget::resetSelectionInfo() +{ + selection_info->setText({}); +} + + + +QToolButton* TagSelectWidget::newToolButton(const QIcon& icon, const QString& text) +{ + QToolButton* button = new QToolButton(); + button->setToolButtonStyle(Qt::ToolButtonIconOnly); + button->setToolTip(text); + button->setIcon(icon); + button->setText(text); + button->setWhatsThis(Util::makeWhatThis("tag_selector.html")); + return button; +} + + + +void TagSelectWidget::showEvent(QShowEvent* event) +{ + if (!event->spontaneous()) + { + auto last_row = query_table->rowCount() - 1; + query_table->setCurrentCell(last_row, 1); + if (!query_table->currentItem()->text().isEmpty()) + query_table->setCurrentCell(last_row, 3); + query_table->editItem(query_table->currentItem()); + } +} + + + +void TagSelectWidget::showHelp() +{ + Util::showHelp(controller->getWindow(), "tag_selector.html"); +} + + + +void TagSelectWidget::addRowItems(int row) +{ + QTableWidgetItem* item = new QTableWidgetItem(); + query_table->setItem(row, 1, item); + item = new QTableWidgetItem(); + query_table->setItem(row, 3, item); + + QComboBox* compare_op = new QComboBox(); + for (auto op : { ObjectQuery::OperatorIs, ObjectQuery::OperatorIsNot, ObjectQuery::OperatorContains }) + compare_op->addItem(ObjectQuery::labelFor(op), QVariant::fromValue(op)); + query_table->setCellWidget(row, 2, compare_op); + connect(compare_op, &QComboBox::currentTextChanged, this, &TagSelectWidget::resetSelectionInfo); + + if (row == 0) + { + // The first row doesn't use a logical operator + item = new QTableWidgetItem(); + item->setFlags(Qt::NoItemFlags); + item->setBackground(QBrush(QGuiApplication::palette().window())); + query_table->setItem(row, 0, item); + } + else + { + QComboBox* logical_op = new QComboBox(); + auto and_label = QString { QLatin1String(" ") + ObjectQuery::labelFor(ObjectQuery::OperatorAnd) }; + logical_op->addItem(and_label, QVariant::fromValue(ObjectQuery::OperatorAnd)); + logical_op->addItem(ObjectQuery::labelFor(ObjectQuery::OperatorOr), QVariant::fromValue(ObjectQuery::OperatorOr)); + query_table->setCellWidget(row, 0, logical_op); + connect(logical_op, &QComboBox::currentTextChanged, this, &TagSelectWidget::resetSelectionInfo); + } +} + + + +void TagSelectWidget::cellChanged(int row, int column) +{ + resetSelectionInfo(); + switch(column) + { + case 1: + case 3: + { + auto item = query_table->item(row, column); + item->setText(item->text().trimmed()); + break; + } + default: + ; // nothing + } +} + + + +void TagSelectWidget::addRow() +{ + int row = query_table->currentRow() + 1; + + // When nothing is selected, add to the end + if (row == 0) + row = query_table->rowCount(); + + query_table->insertRow(row); + addRowItems(row); + + // Move the selection to the new row + int col = query_table->currentColumn(); + query_table->setCurrentCell(row, col); +} + + +void TagSelectWidget::deleteRow() +{ + // Always need one row + if (query_table->rowCount() == 1) + return; + + int row = query_table->currentRow(); + + // When nothing is selected, delete from the end + if (row == -1) + row = query_table->rowCount() - 1; + + query_table->removeRow(row); + + // If we delete first row, need to fix logical operator + if (row == 0) + { + query_table->removeCellWidget(row, 0); + QTableWidgetItem* item = new QTableWidgetItem(); + item->setFlags(Qt::NoItemFlags); + item->setBackground(QBrush(QGuiApplication::palette().window())); + query_table->setItem(row, 0, item); + } +} + + +void TagSelectWidget::moveRow(bool up) +{ + int row = query_table->currentRow(); + int max_row = query_table->rowCount(); + + // When nothing is selected, move the last row + if (row == -1) + row = max_row - 1; + + // Cant move first row up or last row down + if ((up && row < 1) || (!up && row == max_row - 1)) + return; + + // Moving the current row down is just moving the row below up.. + if (!up) + row += 1; + + // Col 1, 3 are items + auto top_item = query_table->takeItem(row - 1, 1); + auto bottom_item = query_table->takeItem(row, 1); + query_table->setItem(row, 1, top_item); + query_table->setItem(row - 1, 1, bottom_item); + top_item = query_table->takeItem(row - 1, 3); + bottom_item = query_table->takeItem(row, 3); + query_table->setItem(row, 3, top_item); + query_table->setItem(row - 1, 3, bottom_item); + + // Col 2 is comparison combobox + auto top_combo = qobject_cast(query_table->cellWidget(row - 1, 2)); + auto bottom_combo = qobject_cast(query_table->cellWidget(row, 2)); + auto top_selection = top_combo->currentIndex(); + auto bottom_selection = bottom_combo->currentIndex(); + top_combo->setCurrentIndex(bottom_selection); + bottom_combo->setCurrentIndex(top_selection); + + // Ignore the swap on the first row because there is nothing to swap + if (row - 1 != 0 ) + { + // Col 0 is relation combobox + top_combo = qobject_cast(query_table->cellWidget(row - 1, 0)); + bottom_combo = qobject_cast(query_table->cellWidget(row, 0)); + top_selection = top_combo->currentIndex(); + bottom_selection = bottom_combo->currentIndex(); + top_combo->setCurrentIndex(bottom_selection); + bottom_combo->setCurrentIndex(top_selection); + } + + // Keep the moved row selected + int col = query_table->currentColumn(); + // For the down case we already adjusted the row + if (up) + row -= 1; + query_table->setCurrentCell(row, col); +} + + + +void TagSelectWidget::makeSelection() +{ + query_table->setCurrentItem(nullptr); + if (auto query = makeQuery()) + { + query.selectMatchingObjects(map, controller); + selection_info->setText(tr("%n object(s) selected", nullptr, map->getNumSelectedObjects())); + } + else + { + selection_info->setText(tr("Invalid query")); + } +} + + + +ObjectQuery TagSelectWidget::makeQuery() const +{ + // If there is at least one OR, query will become an OR expression. + ObjectQuery query; + // AND has precedence over OR, so its terms are collected separately. + ObjectQuery and_expression; + + int rowCount = query_table->rowCount(); + for (int row = 0; row < rowCount; ++row) + { + auto key = query_table->item(row, 1)->text(); + auto compare_op = qobject_cast(query_table->cellWidget(row, 2))->currentData().value(); + auto value = query_table->item(row, 3)->text(); + + auto comparison = ObjectQuery(key, compare_op, value); + if (row == 0) + { + // The first term at all + and_expression = std::move(comparison); + } + else + { + auto logical_op = qobject_cast(query_table->cellWidget(row, 0))->currentData().value(); + if (logical_op == ObjectQuery::OperatorAnd) + { + // Add another term to the AND expression + and_expression = ObjectQuery(std::move(comparison), ObjectQuery::OperatorAnd, std::move(and_expression)); + } + else if (logical_op == ObjectQuery::OperatorOr) + { + if (query) + // Add another term to the OR expression + query = ObjectQuery(std::move(and_expression), ObjectQuery::OperatorOr, std::move(query)); + else + // The first term of an OR expression + query = std::move(and_expression); + + // The first term of the next AND expression + and_expression = std::move(comparison); + } + else + { + Q_UNREACHABLE(); + } + } + + // The validness of and_expression is determined by the current line. + if (!and_expression) + break; + } + + if (query && and_expression) + { + // Add the last AND expression to the OR expression + query = ObjectQuery(std::move(and_expression), ObjectQuery::OperatorOr, std::move(query)); + } + else + { + // There was no OR, or the last visited row was not a valid expression. + query = std::move(and_expression); + } + + return query; +} diff --git a/src/gui/widgets/tag_select_widget.h b/src/gui/widgets/tag_select_widget.h new file mode 100644 index 0000000..21165d1 --- /dev/null +++ b/src/gui/widgets/tag_select_widget.h @@ -0,0 +1,91 @@ +/* + * Copyright 2016 Mitchell Krome + * + * This file is part of OpenOrienteering. + * + * OpenOrienteering is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenOrienteering is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenOrienteering. If not, see . + */ + + +#ifndef OPENORIENTEERING_TAG_SELECT_WIDGET_H +#define OPENORIENTEERING_TAG_SELECT_WIDGET_H + +#include + +class QBoxLayout; +class QLabel; +class QTableWidget; +class QToolButton; + +class Map; +class MapEditorController; +class MapView; +class Object; +class ObjectQuery; + +/** + * This widget allows the user to make selections based on an objects tags. + */ +class TagSelectWidget : public QWidget +{ +Q_OBJECT +public: + TagSelectWidget(Map* map, MapView* main_view, MapEditorController* controller, QWidget* parent = nullptr); + ~TagSelectWidget() override; + + void resetSelectionInfo(); + +protected: + /** + * Returns a new QToolButton with a unified appearance. + */ + QToolButton* newToolButton(const QIcon& icon, const QString& text); + + void showEvent(QShowEvent* event) override; + + void showHelp(); + void addRow(); + void deleteRow(); + void moveRow(bool up); + void makeSelection(); + +private: + void addRowItems(int row); + void cellChanged(int row, int column); + + /** + * Builds a query based on the current state of the query table. + * + * Returns an invalid query on error. + */ + ObjectQuery makeQuery() const; + + Map* map; + MapView* main_view; + MapEditorController* controller; + + QTableWidget* query_table; + QBoxLayout* all_query_layout; + + // Buttons + QWidget* list_buttons_group; + QToolButton* add_button; + QToolButton* delete_button; + QToolButton* move_up_button; + QToolButton* move_down_button; + QToolButton* select_button; + QLabel* selection_info; +}; + +#endif diff --git a/src/gui/widgets/tags_widget.cpp b/src/gui/widgets/tags_widget.cpp new file mode 100644 index 0000000..661a791 --- /dev/null +++ b/src/gui/widgets/tags_widget.cpp @@ -0,0 +1,266 @@ +/* + * Copyright 2013, 2014 Kai Pastor + * + * This file is part of OpenOrienteering. + * + * OpenOrienteering is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenOrienteering is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenOrienteering. If not, see . + */ + + +#include "tags_widget.h" + +#include +#include +#include +#include +#include +#include + +#include "../main_window.h" +#include "../../map.h" +#include "../../map_editor.h" +#include "../../object_undo.h" +#include "../../object.h" +#include "../../util.h" + + +TagsWidget::TagsWidget(Map* map, MapView* main_view, MapEditorController* controller, QWidget* parent) + : QWidget(parent), + map(map), + main_view(main_view), + controller(controller) +{ + react_to_changes = false; + + QBoxLayout* layout = new QVBoxLayout(); + layout->setMargin(0); + + tags_table = new QTableWidget(1, 2); + tags_table->setEditTriggers(QAbstractItemView::AllEditTriggers); + tags_table->setSelectionBehavior(QAbstractItemView::SelectRows); + tags_table->setSelectionMode(QAbstractItemView::SingleSelection); + tags_table->setHorizontalHeaderLabels(QStringList() << tr("Key") << tr("Value")); + tags_table->verticalHeader()->setVisible(false); + + QHeaderView* header_view = tags_table->horizontalHeader(); + header_view->setSectionResizeMode(0, QHeaderView::Stretch); + header_view->setSectionResizeMode(1, QHeaderView::Stretch); + header_view->setSectionsClickable(false); + + layout->addWidget(tags_table); + + QToolButton* help_button = newToolButton(QIcon(QString::fromLatin1(":/images/help.png")), tr("Help")); + help_button->setAutoRaise(true); + + QBoxLayout* all_buttons_layout = new QHBoxLayout(); + QStyleOption style_option(QStyleOption::Version, QStyleOption::SO_DockWidget); + all_buttons_layout->setContentsMargins( + style()->pixelMetric(QStyle::PM_LayoutLeftMargin, &style_option) / 2, + style()->pixelMetric(QStyle::PM_LayoutLeftMargin, &style_option) / 2, + style()->pixelMetric(QStyle::PM_LayoutRightMargin, &style_option) / 2, + style()->pixelMetric(QStyle::PM_LayoutBottomMargin, &style_option) / 2 + ); + all_buttons_layout->addWidget(new QLabel(QString::fromLatin1(" ")), 1); + all_buttons_layout->addWidget(help_button); + + layout->addLayout(all_buttons_layout); + + setLayout(layout); + + connect(tags_table, SIGNAL(cellChanged(int,int)), this, SLOT(cellChange(int,int))); + + connect(map, SIGNAL(objectSelectionChanged()), this, SLOT(objectTagsChanged())); + connect(map, SIGNAL(selectedObjectEdited()), this, SLOT(objectTagsChanged())); + + react_to_changes = true; + objectTagsChanged(); +} + +TagsWidget::~TagsWidget() +{ + ; // Nothing +} + +QToolButton* TagsWidget::newToolButton(const QIcon& icon, const QString& text) +{ + QToolButton* button = new QToolButton(); + button->setToolButtonStyle(Qt::ToolButtonIconOnly); + button->setToolTip(text); + button->setIcon(icon); + button->setText(text); + button->setWhatsThis(Util::makeWhatThis("templates.html#setup")); + return button; +} + +// slot +void TagsWidget::showHelp() +{ + Util::showHelp(controller->getWindow(), "tag_editor.html"); +} + +void TagsWidget::setupLastRow() +{ + const int row = tags_table->rowCount() - 1; + tags_table->setItem(row, 0, new QTableWidgetItem()); + QTableWidgetItem* value_item = new QTableWidgetItem(); + value_item->setFlags(value_item->flags() & ~Qt::ItemIsEnabled); + tags_table->setItem(row, 1, value_item); +} + +void TagsWidget::createUndoStep(Object* object) +{ + Q_ASSERT(object); + + ObjectTagsUndoStep* undo_step = new ObjectTagsUndoStep(map); + undo_step->addObject(map->getCurrentPart()->findObjectIndex(object)); + map->push(undo_step); +} + +// slot +void TagsWidget::objectTagsChanged() +{ + if (!react_to_changes) + return; + + react_to_changes = false; + + int row = 0; + const Object* object = map->getFirstSelectedObject(); + if (object) + { + const Object::Tags& tags = object->tags(); + tags_table->clearContents(); + tags_table->setRowCount(tags.size() + 1); + for (Object::Tags::const_iterator tag = tags.constBegin(), end = tags.constEnd(); tag != end; ++tag) + { + tags_table->setItem(row, 0, new QTableWidgetItem(tag.key())); + tags_table->item(row, 0)->setData(Qt::UserRole, tag.key()); + tags_table->setItem(row, 1, new QTableWidgetItem(tag.value())); + ++row; + } + tags_table->sortItems(0); + setupLastRow(); + } + else + { + tags_table->setRowCount(0); + } + + react_to_changes = true; +} + +// slot +void TagsWidget::cellChange(int row, int column) +{ + Object* object = map->getFirstSelectedObject(); + if (!react_to_changes || !object) + return; + + react_to_changes = false; + const QString key = tags_table->item(row, 0)->text().trimmed(); + const QString value = tags_table->item(row, 1)->text(); + + if (column == 1 && key.isEmpty()) + { + // Shall not happen + qWarning("Empty key for modified tag value!"); + } + else if (column == 1) + { + // Value edited: update the tag + createUndoStep(object); + object->setTag(key, value); + if (row + 1 == tags_table->rowCount()) + { + // Append new row, jump to key + tags_table->setRowCount(row + 2); + setupLastRow(); + } + + if (!tags_table->item(row + 1, 1)->flags().testFlag(Qt::ItemIsEnabled)) + { + // Jump to key + tags_table->setCurrentCell(row + 1, 0); + } + else + { + // Jump to value + tags_table->setCurrentCell(row + 1, 1); + } + } + else if (column == 0) + { + const QString old_key = tags_table->item(row, 0)->data(Qt::UserRole).toString(); + if (old_key == key && !key.isEmpty()) + { + // Key edited but not changed: do nothing + } + else if (!old_key.isEmpty() && key.isEmpty()) + { + // Key deleted: remove tag + createUndoStep(object); + object->removeTag(old_key); + tags_table->removeRow(row); + if (row > 0) + { + // Jump to previous row + tags_table->setCurrentCell(row - 1, 1); + } + else + { + // Reset current row + tags_table->item(row, 1)->setText({}); + QTableWidgetItem* value_item = tags_table->item(row, 1); + value_item->setFlags(value_item->flags() & ~Qt::ItemIsEnabled); + } + } + else if (!key.isEmpty()) + { + // Key edited: update the tags + if (object->tags().contains(key)) + { + QMessageBox::critical(window(), tr("Key exists"), + tr("The key \"%1\" already exists and must not be used twice.").arg(key) + ); + tags_table->item(row, column)->setText(old_key); + tags_table->setCurrentCell(row, column); + } + else + { + if (value.isEmpty() && old_key.isEmpty()) + { + // New key, empty value - dont insert yet + tags_table->item(row, 0)->setData(Qt::UserRole, QLatin1String("ABOUT TO INSERT NEW VALUE")); + tags_table->setCurrentCell(row, 1); + } + else + { + // New key with value - update tags + createUndoStep(object); + object->removeTag(old_key); + object->setTag(key, value); + } + tags_table->item(row, 0)->setData(Qt::UserRole, key); + if (tags_table->rowCount() == row + 1) + { + QTableWidgetItem* value_item = tags_table->item(row, 1); + value_item->setFlags(value_item->flags() | Qt::ItemIsEnabled); + } + tags_table->setCurrentCell(row, 1); + } + } + } + + react_to_changes = true; +} diff --git a/src/gui/widgets/tags_widget.h b/src/gui/widgets/tags_widget.h new file mode 100644 index 0000000..8e55c0b --- /dev/null +++ b/src/gui/widgets/tags_widget.h @@ -0,0 +1,95 @@ +/* + * Copyright 2013 Kai Pastor + * + * This file is part of OpenOrienteering. + * + * OpenOrienteering is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenOrienteering is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenOrienteering. If not, see . + */ + + +#ifndef OPENORIENTEERING_TAGS_WIDGET_H +#define OPENORIENTEERING_TAGS_WIDGET_H + +#include + +class QTableWidget; +class QToolButton; + +class Map; +class MapEditorController; +class MapView; +class Object; + + +/** + * This widget allows for display and editing of tags, i.e. key-value pairs. + */ +class TagsWidget : public QWidget +{ +Q_OBJECT +public: + /** Constructs a new tags widget for the given map. */ + explicit TagsWidget(Map* map, MapView* main_view, MapEditorController* controller, QWidget* parent = NULL); + + /** Destroys the widget. */ + virtual ~TagsWidget(); + +protected slots: + /** + * Updates the widget from the current object's tags. + * + * Does nothing if react_to_changes is set to false. + */ + void objectTagsChanged(); + + /** + * Updates the current object's tags from the widget. + * + * Does nothing if react_to_changes is set to false. + */ + void cellChange(int row, int column); + + /** + * Opens the help page for this widget. + */ + void showHelp(); + +protected: + /** + * Returns a new QToolButton with a unified appearance. + */ + QToolButton* newToolButton(const QIcon& icon, const QString& text); + + /** + * Sets up the last row: blank cells, right one not editable. + */ + void setupLastRow(); + + /** + * Creates and registers an undo step for the given object. + * + * @param object must not be null. + */ + void createUndoStep(Object* object); + +private: + Map* map; + MapView* main_view; + MapEditorController* controller; + bool react_to_changes; + + QTableWidget* tags_table; +}; + +#endif // TAGS_WIDGET_H diff --git a/src/gui/widgets/template_list_widget.cpp b/src/gui/widgets/template_list_widget.cpp new file mode 100644 index 0000000..446b357 --- /dev/null +++ b/src/gui/widgets/template_list_widget.cpp @@ -0,0 +1,1313 @@ +/* + * Copyright 2012, 2013 Thomas Schöps + * Copyright 2012-2016 Kai Pastor + * + * This file is part of OpenOrienteering. + * + * OpenOrienteering is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenOrienteering is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenOrienteering. If not, see . + */ + + +#include "template_list_widget.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "segmented_button_layout.h" +#include "../main_window.h" +#include "../../core/georeferencing.h" +#include "../../map.h" +#include "../../map_editor.h" +#include "../../map_widget.h" +#include "../../object.h" +#include "../../settings.h" +#include "../../template.h" +#include "../../template_adjust.h" +#include "../../template_map.h" +#include "../../template_position_dock_widget.h" +#include "../../template_tool_move.h" +#include "../../util.h" +#include "../../util/item_delegates.h" +#include "../../util/scoped_signals_blocker.h" + + +// ### ApplyTemplateTransform ### + +/** + * A local functor which is used when importing map templates into the current map. + */ +struct ApplyTemplateTransform +{ + constexpr ApplyTemplateTransform(const TemplateTransform& transform) + : transform(transform) + { + // nothing else + } + + inline bool operator()(Object* object, MapPart* part, int object_index) const + { + Q_UNUSED(part); + Q_UNUSED(object_index); + object->rotate(transform.template_rotation); + object->scale(transform.template_scale_x, transform.template_scale_y); + object->move(transform.template_x, transform.template_y); + object->update(); + return true; + } +private: + const TemplateTransform& transform; +}; + + + +// ### TemplateListWidget ### + +// Template grouping implementation is incomplete +#define NO_TEMPLATE_GROUP_SUPPORT + +TemplateListWidget::TemplateListWidget(Map* map, MapView* main_view, MapEditorController* controller, QWidget* parent) +: QWidget(parent) +, map(map) +, main_view(main_view) +, controller(controller) +, mobile_mode(controller->isInMobileMode()) +, name_column(3) +{ + Q_ASSERT(main_view); + Q_ASSERT(controller); + + setWhatsThis(Util::makeWhatThis("templates.html#setup")); + + QStyleOption style_option(QStyleOption::Version, QStyleOption::SO_DockWidget); + + // Wrap the checkbox in a widget and layout to force a margin. + QWidget* top_bar_widget = new QWidget(); + QLayout* top_bar_layout = new QHBoxLayout(top_bar_widget); + + // Reuse the translation from MapEditorController action. + all_hidden_check = new QCheckBox(MapEditorController::tr("Hide all templates")); + top_bar_layout->addWidget(all_hidden_check); + + if (mobile_mode) + { + auto close_action = new QAction(QIcon(QString::fromLatin1(":/images/close.png")), MainWindow::tr("Close"), this); + connect(close_action, &QAction::triggered, this, &TemplateListWidget::closeClicked ); + + auto close_button = new QToolButton(); + close_button->setDefaultAction(close_action); + close_button->setAutoRaise(true); + + top_bar_layout->addWidget(close_button); + } + + top_bar_layout->setContentsMargins( + style()->pixelMetric(QStyle::PM_LayoutLeftMargin, &style_option) / 2, + style()->pixelMetric(QStyle::PM_LayoutTopMargin, &style_option) / 2, + style()->pixelMetric(QStyle::PM_LayoutRightMargin, &style_option) / 2, + 0 // Covered by the main layout's spacing. + ); + + // Template table + template_table = new QTableWidget(map->getNumTemplates() + 1, 4); + QScroller::grabGesture(template_table->viewport(), QScroller::TouchGesture); + template_table->installEventFilter(this); + template_table->setEditTriggers(QAbstractItemView::AllEditTriggers); + template_table->setSelectionBehavior(QAbstractItemView::SelectRows); + template_table->setSelectionMode(QAbstractItemView::SingleSelection); + template_table->verticalHeader()->setVisible(false); +#ifdef NO_TEMPLATE_GROUP_SUPPORT + // Template grouping is not yet implemented. + template_table->hideColumn(2); +#endif + + QHeaderView* header_view = template_table->horizontalHeader(); + if (mobile_mode) + { + header_view->setVisible(false); + template_table->setShowGrid(false); + template_table->hideColumn(3); + name_column = 0; + } + else + { + template_table->setHorizontalHeaderLabels(QStringList() << QString{} << tr("Opacity") << tr("Group") << tr("Filename")); + template_table->horizontalHeaderItem(0)->setData(Qt::ToolTipRole, tr("Show")); + + header_view->setSectionResizeMode(0, QHeaderView::Fixed); + + QStyleOptionButton option; + auto geometry = style()->subElementRect(QStyle::SE_ItemViewItemCheckIndicator, &option, nullptr); + template_table->setColumnWidth(0, geometry.width() * 14 / 10); + + auto header_check_size = geometry.size(); + if (header_check_size.isValid()) + { + QCheckBox header_check; + header_check.setChecked(true); + header_check.setEnabled(false); + QPixmap pixmap(header_check_size); + pixmap.fill(Qt::transparent); + QPainter painter(&pixmap); + QStyleOptionViewItem option; + option.rect = { {0, 0}, geometry.size() }; + style()->drawPrimitive(QStyle::PE_IndicatorViewItemCheck, &option, &painter, nullptr); + painter.end(); + template_table->horizontalHeaderItem(0)->setData(Qt::DecorationRole, pixmap); + } + } + + auto percentage_delegate = new PercentageDelegate(this, 5); + template_table->setItemDelegateForColumn(1, percentage_delegate); + + for (int i = 1; i < 3; ++i) + header_view->setSectionResizeMode(i, QHeaderView::ResizeToContents); + header_view->setSectionResizeMode(name_column, QHeaderView::Stretch); + header_view->setSectionsClickable(false); + + for (int i = 0; i < map->getNumTemplates() + 1; ++i) + addRowItems(i); + + all_templates_layout = new QVBoxLayout(); + all_templates_layout->setMargin(0); + all_templates_layout->addWidget(top_bar_widget); + all_templates_layout->addWidget(template_table, 1); + + QMenu* new_button_menu = new QMenu(this); + if (!mobile_mode) + { + new_button_menu->addAction(QIcon(QString::fromLatin1(":/images/open.png")), tr("Open..."), this, SLOT(openTemplate())); + new_button_menu->addAction(controller->getAction("reopentemplate")); + } + duplicate_action = new_button_menu->addAction(QIcon(QString::fromLatin1(":/images/tool-duplicate.png")), tr("Duplicate"), this, SLOT(duplicateTemplate())); +#if 0 + current_action = new_button_menu->addAction(tr("Sketch")); + current_action->setDisabled(true); + current_action = new_button_menu->addAction(tr("GPS")); + current_action->setDisabled(true); +#endif + + QToolButton* new_button = newToolButton(QIcon(QString::fromLatin1(":/images/plus.png")), tr("Add template...")); + new_button->setPopupMode(QToolButton::InstantPopup); + new_button->setMenu(new_button_menu); + + delete_button = newToolButton(QIcon(QString::fromLatin1(":/images/minus.png")), (tr("Remove"), tr("Close"))); /// \todo Use "Remove instead of "Close" + + SegmentedButtonLayout* add_remove_layout = new SegmentedButtonLayout(); + add_remove_layout->addWidget(new_button); + add_remove_layout->addWidget(delete_button); + + move_up_button = newToolButton(QIcon(QString::fromLatin1(":/images/arrow-up.png")), tr("Move Up")); + move_up_button->setAutoRepeat(true); + move_down_button = newToolButton(QIcon(QString::fromLatin1(":/images/arrow-down.png")), tr("Move Down")); + move_down_button->setAutoRepeat(true); + + SegmentedButtonLayout* up_down_layout = new SegmentedButtonLayout(); + up_down_layout->addWidget(move_up_button); + up_down_layout->addWidget(move_down_button); + + // TODO: Fix string + georef_button = newToolButton(QIcon(QString::fromLatin1(":/images/grid.png")), tr("Georeferenced: %1").remove(QLatin1String(": %1"))); + georef_button->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); + georef_button->setCheckable(true); + georef_button->setChecked(true); + georef_button->setEnabled(false); // TODO + move_by_hand_action = new QAction(QIcon(QString::fromLatin1(":/images/move.png")), tr("Move by hand"), this); + move_by_hand_action->setCheckable(true); + move_by_hand_button = newToolButton(move_by_hand_action->icon(), move_by_hand_action->text()); + move_by_hand_button->setDefaultAction(move_by_hand_action); + adjust_button = newToolButton(QIcon(QString::fromLatin1(":/images/georeferencing.png")), tr("Adjust...")); + adjust_button->setCheckable(true); + + QMenu* edit_menu = new QMenu(this); + position_action = edit_menu->addAction(tr("Positioning...")); + position_action->setCheckable(true); + import_action = edit_menu->addAction(tr("Import and remove"), this, SLOT(importClicked())); + + edit_button = newToolButton(QIcon(QString::fromLatin1(":/images/settings.png")), MapEditorController::tr("&Edit").remove(QLatin1Char('&'))); + edit_button->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); + edit_button->setPopupMode(QToolButton::InstantPopup); + edit_button->setMenu(edit_menu); + + // The buttons row layout + QBoxLayout* list_buttons_layout = new QHBoxLayout(); + list_buttons_layout->setContentsMargins(0,0,0,0); + list_buttons_layout->addLayout(add_remove_layout); + list_buttons_layout->addLayout(up_down_layout); + list_buttons_layout->addWidget(adjust_button); + list_buttons_layout->addWidget(move_by_hand_button); + list_buttons_layout->addWidget(georef_button); + list_buttons_layout->addWidget(edit_button); + + list_buttons_group = new QWidget(); + list_buttons_group->setLayout(list_buttons_layout); + + QBoxLayout* all_buttons_layout = new QHBoxLayout(); + all_buttons_layout->setContentsMargins( + style()->pixelMetric(QStyle::PM_LayoutLeftMargin, &style_option) / 2, + 0, // Covered by the main layout's spacing. + style()->pixelMetric(QStyle::PM_LayoutRightMargin, &style_option) / 2, + style()->pixelMetric(QStyle::PM_LayoutBottomMargin, &style_option) / 2 + ); + all_buttons_layout->addWidget(list_buttons_group); + all_buttons_layout->addWidget(new QLabel(QString::fromLatin1(" ")), 1); + + if (!mobile_mode) + { + QToolButton* help_button = newToolButton(QIcon(QString::fromLatin1(":/images/help.png")), tr("Help")); + help_button->setAutoRaise(true); + all_buttons_layout->addWidget(help_button); + connect(help_button, &QAbstractButton::clicked, this, &TemplateListWidget::showHelp); + } + + all_templates_layout->addLayout(all_buttons_layout); + + setLayout(all_templates_layout); + + //group_button = new QPushButton(QIcon(QString::fromLatin1(":/images/group.png")), tr("(Un)group")); + /*more_button = new QToolButton(); + more_button->setText(tr("More...")); + more_button->setPopupMode(QToolButton::InstantPopup); + more_button->setSizePolicy(QSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed)); + QMenu* more_button_menu = new QMenu(more_button); + more_button_menu->addAction(QIcon(QString::fromLatin1(":/images/window-new.png")), tr("Numeric transformation window")); + more_button_menu->addAction(tr("Set transparent color...")); + more_button_menu->addAction(tr("Trace lines...")); + more_button->setMenu(more_button_menu);*/ + + updateButtons(); + + setAllTemplatesHidden(main_view->areAllTemplatesHidden()); + + // Connections + connect(all_hidden_check, &QAbstractButton::toggled, controller, &MapEditorController::hideAllTemplates); + + connect(template_table, &QTableWidget::cellChanged, this, &TemplateListWidget::cellChange); + connect(template_table->selectionModel(), &QItemSelectionModel::selectionChanged, this, &TemplateListWidget::updateButtons); + connect(template_table, &QTableWidget::cellClicked, this, &TemplateListWidget::cellClicked, Qt::QueuedConnection); + connect(template_table, &QTableWidget::cellDoubleClicked, this, &TemplateListWidget::cellDoubleClicked, Qt::QueuedConnection); + + connect(delete_button, &QAbstractButton::clicked, this, &TemplateListWidget::deleteTemplate); + connect(move_up_button, &QAbstractButton::clicked, this, &TemplateListWidget::moveTemplateUp); + connect(move_down_button, &QAbstractButton::clicked, this, &TemplateListWidget::moveTemplateDown); + + connect(move_by_hand_action, &QAction::triggered, this, &TemplateListWidget::moveByHandClicked); + connect(adjust_button, &QAbstractButton::clicked, this, &TemplateListWidget::adjustClicked); + connect(position_action, &QAction::triggered, this, &TemplateListWidget::positionClicked); + + //connect(group_button, SIGNAL(clicked(bool)), this, SLOT(groupClicked())); + //connect(more_button_menu, SIGNAL(triggered(QAction*)), this, SLOT(moreActionClicked(QAction*))); + + connect(main_view, &MapView::visibilityChanged, this, &TemplateListWidget::updateVisibility); + connect(controller, &MapEditorController::templatePositionDockWidgetClosed, this, &TemplateListWidget::templatePositionDockWidgetClosed); +} + +TemplateListWidget::~TemplateListWidget() +{ + ; // Nothing +} + +QToolButton* TemplateListWidget::newToolButton(const QIcon& icon, const QString& text) +{ + QToolButton* button = new QToolButton(); + button->setToolButtonStyle(Qt::ToolButtonIconOnly); + button->setToolTip(text); + button->setIcon(icon); + button->setText(text); + button->setWhatsThis(Util::makeWhatThis("templates.html#setup")); + return button; +} + +// slot +void TemplateListWidget::setAllTemplatesHidden(bool value) +{ + all_hidden_check->setChecked(value); + + bool enabled = !value; + template_table->setEnabled(enabled); + list_buttons_group->setEnabled(enabled); + updateButtons(); +} + +void TemplateListWidget::addTemplateAt(Template* new_template, int pos) +{ + /*int row; + if (pos >= 0) + row = template_table->rowCount() - 1 - ((pos >= map->getFirstFrontTemplate()) ? (pos + 1) : pos); + else + row = template_table->rowCount() - 1 - map->getFirstFrontTemplate();*/ + + if (pos < map->getFirstFrontTemplate()) + map->setFirstFrontTemplate(map->getFirstFrontTemplate() + 1); + if (pos < 0) + pos = map->getFirstFrontTemplate() - 1; + + map->addTemplate(new_template, pos); + map->setTemplateAreaDirty(pos); + + map->setTemplatesDirty(); +} + +std::unique_ptr

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 CZy=fg literal 0 HcmV?d00001 diff --git a/images/mapper-icon/README.txt b/images/mapper-icon/README.txt new file mode 100644 index 0000000..023fe85 --- /dev/null +++ b/images/mapper-icon/README.txt @@ -0,0 +1,4 @@ +There are two Photoshop files for the icons, one for large sized icons and one for small sizes. +Due to having a few different effects on them the icons where made in PS. The main parts are vector and should be fine to scale up if needed (the large icon is 512px now). + +The Photoshop files are licensed under Creative Commons Attribution 4.0 International Licenses. \ No newline at end of file diff --git a/images/mapper-icon/mapper-help.xcf b/images/mapper-icon/mapper-help.xcf new file mode 100644 index 0000000000000000000000000000000000000000..ee192cb06c5a0714bff1693bbb57a4db459debe2 GIT binary patch literal 6244 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 yvINX%7PBw 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 literal 0 HcmV?d00001 diff --git a/images/open-orienteering.png b/images/open-orienteering.png new file mode 100644 index 0000000000000000000000000000000000000000..e1db26415abf6a4650008ac7810f87279fde5aaf GIT binary patch literal 45070 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 RVTgc_!=~1RQWN)!{{s*86^#G@ literal 0 HcmV?d00001 diff --git a/images/open.png b/images/open.png new file mode 100644 index 0000000000000000000000000000000000000000..472484f11279c3e37a20ddcc8277c516ad246115 GIT binary patch literal 1176 zcmV;J1ZVq+P)1yxd$0C6kuV7bR+PdY00{*lQ*M=l z8i@j0IzB)oK0r!@M1^RfLrAAU7s-kOiqb{G#>6NV#`n5+-j|u38H#(!I(Lo}a#ASx zOOJMTcK3OH^E@-NyCMujUZ>=1js9N%@BwbzxZx|Mem2IuchLhvh}>HH`NM|~zg!tW znx z&Mh?nAq1P7oB6@P!AHRDl>lh1(=5xxrAr$aW3bkq30%yC5Q1v8T0cBI{9=21`_`;~ znVfUlTKn$b$Z5|!&XdlVufDtg z{_MP%0o`cSt6FQ+AChLZ%>LhFqBx(7Z0TsvBM}Qt0W>N;D$@u-XLfnM6&qu8zdxYc z?Gk5}dbNZ#lN;pJ!Lx=t&)ie96SLNlWQH`$!HM|>RxCkQsRXoIEixmh1tqLgcycwb zi*cG$Z~BaeIo7%-3jleZt0)@L?+?)C4XS~Ua}H0Qo97pkgHfu{xh3!=ajLB``OyM^ zF(xaQOH`X1tkudmKnk(E_%A5q9HUf|TZiWfg0jbHk|`m?$pV12HXDt`91j%h^-Jj7 zzS8J3ZHY4jPT)`dls(DlRON!Fldzb9)c1Y7AfQQ^OxX*AOy-!wy2(Ca?8H=Vm#s*g zgTW}ZxpRvE*4kt|9@824R9a=CM3d?1O9;q~MH`3CExDO)%P*OgL>Y$T#1qn6T7pyv zfeadyNs60>X%$s}D(4*iBtcj^SO93Z+hS*D$3(GWaO(K; zWQgp(;tse($HzmPB*O>0?RG5;!*~t=cu^Gn^vj|6Os(Vpw*Sf>yJzIU0$80M96$Ks z>*6&r`!#E~+s$BY?af-y+H^Q6gv?ojDIcPR55KRq$62A|r46qc=Z1 z+Wyip<*w4l7+;fWN4R2eBK$)#e#le_XtH!?-*5e(w7>yEWtqm~gC5mEkLvKtb(-=m zCvc)Z$MkGnb8EggjfB+-Sgo*g90Z2XlnHW2GQO0_g1=Iqui0HzexbOmRcrPKP^eNt zvAm3#NCZ}m#E1%Ua7zhftEFyJV|$TDk&cL#fTO7i*<)j%-J{}sK5?$+m(aqNiSV^X z?a}IrvQwock&Ggx+7b;Mf11iI$j$rQRI`TyBm})T zkQV$JBFlnyj|IF6;>f@Ngk-;H!XeP<$nNGNCWC@hBIL0^2>Y<)7hxazf}iw^oc`|e z%5*A%PKdzUjoHVmjOC_nx;%mpdBA$c5fNkzO|kN{zZY3Ey-4iu4u0zu~pBtC?BFOSKEuuqcZ zQ{Vg2h=g=br<&avN+!#^_8~3~|zxuliPcH(HFywfA~WL4JP0 zC)LK?T1f~YxHt@125wEWSXheO4)7Umn^6tdB%sx%_ck{kC?W|00ml$zk%!$G!T3Vh z%SmKgcfT{Z83f{H!CMVkZ`RiAt)wW52ro~954ymFB#heGh$u?mpX+0;#Xe8dw44gK z!C)ZnBk-b0Z73`*{>WJQght?25OP@{Nx<+F3)hM`VPlz-@tnC_uB5>AdVSmw5ZfsA zkH;Eniy%t~EZl@Fi?Gdem~w<&3@f%iXty&OjW8OGYtF^?aW(KxQ}(-cwbf->Ed|zX zfygmf@{6#|aX~?n&t4etTi08e*=$~ujL~SkGapw2+x7aBdusNpg@7CE@(ct~#>fl@ zub;OT?PJcMFEQ|Y$MLT3BhYq8{m_#Y6?qwjr4Yjb5b0`M`}sU39AO6|@XvL2Bv<8< zPQ!E}t?}VUN+{m%g2;M6C^Nu_l%Irny62C?YJ9x-KS&pM5zu6*UZ8R)LI^s+F3sU$ zPw%2-eD34U-~3&PuEuOO-vt&O$Lb>PvAm-LBo#h1M>|7>&2=T>#Y;PrZKw*W=gxBb4qR?msb)jn#(J%3R$011EyK%{Bf8x27$ z$Xc;Co6UDZKmfr0UC>^)K?0BlKo!TLgvb~ILeyxQwxy~8B>-Hv!M}Pxh<~{$H_K79 cxcu+hKe~1czV38>V*mgE07*qoM6N<$g8$T4I{*Lx literal 0 HcmV?d00001 diff --git a/images/paste.png b/images/paste.png new file mode 100644 index 0000000000000000000000000000000000000000..dd429ced625603273671b08c983a1c31c8207649 GIT binary patch literal 1027 zcmV+e1pNDnP)Z-HRJl7>A$v%EzX&*$-%mc%!W(R|T(17YYk5UI?o~uY^Sc z{sFpTE%*lrx*!UrA}AEu3%wCVtWZ`#Dz13P!~hpxIKI(U z@|uV?l$G82XIWV}i(w2N?eEt^ZEQR5*Il>A*47OcYuC^sQ`C^2p=s}LeEshQ2w2cn zte;<6Frpm*F8>aN!sFEIduWFZGMP+&z(@y8)0mx|L*xdlXYyoIdgyt#C+1f_KUfFC z03!I}zgg#b=;i|5D&+I?hzKBv0EpLb=-$jszweLQOQiKQ09hI={_{Cc9=8zbTNwff z#zQy9#S3rw*X44VYV{7LX$3?*@W90(K&@88FbvjTeFNLJ0eENQZB(%7H~=r|^#=f~ ztUSZjt6M0g#x?gt*L9Yb&eCY?qm)ZNKi9{L={^LYWEgXGb(Q7iWtz=aA^-r>H2ifk zZtP(I1p|i$VcWK!&ZHqCA&U}O5Cb`N1VzL31ORcA+uPfZBwQ+$LZXQ>5a&~=R7xy9 zYW9f%rnO)o4CD5OIG|X7q!z@@G$>doJjU#-{U{a;H;P&iP4}qTM>FuhEg0u>IPKB; z=&=(m!b+tQ5*Zc@-h*PX7=rM2(5Wr(X4ik6CNH+Q*^9^kAckO~1(Sv2AwoOgAwV(< z0v`--kf;UGfo$8RP$)!T`ey^f80_m)Z$zG8u~=gA?8CD*48t$pp=GMKAbR*nDy-|e zFKn77ylP1EF~Pd*Hdm$FhgU1#X%HW5H6HD+NA`y5R7 z^UuBL3p!4R?|=9Xr_)IWAU=Q_D>%w$uZV~*UfZj2^Ov7!HCv=oR?-ag1zcB+6ps4r z)g8wnolc{a;&$aWf8G5P=b(d~J4UD5nQjdzrO0MyhE6q_rlIS4sCcj1y}$3$>2&z^ z+BdY@ZB*A~etwRHg++Gm?h?rGdBWnPd=dPJ9Zl#!DMQ;4&``h$VAlgkA9U2mU*6n%1+Px(3`s;mR9M69ms?C6WfaH%Gt06p%k03Ga;KWAsX;7DvCvT2LP9D9w3U*mjnewy zJz8wyYfEDKVxkW|)GDSvKrGrcv6`l|HVvsYDX|R{2rl=fT$WvSft}gexqsseCWN-K zz;62DNls>xIhWt$`+wh=0Uona@hbfB0a!=^+iU`Mi;8in^(xm6z*rq;ibwNfl}Jk8 z`qZ7z4mQ7WC}BszGu%?WdAsE79+7@t9ZSapz?R}T^GV~U1zBED=D~41+Z`}h2Fx$L zS!FAVJHXNXsjio+8X7Z$i8S19!0m=dmZ5QKvO&??SH~yBviV#4Gi^Hyi_Yg3HZphl zFtW{Nm=+f?p(t?M2&bF$?zjTjt)$IW+nf_HS)ec!y!G|44-8;xzF(ioq|S9*j?BhQ zgm2d}2g{s=CkpbEq?Dz5Q0FKJ$#(FDhHjx}cu?UQJRXp^XyC|;Y+6=Y`q!@VT`WK# z1aBiz_#V0_VrqUM95hjNU0u)~mK&2La5(6;hB{ZiiB3QyFbGXr!UC_u)ANlw8t6Oq zI~fng|`fu1qZnDqDFKHJHC^> zO>NhFLbSEky$jy2NqMiLe0MR+vXrzq3RUofixBjCL`B!hPv<(hTkEN}E`Zlv*8J?; z+><56&)GCNgou9-gaEx`BK#qJWJu(WulI%413+zItrri~ROG-Q2+!VuVdxl|kum0# z{G3P{A9dQrL<1kz+drzRC@W+b7UKLMbeY2fuVZLh7Bpg-`X+amAss$ zzH+wZ!6_G001K5^`^1xZtjhagXc15eN#Jyrrx7~U@%w`_KIQ|ltdUMpb6n?esdid{HjPf-_IC?YL zng4WYT2J4I*4APx#24YJ`L;(K){{a7>y{D4^000SaNLh0L01FcU01FcV0GgZ_00007bV*G`2igk> z6A~uDFavb}00IU{L_t(o!|j$qYZFlr$A51(=|-uRf*&B@K~Oxkr&1LJ@k8iYJbLjg zf+#2+`~redz2qBsk$Msl3IJM;ID-83vo(`;&c$-rA?-`m;wznS^J zH!zc#%;c0MOlq*&SXzkNVRzWt`rR)R|F2R8btO*P&u_g<2In5We^4p{(KO-PZf&vM z+L|f_(P`Jfu>f$qv~6WN$GxZggaBM?T$zupx+tk4yyqOS49fMlR~JXwe!SECI}v~z zYs)ImsT*~W1p={42q1)h3S!Rw92zNEZ4~7XjlhfBuZmN1{hUh>0>Y8Rqnl4~ye9Q< zONM1@Pd_{^mjaXVWB)rLgzQ}i$4K#9m(kqYAjJ_WT^S}rIH`$AUNm5a)V(r!$w+ zuYTqt?vB*2^aQYMctI}(Kt(-@kh>@EKCd0M(+bnJWFd>f;0Qy~r)>DZuD!5{>3hO4 gcAB->GnrKW0l|3&nN?Iw7XSbN07*qoM6N<$f<B;f_VO-s@>-3j-Gt*hUTB+ zZH>2k(TOzgQy^62^*}@2C*K0JE8n)T^u|Fe`---!mMSTDlv7(G4N1X$Y3zHWNzz*l zngpJz94MvD^tEz&q#P`ddmdWZSKoHkbzBaww5*k`{xS!Tfrh{{0j?au(v3;MGjJyz z22NGQ*5wc{kKXTo^b-azuB8jpDjJL_7RcaH(A2?|bXxja3tsu^&;J{O5QE1-Q`K>Z zxJE?!Se=H&TUu+SF-dO1Z@cwEMA@!yz3oVLiKHSTubybsDr| zZO%xWW1xMfO%$4Hs+0>)^w8H5>qpJ=nU2x9F2|k`pNU2;Jpcc1;!=2$4dSim#00nv z#c>I@V*Jyqy^;$Trd2c;Q7n+cqoApSE9tb4*Fx}eMwVAx;iA7t&fQr8^}8JhfXZL`)UnXhj6Au#BjPh@H&L(NeFZ;33dd zQl+$vC9Q4FNSnRTsI-YfQ?HyzgeQ9F_g3dez#Ey4(YaK*yr^0q1n-YX1?d;5zUOO+ z6(Yd|xQ%l~X>bQcoU@3th_k_5P7ZpQmvwo8Ykg)uG*jtxdHKdJuRroIuk^SI&IJUX zu8#A9E-!EowVu(^GnksE_bh+eO@8x%z|-mS%6{-xEv{xisGHu#z-*45%UufX)#dec zP0g-umsj#TVY0Z|3hkhWd3`vL_{le#-Z*F_UvYNzySy@Zq*KEJU0zulBfGr7^j3o= zfv5f~F9$x%Yqj)A=9UzP06>GG;P%xkHuzrewxpds)~fNMu^Xz21Pz%y_s z9R^P8h=>;q-_Ygt4AAtFGN;R{^4O52zK4_Q&VleKXzJifI*odm*YtJ;*U;q!$N>}{ z2TfJSA>tYl=_7R-;^g35NNcT>?vx1d)NZX1LD}`Kw;jnYkyJ#a)f0_cWo?eudS%J? z2sD*cDFq>|ZO%xWBcPSiCJIe8RZ4{?dgyC?(|*)Ec{)bt(&_RF*5w7k6KoLcIWYll zLvvjA?VyKl-EQVxi#QwP<>Y$34l%gzJ1L5-%Znb{wuMKcx~vejXt_@F0bgTnqAc{uLy*SydG$1Iz=P71SX#&+CtMC2d(5Q&aQfwR}PPIYD=Vz?()jh z7}e#4rnee23A`!K@=D=R(X(25M4sh^z^g$+;Z5oC;?mj*&?KLyww@MfCENK%G6Aj} z!P1RM!833t9R^Nm#51ZUhd6nZo^w;Wytpg5bYWUWgAv67DLe|AI=GTfOJ6I&%N>Pu zc_DHDg~vftl>>;lMnw8ZorXAh+qRI_S}ENr5#XuaS|MVp07ok#XoY1&MMUakZjP3E zB?S+Grjjb9Wh`lJb4J?ig+`@K6qC*i76lvC!9s|uxL&Smrk|ElW#UWhrVqzebtsyS< zh@>vslqMjZ?4(D<0o!zS{WZhp#Kh!PkSA=;Umuz$2ZoT0mF~n0b+$$3h9;MPp#&Qz zY9mH;4-;I93{3<&>>G1w=-Q>jamETo;kkNO&Oqss>3ZXONG3A9x43;%+J*S${Uyxq z#`^2I*y-@2J<#CD>^d*XYNO{DAJ!zq`83yJW$CV^!&urH#yZGd^ZCGHO{EW(w@FGj z;8KsVTGJd7+=I5U;*!xBjnCtEp>}x%jU9PMPL?3nnY$^d(ggIksX|6Y`yq=Y4)on^ zVW>(nU5!uJ$K4D|y%D4}jmr~A@PZxd>Idvjy^2RscH1zNubW(6SC)XA<1N61*e*jT zHQq?k-Kuzw2hSljoK|ZC933&z(=ns8p3~?~QW&ZF8{D2;=#JhVHsjl52KKas4DqKh zLdyH}7t6s^4%uA2kVC^a9Ac8fq}w(ohNGrRJ>=Rp4Pfnv`n%hsu%9)8PmeS?xK0u_ ze3tm3JiCMoW0(})>(L=;vpXExt#FvM=UfW9oLJunG(J}M;^OuSHmwSbunD6wfSQ|| zI&1Cli$O69;P)^n*^v80%`|mpvf^~FZApYh8Icj}ncS>?L4q8eG0ZSN4Wxw zmD)D?&}T!nmOZl(bVyW+`Vj*3fXRWdI4pGgy^ZaJ&~E(nX5q2K6H3yafvwCC7w)I# z1G53g;Wzg8ne*P6Ap7y>T4@zu=mmCK#(L*fa_y0}qW;JD&22zq}PaEuAx*5S1VD%9A{xeUcR~tDd z)UpdeVm?a}H=oh%HFzEZ@6R<(M5_>PG6k}3+HffhXKIxpc|kHkz)kq#ops5ppn}%E zzuZ%xruKXj?U04JDc(m)}Q&u=9v;?hy^koNYazFK++c>3-bn1Mk^Np!UjlB0fB2#dbINqEf76i}qxl=3Se~ z{KBMe?0n0=(LK>*gT9I-JA@Yf?c--b=0!B{7v;l5PnA@wuiw^KI8A>tbhfYG)O~RI zPzOIgtYO!KWM_CjN8e}Nsvhjv1gP;>+PC3h&Q5-%}-YP=OqY;KM2 z?t&yslF>ED#EJrkmh8l`Y%2W`t0Ifb$@{2?XeCvGFtdHAPm`#FtG)xuS5zYGD3VkU z$3AM`h@pOmDD4WA4OxDSZZK({a2YMS!9^(eAiJnnlS(`5iRQ&*V%>p9zywoDK>>c< z=%Os4l~_F*XCoU{T`)8*&2 z)vVN1=o;Ls;t>Dk9faC-)~Ig0xF=K;qA#8u>GhjQLs++0W?77)B=4}3G;P&xG`Wg~I9X)ISmS*! z0}pZN{YX7brRdGYle(pL2=4nhkQ5b&n&Vs}z1a>xgJJ9AFGtM?@>~zG%XJee`7A)M zO0Dv&I>jktW(HRn%bL~Rce~J8w@39M_GTo?o}Oz*5htTUVAeX)DfVW+Y05t}H&!Rt zgu-8`64v`1YR|2Y%3S-1N8BVQr-6H1Ry%aM!V4J)A?_#XM-qrqM3&Pd)_;~l#pu{! z+7M{Z!sM zmuW21a#fwhcUv@_%%$JVdHRAM!J6(|cwQBmhfnfuSMbuXmdD7H;5R;nfa$%vT7EYT zDwjit1l)W5i(3KS8=87&VQLo2{rFk>?Xk9fksw0--kvLS=UXn(OJk0x;cxy4hWD|M zBg6OkA>hOq)9*DPeY;{2RG@-OM<2R_5_Q}HAZhAU(6)lhn_-{H;W|b?3P4Ha!8H2P zjukg+m!-!8(CEN9wyU>+hlZnzrKk%24Sr;by3{xD>wkd%+c)s75(&matd5&d^$mHfiY^?e@kjQB;bJf6akLU=X<- z>g_TB)|Fx`QNfmc;Bd*;1{#Iq(;0o!jG$5;)gj`En{YrAUFPa zNBO7ETz2)!9am8k5Qux7W}nLUW12bTHoHfk$En-OoRgsxVXDSlt=@)qt=Gv<8u=!o zCE(<#kZ5Z~?G(&oGj;zUv@!g$fRMg_cBMS$kCJPA96050ZCPqmiCFrRmQthGVfy(L3Ht|qOyZbb5Za)kOf0s;b8PAd_o|6WGfRBsu0Lq`KiALd{_>E z4-|Mj-hY3aCW}AZ&pMiSx`AVY_A7+$Gnv*m9k|$+{D@jP*g+NL-@K7kVXRd|K$JMN zP;=cud%R;@58lnZRjG!tH;MbBDls!%fsAIwT+{#POX(W(wVt`8*dB|b3>LQbvy0H3 zt>+!wJ-a6QPkk5=2&E8Rq)O>6{8uJXhFkat{x|+Y$}_L3DP|hH`x^bwR)Gq^AlR() zoC0sSRGTty(@_VN(guk*WwU9b>;vgFWe-Rdzp8fIL;**$-Xiu8w)NPg5;=XqOtgbE zcTg<3=<~~eAON#oQuoa|>kd9pvwy^`i4pTY1i@88g(ZF>WusIv)I^P!coTGB97>3D zHV^ZoLsY2XSy9GE;~u(pxQbSKT=}i|`|lMupuN3yCD&DxX1Ma_i#L7%aRXVnE*D7Z z{q@>EoU8&%5Dyz2$Ul>q>F@u!;S=ovyN`JdG_LelN&dT$T`Srq^0NUx#62^M&e@H^ zJkX!>&4Y}X`%@v+GmfUhc#OeFeSOh)`=Q_M*UYEtqpF(*wd=X!3KN713Qe-IHW%u0 zx?hFPF4bNtpIHi*@p^(?@2Q!&2W9U@<7FX_uP@87@6)4|CCa8OBF`2}!FOOdhn?^# zEBbCg3BviIi~1*hEU%3@VBQ#pgtzRyfB_c#SUcnJtE4(RDBHURXU zU#u?hV@?As$`zu3THyTL{4DGCXzU}%u>?O=NZSfxr+$`3c;!osU=yY#hyb_5W00006VoOIv0RI60 z0RN!9r;`8x010qNS#tmY3ljhU3ljkVnw%H_000McNliru+zb{C7&9!n`KkZ_0{cls zK~!ko-B??aqc9BYPUW&O=OH<+_5%d6Ek7_@8HlUqgN(4dCAlR;Km?sj1Oxz*6`N(d zn$5S?a|PX82CIk&=%5$bcKR|ikqDtBw|bhDXoyB*A-4Qx-&vmZ7$ygIxGV$PvWd}= zIl<>qACcrvWCvl0u?Dpb+3xCt&WS0e*!D4!1j}a2Hu_g0X5Z1(ih|9g<=J!3PRwGm zwhvrzS-`D`c}`b?mn5h0ixV`bpZ;I3i>Bsd^l(i@{qqh>-_g~MnH90p4UGw=#D)YV zQAI~BV-@YuJO4)aysc7_6I<(1-Is|P5`dKMgROJlE#khS@~1l#dGkQRbS2e=l<6Ja z_40Z{tT5C><1aWAd&}PTYg-?>?H4`-Uea|i05JGHsC}no6WP850!n79k!vZWJy4(1 z$a?z}GowJ-+qac<9>$?kU#m~!Ee8I zf|n$x_qh~d22emL-TPCKbH&3EnW`vNK;tF5y#ZSzm=YUqzm%BgHJ9M$KrK~*9cpO_ zx=#4zI>(yS_SU7VE(#8i!@bBon=_oGu{6UXRt8C5b%FrmIex7DVxj$F{*h73j8Z1p zcUsvZfItL7W(0?)UrI3h;PaexVEm`jrw(ovs9LIsGEQ>{^(6ucz5!;J+XPqO!JJq@0?og%>`mNt@+-ijox;_d*2$%gTP;CFD{hFr9ZNH{z z!aUDi2QP`>4^8bmB^ztIo++8FMy{oh_CS43BkS!`%8U|eZ{Jqdc^FSmzou#0ew*j{ z^z_R_VLPJ~6}5GSNt^90r(Y?ttf^lK-g5f2Mn+2a{#4{V@$f|E==4iL&-1+5Td*~P zDY4=9ONn`2^9b6z*-NlTEiFOU3BO$DSd-e`x^&g`51Ze2xikGYy#N3J07*qoM6N<$ Ef}!P{mjD0& literal 0 HcmV?d00001 diff --git a/images/print-mode-raster.png b/images/print-mode-raster.png new file mode 100644 index 0000000000000000000000000000000000000000..e6e976e1bcd33281121fe2504b770faaa35d3c9c GIT binary patch literal 1686 zcmV;H25I?;P)