+2013-05-06 Carl Hetherington <cth@carlh.net>
+
+ * Fix resizing / redraw problems in audio viewer
+ on Windows.
+
+2013-05-06 Carl Hetherington <cth@carlh.net>
+
+ * Version 0.89 released.
+
+2013-05-04 Carl Hetherington <cth@carlh.net>
+
+ * Version 0.89beta1 released.
+
+2013-05-04 Carl Hetherington <cth@carlh.net>
+
+ * Very simple batch converter added (#127).
+
+ * Add preference for CPL issuer and creator (#122).
+
+ * Add preference for default format and DCP content
+ type (#133).
+
2013-04-28 Carl Hetherington <cth@carlh.net>
* Version 0.88 released.
--- /dev/null
+[Desktop Entry]
+Encoding=UTF-8
+Version=1.0
+Type=Application
+Terminal=false
+Exec=@PREFIX@/bin/dvdomatic_batch
+Name=DVD-o-matic Batch Converter
+Icon=dvdomatic
+Comment=Batch DCP generator
+Categories=AudioVideo;Video
--- /dev/null
+#!/bin/bash
+
+export LD_LIBRARY_PATH=build/src/lib:build/src/wx:build/src/asdcplib/src:$LD_LIBRARY_PATH
+if [ "$1" == "--debug" ]; then
+ shift
+ gdb --args build/src/tools/dvdomatic_batch "$*"
+elif [ "$1" == "--valgrind" ]; then
+ shift
+ valgrind --tool="memcheck" build/src/tools/dvdomatic_batch $*
+elif [ "$1" == "--i18n" ]; then
+ shift
+ LANGUAGE=fr_FR.UTF8 LANG=fr_FR.UTF8 build/src/tools/dvdomatic_batch "$*"
+else
+ build/src/tools/dvdomatic_batch
+fi
#include <libdcp/exceptions.h>
#include "job.h"
#include "util.h"
+#include "cross.h"
#include "i18n.h"
return _state == FINISHED_CANCELLED;
}
+bool
+Job::paused () const
+{
+ boost::mutex::scoped_lock lm (_state_mutex);
+ return _state == PAUSED;
+}
+
/** Set the state of this job.
* @param s New state.
*/
_progress_unknown = false;
_stack.back().normalised = p;
boost::this_thread::interruption_point ();
+
+ if (paused ()) {
+ dcpomatic_sleep (1);
+ }
}
/** @return fractional overall progress, or -1 if not known */
_thread->interrupt ();
_thread->join ();
}
+
+void
+Job::pause ()
+{
+ if (running ()) {
+ set_state (PAUSED);
+ }
+}
+
+void
+Job::resume ()
+{
+ if (paused ()) {
+ set_state (RUNNING);
+ }
+}
virtual void run () = 0;
void start ();
+ void pause ();
+ void resume ();
void cancel ();
bool is_new () const;
bool finished_ok () const;
bool finished_in_error () const;
bool finished_cancelled () const;
+ bool paused () const;
std::string error_summary () const;
std::string error_details () const;
enum State {
NEW, ///< the job hasn't been started yet
RUNNING, ///< the job is running
+ PAUSED, ///< the job has been paused
FINISHED_OK, ///< the job has finished successfully
FINISHED_ERROR, ///< the job has finished in error
FINISHED_CANCELLED ///< the job was cancelled
#endif
void
-dcpomatic_setup_i18n (string lang)
+dcpomatic_setup_gettext_i18n (string lang)
{
#ifdef DCPOMATIC_POSIX
lang += ".UTF8";
extern std::string dependency_version_summary ();
extern double seconds (struct timeval);
extern void dcpomatic_setup ();
-extern void dcpomatic_setup_i18n (std::string);
+extern void dcpomatic_setup_gettext_i18n (std::string);
extern std::vector<std::string> split_at_spaces_considering_quotes (std::string);
extern std::string md5_digest (boost::filesystem::path);
extern std::string md5_digest (void const *, int);
static std::string film_to_load;
static std::string film_to_create;
static wxMenu* jobs_menu = 0;
-static wxLocale* locale = 0;
static void set_menu_sensitivity ();
film_editor = new FilmEditor (film, panel);
film_viewer = new FilmViewer (film, panel);
- JobManagerView* job_manager_view = new JobManagerView (panel);
+ JobManagerView* job_manager_view = new JobManagerView (panel, static_cast<JobManagerView::Buttons> (0));
_top_sizer = new wxBoxSizer (wxHORIZONTAL);
_top_sizer->Add (film_editor, 0, wxALL, 6);
};
#endif
-void
-setup_i18n ()
-{
- int language = wxLANGUAGE_DEFAULT;
-
- ofstream f ("c:/users/carl hetherington/foo", std::ios::app);
- f << "Hello.\n";
-
- boost::optional<string> config_lang = Config::instance()->language ();
- if (config_lang && !config_lang->empty ()) {
- f << "Configured language " << config_lang.get() << "\n";
- wxLanguageInfo const * li = wxLocale::FindLanguageInfo (std_to_wx (config_lang.get ()));
- f << "LanguageInfo " << li << "\n";
- if (li) {
- language = li->Language;
- f << "language=" << language << " cf " << wxLANGUAGE_DEFAULT << " " << wxLANGUAGE_ENGLISH << "\n";
- }
- }
-
- if (wxLocale::IsAvailable (language)) {
- f << "Language is available.\n";
- locale = new wxLocale (language, wxLOCALE_LOAD_DEFAULT);
-
-#ifdef DCPOMATIC_WINDOWS
- locale->AddCatalogLookupPathPrefix (std_to_wx (mo_path().string()));
-#endif
-
- locale->AddCatalog (wxT ("libdcpomatic-wx"));
- locale->AddCatalog (wxT ("dcpomatic"));
-
- if (!locale->IsOk()) {
- f << "Locale is not ok.\n";
- delete locale;
- locale = new wxLocale (wxLANGUAGE_ENGLISH);
- language = wxLANGUAGE_ENGLISH;
- }
- }
-
- if (locale) {
- dcpomatic_setup_i18n (wx_to_std (locale->GetCanonicalName ()));
- }
-}
-
class App : public wxApp
{
bool OnInit ()
hasn't yet been called and there aren't any scalers, filters etc.
set up yet.
*/
- setup_i18n ();
+ dcpomatic_setup_i18n ();
/* Set things up, including scalers / filters etc.
which will now be internationalised correctly.
obj.target = t
if not bld.env.DISABLE_GUI:
- for t in ['dcpomatic', 'dcpomatic_server']:
+ for t in ['dcpomatic', 'dcpomatic_batch', 'dcpomatic_server']:
obj = bld(features = 'cxx cxxprogram')
obj.uselib = 'DCP CXML OPENJPEG AVFORMAT AVFILTER AVCODEC AVUTIL SWSCALE POSTPROC'
obj.includes = ['..']
using boost::shared_ptr;
/** Must be called in the GUI thread */
-JobManagerView::JobManagerView (wxWindow* parent)
+JobManagerView::JobManagerView (wxWindow* parent, Buttons buttons)
: wxScrolledWindow (parent)
+ , _buttons (buttons)
{
_panel = new wxPanel (this);
wxSizer* sizer = new wxBoxSizer (wxVERTICAL);
sizer->Add (_panel, 1, wxEXPAND);
SetSizer (sizer);
+
+ int N = 5;
+ if (buttons & PAUSE) {
+ ++N;
+ }
- _table = new wxFlexGridSizer (5, 6, 6);
+ _table = new wxFlexGridSizer (N, 6, 6);
_table->AddGrowableCol (1, 1);
_panel->SetSizer (_table);
_table->Insert (index, m, 0, wxALIGN_CENTER_VERTICAL | wxALL, 6);
JobRecord r;
+ int n = 1;
r.finalised = false;
r.scroll_nudged = false;
r.gauge = new wxGauge (_panel, wxID_ANY, 100);
- _table->Insert (index + 1, r.gauge, 1, wxEXPAND | wxLEFT | wxRIGHT);
+ _table->Insert (index + n, r.gauge, 1, wxEXPAND | wxLEFT | wxRIGHT);
+ ++n;
r.message = new wxStaticText (_panel, wxID_ANY, std_to_wx (""));
- _table->Insert (index + 2, r.message, 1, wxALIGN_CENTER_VERTICAL | wxALL, 6);
+ _table->Insert (index + n, r.message, 1, wxALIGN_CENTER_VERTICAL | wxALL, 6);
+ ++n;
r.cancel = new wxButton (_panel, wxID_ANY, _("Cancel"));
r.cancel->Connect (wxID_ANY, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler (JobManagerView::cancel_clicked), 0, this);
- _table->Insert (index + 3, r.cancel, 1, wxALIGN_CENTER_VERTICAL | wxALL, 6);
-
+ _table->Insert (index + n, r.cancel, 1, wxALIGN_CENTER_VERTICAL | wxALL, 6);
+ ++n;
+
+ if (_buttons & PAUSE) {
+ r.pause = new wxButton (_panel, wxID_ANY, _("Pause"));
+ r.pause->Connect (wxID_ANY, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler (JobManagerView::pause_clicked), 0, this);
+ _table->Insert (index + n, r.pause, 1, wxALIGN_CENTER_VERTICAL | wxALL, 6);
+ ++n;
+ }
+
r.details = new wxButton (_panel, wxID_ANY, _("Details..."));
r.details->Connect (wxID_ANY, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler (JobManagerView::details_clicked), 0, this);
r.details->Enable (false);
- _table->Insert (index + 4, r.details, 1, wxALIGN_CENTER_VERTICAL | wxALL, 6);
+ _table->Insert (index + n, r.details, 1, wxALIGN_CENTER_VERTICAL | wxALL, 6);
+ ++n;
_job_records[*i] = r;
}
index += 5;
+ if (_buttons & PAUSE) {
+ ++index;
+ }
}
_table->Layout ();
}
}
}
+
+void
+JobManagerView::pause_clicked (wxCommandEvent& ev)
+{
+ wxObject* o = ev.GetEventObject ();
+ for (map<boost::shared_ptr<Job>, JobRecord>::iterator i = _job_records.begin(); i != _job_records.end(); ++i) {
+ if (i->second.pause == o) {
+ if (i->first->paused()) {
+ i->first->resume ();
+ i->second.pause->SetLabel (_("Pause"));
+ } else {
+ i->first->pause ();
+ i->second.pause->SetLabel (_("Resume"));
+ }
+ }
+ }
+}
+
class JobManagerView : public wxScrolledWindow
{
public:
- JobManagerView (wxWindow *);
+ enum Buttons {
+ PAUSE = 0x1,
+ };
+
+ JobManagerView (wxWindow *, Buttons);
void update ();
private:
void periodic (wxTimerEvent &);
void cancel_clicked (wxCommandEvent &);
+ void pause_clicked (wxCommandEvent &);
void details_clicked (wxCommandEvent &);
boost::shared_ptr<wxTimer> _timer;
wxGauge* gauge;
wxStaticText* message;
wxButton* cancel;
+ wxButton* pause;
wxButton* details;
bool finalised;
bool scroll_nudged;
};
std::map<boost::shared_ptr<Job>, JobRecord> _job_records;
+ Buttons _buttons;
};
#include <wx/filepicker.h>
#include <wx/spinctrl.h>
#include "wx_util.h"
+#include "config.h"
+#include "util.h"
using namespace std;
using namespace boost;
bool
confirm_dialog (wxWindow* parent, wxString m)
{
- wxMessageDialog* d = new wxMessageDialog (parent, m, _("DVD-o-matic"), wxYES_NO | wxICON_QUESTION);
+ wxMessageDialog* d = new wxMessageDialog (parent, m, _("DCP-o-matic"), wxYES_NO | wxICON_QUESTION);
int const r = d->ShowModal ();
d->Destroy ();
return r == wxID_YES;
widget->SetValue (value);
}
}
+
+void
+dcpomatic_setup_i18n ()
+{
+ int language = wxLANGUAGE_DEFAULT;
+
+ boost::optional<string> config_lang = Config::instance()->language ();
+ if (config_lang && !config_lang->empty ()) {
+ wxLanguageInfo const * li = wxLocale::FindLanguageInfo (std_to_wx (config_lang.get ()));
+ if (li) {
+ language = li->Language;
+ }
+ }
+
+ wxLocale* locale = 0;
+ if (wxLocale::IsAvailable (language)) {
+ locale = new wxLocale (language, wxLOCALE_LOAD_DEFAULT);
+
+#ifdef DCPOMATIC_WINDOWS
+ locale->AddCatalogLookupPathPrefix (std_to_wx (mo_path().string()));
+#endif
+
+ locale->AddCatalog (wxT ("libdcpomatic-wx"));
+ locale->AddCatalog (wxT ("dcpomatic"));
+
+ if (!locale->IsOk()) {
+ delete locale;
+ locale = new wxLocale (wxLANGUAGE_ENGLISH);
+ language = wxLANGUAGE_ENGLISH;
+ }
+ }
+
+ if (locale) {
+ dcpomatic_setup_gettext_i18n (wx_to_std (locale->GetCanonicalName ()));
+ }
+}
extern wxStaticText* add_label_to_grid_bag_sizer (wxGridBagSizer *, wxWindow *, wxString, wxGBPosition, wxGBSpan span = wxDefaultSpan);
extern std::string wx_to_std (wxString);
extern wxString std_to_wx (std::string);
+extern void dcpomatic_setup_i18n ();
/** @class ThreadedStaticText
*
File "%binaries%/src/wx/dcpomatic-wx.dll"
File "%binaries%/src/lib/dcpomatic.dll"
File "%binaries%/src/tools/dcpomatic.exe"
+File "%binaries%/src/tools/dcpomatic_batch.exe"
File "%binaries%/src/tools/dcpomatic_server_cli.exe"
File "%binaries%/src/tools/dcpomatic_server.exe"
File "%binaries%/src/tools/mo/sv_SE/dcpomatic.mo"
CreateShortCut "$DESKTOP\DCP-o-matic.lnk" "$INSTDIR\bin\dcpomatic.exe" ""
+CreateShortCut "$DESKTOP\DCP-o-matic batch converter.lnk" "$INSTDIR\bin\dcpomatic_batch.exe" ""
CreateShortCut "$DESKTOP\DCP-o-matic encode server.lnk" "$INSTDIR\bin\dcpomatic_server.exe" ""
CreateDirectory "$SMPROGRAMS\DCP-o-matic"
CreateShortCut "$SMPROGRAMS\DCP-o-matic\Uninstall DCP-o-matic.lnk" "$INSTDIR\Uninstall.exe" "" "$INSTDIR\Uninstall.exe" 0
CreateShortCut "$SMPROGRAMS\DCP-o-matic\DCP-o-matic.lnk" "$INSTDIR\bin\dcpomatic.exe" "" "$INSTDIR\bin\dcpomatic.exe" 0
+CreateShortCut "$SMPROGRAMS\DCP-o-matic\DCP-o-matic batch converter.lnk" "$INSTDIR\bin\dcpomatic.exe" "" "$INSTDIR\bin\dcpomatic_batch.exe" 0
CreateShortCut "$SMPROGRAMS\DCP-o-matic\DCP-o-matic encode server.lnk" "$INSTDIR\bin\dcpomatic_server.exe" "" "$INSTDIR\bin\dcpomatic_server.exe" 0
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\DCP-o-matic" "DisplayName" "DCP-o-matic (remove only)"
RMDir /r "$INSTDIR\*.*"
RMDir "$INSTDIR"
Delete "$DESKTOP\DCP-o-matic.lnk"
+Delete "$DESKTOP\DCP-o-matic batch converter.lnk"
Delete "$DESKTOP\DCP-o-matic encode server.lnk"
Delete "$SMPROGRAMS\DCP-o-matic\*.*"
RmDir "$SMPROGRAMS\DCP-o-matic"
File "%binaries%/src/wx/dcpomatic-wx.dll"
File "%binaries%/src/lib/dcpomatic.dll"
File "%binaries%/src/tools/dcpomatic.exe"
+File "%binaries%/src/tools/dcpomatic_batch.exe"
File "%binaries%/src/tools/dcpomatic_server_cli.exe"
File "%binaries%/src/tools/dcpomatic_server.exe"
File "%binaries%/src/tools/mo/sv_SE/dcpomatic.mo"
CreateShortCut "$DESKTOP\DCP-o-matic.lnk" "$INSTDIR\bin\dcpomatic.exe" ""
+CreateShortCut "$DESKTOP\DCP-o-matic batch converter.lnk" "$INSTDIR\bin\dcpomatic_batch.exe" ""
CreateShortCut "$DESKTOP\DCP-o-matic encode server.lnk" "$INSTDIR\bin\dcpomatic_server.exe" ""
CreateDirectory "$SMPROGRAMS\DCP-o-matic"
CreateShortCut "$SMPROGRAMS\DCP-o-matic\Uninstall DCP-o-matic.lnk" "$INSTDIR\Uninstall.exe" "" "$INSTDIR\Uninstall.exe" 0
CreateShortCut "$SMPROGRAMS\DCP-o-matic\DCP-o-matic.lnk" "$INSTDIR\bin\dcpomatic.exe" "" "$INSTDIR\bin\dcpomatic.exe" 0
+CreateShortCut "$SMPROGRAMS\DCP-o-matic\DCP-o-matic batch converter.lnk" "$INSTDIR\bin\dcpomatic.exe" "" "$INSTDIR\bin\dcpomatic_batch.exe" 0
CreateShortCut "$SMPROGRAMS\DCP-o-matic\DCP-o-matic encode server.lnk" "$INSTDIR\bin\dcpomatic_server.exe" "" "$INSTDIR\bin\dcpomatic_server.exe" 0
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\DCP-o-matic" "DisplayName" "DCP-o-matic (remove only)"
RMDir /r "$INSTDIR\*.*"
RMDir "$INSTDIR"
Delete "$DESKTOP\DCP-o-matic.lnk"
+Delete "$DESKTOP\DCP-o-matic batch converter.lnk"
Delete "$DESKTOP\DCP-o-matic encode server.lnk"
Delete "$SMPROGRAMS\DCP-o-matic\*.*"
RmDir "$SMPROGRAMS\DCP-o-matic"
conf.env.append_value('CXXFLAGS', '-O2')
if not conf.options.static:
- conf.check_cfg(package = 'libdcp', atleast_version = '0.45', args = '--cflags --libs', uselib_store = 'DCP', mandatory = True)
+ conf.check_cfg(package = 'libdcp', atleast_version = '0.49', args = '--cflags --libs', uselib_store = 'DCP', mandatory = True)
conf.check_cfg(package = 'libcxml', atleast_version = '0.01', args = '--cflags --libs', uselib_store = 'CXML', mandatory = True)
conf.check_cfg(package = 'libavformat', args = '--cflags --libs', uselib_store = 'AVFORMAT', mandatory = True)
conf.check_cfg(package = 'libavfilter', args = '--cflags --libs', uselib_store = 'AVFILTER', mandatory = True)
obj.target = 'dcpomatic.desktop'
obj.dict = d
- bld.install_files('${PREFIX}/share/applications', 'dcpomatic.desktop')
+ obj = bld(features = 'subst')
+ obj.source = 'dcpomatic_batch.desktop.in'
+ obj.target = 'dcpomatic_batch.desktop'
+ obj.dict = d
+
+ bld.install_files('${PREFIX}/share/applications', ['dcpomatic.desktop', 'dcpomatic_batch.desktop'])
+
for r in ['22x22', '32x32', '48x48', '64x64', '128x128']:
bld.install_files('${PREFIX}/share/icons/hicolor/%s/apps' % r, 'icons/%s/dcpomatic.png' % r)