summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorStanislaw Halik <sthalik@misaki.pl>2018-04-03 12:26:38 +0200
committerStanislaw Halik <sthalik@misaki.pl>2018-04-05 03:23:13 +0200
commiteb32a2ac02c6d1adcfeb0a1a5522f8aaea442489 (patch)
treeb15b4ab34600e9c5d5da17eac33ea687167bbfc7
parent22a853b388597e9549125df69508c1c38706dd1d (diff)
i18n: provide for non-QObject classes
See compat/tr.hpp for comment.
-rw-r--r--api/plugin-api.cpp7
-rw-r--r--api/plugin-api.hpp24
-rw-r--r--api/plugin-support.hpp4
-rw-r--r--cmake/opentrack-i18n.cmake1
-rw-r--r--cmake/opentrack-install.cmake9
-rw-r--r--compat/macros.hpp15
-rw-r--r--compat/tr.cpp17
-rw-r--r--compat/tr.hpp19
-rw-r--r--logic/extensions.cpp2
-rw-r--r--logic/extensions.hpp2
-rw-r--r--logic/runtime-libraries.cpp12
-rw-r--r--logic/runtime-libraries.hpp6
-rw-r--r--logic/work.cpp8
-rw-r--r--logic/work.hpp6
14 files changed, 95 insertions, 37 deletions
diff --git a/api/plugin-api.cpp b/api/plugin-api.cpp
index 6c9a21bc..004938f1 100644
--- a/api/plugin-api.cpp
+++ b/api/plugin-api.cpp
@@ -5,7 +5,7 @@ using namespace plugin_api::detail;
// these exist so that vtable is emitted in a single compilation unit, not all of them.
-Metadata::~Metadata() {}
+Metadata_::~Metadata_() {}
IFilter::~IFilter() {}
IProtocol::~IProtocol() {}
ITracker::~ITracker() {}
@@ -37,7 +37,7 @@ module_status ITracker::error(const QString& error)
return module_status(error);
}
-Metadata::Metadata() {}
+Metadata_::Metadata_() {}
IFilter::IFilter() {}
IFilterDialog::IFilterDialog() {}
IProtocol::IProtocol() {}
@@ -69,5 +69,6 @@ module_status module_status_mixin::status_ok() { return module_status(); }
module_status module_status_mixin::error(const QString& error)
{
- return module_status(error.isEmpty() ? _("Unknown error") : error);
+ return module_status(error.isEmpty() ? "Unknown error" : error);
}
+
diff --git a/api/plugin-api.hpp b/api/plugin-api.hpp
index 4a797f73..75555e93 100644
--- a/api/plugin-api.hpp
+++ b/api/plugin-api.hpp
@@ -16,6 +16,7 @@
#include <QDialog>
#include "compat/simple-mat.hpp"
+#include "compat/tr.hpp"
#include "export.hpp"
using Pose = Mat<double, 6, 1>;
@@ -49,14 +50,14 @@ private slots:
#define OPENTRACK_DECLARE_PLUGIN_INTERNAL(ctor_class, ctor_ret_class, metadata_class, dialog_class, dialog_ret_class) \
extern "C" OTR_PLUGIN_EXPORT ctor_ret_class* GetConstructor(); \
- extern "C" OTR_PLUGIN_EXPORT Metadata* GetMetadata(); \
+ extern "C" OTR_PLUGIN_EXPORT Metadata_* GetMetadata(); \
extern "C" OTR_PLUGIN_EXPORT dialog_ret_class* GetDialog(); \
\
extern "C" OTR_PLUGIN_EXPORT ctor_ret_class* GetConstructor() \
{ \
return new ctor_class; \
} \
- extern "C" OTR_PLUGIN_EXPORT Metadata* GetMetadata() \
+ extern "C" OTR_PLUGIN_EXPORT Metadata_* GetMetadata() \
{ \
return new metadata_class; \
} \
@@ -67,19 +68,26 @@ private slots:
// implement this in all plugins
// also you must link against "opentrack-api" in CMakeLists.txt to avoid vtable link errors
-struct OTR_API_EXPORT Metadata
+class OTR_API_EXPORT Metadata_
{
- Metadata(const Metadata&) = delete;
- Metadata(Metadata&&) = delete;
- Metadata& operator=(const Metadata&) = delete;
- Metadata();
+public:
+ Metadata_();
// plugin name to be displayed in the interface
virtual QString name() = 0;
// plugin icon, you can return an empty QIcon()
virtual QIcon icon() = 0;
// optional destructor
- virtual ~Metadata();
+ virtual ~Metadata_();
+};
+
+class OTR_API_EXPORT Metadata : public TR, public Metadata_
+{
+ Q_OBJECT
+
+public:
+ Metadata() {}
+ ~Metadata() {}
};
struct OTR_API_EXPORT module_status final
diff --git a/api/plugin-support.hpp b/api/plugin-support.hpp
index 8fc01b98..b3f3396b 100644
--- a/api/plugin-support.hpp
+++ b/api/plugin-support.hpp
@@ -32,7 +32,7 @@
#define OPENTRACK_SOLIB_PREFIX "lib"
extern "C" typedef void* (*OPENTRACK_CTOR_FUNPTR)(void);
-extern "C" typedef Metadata* (*OPENTRACK_METADATA_FUNPTR)(void);
+extern "C" typedef Metadata_* (*OPENTRACK_METADATA_FUNPTR)(void);
struct dylib final
{
@@ -72,7 +72,7 @@ struct dylib final
if (check((Meta = (OPENTRACK_METADATA_FUNPTR) handle.resolve("GetMetadata"), !Meta)))
return;
- auto m = std::unique_ptr<Metadata>(Meta());
+ auto m = std::unique_ptr<Metadata_>(Meta());
icon = m->icon();
name = m->name();
diff --git a/cmake/opentrack-i18n.cmake b/cmake/opentrack-i18n.cmake
index 34d1a3c3..4416a272 100644
--- a/cmake/opentrack-i18n.cmake
+++ b/cmake/opentrack-i18n.cmake
@@ -6,7 +6,6 @@ function(otr_i18n_for_target_directory n)
foreach(i ${opentrack_all-translations})
set(t "${CMAKE_CURRENT_SOURCE_DIR}/lang/${i}.ts")
set(t2 "${CMAKE_CURRENT_BINARY_DIR}/lang/${i}.ts")
- set_property(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" PROPERTY CLEAN_NO_CUSTOM 1)
set(input ${${k}-cc} ${${k}-hh} ${${k}-ui} ${${k}-rc})
add_custom_command(OUTPUT "${t2}"
COMMAND "${CMAKE_COMMAND}" -E make_directory "${CMAKE_CURRENT_SOURCE_DIR}/lang"
diff --git a/cmake/opentrack-install.cmake b/cmake/opentrack-install.cmake
index 406a4dbb..074f6d97 100644
--- a/cmake/opentrack-install.cmake
+++ b/cmake/opentrack-install.cmake
@@ -35,6 +35,11 @@ function(install_sources)
endif()
endfunction()
+function(cleanup_visual_studio_debug)
+ otr_escape_string(pfx "${CMAKE_INSTALL_PREFIX}")
+ install(CODE "file(REMOVE_RECURSE \"${pfx}/.vs\")")
+endfunction()
+
otr_install_dir("${opentrack-doc-pfx}" ${CMAKE_SOURCE_DIR}/3rdparty-notices)
otr_install_dir("${opentrack-doc-pfx}" "${CMAKE_SOURCE_DIR}/settings" "${CMAKE_SOURCE_DIR}/contrib")
@@ -56,6 +61,10 @@ otr_install_misc("${opentrack-doc-src-pfx}" FILES "${CMAKE_SOURCE_DIR}/AUTHORS.m
# this must be done last because the files may be in use already
# do it last so in case of file-in-use failure, the rest is installed
+if(MSVC AND CMAKE_HOST_SYSTEM_NAME STREQUAL "Windows")
+ cleanup_visual_studio_debug()
+endif()
+
otr_install_exec("${opentrack-hier-pfx}" FILES "${CMAKE_SOURCE_DIR}/bin/freetrackclient.dll")
otr_install_exec("${opentrack-hier-pfx}" FILES
"${CMAKE_SOURCE_DIR}/bin/NPClient.dll"
diff --git a/compat/macros.hpp b/compat/macros.hpp
index c8fbca20..b0c7a51d 100644
--- a/compat/macros.hpp
+++ b/compat/macros.hpp
@@ -1,16 +1,9 @@
#pragma once
-#if !defined __WINE__
-# include <QCoreApplication>
-# define otr_tr(...) (QCoreApplication::translate(OTR_MODULE_NAME, __VA_ARGS__))
-# define _(...) (otr_tr(__VA_ARGS__))
-#endif
-
#if defined _MSC_VER
-#
-# define MEMORY_BARRIER _ReadWriteBarrier()
+# define MEMORY_BARRIER() _ReadWriteBarrier()
#else
-# define MEMORY_BARRIER asm volatile("" ::: "memory")
+# define MEMORY_BARRIER() asm volatile("" ::: "memory")
#endif
#if defined _MSC_VER
@@ -52,3 +45,7 @@
#else
# define OTR_FUNNAME (__PRETTY_FUNCTION__)
#endif
+
+#if defined __cplusplus
+# define thunk(...) ([&]() { __VA_ARGS__; })
+#endif
diff --git a/compat/tr.cpp b/compat/tr.cpp
new file mode 100644
index 00000000..b3349435
--- /dev/null
+++ b/compat/tr.cpp
@@ -0,0 +1,17 @@
+#include "tr.hpp"
+
+
+TR::TR() {}
+
+TR::TR(const TR&) {}
+
+TR&TR::operator=(const TR& other)
+{
+ if (this == &other)
+ return *this;
+
+ TR::~TR();
+ return *new (this) TR;
+}
+
+TR::~TR() {}
diff --git a/compat/tr.hpp b/compat/tr.hpp
new file mode 100644
index 00000000..7bb4fb71
--- /dev/null
+++ b/compat/tr.hpp
@@ -0,0 +1,19 @@
+#pragma once
+
+#include <QObject>
+#include "export.hpp"
+
+// The class does nothing except provide a fake assignment operator for QObject
+// It's meant to be used inside classes that need i18n support but are returned by value.
+
+class OTR_COMPAT_EXPORT TR : public QObject
+{
+ Q_OBJECT
+
+public:
+ TR();
+ TR(const TR&);
+ ~TR() override;
+
+ TR& operator=(const TR& other);
+};
diff --git a/logic/extensions.cpp b/logic/extensions.cpp
index 22eef6df..438f6dde 100644
--- a/logic/extensions.cpp
+++ b/logic/extensions.cpp
@@ -39,7 +39,7 @@ event_handler::event_handler(Modules::dylib_list const& extensions) : ext_bundle
{
std::shared_ptr<IExtension> ext(reinterpret_cast<IExtension*>(lib->Constructor()));
std::shared_ptr<IExtensionDialog> dlg(reinterpret_cast<IExtensionDialog*>(lib->Dialog()));
- std::shared_ptr<Metadata> m(reinterpret_cast<Metadata*>(lib->Meta()));
+ std::shared_ptr<Metadata_> m(reinterpret_cast<Metadata_*>(lib->Meta()));
const ext_mask mask = ext->hook_types();
diff --git a/logic/extensions.hpp b/logic/extensions.hpp
index 4d6763b2..3368b118 100644
--- a/logic/extensions.hpp
+++ b/logic/extensions.hpp
@@ -23,7 +23,7 @@ struct OTR_LOGIC_EXPORT event_handler final
{
using ext = std::shared_ptr<IExtension>;
using dlg = std::shared_ptr<IExtensionDialog>;
- using m = std::shared_ptr<Metadata>;
+ using m = std::shared_ptr<Metadata_>;
ext logic;
dlg dialog;
diff --git a/logic/runtime-libraries.cpp b/logic/runtime-libraries.cpp
index d05e90c2..aa38b032 100644
--- a/logic/runtime-libraries.cpp
+++ b/logic/runtime-libraries.cpp
@@ -6,7 +6,7 @@
runtime_libraries::runtime_libraries(QFrame* frame, dylibptr t, dylibptr p, dylibptr f)
{
module_status status =
- module_status_mixin::error(otr_tr("Library load failure"));
+ module_status_mixin::error(tr("Library load failure"));
using namespace options;
@@ -19,8 +19,8 @@ runtime_libraries::runtime_libraries(QFrame* frame, dylibptr t, dylibptr p, dyli
if(status = pProtocol->initialize(), !status.is_ok())
{
- status = _("Error occurred while loading protocol %1\n\n%2\n")
- .arg(p->name).arg(status.error);
+ status = tr("Error occurred while loading protocol %1\n\n%2\n")
+ .arg(p->name).arg(status.error);
goto end;
}
@@ -36,14 +36,14 @@ runtime_libraries::runtime_libraries(QFrame* frame, dylibptr t, dylibptr p, dyli
if (pFilter)
if(status = pFilter->initialize(), !status.is_ok())
{
- status = _("Error occurred while loading filter %1\n\n%2\n")
+ status = tr("Error occurred while loading filter %1\n\n%2\n")
.arg(f->name).arg(status.error);
goto end;
}
if (status = pTracker->start_tracker(frame), !status.is_ok())
{
- status = _("Error occurred while loading tracker %1\n\n%2\n")
+ status = tr("Error occurred while loading tracker %1\n\n%2\n")
.arg(t->name).arg(status.error);
goto end;
}
@@ -57,6 +57,6 @@ end:
pProtocol = nullptr;
if (!status.is_ok())
- QMessageBox::critical(nullptr, "Startup failure", status.error, QMessageBox::Cancel, QMessageBox::NoButton);
+ QMessageBox::critical(nullptr, tr("Startup failure"), status.error, QMessageBox::Cancel, QMessageBox::NoButton);
}
diff --git a/logic/runtime-libraries.hpp b/logic/runtime-libraries.hpp
index 1105c179..acf5bf30 100644
--- a/logic/runtime-libraries.hpp
+++ b/logic/runtime-libraries.hpp
@@ -9,12 +9,16 @@
#pragma once
#include "api/plugin-support.hpp"
+#include "compat/tr.hpp"
#include "export.hpp"
#include <QFrame>
-struct OTR_LOGIC_EXPORT runtime_libraries final
+class OTR_LOGIC_EXPORT runtime_libraries final : public TR
{
+ Q_OBJECT
+
+public:
using dylibptr = std::shared_ptr<dylib>;
std::shared_ptr<ITracker> pTracker;
diff --git a/logic/work.cpp b/logic/work.cpp
index 090158eb..16538382 100644
--- a/logic/work.cpp
+++ b/logic/work.cpp
@@ -16,9 +16,9 @@ QString Work::browse_datalogging_file(main_settings &s)
Since the freeze is apparently random, I'm not sure it helped.
*/
QString newfilename = QFileDialog::getSaveFileName(nullptr,
- otr_tr("Select filename"),
+ tr("Select filename"),
filename,
- otr_tr("CSV File (*.csv)"),
+ tr("CSV File (*.csv)"),
nullptr);
if (!newfilename.isEmpty())
{
@@ -45,8 +45,8 @@ std::shared_ptr<TrackLogger> Work::make_logger(main_settings &s)
{
logger = nullptr;
QMessageBox::warning(nullptr,
- otr_tr("Logging error"),
- otr_tr("Unable to open file '%1'. Proceeding without logging.").arg(s.tracklogging_filename),
+ tr("Logging error"),
+ tr("Unable to open file '%1'. Proceeding without logging.").arg(s.tracklogging_filename),
QMessageBox::Ok, QMessageBox::NoButton);
}
else
diff --git a/logic/work.hpp b/logic/work.hpp
index a0033f62..d5bb201e 100644
--- a/logic/work.hpp
+++ b/logic/work.hpp
@@ -16,6 +16,7 @@
#include "tracklogger.hpp"
#include "logic/runtime-libraries.hpp"
#include "api/plugin-support.hpp"
+#include "compat/tr.hpp"
#include <QObject>
#include <QFrame>
@@ -24,8 +25,11 @@
#include <tuple>
#include <functional>
-struct OTR_LOGIC_EXPORT Work final
+class OTR_LOGIC_EXPORT Work final : public TR
{
+ Q_OBJECT
+
+public:
using fn_t = std::function<void(bool)>;
using key_tuple = std::tuple<key_opts&, fn_t, bool>;
main_settings s; // tracker needs settings, so settings must come before it