diff --git a/.circleci/config.yml b/.circleci/config.yml
index 8ae0c0b671..ac35cc8b7d 100644
--- a/.circleci/config.yml
+++ b/.circleci/config.yml
@@ -120,7 +120,9 @@ jobs:
- restore_cache:
keys:
- macos-cache-v2-universal-{{checksum "ci/macos-universal-deps.sh"}}-{{checksum "ci/universal-build-macos.sh"}}
+ - run: ci/macos-sign-setup.sh
- run: ci/universal-build-macos.sh
+ - run: ci/macos-sign-cleanup.sh
- save_cache:
key: macos-cache-v2-universal-{{checksum "ci/macos-universal-deps.sh"}}-{{checksum "ci/universal-build-macos.sh"}}
paths:
@@ -147,7 +149,9 @@ jobs:
- restore_cache:
keys:
- macos-cache-v2-intel-{{checksum "ci/macos-universal-deps.sh"}}-{{checksum "ci/universal-build-macos.sh"}}
+ - run: ci/macos-sign-setup.sh
- run: ci/universal-build-macos.sh
+ - run: ci/macos-sign-cleanup.sh
- save_cache:
key: macos-cache-v2-intel-{{checksum "ci/macos-universal-deps.sh"}}-{{checksum "ci/universal-build-macos.sh"}}
paths:
diff --git a/CMakeLists.txt b/CMakeLists.txt
index f4c239a85c..a56d85b926 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -931,6 +931,7 @@ set(GUI_SRC
${GUI_SRC_DIR}/NMEALogWindow.cpp
${GUI_SRC_DIR}/ocpCursor.cpp
${GUI_SRC_DIR}/ocpn_app.cpp
+ ${GUI_SRC_DIR}/ocpn_plugin_gui.cpp
${GUI_SRC_DIR}/OCPN_AUIManager.cpp
${GUI_SRC_DIR}/ocpndc.cpp
${GUI_SRC_DIR}/ocpn_frame.cpp
@@ -1874,6 +1875,7 @@ if (APPLE)
set_target_properties(
${PACKAGE_NAME} PROPERTIES MACOSX_BUNDLE_INFO_PLIST
"${CMAKE_SOURCE_DIR}/buildosx/Info.plist.in"
+ XCODE_ATTRIBUTE_ENABLE_HARDENED_RUNTIME YES
)
endif ()
diff --git a/buildosx/entitlements.plist b/buildosx/entitlements.plist
new file mode 100644
index 0000000000..d161ccd944
--- /dev/null
+++ b/buildosx/entitlements.plist
@@ -0,0 +1,18 @@
+
+
+
+
+ com.apple.security.cs.allow-jit
+
+ com.apple.security.cs.allow-unsigned-executable-memory
+
+ com.apple.security.cs.disable-executable-page-protection
+
+ com.apple.security.cs.allow-dyld-environment-variables
+
+ com.apple.security.cs.disable-library-validation
+
+ com.apple.security.get-task-allow
+
+
+
diff --git a/ci/circleci-build-android-corelib-armhf.sh b/ci/circleci-build-android-corelib-armhf.sh
index 28d7f72150..be7b8a418b 100755
--- a/ci/circleci-build-android-corelib-armhf.sh
+++ b/ci/circleci-build-android-corelib-armhf.sh
@@ -27,6 +27,7 @@ cd $builddir && rm -rf *
cmake \
-DCMAKE_BUILD_TYPE=Release \
-DOCPN_TARGET_TUPLE:STRING="Android-armhf;16;armhf" \
+ -DOCPN_BUILD_SAMPLE=ON \
-Dtool_base="$HOME/android-sdk/ndk/26.1.10909125/toolchains/llvm/prebuilt/linux-x86_64"\
..
diff --git a/ci/generic-build-debian.sh b/ci/generic-build-debian.sh
index 17467ebb48..30ba471c5e 100755
--- a/ci/generic-build-debian.sh
+++ b/ci/generic-build-debian.sh
@@ -69,6 +69,7 @@ else
-DCMAKE_BUILD_TYPE=RelWithDebInfo \
-DOCPN_CI_BUILD:BOOL=ON \
-DOCPN_USE_BUNDLED_LIBS=OFF \
+ -DOCPN_BUILD_SAMPLE=ON \
..
make -sj2
dbus-run-session make run-tests || :
diff --git a/ci/generic-build-flatpak.sh b/ci/generic-build-flatpak.sh
index 72988e4773..3d4354f21e 100755
--- a/ci/generic-build-flatpak.sh
+++ b/ci/generic-build-flatpak.sh
@@ -37,6 +37,13 @@ cd flatpak
sed -i -e '/url:/s|\.\.|https://github.com/OpenCPN/OpenCPN.git|' \
-e "/BUILD_NUMBER/s/0/$BUILD_NUMBER/" \
org.opencpn.OpenCPN.yaml
+ed org.opencpn.OpenCPN.yaml << EOF
+/DOCPN_FLATPAK=ON/
+i
+ - -DOCPN_BUILD_SAMPLE=ON \\
+.
+wq
+EOF
test -d ../build || mkdir ../build
cd ../build
diff --git a/ci/generic-build-macos.sh b/ci/generic-build-macos.sh
index 59f6ecdd5b..8b763c63bc 100755
--- a/ci/generic-build-macos.sh
+++ b/ci/generic-build-macos.sh
@@ -60,6 +60,7 @@ cmake -DOCPN_CI_BUILD=$CI_BUILD \
-DCMAKE_INSTALL_PREFIX=/tmp/opencpn \
-DOCPN_RELEASE=0 \
-DOCPN_BUILD_TEST=ON \
+ -DOCPN_BUILD_SAMPLE=ON \
..
# Compile OpenCPN
diff --git a/ci/macos-sign-cleanup.sh b/ci/macos-sign-cleanup.sh
new file mode 100755
index 0000000000..c8b84d0db0
--- /dev/null
+++ b/ci/macos-sign-cleanup.sh
@@ -0,0 +1,15 @@
+#!/usr/bin/env bash
+
+set -x
+
+echo "Cleaning up the Apple developer account information keychain"
+
+if [ -z "${APPLE_DEVELOPER_ID}" ]; then
+ echo "Apple developer account not set up, exiting..."
+ exit 0
+fi
+
+KEYCHAIN_PATH="app-signing.keychain-db"
+
+# Clean up the keychain
+security delete-keychain "${KEYCHAIN_PATH}"
diff --git a/ci/macos-sign-setup.sh b/ci/macos-sign-setup.sh
new file mode 100755
index 0000000000..7b0fecd1ad
--- /dev/null
+++ b/ci/macos-sign-setup.sh
@@ -0,0 +1,39 @@
+#!/usr/bin/env bash
+
+set -x
+
+echo "Importing Apple developer certificates"
+
+if [ -z "${APPLE_DEVELOPER_ID}" ]; then
+ echo "Apple developer account not set up, exiting..."
+ exit 0
+fi
+
+KEYCHAIN_PATH="app-signing.keychain-db"
+APP_P12="app.p12"
+INST_P12="inst.p12"
+
+# Store the certificates to the keychain
+echo -n "${DEVELOPER_ID_APPLICATION_P12}" | base64 --decode -o "${APP_P12}"
+echo -n "${DEVELOPER_ID_INSTALLER_P12}" | base64 --decode -o "${INST_P12}"
+
+# Create temporary keychain
+security create-keychain -p "${KEYCHAIN_PASSWORD}" "${KEYCHAIN_PATH}"
+security set-keychain-settings -lut 21600 "${KEYCHAIN_PATH}"
+security unlock-keychain -p "${KEYCHAIN_PASSWORD}" "${KEYCHAIN_PATH}"
+
+# Import the Apple intermediate CA certificate into the keychain
+wget https://www.apple.com/certificateauthority/DeveloperIDG2CA.cer
+security import DeveloperIDG2CA.cer -k "${KEYCHAIN_PATH}"
+
+# Import certificates to keychain
+security import "${APP_P12}" -P "${DEVELOPER_ID_APPLICATION_P12_PASS}" -A -t cert -f pkcs12 -k "${KEYCHAIN_PATH}"
+security import "${INST_P12}" -P "${DEVELOPER_ID_INSTALLER_P12_PASS}" -A -t cert -f pkcs12 -k "${KEYCHAIN_PATH}"
+security set-key-partition-list -S apple-tool:,apple: -k "$KEYCHAIN_PASSWORD" "${KEYCHAIN_PATH}"
+security list-keychain -d user -s "${KEYCHAIN_PATH}"
+security default-keychain -d user -s "${KEYCHAIN_PATH}"
+
+security find-identity -v -p codesigning
+
+# Clean up the P12 files
+rm -f "${APP_P12}" "${INST_P12}"
diff --git a/ci/macos-universal-deps.sh b/ci/macos-universal-deps.sh
index cd24f4066e..03ea7e00a3 100755
--- a/ci/macos-universal-deps.sh
+++ b/ci/macos-universal-deps.sh
@@ -22,16 +22,16 @@ echo "Installing dependencies for ${arch} into ${cache_dir}"
ogg_version="1.3.5"
vorbis_version="1.3.7"
flac_version="1.4.3"
-opus_version="1.4"
+opus_version="1.5.2"
blake2_version="0.98.1"
zstd_version="1.5.6"
-libarchive_version="3.7.3"
-mpg123_version="1.32.4"
+libarchive_version="3.7.7"
+mpg123_version="1.32.8"
lame_version="3.100"
libsndfile_version="1.2.2"
libusb_version="1.0.27"
-openssl_version="3.0.13"
-wx_version="3.2.5"
+openssl_version="3.0.15"
+wx_version="3.2.6"
macos_deployment_target="10.13"
@@ -166,7 +166,7 @@ cd ..
rm -rf opus-${opus_version}
#blake2
-if [ ! -f libb2-${blake2_version}.tar.gz ]; then
+if [ ! -f libb2-${blake2_version}.tar.gz ]; then
wget https://github.com/BLAKE2/libb2/releases/download/v${blake2_version}/libb2-${blake2_version}.tar.gz
fi
tar xzf libb2-${blake2_version}.tar.gz
@@ -228,7 +228,20 @@ cd libarchive-${libarchive_version}
#lipo -create libarchive.13.dylib.x86-64 libarchive.13.dylib.arm64 -output .libs/libarchive.13.dylib
mkdir bld
cd bld
-cmake -DCMAKE_OSX_ARCHITECTURES="${arch}" -DCMAKE_INSTALL_PREFIX=${cache_dir} -DENABLE_LZ4=false -DZSTD_INCLUDE_DIR=${cache_dir}/include -DZSTD_LIBRARY=${cache_dir}/lib/libzstd.dylib -DLIBB2_INCLUDE_DIR=${cache_dir}/include -DLIBB2_LIBRARY=${cache_dir}/lib/libb2.dylib -DCMAKE_POLICY_DEFAULT_CMP0068=NEW -DCMAKE_SKIP_BUILD_RPATH=FALSE -DCMAKE_BUILD_WITH_INSTALL_RPATH=FALSE -DCMAKE_INSTALL_RPATH=${cache_dir}/lib -DCMAKE_INSTALL_RPATH_USE_LINK_PATH=TRUE ..
+cmake -DCMAKE_OSX_ARCHITECTURES="${arch}" \
+ -DCMAKE_INSTALL_PREFIX=${cache_dir} \
+ -DENABLE_LZ4=false \
+ -DZSTD_INCLUDE_DIR=${cache_dir}/include \
+ -DZSTD_LIBRARY=${cache_dir}/lib/libzstd.dylib \
+ -DLIBB2_INCLUDE_DIR=${cache_dir}/include \
+ -DLIBB2_LIBRARY=${cache_dir}/lib/libb2.dylib \
+ -DCMAKE_POLICY_DEFAULT_CMP0068=NEW \
+ -DCMAKE_SKIP_BUILD_RPATH=FALSE \
+ -DCMAKE_BUILD_WITH_INSTALL_RPATH=FALSE \
+ -DCMAKE_INSTALL_RPATH=${cache_dir}/lib \
+ -DCMAKE_INSTALL_RPATH_USE_LINK_PATH=TRUE \
+ -DOCPN_BUILD_SAMPLE=ON \
+ ..
#-DCMAKE_MACOSX_RPATH=FALSE ..
make -j ${ncp}
make install
@@ -349,7 +362,7 @@ fi
tar xjf openssl-${openssl_version}.tar.gz
cd openssl-${openssl_version}
if [[ "${arch}" = *"x86_64"* ]]; then
- ./Configure --prefix="${cache_dir}" darwin64-x86_64-cc shared
+ ./Configure --prefix="${cache_dir}" darwin64-x86_64-cc shared
make -j ${ncpu}
if [[ "${arch}" = *"x86_64"* ]] && [[ "${arch}" = *"arm64"* ]]; then
mv libcrypto.3.dylib libcrypto.3.dylib.x86-64
diff --git a/ci/universal-build-macos.sh b/ci/universal-build-macos.sh
index e5c52928c9..50a129c26d 100755
--- a/ci/universal-build-macos.sh
+++ b/ci/universal-build-macos.sh
@@ -93,6 +93,7 @@ cmake -DOCPN_CI_BUILD=$CI_BUILD \
-DCMAKE_INSTALL_PREFIX=/tmp/opencpn -DCMAKE_OSX_DEPLOYMENT_TARGET=${MACOSX_DEPLOYMENT_TARGET} \
-DOCPN_RELEASE=${RELEASE} \
-DOCPN_BUILD_TEST=OFF \
+ -DOCPN_BUILD_SAMPLE=ON \
-DOCPN_USE_DEPS_BUNDLE=ON \
-DCMAKE_OSX_ARCHITECTURES="${ARCHS}" \
-DOCPN_USE_SYSTEM_LIBARCHIVE=OFF \
@@ -123,7 +124,16 @@ make install # Dunno why the second is needed but it is, otherwise
# plugin data is not included in the bundle
# Make sure the code signatures are correct
-codesign --force --deep --sign - /tmp/opencpn/bin/OpenCPN.app
+if [ -z "${APPLE_DEVELOPER_ID}" ]; then
+ # We do not have a paid Apple developer account, let's just reset the signatures
+ codesign --force --deep --sign - /tmp/opencpn/bin/OpenCPN.app
+else
+ # We do have an account and did set up the certificates in ci/mac-sign.sh, let's sign the application bundle
+ codesign --verbose --sign "${APPLE_DEVELOPER_ID}" --options=runtime --timestamp --options=runtime /tmp/opencpn/bin/OpenCPN.app/Contents/PlugIns/*.dylib
+ codesign --deep --force --verbose --sign "${APPLE_DEVELOPER_ID}" --entitlements ../buildosx/entitlements.plist --timestamp --options=runtime /tmp/opencpn/bin/OpenCPN.app
+fi
+
+codesign -dv --verbose /tmp/opencpn/bin/OpenCPN.app
dsymutil -o OpenCPN.dSYM /tmp/opencpn/bin/OpenCPN.app/Contents/MacOS/OpenCPN
tar czf OpenCPN-$(git rev-parse --short HEAD).dSYM.tar.gz OpenCPN.dSYM
@@ -133,5 +143,18 @@ if [[ ! -z "${CREATE_DMG+x}" ]]; then
make create-dmg
fi
+# Sign the installer if we have an Apple developer account set up
+if [ -n "${APPLE_DEVELOPER_ID}" ]; then
+ shopt -s nullglob
+ for pkg_file in OpenCPN*.pkg; do
+ productsign --sign "${APPLE_DEVELOPER_ID}" "${pkg_file}" pkg.signed
+ mv pkg.signed "${pkg_file}"
+ done
+ # The resulting package has to be submitted to Apple for notarization
+ # xcrun notarytool submit --apple-id --team-id --password
+ # Once succesfully notarized, run the stapler to include the notarization ticket into the installer
+ # xcrun stapler staple
+fi
+
# The build is over, if there is error now it is not ours
set +e
diff --git a/cli/CMakeLists.txt b/cli/CMakeLists.txt
index 286aaea35e..9bd5632d59 100644
--- a/cli/CMakeLists.txt
+++ b/cli/CMakeLists.txt
@@ -86,4 +86,7 @@ if (APPLE)
PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ
WORLD_EXECUTE GROUP_EXECUTE OWNER_EXECUTE
)
+ set_target_properties(opencpn-cmd PROPERTIES
+ XCODE_ATTRIBUTE_ENABLE_HARDENED_RUNTIME YES
+ )
endif ()
diff --git a/glutil/CMakeLists.txt b/glutil/CMakeLists.txt
index d1253589a8..52e9afdc55 100644
--- a/glutil/CMakeLists.txt
+++ b/glutil/CMakeLists.txt
@@ -43,7 +43,7 @@ if (CMAKE_HOST_WIN32)
target_link_libraries(
${APP_TARGET} PRIVATE setupapi.lib "GLU_static" psapi.lib
iphlpapi.lib # glu32.lib
- )
+ )
# use gdi plus only on MSVC, it is not a free library
if (MSVC)
target_link_libraries(${APP_TARGET} PRIVATE gdiplus.lib)
@@ -78,4 +78,7 @@ if (APPLE)
PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ
WORLD_EXECUTE GROUP_EXECUTE OWNER_EXECUTE
)
+ set_target_properties(${APP_TARGET} PROPERTIES
+ XCODE_ATTRIBUTE_ENABLE_HARDENED_RUNTIME YES
+ )
endif ()
diff --git a/glutil/console.cpp b/glutil/console.cpp
index 7473dce0c8..065f74605c 100644
--- a/glutil/console.cpp
+++ b/glutil/console.cpp
@@ -1,5 +1,3 @@
-/** \file console.cpp Simple CLI application to check OpenGL capabilities. */
-
/**************************************************************************
* Copyright (C) 2022 Alec Leamas *
* Copyright (C) 2024 Pavel Kalian *
@@ -18,7 +16,11 @@
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
- ***************************************************************************
+ ***************************************************************************/
+
+/**
+ * \file
+ * Simple CLI application to check OpenGL capabilities.
*/
#include "wx/wxprec.h"
diff --git a/gui/include/gui/comm_overflow_dlg.h b/gui/include/gui/comm_overflow_dlg.h
index ca1ed79068..3d57ce73c9 100644
--- a/gui/include/gui/comm_overflow_dlg.h
+++ b/gui/include/gui/comm_overflow_dlg.h
@@ -17,7 +17,10 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
**************************************************************************/
-/** \file comm_oveflow_dlg.h Popup dialog on communication overflows. */
+/**
+ * \file
+ * Popup dialog on communication overflows
+ */
#ifndef COMM_OVERFLOW_DLG_H__
#define COMM_OVERFLOW_DLG_H__
diff --git a/gui/include/gui/gui_lib.h b/gui/include/gui/gui_lib.h
index de707daaf5..9794089704 100644
--- a/gui/include/gui/gui_lib.h
+++ b/gui/include/gui/gui_lib.h
@@ -17,7 +17,10 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
**************************************************************************/
-/** \file gui_lib.h General purpose GUI support. */
+/**
+ * \file
+ * General purpose GUI support.
+ */
#ifndef GUI_LIB_H__
#define GUI_LIB_H__
diff --git a/gui/include/gui/ocpn_frame.h b/gui/include/gui/ocpn_frame.h
index 1f0148662c..f8b61a65ce 100644
--- a/gui/include/gui/ocpn_frame.h
+++ b/gui/include/gui/ocpn_frame.h
@@ -333,6 +333,7 @@ class MyFrame : public wxFrame {
void InitApiListeners();
void ReleaseApiListeners();
void UpdateStatusBar(void);
+ void ConfigureStatusBar();
private:
void CheckToolbarPosition();
diff --git a/gui/include/gui/pluginmanager.h b/gui/include/gui/pluginmanager.h
index 14d70e1890..27477b9fef 100644
--- a/gui/include/gui/pluginmanager.h
+++ b/gui/include/gui/pluginmanager.h
@@ -123,7 +123,8 @@ enum ActionVerb {
REINSTALL_MANAGED_VERSION,
DOWNGRADE_INSTALLED_MANAGED_VERSION,
UNINSTALL_MANAGED_VERSION,
- INSTALL_MANAGED_VERSION
+ INSTALL_MANAGED_VERSION,
+ UPDATE_IMPORTED_VERSION
};
class PlugInMenuItemContainer {
@@ -256,6 +257,7 @@ class PlugInManager : public wxEvtHandler {
bool SendMouseEventToPlugins(wxMouseEvent& event);
bool SendKeyEventToPlugins(wxKeyEvent& event);
+ void SendPreShutdownHookToPlugins();
void SendBaseConfigToAllPlugIns();
void SendS52ConfigToAllPlugIns(bool bReconfig = false);
diff --git a/gui/include/gui/udev_rule_mgr.h b/gui/include/gui/udev_rule_mgr.h
index 038c074567..9c1e8d3304 100644
--- a/gui/include/gui/udev_rule_mgr.h
+++ b/gui/include/gui/udev_rule_mgr.h
@@ -18,8 +18,9 @@
**************************************************************************/
/**
- * \file udev_rule_mgr.h Access checks for comm devices and dongle.
+ * \file
*
+ * Access checks for comm devices and dongle.
* Only making anything useful on Linux.
*/
diff --git a/gui/src/chcanv.cpp b/gui/src/chcanv.cpp
index 9050d1723d..3b362b7ebd 100644
--- a/gui/src/chcanv.cpp
+++ b/gui/src/chcanv.cpp
@@ -1218,6 +1218,7 @@ void ChartCanvas::SetShowGPS(bool bshow) {
}
void ChartCanvas::SetShowGPSCompassWindow(bool bshow) {
+ m_bShowCompassWin = bshow;
if (m_Compass) {
m_Compass->Show(m_bShowCompassWin);
if (m_bShowCompassWin) m_Compass->UpdateStatus();
@@ -7119,7 +7120,10 @@ bool ChartCanvas::MouseEventMUIBar(wxMouseEvent &event) {
cursor_region = CENTER;
if (!g_btouch) SetCanvasCursor(event);
- return true;
+ if (m_muiBar)
+ return true;
+ else
+ return false;
}
bool ChartCanvas::MouseEventSetup(wxMouseEvent &event, bool b_handle_dclick) {
diff --git a/gui/src/comm_overflow_dlg.cpp b/gui/src/comm_overflow_dlg.cpp
index ae9587b811..8b46d8922d 100644
--- a/gui/src/comm_overflow_dlg.cpp
+++ b/gui/src/comm_overflow_dlg.cpp
@@ -17,7 +17,10 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
**************************************************************************/
-/** \file comm_oveflow_dlg.cpp Implement comm_oveflow_dlg.cpp.h. */
+/**
+ * \file
+ * Implement comm_oveflow_dlg.cpp.h.
+ */
#include
diff --git a/gui/src/glChartCanvas.cpp b/gui/src/glChartCanvas.cpp
index b66984efce..464f7df22a 100644
--- a/gui/src/glChartCanvas.cpp
+++ b/gui/src/glChartCanvas.cpp
@@ -4995,14 +4995,9 @@ void glChartCanvas::onZoomTimerEvent(wxTimerEvent &event) {
ZoomProject(m_runoffsetx, m_runoffsety, m_runswidth, m_runsheight);
} else {
- // qDebug() << "onZoomTimerEvent DONE" << m_nRun << m_nTotal;
-
zoomTimer.Stop();
if (m_zoomFinal) {
- // qDebug() << "onZoomTimerEvent FINALZOOM" << m_zoomFinalZoom;
-
- m_pParentCanvas->ZoomCanvas(m_zoomFinalZoom, false);
-
+ m_pParentCanvas->ZoomCanvasSimple(m_zoomFinalZoom);
if (m_zoomFinaldx || m_zoomFinaldy) {
m_pParentCanvas->PanCanvas(m_zoomFinaldx, m_zoomFinaldy);
}
@@ -5487,6 +5482,9 @@ void glChartCanvas::OnEvtZoomGesture(wxZoomGestureEvent &event) {
// qDebug() << "finish totalzoom" << total_zoom_val <<
// projected_scale;
+ // Some ptaforms generate spurious gestureEnd events. Guard for this.
+ if (!m_binGesture) return;
+
float cc_x = m_fbo_offsetx + (m_fbo_swidth / 2);
float cc_y = m_fbo_offsety + (m_fbo_sheight / 2);
float dy = 0;
diff --git a/gui/src/gui_lib.cpp b/gui/src/gui_lib.cpp
index d1a3d37fad..c0f467b7e7 100644
--- a/gui/src/gui_lib.cpp
+++ b/gui/src/gui_lib.cpp
@@ -17,7 +17,10 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
**************************************************************************/
-/** \file gui_lib.cpp Implements gui_lib.h */
+/**
+ * \file
+ * Implements gui_lib.h
+ */
#include
#include
diff --git a/gui/src/hotkeys_dlg.cpp b/gui/src/hotkeys_dlg.cpp
index 040501b6f6..42612b2bb5 100644
--- a/gui/src/hotkeys_dlg.cpp
+++ b/gui/src/hotkeys_dlg.cpp
@@ -68,23 +68,28 @@ class ButtonsSizer : public wxStdDialogButtonSizer {
/** Overall help message: key functions and bindings in a string matrix */
class GridSizer : public wxGridSizer {
+private:
+ static constexpr int kGridSize{4};
+ static constexpr int kNumMsgs{12};
+ using MsgLine = std::array;
+ using Messages = std::array;
+
public:
- GridSizer(wxWindow* parent) : wxGridSizer(kMacMessages[0].size()) {
+ GridSizer(wxWindow* parent) : wxGridSizer(kGridSize) {
const auto osSystemId = wxPlatformInfo::Get().GetOperatingSystemId();
- const auto& kMessages =
+ const Messages& kMessages =
(osSystemId & wxOS_MAC) ? kMacMessages : kWinLinuxMessages;
- for (auto line = kMessages.begin(); line != kMessages.end(); line++) {
- for (auto word = line->begin(); word != line->end(); word++) {
- Add(new wxStaticText(parent, wxID_ANY, *word),
+
+ for (const MsgLine& line : kMessages)
+ for (const wxString& word : line)
+ Add(new wxStaticText(parent, wxID_ANY, word),
wxSizerFlags().DoubleBorder());
- }
- }
}
private:
// It's unclear whether _() actually works in this context or
// if wxTRANSLATE is needed instead...
- const std::array, 12> kWinLinuxMessages{
+ const Messages kWinLinuxMessages{
// clang-format off
{{_("Zoom in"), "+, PgUp",
_("Zoom out"), "-, PgDown"},
@@ -110,7 +115,7 @@ class GridSizer : public wxGridSizer {
{_("Drop mark"), _("Ctrl O, space bar"),
"", ""}}};
- const std::array, 12> kMacMessages{
+ const Messages kMacMessages{
{{_("Zoom in"), "+, PgUp",
_("Zoom out"), "-, PgDown"},
{_("Fine zoom in"), "Alt +",
diff --git a/gui/src/load_errors_dlg.cpp b/gui/src/load_errors_dlg.cpp
index 2adc8747c5..6f86c8d6aa 100644
--- a/gui/src/load_errors_dlg.cpp
+++ b/gui/src/load_errors_dlg.cpp
@@ -18,8 +18,8 @@
**************************************************************************/
/**
- * \file load_errors_dlg.h
- * \brief Handle dialog reporting plugin load errors.
+ * \file
+ * Handle dialog reporting plugin load errors.
*
* PluginLoader emits an event containing a list of all plugins which cannot
* be loaded for various reasons when loading is complete. If this list is
diff --git a/gui/src/navutil.cpp b/gui/src/navutil.cpp
index 4795b98579..814fae1629 100644
--- a/gui/src/navutil.cpp
+++ b/gui/src/navutil.cpp
@@ -645,7 +645,7 @@ int MyConfig::LoadMyConfig() {
g_nAWDefault = 50;
g_nAWMax = 1852;
- g_ObjQFileExt = _T("txt,rtf,png,html,gif,tif");
+ g_ObjQFileExt = _T("txt,rtf,png,html,gif,tif,jpg");
// Load the raw value, with no defaults, and no processing
int ret_Val = LoadMyConfigRaw();
diff --git a/gui/src/ocpn_frame.cpp b/gui/src/ocpn_frame.cpp
index c0a9782ca9..67d06f3505 100644
--- a/gui/src/ocpn_frame.cpp
+++ b/gui/src/ocpn_frame.cpp
@@ -631,7 +631,7 @@ static void onBellsFinishedCB(void *ptr) {
static void OnDriverMsg(const ObservedEvt &ev) {
auto msg = ev.GetString().ToStdString();
- OCPNMessageBox(GetTopWindow(), msg, _("Communication Error"), 0, 15);
+ OCPNMessageBox(GetTopWindow(), msg, _("Communication Error"));
}
// My frame constructor
@@ -1562,6 +1562,9 @@ void MyFrame::OnCloseWindow(wxCloseEvent &event) {
}
}
+ // Give any requesting plugins a PreShutdownHook call
+ g_pi_manager->SendPreShutdownHookToPlugins();
+
// We save perspective before closing to restore position next time
// Pane is not closed so the child is not notified (OnPaneClose)
if (g_pAISTargetList) {
@@ -3379,7 +3382,7 @@ void MyFrame::SetToolbarItemSVG(int tool_id, wxString normalSVGfile,
}
}
-void MyFrame::ApplyGlobalSettings(bool bnewtoolbar) {
+void MyFrame::ConfigureStatusBar() {
// ShowDebugWindow as a wxStatusBar
m_StatusBarFieldCount = g_Platform->GetStatusBarFieldCount();
@@ -3401,6 +3404,10 @@ void MyFrame::ApplyGlobalSettings(bool bnewtoolbar) {
SetStatusBar(NULL);
}
}
+}
+
+void MyFrame::ApplyGlobalSettings(bool bnewtoolbar) {
+ ConfigureStatusBar();
wxSize lastOptSize = options_lastWindowSize;
SendSizeEvent();
diff --git a/gui/src/ocpn_plugin_gui.cpp b/gui/src/ocpn_plugin_gui.cpp
new file mode 100644
index 0000000000..8a040e71ff
--- /dev/null
+++ b/gui/src/ocpn_plugin_gui.cpp
@@ -0,0 +1,2487 @@
+/***************************************************************************
+ *
+ * Project: OpenCPN
+ * Purpose: PlugIn GUI API Functions
+ * Author: David Register
+ *
+ ***************************************************************************
+ * Copyright (C) 2024 by David S. Register *
+ * *
+ * 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., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+ **************************************************************************/
+// #include
+// #include
+// #include
+// #include
+// #include
+// #include
+// #include
+// #include
+// #include
+// #include
+// #include
+// #include
+// #include
+// #include
+// #include
+
+#include "dychart.h"
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include "ocpn_plugin.h"
+#include "pluginmanager.h"
+#include "toolbar.h"
+#include "options.h"
+#include "s52plib.h"
+#include "model/route.h"
+#include "model/track.h"
+#include "routemanagerdialog.h"
+#include "model/multiplexer.h"
+#include "chartdb.h"
+#include "OCPNPlatform.h"
+#include "OCPN_AUIManager.h"
+#include "FontMgr.h"
+#include "gui_lib.h"
+#include "model/ais_decoder.h"
+#include "ocpn_app.h"
+#include "ocpn_frame.h"
+#include "svg_utils.h"
+#include "navutil.h"
+#include "model/comm_navmsg_bus.h"
+#include "chcanv.h"
+#include "piano.h"
+#include "waypointman_gui.h"
+#include "routeman_gui.h"
+#include "glChartCanvas.h"
+#include "SoundFactory.h"
+#include "SystemCmdSound.h"
+#include "ais.h"
+
+extern PlugInManager* s_ppim;
+extern MyConfig* pConfig;
+extern OCPN_AUIManager* g_pauimgr;
+
+#if wxUSE_XLOCALE || !wxCHECK_VERSION(3, 0, 0)
+extern wxLocale* plocale_def_lang;
+#endif
+
+extern OCPNPlatform* g_Platform;
+extern ChartDB* ChartData;
+extern MyFrame* gFrame;
+extern ocpnStyle::StyleManager* g_StyleManager;
+extern options* g_pOptions;
+extern Multiplexer* g_pMUX;
+extern bool g_bShowChartBar;
+extern Routeman* g_pRouteMan;
+extern Select* pSelect;
+extern RouteManagerDialog* pRouteManagerDialog;
+extern RouteList* pRouteList;
+extern std::vector