+2014-09-03 Carl Hetherington <cth@carlh.net>
+
+ * Version 1.73.2 released.
+
+2014-09-03 Carl Hetherington <cth@carlh.net>
+
+ * Fix server certificate downloads on OS X (#376).
+
+2014-09-02 Carl Hetherington <cth@carlh.net>
+
+ * Improve behaviour of batch converter window when it is shrunk (#338).
+
+2014-09-01 Carl Hetherington <cth@carlh.net>
+
+ * Version 1.73.1 released.
+
2014-08-31 Carl Hetherington <cth@carlh.net>
* Remove configurable CPL <Creator> and use "DCP-o-matic (version) (git)"
-<<<<<<< HEAD
dcpomatic (2.0.4-1) UNRELEASED; urgency=low
-=======
-dcpomatic (1.73.0-1) UNRELEASED; urgency=low
->>>>>>> origin/master
* New upstream release.
* New upstream release.
# i18n: DCP-o-matic .mo files
for lang in de_DE es_ES fr_FR it_IT sv_SE nl_NL; do
- mkdir "$WORK/$resources/$lang/LC_MESSAGES"
+ mkdir -p "$WORK/$resources/$lang/LC_MESSAGES"
cp build/src/lib/mo/$lang/*.mo "$WORK/$resources/$lang/LC_MESSAGES"
cp build/src/wx/mo/$lang/*.mo "$WORK/$resources/$lang/LC_MESSAGES"
cp build/src/tools/mo/$lang/*.mo "$WORK/$resources/$lang/LC_MESSAGES"
d << "_" << container()->isdcf_name();
}
- /* XXX: this only works for content which has been scaled to a given ratio,
- and uses the first bit of content only.
- */
+ /* XXX: this uses the first bit of content only */
/* The standard says we don't do this for trailers, for some strange reason */
if (dcp_content_type() && dcp_content_type()->libdcp_kind() != dcp::TRAILER) {
ContentList cl = content ();
Ratio const * content_ratio = 0;
- for (ContentList::const_iterator i = cl.begin(); i != cl.end(); ++i) {
+ for (ContentList::iterator i = cl.begin(); i != cl.end(); ++i) {
shared_ptr<VideoContent> vc = dynamic_pointer_cast<VideoContent> (*i);
- if (vc && (content_ratio == 0 || vc->scale().ratio() != content_ratio)) {
- content_ratio = vc->scale().ratio();
+ if (vc) {
+ /* Here's the first piece of video content */
+ if (vc->scale().ratio ()) {
+ content_ratio = vc->scale().ratio ();
+ } else {
+ content_ratio = Ratio::from_ratio (vc->video_size().ratio ());
+ }
+ break;
}
}
curl_easy_setopt (curl, CURLOPT_WRITEFUNCTION, get_from_zip_url_data);
curl_easy_setopt (curl, CURLOPT_WRITEDATA, f);
curl_easy_setopt (curl, CURLOPT_FTP_USE_EPSV, 0);
+ /* Maximum time is 20s */
+ curl_easy_setopt (curl, CURLOPT_TIMEOUT, 20);
CURLcode const cr = curl_easy_perform (curl);
url += "/";
}
curl_easy_setopt (curl, CURLOPT_URL, url.c_str ());
+ /* 20s timeout */
+ curl_easy_setopt (curl, CURLOPT_TIMEOUT, 20);
string ls_raw;
struct curl_slist* commands = 0;
return *j;
}
+
+/** @return Ratio corresponding to a given fractional ratio (+/- 0.01), or 0 */
+Ratio const *
+Ratio::from_ratio (float r)
+{
+ vector<Ratio const *>::iterator j = _ratios.begin ();
+ while (j != _ratios.end() && fabs ((*j)->ratio() - r) > 0.01) {
+ ++j;
+ }
+
+ if (j == _ratios.end ()) {
+ return 0;
+ }
+
+ return *j;
+}
+
static void setup_ratios ();
static Ratio const * from_id (std::string i);
+ static Ratio const * from_ratio (float r);
static std::vector<Ratio const *> all () {
return _ratios;
}
}
}
+ /* Do something next time the UI is idle */
+ template <typename T>
+ void when_idle (T f) {
+ _service.post (f);
+ }
+
/** Call this in the UI when it is idle */
size_t ui_idle () {
+ /* This executes any functors that have been post()ed to _service */
return _service.poll ();
}
return true;
}
+ /* An unhandled exception has occurred inside the main event loop */
bool OnExceptionInMainLoop ()
{
- error_dialog (0, _("An unknown exception occurred. Please report this problem to the DCP-o-matic author (carl@dcpomatic.com)."));
+ try {
+ throw;
+ } catch (exception& e) {
+ error_dialog (0, wxString::Format (_("An exception occurred (%s). Please report this problem to the DCP-o-matic author (carl@dcpomatic.com)."), e.what ()));
+ } catch (...) {
+ error_dialog (0, _("An unknown exception occurred. Please report this problem to the DCP-o-matic author (carl@dcpomatic.com)."));
+ }
+
+ /* This will terminate the program */
return false;
}
-
+
void OnUnhandledException ()
{
error_dialog (0, _("An unknown exception occurred. Please report this problem to the DCP-o-matic author (carl@dcpomatic.com)."));
/*
- Copyright (C) 2013 Carl Hetherington <cth@carlh.net>
+ Copyright (C) 2013-2014 Carl Hetherington <cth@carlh.net>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
#include "lib/film.h"
#include "lib/job_manager.h"
#include "wx/wx_util.h"
+#include "wx/about_dialog.h"
#include "wx/wx_ui_signaller.h"
#include "wx/job_manager_view.h"
public:
Frame (wxString const & title)
: wxFrame (NULL, -1, title)
+ , _sizer (new wxBoxSizer (wxVERTICAL))
{
wxMenuBar* bar = new wxMenuBar;
setup_menu (bar);
s->Add (panel, 1, wxEXPAND);
SetSizer (s);
- wxSizer* sizer = new wxBoxSizer (wxVERTICAL);
-
JobManagerView* job_manager_view = new JobManagerView (panel, JobManagerView::PAUSE);
- sizer->Add (job_manager_view, 1, wxALL | wxEXPAND, 6);
+ _sizer->Add (job_manager_view, 1, wxALL | wxEXPAND, 6);
wxSizer* buttons = new wxBoxSizer (wxHORIZONTAL);
wxButton* add = new wxButton (panel, wxID_ANY, _("Add Film..."));
add->Bind (wxEVT_COMMAND_BUTTON_CLICKED, boost::bind (&Frame::add_film, this));
buttons->Add (add, 1, wxALL, 6);
- sizer->Add (buttons, 0, wxALL, 6);
+ _sizer->Add (buttons, 0, wxALL, 6);
- panel->SetSizer (sizer);
+ panel->SetSizer (_sizer);
Bind (wxEVT_CLOSE_WINDOW, boost::bind (&Frame::close, this, _1));
+ Bind (wxEVT_SIZE, boost::bind (&Frame::sized, this, _1));
}
private:
+ void sized (wxSizeEvent& ev)
+ {
+ _sizer->Layout ();
+ ev.Skip ();
+ }
+
bool should_close ()
{
if (!JobManager::instance()->work_to_do ()) {
void help_about ()
{
- wxAboutDialogInfo info;
- info.SetName (_("DCP-o-matic Batch Converter"));
- if (strcmp (dcpomatic_git_commit, "release") == 0) {
- info.SetVersion (std_to_wx (String::compose ("version %1", dcpomatic_version)));
- } else {
- info.SetVersion (std_to_wx (String::compose ("version %1 git %2", dcpomatic_version, dcpomatic_git_commit)));
- }
- info.SetDescription (_("Free, open-source DCP generation from almost anything."));
- info.SetCopyright (_("(C) 2012-2013 Carl Hetherington, Terrence Meiczinger, Paul Davis, Ole Laursen"));
-
- wxArrayString authors;
- authors.Add (wxT ("Carl Hetherington"));
- authors.Add (wxT ("Terrence Meiczinger"));
- authors.Add (wxT ("Paul Davis"));
- authors.Add (wxT ("Ole Laursen"));
- info.SetDevelopers (authors);
-
- wxArrayString translators;
- translators.Add (wxT ("Olivier Perriere"));
- translators.Add (wxT ("Lilian Lefranc"));
- translators.Add (wxT ("Thierry Journet"));
- translators.Add (wxT ("Massimiliano Broggi"));
- translators.Add (wxT ("Manuel AC"));
- translators.Add (wxT ("Adam Klotblixt"));
- info.SetTranslators (translators);
-
- info.SetWebSite (wxT ("http://carlh.net/software/dcpomatic"));
- wxAboutBox (info);
+ AboutDialog* d = new AboutDialog (this);
+ d->ShowModal ();
+ d->Destroy ();
}
void add_film ()
}
boost::optional<boost::filesystem::path> _last_parent;
+ wxSizer* _sizer;
};
static const wxCmdLineEntryDesc command_line_description[] = {
void
DCPPanel::film_content_changed (int property)
{
- if (property == FFmpegContentProperty::AUDIO_STREAM || property == SubtitleContentProperty::USE_SUBTITLES) {
+ if (property == FFmpegContentProperty::AUDIO_STREAM ||
+ property == SubtitleContentProperty::USE_SUBTITLES ||
+ property == VideoContentProperty::VIDEO_SCALE) {
setup_dcp_name ();
}
}
#include <curl/curl.h>
#include "lib/compose.hpp"
#include "lib/internet.h"
+#include "lib/ui_signaller.h"
#include "dolby_certificate_dialog.h"
#include "wx_util.h"
_country->Append (_("Fetching..."));
_country->SetSelection (0);
- run_gui_loop ();
-
+
+#ifdef DCPOMATIC_OSX
+ /* See DoremiCertificateDialog for discussion about this daft delay */
+ wxMilliSleep (200);
+#endif
+ ui_signaller->when_idle (boost::bind (&DolbyCertificateDialog::finish_setup_countries, this));
+}
+
+void
+DolbyCertificateDialog::finish_setup_countries ()
+{
list<string> const countries = get_dir ("");
_country->Clear ();
for (list<string>::const_iterator i = countries.begin(); i != countries.end(); ++i) {
_cinema->Clear ();
_cinema->Append (_("Fetching..."));
_cinema->SetSelection (0);
- run_gui_loop ();
-
+
+#ifdef DCPOMATIC_OSX
+ wxMilliSleep (200);
+#endif
+ ui_signaller->when_idle (boost::bind (&DolbyCertificateDialog::finish_country_selected, this));
+}
+
+void
+DolbyCertificateDialog::finish_country_selected ()
+{
list<string> const cinemas = get_dir (wx_to_std (_country->GetStringSelection()));
_cinema->Clear ();
for (list<string>::const_iterator i = cinemas.begin(); i != cinemas.end(); ++i) {
_serial->Clear ();
_serial->Append (_("Fetching..."));
_serial->SetSelection (0);
- run_gui_loop ();
+#ifdef DCPOMATIC_OSX
+ wxMilliSleep (200);
+#endif
+ ui_signaller->when_idle (boost::bind (&DolbyCertificateDialog::finish_cinema_selected, this));
+}
+
+void
+DolbyCertificateDialog::finish_cinema_selected ()
+{
string const dir = String::compose ("%1/%2", wx_to_std (_country->GetStringSelection()), wx_to_std (_cinema->GetStringSelection()));
list<string> const zips = get_dir (dir);
DolbyCertificateDialog::download ()
{
_message->SetLabel (_("Downloading certificate"));
- run_gui_loop ();
+#ifdef DCPOMATIC_OSX
+ wxMilliSleep (200);
+#endif
+
+ ui_signaller->when_idle (boost::bind (&DolbyCertificateDialog::finish_download, this));
+}
+
+void
+DolbyCertificateDialog::finish_download ()
+{
string const zip = string_client_data (_serial->GetClientObject (_serial->GetSelection ()));
string const file = String::compose (
private:
void download ();
+ void finish_download ();
void setup_countries ();
+ void finish_setup_countries ();
void country_selected ();
+ void finish_country_selected ();
void cinema_selected ();
+ void finish_cinema_selected ();
void serial_selected ();
std::list<std::string> get_dir (std::string) const;
#include <zip.h>
#include "lib/compose.hpp"
#include "lib/util.h"
+#include "lib/ui_signaller.h"
#include "lib/internet.h"
#include "doremi_certificate_dialog.h"
#include "wx_util.h"
}
_message->SetLabel (_("Downloading certificate"));
- run_gui_loop ();
+#ifdef DCPOMATIC_OSX
+ /* This is necessary on OS X, otherwise the SetLabel() above has no visible effect */
+ wxMilliSleep (200);
+#endif
+
+ ui_signaller->when_idle (boost::bind (&DoremiCertificateDialog::finish_download, this, serial));
+}
+
+void
+DoremiCertificateDialog::finish_download (string serial)
+{
/* Try dcp2000, imb and ims prefixes (see mantis #375) */
optional<string> error = get_from_zip_url (
void download ();
void set_sensitivity ();
+ void finish_download (std::string serial);
+
wxTextCtrl* _serial;
};
_panel->SetSizer (_table);
SetScrollRate (0, 32);
+ EnableScrolling (false, true);
Bind (wxEVT_TIMER, boost::bind (&JobManagerView::periodic, this));
_timer.reset (new wxTimer (this));
_timer->Start (1000);
-
+
+ Bind (wxEVT_SIZE, boost::bind (&JobManagerView::sized, this, _1));
JobManager::instance()->JobAdded.connect (bind (&JobManagerView::job_added, this, _1));
}
+void
+JobManagerView::sized (wxSizeEvent& ev)
+{
+ _table->FitInside (_panel);
+ _table->Layout ();
+ ev.Skip ();
+}
+
void
JobManagerView::job_added (weak_ptr<Job> j)
{
private:
void job_added (boost::weak_ptr<Job>);
void periodic ();
+ void sized (wxSizeEvent &);
wxPanel* _panel;
wxFlexGridSizer* _table;
/*
- Copyright (C) 2012 Carl Hetherington <cth@carlh.net>
+ Copyright (C) 2012-2014 Carl Hetherington <cth@carlh.net>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
return w->GetValue ();
}
-void
-run_gui_loop ()
-{
- while (wxTheApp->Pending ()) {
- wxTheApp->Dispatch ();
- }
-}
-
/** @param s String of the form Context|String
* @return translation, or String if no translation is available.
*/
extern std::string wx_to_std (wxString);
extern wxString std_to_wx (std::string);
extern void dcpomatic_setup_i18n ();
-extern void run_gui_loop ();
extern wxString context_translation (wxString);
/** @class ThreadedStaticText