summaryrefslogtreecommitdiff
path: root/src/wx
diff options
context:
space:
mode:
authorCarl Hetherington <cth@carlh.net>2025-01-26 02:18:21 +0100
committerCarl Hetherington <cth@carlh.net>2025-01-26 02:21:16 +0100
commit69fabac6d2219c07cfdcd9a8fe6e92bf4669be46 (patch)
tree1627020b59fb7380f6e7a4d5ba42de8f1955242c /src/wx
parent811e70bdd09a618f8b0a512950a7f3254c591614 (diff)
Add a simple cucumber test.
Diffstat (limited to 'src/wx')
-rw-r--r--src/wx/content_panel.cc35
-rw-r--r--src/wx/content_panel.h5
-rw-r--r--src/wx/cucumber_bridge.cc110
-rw-r--r--src/wx/cucumber_bridge.h75
-rw-r--r--src/wx/cucumber_registry.cc71
-rw-r--r--src/wx/cucumber_registry.h41
-rw-r--r--src/wx/film_editor.cc15
-rw-r--r--src/wx/film_editor.h6
-rw-r--r--src/wx/wscript6
9 files changed, 363 insertions, 1 deletions
diff --git a/src/wx/content_panel.cc b/src/wx/content_panel.cc
index 98eb88ee7..4e3c4d729 100644
--- a/src/wx/content_panel.cc
+++ b/src/wx/content_panel.cc
@@ -22,6 +22,10 @@
#include "audio_panel.h"
#include "content_panel.h"
#include "content_timeline_dialog.h"
+#ifdef DCPOMATIC_CUCUMBER
+#include "cucumber_bridge.h"
+#include "cucumber_registry.h"
+#endif
#include "dcpomatic_button.h"
#include "dir_dialog.h"
#include "file_dialog.h"
@@ -46,6 +50,7 @@
#include "lib/film.h"
#include "lib/film_util.h"
#include "lib/image_content.h"
+#include "lib/job_manager.h"
#include "lib/log.h"
#include "lib/playlist.h"
#include "lib/string_text_file.h"
@@ -1021,3 +1026,33 @@ ContentPanel::window() const
{
return _splitter;
}
+
+
+#ifdef DCPOMATIC_CUCUMBER
+void
+ContentPanel::cucumber_add_content_file (string filename)
+{
+ add_files({filename});
+ auto jm = JobManager::instance();
+ while (jm->work_to_do()) {
+ while (signal_manager->ui_idle()) {}
+ dcpomatic_sleep_seconds(1);
+ }
+}
+
+
+std::string
+ContentPanel::cucumber_get_content_list ()
+{
+ if (!_film) {
+ return {};
+ }
+
+ std::string s;
+ for (auto content: _film->content()) {
+ bool alert;
+ s += wx_to_std(text_for_content(content, alert)) + "\n";
+ }
+ return s;
+}
+#endif
diff --git a/src/wx/content_panel.h b/src/wx/content_panel.h
index f99d518a2..5a273888e 100644
--- a/src/wx/content_panel.h
+++ b/src/wx/content_panel.h
@@ -96,6 +96,11 @@ public:
void add_dcp(boost::filesystem::path dcp);
void add_folder(boost::filesystem::path folder);
+#ifdef DCPOMATIC_CUCUMBER
+ void cucumber_add_content_file(std::string filename);
+ std::string cucumber_get_content_list();
+#endif
+
boost::signals2::signal<void (void)> SelectionChanged;
private:
diff --git a/src/wx/cucumber_bridge.cc b/src/wx/cucumber_bridge.cc
new file mode 100644
index 000000000..3b9f896c9
--- /dev/null
+++ b/src/wx/cucumber_bridge.cc
@@ -0,0 +1,110 @@
+/*
+ Copyright (C) 2020 Carl Hetherington <cth@carlh.net>
+
+ This file is part of DCP-o-matic.
+
+ DCP-o-matic 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.
+
+ DCP-o-matic 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 DCP-o-matic. If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+
+#include "cucumber_bridge.h"
+#include "lib/nanomsg.h"
+#include "lib/dcpomatic_assert.h"
+#include <dcp/raw_convert.h>
+#include <boost/ref.hpp>
+#include <iostream>
+
+
+using std::string;
+using boost::optional;
+using boost::bind;
+
+
+CucumberBridge::CucumberBridge()
+ : _nanomsg(true, "cucumber")
+{
+
+}
+
+
+void
+CucumberBridge::listener()
+{
+ if (!_nanomsg.send(CUCUMBER_BRIDGE_READY "\n", 200)) {
+ std::cerr << "Could not say hello to cucumber server.\n";
+ }
+
+ while (true) {
+ auto id = _nanomsg.receive(-1);
+ if (!id) {
+ continue;
+ }
+
+ Message message;
+ message.id = *id;
+
+ if (
+ *id == CUCUMBER_BRIDGE_CLICK_REGISTERED_BUTTON ||
+ *id == CUCUMBER_BRIDGE_CLICK_BUTTON_ID ||
+ *id == CUCUMBER_BRIDGE_SELECT_MENU ||
+ *id == CUCUMBER_BRIDGE_TYPE ||
+ *id == CUCUMBER_BRIDGE_ADD_CONTENT_FILE
+ ) {
+ auto p = _nanomsg.receive(100);
+ DCPOMATIC_ASSERT(p);
+ message.parameter = *p;
+ }
+
+ boost::mutex::scoped_lock lm(_mutex);
+ _queue.push_back(message);
+ }
+}
+
+
+void
+CucumberBridge::start()
+{
+ wxTheApp->Bind(wxEVT_IDLE, boost::bind(&CucumberBridge::idle, this));
+ _thread = boost::thread(&CucumberBridge::listener, this);
+}
+
+
+void
+CucumberBridge::idle()
+{
+ boost::mutex::scoped_lock lm(_mutex);
+ if (_queue.empty()) {
+ return;
+ }
+
+ auto message = _queue.front();
+ _queue.pop_front();
+ lm.unlock();
+
+ if (message.id == CUCUMBER_BRIDGE_CLICK_REGISTERED_BUTTON) {
+ ClickRegisteredButton(*message.parameter);
+ } else if (message.id == CUCUMBER_BRIDGE_CLICK_BUTTON_ID) {
+ ClickButtonId(static_cast<wxStandardID>(dcp::raw_convert<int>(*message.parameter)));
+ } else if (message.id == CUCUMBER_BRIDGE_SELECT_MENU) {
+ SelectMenu(*message.parameter);
+ } else if (message.id == CUCUMBER_BRIDGE_TYPE) {
+ Type(*message.parameter);
+ } else if (message.id == CUCUMBER_BRIDGE_ADD_CONTENT_FILE) {
+ AddContentFile(*message.parameter);
+ } else if (message.id == CUCUMBER_BRIDGE_GET_CONTENT_LIST) {
+ /* I hope it's OK to send and receive from nanomsg sockets from different threads */
+ _nanomsg.send(GetContentList()->c_str(), -1);
+ }
+}
diff --git a/src/wx/cucumber_bridge.h b/src/wx/cucumber_bridge.h
new file mode 100644
index 000000000..658480855
--- /dev/null
+++ b/src/wx/cucumber_bridge.h
@@ -0,0 +1,75 @@
+/*
+ Copyright (C) 2020 Carl Hetherington <cth@carlh.net>
+
+ This file is part of DCP-o-matic.
+
+ DCP-o-matic 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.
+
+ DCP-o-matic 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 DCP-o-matic. If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+
+#include "lib/nanomsg.h"
+#include "lib/signaller.h"
+#include <boost/signals2.hpp>
+#include <boost/thread.hpp>
+#include <wx/wx.h>
+
+
+#define CUCUMBER_BRIDGE_READY "ready"
+#define CUCUMBER_BRIDGE_CLICK_REGISTERED_BUTTON "click_registered_button"
+#define CUCUMBER_BRIDGE_CLICK_BUTTON_ID "click_button_id"
+#define CUCUMBER_BRIDGE_SELECT_MENU "select_menu"
+#define CUCUMBER_BRIDGE_TYPE "type"
+#define CUCUMBER_BRIDGE_CHARACTER "character"
+#define CUCUMBER_BRIDGE_ADD_CONTENT_FILE "add_content_file"
+#define CUCUMBER_BRIDGE_GET_CONTENT_LIST "get_content_list"
+
+#define CUCUMBER_MENU_FILE_NEW "file_new"
+
+
+class Nanomsg;
+
+
+class CucumberBridge : public Signaller
+{
+public:
+ CucumberBridge();
+
+ void start();
+
+ /* Emitted in the GUI thread */
+ boost::signals2::signal<void (std::string)> ClickRegisteredButton;
+ boost::signals2::signal<void (wxStandardID)> ClickButtonId;
+ boost::signals2::signal<void (std::string)> SelectMenu;
+ boost::signals2::signal<void (std::string)> Type;
+ boost::signals2::signal<void (std::string)> AddContentFile;
+ boost::signals2::signal<std::string ()> GetContentList;
+
+private:
+ void listener();
+ void idle();
+
+ struct Message
+ {
+ std::string id;
+ boost::optional<std::string> parameter;
+ };
+
+ boost::thread _thread;
+ boost::mutex _mutex;
+ std::list<Message> _queue;
+
+ Nanomsg _nanomsg;
+};
+
diff --git a/src/wx/cucumber_registry.cc b/src/wx/cucumber_registry.cc
new file mode 100644
index 000000000..d4684d67a
--- /dev/null
+++ b/src/wx/cucumber_registry.cc
@@ -0,0 +1,71 @@
+/*
+ Copyright (C) 2020 Carl Hetherington <cth@carlh.net>
+
+ This file is part of DCP-o-matic.
+
+ DCP-o-matic 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.
+
+ DCP-o-matic 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 DCP-o-matic. If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+
+#include "cucumber_registry.h"
+#include "lib/dcpomatic_assert.h"
+#include <wx/wx.h>
+
+
+using std::map;
+using std::string;
+
+
+CucumberRegistry* CucumberRegistry::_instance = 0;
+
+
+CucumberRegistry *
+CucumberRegistry::instance()
+{
+ if (!_instance) {
+ _instance = new CucumberRegistry();
+ }
+
+ return _instance;
+}
+
+
+void
+CucumberRegistry::add(string id, wxButton* button)
+{
+ _buttons[id] = button;
+}
+
+
+void
+CucumberRegistry::remove(wxButton* button)
+{
+ for (map<string, wxButton*>::iterator i = _buttons.begin(); i != _buttons.end(); ++i) {
+ if (i->second == button) {
+ _buttons.erase(i);
+ return;
+ }
+ }
+}
+
+
+void
+CucumberRegistry::click_button(string id)
+{
+ auto i = _buttons.find(id);
+ DCPOMATIC_ASSERT(i != _buttons.end());
+ wxPostEvent(i->second, wxCommandEvent(wxEVT_BUTTON));
+}
+
diff --git a/src/wx/cucumber_registry.h b/src/wx/cucumber_registry.h
new file mode 100644
index 000000000..c08053c48
--- /dev/null
+++ b/src/wx/cucumber_registry.h
@@ -0,0 +1,41 @@
+/*
+ Copyright (C) 2020 Carl Hetherington <cth@carlh.net>
+
+ This file is part of DCP-o-matic.
+
+ DCP-o-matic 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.
+
+ DCP-o-matic 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 DCP-o-matic. If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+
+#include <map>
+#include <string>
+
+class wxButton;
+
+class CucumberRegistry
+{
+public:
+ void add(std::string id, wxButton* button);
+ void remove(wxButton* button);
+ void click_button(std::string id);
+
+ static CucumberRegistry* instance();
+
+private:
+ static CucumberRegistry* _instance;
+
+ std::map<std::string, wxButton*> _buttons;
+};
+
diff --git a/src/wx/film_editor.cc b/src/wx/film_editor.cc
index fae02787a..d0e9bf4a7 100644
--- a/src/wx/film_editor.cc
+++ b/src/wx/film_editor.cc
@@ -189,3 +189,18 @@ FilmEditor::first_shown ()
_content_panel->first_shown ();
}
+
+#ifdef DCPOMATIC_CUCUMBER
+void
+FilmEditor::cucumber_add_content_file(string filename)
+{
+ _content_panel->cucumber_add_content_file(filename);
+}
+
+
+string
+FilmEditor::cucumber_get_content_list()
+{
+ return _content_panel->cucumber_get_content_list();
+}
+#endif
diff --git a/src/wx/film_editor.h b/src/wx/film_editor.h
index 54d639ef5..70ee3be8b 100644
--- a/src/wx/film_editor.h
+++ b/src/wx/film_editor.h
@@ -65,6 +65,12 @@ public:
private:
+#ifdef DCPOMATIC_CUCUMBER
+ friend class DOMFrame;
+ void cucumber_add_content_file(std::string filename);
+ std::string cucumber_get_content_list();
+#endif
+
/* Handle changes to the model */
void film_change(ChangeType, FilmProperty);
void film_content_change (ChangeType type, int);
diff --git a/src/wx/wscript b/src/wx/wscript
index 583fe4bb0..73b92fac9 100644
--- a/src/wx/wscript
+++ b/src/wx/wscript
@@ -333,7 +333,7 @@ def build(bld):
obj.name = 'libdcpomatic2-wx'
obj.export_includes = ['..']
- obj.uselib = 'BOOST_FILESYSTEM BOOST_THREAD BOOST_REGEX WXWIDGETS DCP SUB ZIP CXML RTAUDIO ICU AVUTIL '
+ obj.uselib = 'BOOST_FILESYSTEM BOOST_THREAD BOOST_REGEX WXWIDGETS DCP SUB ZIP CXML RTAUDIO ICU AVUTIL NANOMSG'
if bld.env.TARGET_LINUX:
obj.uselib += 'GTK GL GLU '
if bld.env.TARGET_WINDOWS_64 or bld.env.TARGET_WINDOWS_32:
@@ -341,6 +341,10 @@ def build(bld):
if bld.env.TARGET_OSX:
obj.framework = ['CoreAudio', 'OpenGL']
obj.use = 'libdcpomatic2'
+
+ global sources
+ if bld.env.ENABLE_CUCUMBER:
+ sources += " cucumber_bridge.cc cucumber_registry.cc"
obj.source = sources
obj.target = 'dcpomatic2-wx'