/*
- Copyright (C) 2012-2021 Carl Hetherington <cth@carlh.net>
+ Copyright (C) 2012-2022 Carl Hetherington <cth@carlh.net>
This file is part of DCP-o-matic.
#include "wx/about_dialog.h"
#include "wx/content_panel.h"
+#ifdef DCPOMATIC_CUCUMBER
+#include "wx/cucumber_bridge.h"
+#include "wx/cucumber_registry.h"
+#endif
#include "wx/dkdm_dialog.h"
#include "wx/export_subtitles_dialog.h"
#include "wx/export_video_file_dialog.h"
#include "lib/version.h"
#include "lib/video_content.h"
#include <dcp/exceptions.h>
+#include <dcp/filesystem.h>
#include <dcp/raw_convert.h>
#include <dcp/warnings.h>
LIBDCP_DISABLE_WARNINGS
LIBDCP_ENABLE_WARNINGS
#ifdef __WXGTK__
#include <X11/Xlib.h>
+extern "C" {
+#include <xdo.h>
+}
#endif
#ifdef __WXMSW__
#include <shellapi.h>
, _right_panel(new wxPanel(_splitter, wxID_ANY))
, _film_viewer(_right_panel)
{
-#if defined(DCPOMATIC_WINDOWS)
- if (Config::instance()->win32_console()) {
- AllocConsole();
-
- HANDLE handle_out = GetStdHandle(STD_OUTPUT_HANDLE);
- int hCrt = _open_osfhandle((intptr_t) handle_out, _O_TEXT);
- FILE* hf_out = _fdopen(hCrt, "w");
- setvbuf(hf_out, NULL, _IONBF, 1);
- *stdout = *hf_out;
-
- HANDLE handle_in = GetStdHandle(STD_INPUT_HANDLE);
- hCrt = _open_osfhandle((intptr_t) handle_in, _O_TEXT);
- FILE* hf_in = _fdopen(hCrt, "r");
- setvbuf(hf_in, NULL, _IONBF, 128);
- *stdin = *hf_in;
-
- cout << "DCP-o-matic is starting." << "\n";
- }
-#endif
auto bar = new wxMenuBar;
setup_menu (bar);
}
catch (FileNotFoundError& e) {
auto const dir = e.file().parent_path();
- if (boost::filesystem::exists(dir / "ASSETMAP") || boost::filesystem::exists(dir / "ASSETMAP.xml")) {
+ if (dcp::filesystem::exists(dir / "ASSETMAP") || dcp::filesystem::exists(dir / "ASSETMAP.xml")) {
error_dialog (
this, _("Could not open this folder as a DCP-o-matic project."),
_("It looks like you are trying to open a DCP. File -> Open is for loading DCP-o-matic projects, not DCPs. To import a DCP, create a new project with File -> New and then click the \"Add DCP...\" button.")
return _film;
}
+#ifdef DCPOMATIC_CUCUMBER
+ void cucumber_add_content_file (string filename) {
+ std::cout << ".cucumber_add_content_file\n";
+ _film_editor->cucumber_add_content_file (filename);
+ }
+
+ /* Could be called from any thread */
+ std::string cucumber_get_content_list () {
+ std::cout << ".cucumber_get_content_list\n";
+ return _film_editor->cucumber_get_content_list();
+ }
+#endif
+
private:
void show (wxShowEvent& ev)
void edit_copy ()
{
auto const sel = _film_editor->content_panel()->selected();
- DCPOMATIC_ASSERT (sel.size() == 1);
- _clipboard = sel.front()->clone();
+ if (sel.size() == 1) {
+ _clipboard = sel.front()->clone();
+ }
}
void edit_paste ()
{
- DCPOMATIC_ASSERT (_clipboard);
+ if (!_clipboard) {
+ return;
+ }
PasteDialog dialog(this, static_cast<bool>(_clipboard->video), static_cast<bool>(_clipboard->audio), !_clipboard->text.empty());
if (dialog.ShowModal() != wxID_OK) {
/* Remove any existing DCP if the user agrees */
auto const dcp_dir = _film->dir (_film->dcp_name(), false);
- if (boost::filesystem::exists(dcp_dir)) {
+ if (dcp::filesystem::exists(dcp_dir)) {
if (!confirm_dialog (this, wxString::Format (_("Do you want to overwrite the existing DCP %s?"), std_to_wx(dcp_dir.string()).data()))) {
return;
}
- boost::filesystem::remove_all (dcp_dir);
+ dcp::filesystem::remove_all(dcp_dir);
}
try {
return;
}
- if (boost::filesystem::exists(dialog.path())) {
+ if (dcp::filesystem::exists(dialog.path())) {
bool ok = confirm_dialog(
this,
wxString::Format(_("File %s already exists. Do you want to overwrite it?"), std_to_wx(dialog.path().string()).data())
{ wxCMD_LINE_OPTION, "c", "content", "add content file / directory", wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_OPTIONAL },
{ wxCMD_LINE_OPTION, "d", "dcp", "add content DCP", wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_OPTIONAL },
{ wxCMD_LINE_SWITCH, "v", "version", "show DCP-o-matic version", wxCMD_LINE_VAL_NONE, wxCMD_LINE_PARAM_OPTIONAL },
+#ifdef DCPOMATIC_CUCUMBER
+ { wxCMD_LINE_SWITCH, "t", "cucumber", "enable cucumber tests", wxCMD_LINE_VAL_NONE, wxCMD_LINE_PARAM_OPTIONAL },
+#endif
{ wxCMD_LINE_OPTION, "", "config", "directory containing config.xml and cinemas.xml", wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_OPTIONAL },
{ wxCMD_LINE_PARAM, 0, 0, "film to load or create", wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_OPTIONAL },
{ wxCMD_LINE_NONE, "", "", "", wxCmdLineParamType (0), 0 }
bool OnInit () override
{
try {
+
+#if defined(DCPOMATIC_WINDOWS)
+ if (Config::instance()->win32_console()) {
+ AllocConsole();
+
+ HANDLE handle_out = GetStdHandle(STD_OUTPUT_HANDLE);
+ int hCrt = _open_osfhandle((intptr_t) handle_out, _O_TEXT);
+ FILE* hf_out = _fdopen(hCrt, "w");
+ setvbuf(hf_out, NULL, _IONBF, 1);
+ *stdout = *hf_out;
+
+ HANDLE handle_in = GetStdHandle(STD_INPUT_HANDLE);
+ hCrt = _open_osfhandle((intptr_t) handle_in, _O_TEXT);
+ FILE* hf_in = _fdopen(hCrt, "r");
+ setvbuf(hf_in, NULL, _IONBF, 128);
+ *stdin = *hf_in;
+
+ cout << "DCP-o-matic is starting." << "\n";
+ }
+#endif
wxInitAllImageHandlers ();
Config::FailedToLoad.connect(boost::bind(&App::config_failed_to_load, this, _1));
signal_manager = new wxSignalManager (this);
Bind (wxEVT_IDLE, boost::bind (&App::idle, this, _1));
- if (!_film_to_load.empty() && boost::filesystem::is_directory(_film_to_load)) {
+ if (!_film_to_load.empty() && dcp::filesystem::is_directory(_film_to_load)) {
try {
_frame->load_film (_film_to_load);
} catch (exception& e) {
notes.Centre();
notes.ShowModal();
}
+
+#ifdef DCPOMATIC_CUCUMBER
+ if (_cucumber_bridge) {
+ _cucumber_bridge->start();
+ }
+#endif
}
catch (exception& e)
{
return true;
}
- void OnInitCmdLine (wxCmdLineParser& parser) override
+ int FilterEvent(wxEvent& event) override
+ {
+ auto key = dynamic_cast<wxKeyEvent*>(&event);
+ if (key && key->GetEventType() == wxEVT_CHAR) {
+ std::cout << "CHAR: " << key->m_keyCode << " " << key->m_uniChar << " " << key->m_rawCode << " " << key->m_rawFlags << "\n";
+ } else if (key && key->GetEventType() == wxEVT_KEY_UP) {
+ std::cout << "KEY_UP: " << key->m_keyCode << " " << key->m_uniChar << " " << key->m_rawCode << " " << key->m_rawFlags << "\n";
+ } else if (key && key->GetEventType() == wxEVT_KEY_DOWN) {
+ std::cout << "KEY_DOWN: " << key->m_keyCode << " " << key->m_uniChar << " " << key->m_rawCode << " " << key->m_rawFlags << "\n";
+ }
+ return -1;
+ }
+
+ void OnInitCmdLine(wxCmdLineParser& parser) override
{
parser.SetDesc (command_line_description);
parser.SetSwitchChars (wxT ("-"));
State::override_path = wx_to_std (config);
}
+#ifdef DCPOMATIC_CUCUMBER
+ if (parser.Found(wxT("cucumber"))) {
+ _cucumber_bridge = new CucumberBridge ();
+ _cucumber_bridge->ClickButton.connect (bind(&App::cucumber_click_button, this, _1));
+ _cucumber_bridge->SelectMenu.connect (bind(&App::cucumber_select_menu, this, _1));
+ _cucumber_bridge->Type.connect (bind(&App::cucumber_type, this, _1));
+ _cucumber_bridge->AddContentFile.connect (bind(&App::cucumber_add_content_file, this, _1));
+ _cucumber_bridge->GetContentList.connect (bind(&App::cucumber_get_content_list, this));
+ }
+#endif
+
return true;
}
+
+#ifdef DCPOMATIC_CUCUMBER
+ void cucumber_add_content_file (string filename)
+ {
+ _frame->cucumber_add_content_file (filename);
+ }
+
+
+ std::string cucumber_get_content_list ()
+ {
+ return _frame->cucumber_get_content_list ();
+ }
+
+
+ void cucumber_click_button (string id)
+ {
+ CucumberRegistry::instance()->click_button (id);
+ }
+
+
+ void cucumber_select_menu (string id)
+ {
+ if (id == CUCUMBER_MENU_FILE_NEW) {
+ wxPostEvent (_frame, wxMenuEvent(wxEVT_MENU, ID_file_new));
+ }
+ }
+
+
+ void cucumber_type (string text)
+ {
+#ifdef DCPOMATIC_LINUX
+ // xdo_t* xdo = xdo_new (NULL);
+ // xdo_enter_text_window (xdo, CURRENTWINDOW, text.c_str(), 200000);
+ // xdo_send_keysequence_window (xdo, CURRENTWINDOW, "Return", 200000);
+ // xdo_free (xdo);
+ auto send = [this](int code, int rawcode) {
+ auto event = wxKeyEvent(wxEVT_KEY_DOWN);
+ event.SetEventObject(this);
+ event.m_keyCode = event.m_uniChar = code;
+ event.m_rawCode = rawcode;
+ std::cout << "process " << code << " " << rawcode << "\n";
+ ProcessEvent (event);
+
+ event = wxKeyEvent(wxEVT_CHAR);
+ event.SetEventObject(this);
+ event.m_keyCode = event.m_uniChar = code;
+ event.m_rawCode = rawcode;
+ std::cout << "process " << code << " " << rawcode << "\n";
+ ProcessEvent (event);
+
+ event = wxKeyEvent(wxEVT_KEY_UP);
+ event.SetEventObject(this);
+ event.m_keyCode = event.m_uniChar = code;
+ event.m_rawCode = rawcode;
+ std::cout << "process " << code << " " << rawcode << "\n";
+ ProcessEvent (event);
+ };
+
+ for (auto i = 0U; i < text.length(); ++i) {
+ send (text[i], text[i]);
+ }
+ send (WXK_RETURN, 65293);
+#endif
+ }
+#endif
+
void report_exception ()
{
try {
void close_splash ()
{
- _splash->Destroy();
- _splash = nullptr;
+ if (_splash) {
+ _splash->Destroy();
+ _splash = nullptr;
+ }
}
void config_failed_to_load (Config::LoadFailure what)
}
DOMFrame* _frame = nullptr;
- wxSplashScreen* _splash;
+ wxSplashScreen* _splash = nullptr;
shared_ptr<wxTimer> _timer;
string _film_to_load;
string _film_to_create;
string _content_to_add;
string _dcp_to_add;
+#ifdef DCPOMATIC_CUCUMBER
+ CucumberBridge* _cucumber_bridge = nullptr;
+#endif
};