summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorCarl Hetherington <cth@carlh.net>2025-04-30 02:22:18 +0200
committerCarl Hetherington <cth@carlh.net>2025-06-03 22:46:26 +0200
commit8e84a2e70cf228b91f089e7eec23fe8c7e334666 (patch)
treec3a4d3086f7c97281c50cacab6bac7c561844b15 /src
parentfb5b8ae43e373c37b78202217528be73efa162cc (diff)
Adjust main DoM upload to be to multiple destinations.
Diffstat (limited to 'src')
-rw-r--r--src/lib/upload_job.cc2
-rw-r--r--src/tools/dcpomatic.cc17
-rw-r--r--src/wx/upload_destination_panel.cc190
-rw-r--r--src/wx/upload_destination_panel.h60
-rw-r--r--src/wx/upload_dialog.cc70
-rw-r--r--src/wx/upload_dialog.h42
-rw-r--r--src/wx/wscript2
7 files changed, 377 insertions, 6 deletions
diff --git a/src/lib/upload_job.cc b/src/lib/upload_job.cc
index b43526c56..4fee6f063 100644
--- a/src/lib/upload_job.cc
+++ b/src/lib/upload_job.cc
@@ -64,7 +64,7 @@ UploadJob::~UploadJob ()
string
UploadJob::name () const
{
- return fmt::format(_("Copy DCP to {}"), _destination.name);
+ return fmt::format(_("Upload DCP to {}"), _destination.name);
}
diff --git a/src/tools/dcpomatic.cc b/src/tools/dcpomatic.cc
index 4ab9c03ed..8c3054bd5 100644
--- a/src/tools/dcpomatic.cc
+++ b/src/tools/dcpomatic.cc
@@ -54,6 +54,7 @@
#include "wx/system_information_dialog.h"
#include "wx/templates_dialog.h"
#include "wx/update_dialog.h"
+#include "wx/upload_dialog.h"
#include "wx/video_waveform_dialog.h"
#include "wx/wx_signal_manager.h"
#include "wx/wx_util.h"
@@ -97,6 +98,7 @@
#include "lib/transcode_job.h"
#include "lib/unzipper.h"
#include "lib/update_checker.h"
+#include "lib/upload_job.h"
#include "lib/variant.h"
#include "lib/version.h"
#include "lib/video_content.h"
@@ -241,7 +243,7 @@ enum {
ID_jobs_make_self_dkdm,
ID_jobs_export_video_file,
ID_jobs_export_subtitles,
- ID_jobs_send_dcp_to_tms,
+ ID_jobs_upload_dcp,
ID_jobs_show_dcp,
ID_jobs_open_dcp_in_player,
ID_view_closed_captions,
@@ -352,7 +354,7 @@ public:
Bind (wxEVT_MENU, boost::bind (&DOMFrame::jobs_make_self_dkdm, this), ID_jobs_make_self_dkdm);
Bind (wxEVT_MENU, boost::bind (&DOMFrame::jobs_export_video_file, this), ID_jobs_export_video_file);
Bind (wxEVT_MENU, boost::bind (&DOMFrame::jobs_export_subtitles, this), ID_jobs_export_subtitles);
- Bind (wxEVT_MENU, boost::bind (&DOMFrame::jobs_send_dcp_to_tms, this), ID_jobs_send_dcp_to_tms);
+ Bind (wxEVT_MENU, boost::bind (&DOMFrame::jobs_upload_dcp, this), ID_jobs_upload_dcp);
Bind (wxEVT_MENU, boost::bind (&DOMFrame::jobs_show_dcp, this), ID_jobs_show_dcp);
Bind (wxEVT_MENU, boost::bind (&DOMFrame::jobs_open_dcp_in_player, this), ID_jobs_open_dcp_in_player);
Bind (wxEVT_MENU, boost::bind (&DOMFrame::view_closed_captions, this), ID_view_closed_captions);
@@ -1068,9 +1070,14 @@ private:
}
- void jobs_send_dcp_to_tms ()
+ void jobs_upload_dcp()
{
- _film->send_dcp_to_tms ();
+ UploadDialog dialog(this);
+ if (dialog.ShowModal() == wxID_OK) {
+ for (auto const& destination: dialog.destinations()) {
+ JobManager::instance()->add(make_shared<UploadJob>(_film, destination));
+ }
+ }
}
void jobs_show_dcp ()
@@ -1403,7 +1410,7 @@ private:
add_item (jobs_menu, _("Export video file...\tCtrl-E"), ID_jobs_export_video_file, NEEDS_FILM);
add_item (jobs_menu, _("Export subtitles..."), ID_jobs_export_subtitles, NEEDS_FILM);
jobs_menu->AppendSeparator ();
- add_item (jobs_menu, _("&Send DCP to TMS"), ID_jobs_send_dcp_to_tms, NEEDS_FILM | NOT_DURING_DCP_CREATION | NEEDS_CPL);
+ add_item (jobs_menu, _("&Upload DCP..."), ID_jobs_upload_dcp, NEEDS_FILM | NOT_DURING_DCP_CREATION | NEEDS_CPL);
#if defined(DCPOMATIC_OSX)
add_item (jobs_menu, _("S&how DCP in Finder"), ID_jobs_show_dcp, NEEDS_FILM | NOT_DURING_DCP_CREATION | NEEDS_CPL);
diff --git a/src/wx/upload_destination_panel.cc b/src/wx/upload_destination_panel.cc
new file mode 100644
index 000000000..923b1b222
--- /dev/null
+++ b/src/wx/upload_destination_panel.cc
@@ -0,0 +1,190 @@
+/*
+ Copyright (C) 2025 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 "dcpomatic_button.h"
+#include "upload_destination_dialog.h"
+#include "upload_destination_panel.h"
+#include "wx_util.h"
+#include "lib/config.h"
+#include <wx/treelist.h>
+
+
+using std::vector;
+using boost::optional;
+#if BOOST_VERSION >= 106100
+using namespace boost::placeholders;
+#endif
+
+
+UploadDestinationPanel::UploadDestinationPanel(wxWindow* parent)
+ : wxPanel(parent, wxID_ANY)
+{
+ _list = new wxTreeListCtrl(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTL_NO_HEADER | wxTL_3STATE);
+ _list->AppendColumn(char_to_wx("foo"), 640);
+
+ for (auto destination: Config::instance()->upload_destinations()) {
+ add_destination(destination);
+ }
+
+ auto buttons = new wxBoxSizer(wxVERTICAL);
+
+ _add = new Button(this, _("Add..."));
+ buttons->Add(_add, 0, wxEXPAND | wxTOP | wxBOTTOM, DCPOMATIC_BUTTON_STACK_GAP);
+ _edit = new Button(this, _("Edit..."));
+ buttons->Add(_edit, 0, wxEXPAND | wxTOP | wxBOTTOM, DCPOMATIC_BUTTON_STACK_GAP);
+ _remove = new Button(this, _("Remove"));
+ buttons->Add(_remove, 0, wxEXPAND | wxTOP | wxBOTTOM, DCPOMATIC_BUTTON_STACK_GAP);
+
+ _add->bind(&UploadDestinationPanel::add, this);
+ _edit->bind(&UploadDestinationPanel::edit, this);
+ _remove->bind(&UploadDestinationPanel::remove, this);
+
+ _list->Bind(wxEVT_TREELIST_SELECTION_CHANGED, boost::bind(&UploadDestinationPanel::selection_changed, this));
+ _list->Bind(wxEVT_TREELIST_ITEM_CHECKED, boost::bind(&UploadDestinationPanel::checkbox_changed, this));
+
+ auto sizer = new wxBoxSizer(wxHORIZONTAL);
+ sizer->Add(_list, 1, wxEXPAND);
+ sizer->Add(buttons, 0, wxEXPAND | wxLEFT, DCPOMATIC_SIZER_X_GAP);
+ SetSizerAndFit(sizer);
+}
+
+
+void
+UploadDestinationPanel::checkbox_changed()
+{
+ DestinationsChanged();
+}
+
+
+void
+UploadDestinationPanel::selection_changed()
+{
+ setup_sensitivity();
+}
+
+
+void
+UploadDestinationPanel::setup_sensitivity()
+{
+ auto const selection = static_cast<bool>(selected());
+ _edit->Enable(selection);
+ _remove->Enable(selection);
+}
+
+
+void
+UploadDestinationPanel::add_destination(UploadDestination destination)
+{
+ auto const id = _list->AppendItem(_list->GetRootItem(), std_to_wx(destination.name));
+ _destinations.push_back(std::make_pair(id, destination));
+}
+
+
+void
+UploadDestinationPanel::add()
+{
+ UploadDestinationDialog dialog(this);
+ if (dialog.ShowModal() == wxID_OK) {
+ add_destination(dialog.get()[0]);
+ update_config();
+ }
+}
+
+
+void
+UploadDestinationPanel::update_config()
+{
+ vector<UploadDestination> dest;
+ for (auto const& i: _destinations) {
+ dest.push_back(i.second);
+ }
+ Config::instance()->set_upload_destinations(dest);
+}
+
+
+optional<wxTreeListItem>
+UploadDestinationPanel::selected() const
+{
+ wxTreeListItems selection;
+ _list->GetSelections(selection);
+ DCPOMATIC_ASSERT(selection.size() <= 1);
+ if (selection.empty()) {
+ return {};
+ }
+
+ return selection[0];
+}
+
+void
+UploadDestinationPanel::edit()
+{
+ if (auto sel = selected()) {
+ for (auto& i: _destinations) {
+ if (i.first == *sel) {
+ UploadDestinationDialog dialog(this);
+ dialog.set(i.second);
+ if (dialog.ShowModal() == wxID_OK) {
+ i.second = dialog.get()[0];
+ update_config();
+ _list->SetItemText(*sel, std_to_wx(i.second.name));
+ }
+ }
+ }
+ }
+}
+
+
+void
+UploadDestinationPanel::remove()
+{
+ if (auto sel = selected()) {
+ for (auto iter = _destinations.begin(); iter != _destinations.end(); ) {
+ if (iter->first == *sel) {
+ iter = _destinations.erase(iter);
+ _list->DeleteItem(iter->first);
+ } else {
+ ++iter;
+ }
+ }
+ update_config();
+ }
+
+}
+
+
+vector<UploadDestination>
+UploadDestinationPanel::destinations() const
+{
+ vector<UploadDestination> dest;
+
+ for (auto child = _list->GetFirstChild(_list->GetRootItem()); child.IsOk(); child = _list->GetNextSibling(child)) {
+ if (_list->GetCheckedState(child) == wxCHK_CHECKED) {
+ for (auto i: _destinations) {
+ if (i.first == child) {
+ dest.push_back(i.second);
+ }
+ }
+ }
+ }
+
+ return dest;
+}
+
diff --git a/src/wx/upload_destination_panel.h b/src/wx/upload_destination_panel.h
new file mode 100644
index 000000000..05d854885
--- /dev/null
+++ b/src/wx/upload_destination_panel.h
@@ -0,0 +1,60 @@
+/*
+ Copyright (C) 2025 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/upload_destination.h"
+#include <wx/treelist.h>
+#include <wx/wx.h>
+#include <boost/signals2.hpp>
+#include <map>
+
+
+class Button;
+
+
+class UploadDestinationPanel : public wxPanel
+{
+public:
+ UploadDestinationPanel(wxWindow* parent);
+
+ std::vector<UploadDestination> destinations() const;
+
+ boost::signals2::signal<void ()> DestinationsChanged;
+
+private:
+ void add();
+ void edit();
+ void remove();
+
+ void add_destination(UploadDestination destination);
+ boost::optional<wxTreeListItem> selected() const;
+ void selection_changed();
+ void setup_sensitivity();
+ void update_config();
+ void destinations_changed();
+ void checkbox_changed();
+
+ wxTreeListCtrl* _list;
+ Button* _add;
+ Button* _edit;
+ Button* _remove;
+ std::vector<std::pair<wxTreeListItem, UploadDestination>> _destinations;
+};
+
diff --git a/src/wx/upload_dialog.cc b/src/wx/upload_dialog.cc
new file mode 100644
index 000000000..606ba5ee3
--- /dev/null
+++ b/src/wx/upload_dialog.cc
@@ -0,0 +1,70 @@
+/*
+ Copyright (C) 2025 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 "static_text.h"
+#include "upload_destination_panel.h"
+#include "upload_dialog.h"
+#include "wx_util.h"
+#include <wx/wx.h>
+
+
+using std::vector;
+
+
+UploadDialog::UploadDialog(wxWindow* parent)
+ : wxDialog(parent, wxID_ANY, _("Upload DCP"))
+ , _upload_destination_panel(new UploadDestinationPanel(this))
+{
+ auto sizer = new wxBoxSizer(wxVERTICAL);
+
+ wxFont subheading_font(*wxNORMAL_FONT);
+ subheading_font.SetWeight(wxFONTWEIGHT_BOLD);
+
+ sizer->Add(_upload_destination_panel, 1, wxEXPAND | wxALL, DCPOMATIC_DIALOG_BORDER);
+
+ auto buttons = CreateStdDialogButtonSizer(0);
+ sizer->Add(CreateSeparatedSizer(buttons), wxSizerFlags().Expand().DoubleBorder());
+ _start_upload = new wxButton(this, wxID_OK, _("Start upload"));
+ buttons->SetAffirmativeButton(_start_upload);
+ buttons->SetNegativeButton(new wxButton(this, wxID_CANCEL, _("Cancel")));
+ buttons->Realize();
+
+ _upload_destination_panel->DestinationsChanged.connect(boost::bind(&UploadDialog::setup_sensitivity, this));
+ setup_sensitivity();
+
+ SetSizer(sizer);
+ SetSize({640, 480});
+}
+
+
+vector<UploadDestination>
+UploadDialog::destinations() const
+{
+ return _upload_destination_panel->destinations();
+}
+
+
+void
+UploadDialog::setup_sensitivity()
+{
+ _start_upload->Enable(!_upload_destination_panel->destinations().empty());
+}
+
diff --git a/src/wx/upload_dialog.h b/src/wx/upload_dialog.h
new file mode 100644
index 000000000..20f395254
--- /dev/null
+++ b/src/wx/upload_dialog.h
@@ -0,0 +1,42 @@
+/*
+ Copyright (C) 2025 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/upload_destination.h"
+#include <wx/wx.h>
+
+
+class UploadDestinationPanel;
+
+
+class UploadDialog : public wxDialog
+{
+public:
+ UploadDialog(wxWindow* parent);
+
+ std::vector<UploadDestination> destinations() const;
+
+private:
+ void setup_sensitivity();
+
+ UploadDestinationPanel* _upload_destination_panel;
+ wxButton* _start_upload;
+};
+
diff --git a/src/wx/wscript b/src/wx/wscript
index 3890a929c..ae754f0a9 100644
--- a/src/wx/wscript
+++ b/src/wx/wscript
@@ -186,7 +186,9 @@ sources = """
timing_panel.cc
try_unmount_dialog.cc
upload_destination_dialog.cc
+ upload_destination_panel.cc
update_dialog.cc
+ upload_dialog.cc
verify_dcp_dialog.cc
verify_dcp_progress_panel.cc
verify_dcp_result_panel.cc