Add simple copy and paste for content settings (#1051).
authorCarl Hetherington <cth@carlh.net>
Fri, 5 Jan 2018 23:17:16 +0000 (23:17 +0000)
committerCarl Hetherington <cth@carlh.net>
Fri, 5 Jan 2018 23:17:16 +0000 (23:17 +0000)
ChangeLog
src/lib/audio_content.cc
src/lib/subtitle_content.cc
src/lib/video_content.cc
src/tools/dcpomatic.cc
src/wx/content_panel.cc
src/wx/content_panel.h
src/wx/film_editor.h
src/wx/paste_dialog.cc [new file with mode: 0644]
src/wx/paste_dialog.h [new file with mode: 0644]
src/wx/wscript

index 0d7177c6552cad5f86cb2514b5631abbd5b00490..3c7adf9543aaf7a08f7b8e0573dfca6cfd770757 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,7 @@
 2018-01-05  Carl Hetherington  <cth@carlh.net>
 
+       * Add copy and paste for settings (#1051).
+
        * Fix hanging subtitles in some cases (#1101).
 
        * Version 2.11.36 released.
index 8334627762ffcd02856a602471f388ca6532ad26..7ede8284ea4328ffd33186a496fb599b540995fe 100644 (file)
@@ -383,8 +383,8 @@ AudioContent::set_stream (AudioStreamPtr stream)
 void
 AudioContent::take_settings_from (shared_ptr<const AudioContent> c)
 {
-       _gain = c->_gain;
-       _delay = c->_delay;
+       set_gain (c->_gain);
+       set_delay (c->_delay);
 
        size_t i = 0;
        size_t j = 0;
index b603a455da72edf091e5e9507eda24e14f084e86..55493039ce728874d5e0405dd3fc63205f0520b4 100644 (file)
@@ -415,19 +415,19 @@ SubtitleContent::set_outline_width (int w)
 void
 SubtitleContent::take_settings_from (shared_ptr<const SubtitleContent> c)
 {
-       _use = c->_use;
-       _burn = c->_burn;
-       _x_offset = c->_x_offset;
-       _y_offset = c->_y_offset;
-       _x_scale = c->_x_scale;
-       _y_scale = c->_y_scale;
-       _fonts = c->_fonts;
-       _colour = c->_colour;
-       _outline = c->_outline;
-       _shadow = c->_shadow;
-       _effect_colour = c->_effect_colour;
-       _line_spacing = c->_line_spacing;
-       _fade_in = c->_fade_in;
-       _fade_out = c->_fade_out;
-       _outline_width = c->_outline_width;
+       set_use (c->_use);
+       set_burn (c->_burn);
+       set_x_offset (c->_x_offset);
+       set_y_offset (c->_y_offset);
+       set_x_scale (c->_x_scale);
+       set_y_scale (c->_y_scale);
+       maybe_set (_fonts, c->_fonts, SubtitleContentProperty::FONTS);
+       set_colour (c->_colour);
+       set_outline (c->_outline);
+       set_shadow (c->_shadow);
+       set_effect_colour (c->_effect_colour);
+       set_line_spacing (c->_line_spacing);
+       set_fade_in (c->_fade_in);
+       set_fade_out (c->_fade_out);
+       set_outline_width (c->_outline_width);
 }
index d4e814624de8c949a9cd790de392fa536a4986ba..f78dab17eb3bc495db9e280ef0f54a079b9f5aaf 100644 (file)
@@ -531,12 +531,19 @@ VideoContent::set_fade_out (Frame t)
 void
 VideoContent::take_settings_from (shared_ptr<const VideoContent> c)
 {
-       _colour_conversion = c->_colour_conversion;
-       _frame_type = c->_frame_type;
-       _crop = c->_crop;
-       _scale = c->_scale;
-       _fade_in = c->_fade_in;
-       _fade_out = c->_fade_out;
+       if (c->_colour_conversion) {
+               set_colour_conversion (c->_colour_conversion.get());
+       } else {
+               unset_colour_conversion ();
+       }
+       set_frame_type (c->_frame_type);
+       set_left_crop (c->_crop.left);
+       set_right_crop (c->_crop.right);
+       set_top_crop (c->_crop.top);
+       set_bottom_crop (c->_crop.bottom);
+       set_scale (c->_scale);
+       set_fade_in (c->_fade_in);
+       set_fade_out (c->_fade_out);
 }
 
 void
index 90c70abc23f103beba660d2242aa3048580afdd5..b731828f4357a8d1bc0992b567fea4f1c6fe12e4 100644 (file)
@@ -1,5 +1,5 @@
 /*
-    Copyright (C) 2012-2017 Carl Hetherington <cth@carlh.net>
+    Copyright (C) 2012-2018 Carl Hetherington <cth@carlh.net>
 
     This file is part of DCP-o-matic.
 
@@ -42,6 +42,7 @@
 #include "wx/templates_dialog.h"
 #include "wx/nag_dialog.h"
 #include "wx/export_dialog.h"
+#include "wx/paste_dialog.h"
 #include "lib/film.h"
 #include "lib/config.h"
 #include "lib/util.h"
@@ -67,6 +68,8 @@
 #include "lib/ffmpeg_encoder.h"
 #include "lib/transcode_job.h"
 #include "lib/dkdm_wrapper.h"
+#include "lib/audio_content.h"
+#include "lib/subtitle_content.h"
 #include <dcp/exceptions.h>
 #include <dcp/raw_convert.h>
 #include <wx/generic/aboutdlgg.h>
@@ -173,11 +176,14 @@ private:
        wxMessageDialog* _dialog;
 };
 
-#define ALWAYS                       0x0
-#define NEEDS_FILM                   0x1
-#define NOT_DURING_DCP_CREATION      0x2
-#define NEEDS_CPL                    0x4
-#define NEEDS_SELECTED_VIDEO_CONTENT 0x8
+#define ALWAYS                        0x0
+#define NEEDS_FILM                    0x1
+#define NOT_DURING_DCP_CREATION       0x2
+#define NEEDS_CPL                     0x4
+#define NEEDS_SINGLE_SELECTED_CONTENT 0x8
+#define NEEDS_SELECTED_CONTENT        0x10
+#define NEEDS_SELECTED_VIDEO_CONTENT  0x20
+#define NEEDS_CLIPBOARD               0x40
 
 map<wxMenuItem*, int> menu_items;
 
@@ -190,7 +196,9 @@ enum {
        ID_file_duplicate_and_open,
        ID_file_history,
        /* Allow spare IDs after _history for the recent files list */
-       ID_content_scale_to_fit_width = 100,
+       ID_edit_copy = 100,
+       ID_edit_paste,
+       ID_content_scale_to_fit_width,
        ID_content_scale_to_fit_height,
        ID_jobs_make_dcp,
        ID_jobs_make_dcp_batch,
@@ -267,6 +275,8 @@ public:
                Bind (wxEVT_MENU, boost::bind (&DOMFrame::file_duplicate_and_open, this), ID_file_duplicate_and_open);
                Bind (wxEVT_MENU, boost::bind (&DOMFrame::file_history, this, _1),        ID_file_history, ID_file_history + HISTORY_SIZE);
                Bind (wxEVT_MENU, boost::bind (&DOMFrame::file_exit, this),               wxID_EXIT);
+               Bind (wxEVT_MENU, boost::bind (&DOMFrame::edit_copy, this),               ID_edit_copy);
+               Bind (wxEVT_MENU, boost::bind (&DOMFrame::edit_paste, this),              ID_edit_paste);
                Bind (wxEVT_MENU, boost::bind (&DOMFrame::edit_preferences, this),        wxID_PREFERENCES);
                Bind (wxEVT_MENU, boost::bind (&DOMFrame::content_scale_to_fit_width, this), ID_content_scale_to_fit_width);
                Bind (wxEVT_MENU, boost::bind (&DOMFrame::content_scale_to_fit_height, this), ID_content_scale_to_fit_height);
@@ -308,6 +318,7 @@ public:
                set_menu_sensitivity ();
 
                _film_editor->FileChanged.connect (bind (&DOMFrame::file_changed, this, _1));
+               _film_editor->content_panel()->SelectionChanged.connect (boost::bind (&DOMFrame::set_menu_sensitivity, this));
                file_changed ("");
 
                JobManager::instance()->ActiveJobsChanged.connect (boost::bind (&DOMFrame::set_menu_sensitivity, this));
@@ -506,6 +517,37 @@ private:
                Close (false);
        }
 
+       void edit_copy ()
+       {
+               ContentList const sel = _film_editor->content_panel()->selected();
+               DCPOMATIC_ASSERT (sel.size() == 1);
+               _clipboard = sel.front()->clone();
+       }
+
+       void edit_paste ()
+       {
+               DCPOMATIC_ASSERT (_clipboard);
+
+               PasteDialog* d = new PasteDialog (this, static_cast<bool>(_clipboard->video), static_cast<bool>(_clipboard->audio), static_cast<bool>(_clipboard->subtitle));
+               if (d->ShowModal() == wxID_OK) {
+                       BOOST_FOREACH (shared_ptr<Content> i, _film_editor->content_panel()->selected()) {
+                               if (d->video() && i->video) {
+                                       DCPOMATIC_ASSERT (_clipboard->video);
+                                       i->video->take_settings_from (_clipboard->video);
+                               }
+                               if (d->audio() && i->audio) {
+                                       DCPOMATIC_ASSERT (_clipboard->audio);
+                                       i->audio->take_settings_from (_clipboard->audio);
+                               }
+                               if (d->subtitle() && i->subtitle) {
+                                       DCPOMATIC_ASSERT (_clipboard->subtitle);
+                                       i->subtitle->take_settings_from (_clipboard->subtitle);
+                               }
+                       }
+               }
+               d->Destroy ();
+       }
+
        void edit_preferences ()
        {
                if (!_config_dialog) {
@@ -901,6 +943,8 @@ private:
                }
                bool const dcp_creation = (i != jobs.end ()) && !(*i)->finished ();
                bool const have_cpl = _film && !_film->cpls().empty ();
+               bool const have_single_selected_content = _film_editor->content_panel()->selected().size() == 1;
+               bool const have_selected_content = !_film_editor->content_panel()->selected().empty();
                bool const have_selected_video_content = !_film_editor->content_panel()->selected_video().empty();
 
                for (map<wxMenuItem*, int>::iterator j = menu_items.begin(); j != menu_items.end(); ++j) {
@@ -919,10 +963,22 @@ private:
                                enabled = false;
                        }
 
+                       if ((j->second & NEEDS_SELECTED_CONTENT) && !have_selected_content) {
+                               enabled = false;
+                       }
+
+                       if ((j->second & NEEDS_SINGLE_SELECTED_CONTENT) && !have_single_selected_content) {
+                               enabled = false;
+                       }
+
                        if ((j->second & NEEDS_SELECTED_VIDEO_CONTENT) && !have_selected_video_content) {
                                enabled = false;
                        }
 
+                       if ((j->second & NEEDS_CLIPBOARD) && !_clipboard) {
+                               enabled = false;
+                       }
+
                        j->first->Enable (enabled);
                }
        }
@@ -993,10 +1049,13 @@ private:
                add_item (_file_menu, _("&Quit"), wxID_EXIT, ALWAYS);
 #endif
 
+               wxMenu* edit = new wxMenu;
+               add_item (edit, _("Copy settings\tCtrl-C"), ID_edit_copy, NEEDS_FILM | NOT_DURING_DCP_CREATION | NEEDS_SINGLE_SELECTED_CONTENT);
+               add_item (edit, _("Paste settings...\tCtrl-V"), ID_edit_paste, NEEDS_FILM | NOT_DURING_DCP_CREATION | NEEDS_SELECTED_CONTENT | NEEDS_CLIPBOARD);
+
 #ifdef __WXOSX__
                add_item (_file_menu, _("&Preferences...\tCtrl-P"), wxID_PREFERENCES, ALWAYS);
 #else
-               wxMenu* edit = new wxMenu;
                add_item (edit, _("&Preferences...\tCtrl-P"), wxID_PREFERENCES, ALWAYS);
 #endif
 
@@ -1034,9 +1093,7 @@ private:
                add_item (help, _("Report a problem..."), ID_help_report_a_problem, NEEDS_FILM);
 
                m->Append (_file_menu, _("&File"));
-#ifndef __WXOSX__
                m->Append (edit, _("&Edit"));
-#endif
                m->Append (content, _("&Content"));
                m->Append (jobs_menu, _("&Jobs"));
                m->Append (tools, _("&Tools"));
@@ -1146,6 +1203,7 @@ private:
        wxMenuItem* _history_separator;
        boost::signals2::scoped_connection _config_changed_connection;
        bool _update_news_requested;
+       shared_ptr<Content> _clipboard;
 };
 
 static const wxCmdLineEntryDesc command_line_description[] = {
index 843f392809d45e68f3aca113a7d3250f57f920e6..8620fa3e0a410664368e1e54a30bb0c448b375c1 100644 (file)
@@ -266,6 +266,8 @@ ContentPanel::selection_changed ()
        if (_timeline_dialog) {
                _timeline_dialog->set_selection (selected ());
        }
+
+       SelectionChanged ();
 }
 
 void
index cf5782baa6d45e268b94ce6bd391cea85e01c363..475567d28e46e5ada0940e429fc34b1814d4d3eb 100644 (file)
@@ -70,6 +70,8 @@ public:
        void add_file_clicked ();
        bool remove_clicked (bool hotkey);
 
+       boost::signals2::signal<void (void)> SelectionChanged;
+
 private:
        void selection_changed ();
        void add_folder_clicked ();
index 47b333519de266acf98dfec7d3792b80ce4385e5..576cd5ba1b251bab083dec3cab431049bda02ca4 100644 (file)
@@ -43,6 +43,7 @@ public:
        void set_film (boost::shared_ptr<Film>);
 
        boost::signals2::signal<void (boost::filesystem::path)> FileChanged;
+       boost::signals2::signal<void (void)> SelectionChanged;
 
        /* Stuff for panels */
 
diff --git a/src/wx/paste_dialog.cc b/src/wx/paste_dialog.cc
new file mode 100644 (file)
index 0000000..eade314
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+    Copyright (C) 2018 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 "paste_dialog.h"
+
+PasteDialog::PasteDialog (wxWindow* parent, bool video, bool audio, bool subtitle)
+       : TableDialog (parent, _("Paste"), 1, 0, true)
+{
+       _video = new wxCheckBox (this, wxID_ANY, _("Paste video settings"));
+       _video->Enable (video);
+       add (_video);
+       _audio = new wxCheckBox (this, wxID_ANY, _("Paste audio settings"));
+       _audio->Enable (audio);
+       add (_audio);
+       _subtitle = new wxCheckBox (this, wxID_ANY, _("Paste subtitle settings"));
+       _subtitle->Enable (subtitle);
+       add (_subtitle);
+
+       layout ();
+}
+
+bool
+PasteDialog::video () const
+{
+       return _video->GetValue ();
+}
+
+bool
+PasteDialog::audio () const
+{
+       return _audio->GetValue ();
+}
+
+bool
+PasteDialog::subtitle () const
+{
+       return _subtitle->GetValue ();
+}
diff --git a/src/wx/paste_dialog.h b/src/wx/paste_dialog.h
new file mode 100644 (file)
index 0000000..204f421
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+    Copyright (C) 2018 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 "table_dialog.h"
+
+class PasteDialog : public TableDialog
+{
+public:
+       PasteDialog (wxWindow* parent, bool video, bool audio, bool subtitle);
+
+       bool video () const;
+       bool audio () const;
+       bool subtitle () const;
+
+private:
+       wxCheckBox* _video;
+       wxCheckBox* _audio;
+       wxCheckBox* _subtitle;
+};
index 7346f3a2f4073fc250831207fe18190c98d31bda..86065731c35c7a428d51a8d58d6df51d7cddec74 100644 (file)
@@ -76,6 +76,7 @@ sources = """
           name_format_editor.cc
           new_dkdm_folder_dialog.cc
           normal_job_view.cc
+          paste_dialog.cc
           player_config_dialog.cc
           player_information.cc
           playhead_to_timecode_dialog.cc