diff options
| author | Carl Hetherington <cth@carlh.net> | 2014-01-07 16:47:44 +0000 |
|---|---|---|
| committer | Carl Hetherington <cth@carlh.net> | 2014-01-07 16:47:44 +0000 |
| commit | 16d5c07df7752d093df804d3f1141790f633c24b (patch) | |
| tree | 7f26d3b870f5fc6cea3987c9088d01f21e7c02b3 /src | |
| parent | 185c57d06c9fe5416bb03fad0874ed813db2ffe8 (diff) | |
Various update bits.
Diffstat (limited to 'src')
| -rw-r--r-- | src/lib/config.cc | 8 | ||||
| -rw-r--r-- | src/lib/config.h | 19 | ||||
| -rw-r--r-- | src/lib/image_examiner.cc | 2 | ||||
| -rw-r--r-- | src/lib/update.cc | 109 | ||||
| -rw-r--r-- | src/lib/update.h | 26 | ||||
| -rw-r--r-- | src/tools/dcpomatic.cc | 28 | ||||
| -rw-r--r-- | src/wx/config_dialog.cc | 24 | ||||
| -rw-r--r-- | src/wx/config_dialog.h | 5 | ||||
| -rw-r--r-- | src/wx/update_dialog.cc | 61 | ||||
| -rw-r--r-- | src/wx/update_dialog.h | 27 | ||||
| -rw-r--r-- | src/wx/wscript | 1 |
11 files changed, 239 insertions, 71 deletions
diff --git a/src/lib/config.cc b/src/lib/config.cc index 454b03e3a..5a9e1619a 100644 --- a/src/lib/config.cc +++ b/src/lib/config.cc @@ -68,6 +68,8 @@ Config::Config () , _kdm_email ( _("Dear Projectionist\n\nPlease find attached KDMs for $CPL_NAME.\n\nThe KDMs are valid from $START_TIME until $END_TIME.\n\nBest regards,\nDCP-o-matic") ) + , _check_for_updates (false) + , _check_for_test_updates (false) { _allowed_dcp_frame_rates.push_back (24); _allowed_dcp_frame_rates.push_back (25); @@ -180,6 +182,9 @@ Config::read () _mail_password = f.optional_string_child("MailPassword").get_value_or (""); _kdm_from = f.string_child ("KDMFrom"); _kdm_email = f.string_child ("KDMEmail"); + + _check_for_updates = f.optional_bool_child("CheckForUpdates").get_value_or (false); + _check_for_test_updates = f.optional_bool_child("CheckForTestUpdates").get_value_or (false); } void @@ -354,6 +359,9 @@ Config::write () const root->add_child("KDMFrom")->add_child_text (_kdm_from); root->add_child("KDMEmail")->add_child_text (_kdm_email); + root->add_child("CheckForUpdates")->add_child_text (_check_for_updates ? "1" : "0"); + root->add_child("CheckForTestUpdates")->add_child_text (_check_for_test_updates ? "1" : "0"); + doc.write_to_file_formatted (file(false).string ()); } diff --git a/src/lib/config.h b/src/lib/config.h index 67d293884..791e41e8f 100644 --- a/src/lib/config.h +++ b/src/lib/config.h @@ -171,6 +171,14 @@ public: return _kdm_email; } + bool check_for_updates () const { + return _check_for_updates; + } + + bool check_for_test_updates () const { + return _check_for_test_updates; + } + /** @param n New number of local encoding threads */ void set_num_local_encoding_threads (int n) { _num_local_encoding_threads = n; @@ -284,6 +292,14 @@ public: void set_kdm_email (std::string e) { _kdm_email = e; } + + void set_check_for_updates (bool c) { + _check_for_updates = c; + } + + void set_check_for_test_updates (bool c) { + _check_for_test_updates = c; + } void write () const; @@ -341,6 +357,9 @@ private: std::string _mail_password; std::string _kdm_from; std::string _kdm_email; + /** true to check for updates on startup */ + bool _check_for_updates; + bool _check_for_test_updates; /** Singleton instance, or 0 */ static Config* _instance; diff --git a/src/lib/image_examiner.cc b/src/lib/image_examiner.cc index 17064fd45..12fe2b8a6 100644 --- a/src/lib/image_examiner.cc +++ b/src/lib/image_examiner.cc @@ -36,7 +36,7 @@ using boost::shared_ptr; using boost::lexical_cast; using boost::bad_lexical_cast; -ImageExaminer::ImageExaminer (shared_ptr<const Film> film, shared_ptr<const ImageContent> content, shared_ptr<Job> job) +ImageExaminer::ImageExaminer (shared_ptr<const Film> film, shared_ptr<const ImageContent> content, shared_ptr<Job>) : _film (film) , _image_content (content) , _video_length (0) diff --git a/src/lib/update.cc b/src/lib/update.cc index d68979e60..6e5f92edc 100644 --- a/src/lib/update.cc +++ b/src/lib/update.cc @@ -47,7 +47,7 @@ UpdateChecker::UpdateChecker () , _offset (0) , _curl (0) , _state (NOT_RUN) - , _startup (true) + , _emits (0) { curl_global_init (CURL_GLOBAL_ALL); _curl = curl_easy_init (); @@ -59,66 +59,78 @@ UpdateChecker::UpdateChecker () string const agent = "dcpomatic/" + string (dcpomatic_version); curl_easy_setopt (_curl, CURLOPT_USERAGENT, agent.c_str ()); + + _thread = new boost::thread (boost::bind (&UpdateChecker::thread, this)); } UpdateChecker::~UpdateChecker () { + /* We are not cleaning up our thread, but hey well */ + curl_easy_cleanup (_curl); curl_global_cleanup (); delete[] _buffer; } void -UpdateChecker::run (bool startup) -try +UpdateChecker::run () { - boost::mutex::scoped_lock lm (_single_thread_mutex); - - { - boost::mutex::scoped_lock lm (_data_mutex); - _startup = startup; - } - - _offset = 0; - - int r = curl_easy_perform (_curl); - if (r != CURLE_OK) { - set_state (FAILED); - return; - } - - _buffer[_offset] = '\0'; - stringstream s; - s << _buffer; - cxml::Document doc ("Update"); - doc.read_stream (s); - - { - boost::mutex::scoped_lock lm (_data_mutex); - _stable = doc.string_child ("Stable"); - } - - string current = string (dcpomatic_version); - bool current_pre = false; - if (boost::algorithm::ends_with (current, "pre")) { - current = current.substr (0, current.length() - 3); - current_pre = true; - } - - float current_float = lexical_cast<float> (current); - if (current_pre) { - current_float -= 0.005; - } + boost::mutex::scoped_lock lm (_process_mutex); + _condition.notify_one (); +} - if (current_float < lexical_cast<float> (_stable)) { - set_state (YES); - } else { - set_state (NO); +void +UpdateChecker::thread () +{ + while (1) { + boost::mutex::scoped_lock lock (_process_mutex); + _condition.wait (lock); + lock.unlock (); + + try { + _offset = 0; + + int r = curl_easy_perform (_curl); + if (r != CURLE_OK) { + set_state (FAILED); + return; + } + + _buffer[_offset] = '\0'; + stringstream s; + s << _buffer; + cxml::Document doc ("Update"); + doc.read_stream (s); + + { + boost::mutex::scoped_lock lm (_data_mutex); + _stable = doc.string_child ("Stable"); + _test = doc.string_child ("Test"); + } + + string current = string (dcpomatic_version); + bool current_pre = false; + if (boost::algorithm::ends_with (current, "pre")) { + current = current.substr (0, current.length() - 3); + current_pre = true; + } + + float current_float = lexical_cast<float> (current); + if (current_pre) { + current_float -= 0.005; + } + + if (current_float < lexical_cast<float> (_stable)) { + set_state (YES); + } else { + set_state (NO); + } + } catch (...) { + set_state (FAILED); + } } -} catch (...) { - set_state (FAILED); } - + size_t UpdateChecker::write_callback (void* data, size_t size, size_t nmemb) { @@ -134,8 +146,9 @@ UpdateChecker::set_state (State s) { boost::mutex::scoped_lock lm (_data_mutex); _state = s; + _emits++; } - + ui_signaller->emit (boost::bind (boost::ref (StateChanged))); } diff --git a/src/lib/update.h b/src/lib/update.h index b879e9026..a1aefd0a1 100644 --- a/src/lib/update.h +++ b/src/lib/update.h @@ -19,6 +19,7 @@ #include <boost/signals2.hpp> #include <boost/thread/mutex.hpp> +#include <boost/thread/condition.hpp> #include <curl/curl.h> class UpdateChecker @@ -27,7 +28,7 @@ public: UpdateChecker (); ~UpdateChecker (); - void run (bool); + void run (); enum State { YES, @@ -46,10 +47,15 @@ public: return _stable; } - /** @return true if this check was run at startup, otherwise false */ - bool startup () const { + std::string test () { boost::mutex::scoped_lock lm (_data_mutex); - return _startup; + return _test; + } + + /** @return true if the list signal emission was the first */ + bool last_emit_was_first () const { + boost::mutex::scoped_lock lm (_data_mutex); + return _emits == 1; } size_t write_callback (void *, size_t, size_t); @@ -62,18 +68,20 @@ private: static UpdateChecker* _instance; void set_state (State); + void thread (); char* _buffer; int _offset; CURL* _curl; - /** mutex to protect _state, _stable and _startup */ + /** mutex to protect _state, _stable, _test and _emits */ mutable boost::mutex _data_mutex; State _state; std::string _stable; - /** true if this check was run at startup, otherwise false */ - bool _startup; + std::string _test; + int _emits; - /** mutex to ensure that only one query runs at once */ - boost::mutex _single_thread_mutex; + boost::thread* _thread; + boost::mutex _process_mutex; + boost::condition _condition; }; diff --git a/src/tools/dcpomatic.cc b/src/tools/dcpomatic.cc index fcb47f2d1..4e23cf09d 100644 --- a/src/tools/dcpomatic.cc +++ b/src/tools/dcpomatic.cc @@ -42,6 +42,7 @@ #include "wx/kdm_dialog.h" #include "wx/servers_list_dialog.h" #include "wx/hints_dialog.h" +#include "wx/update_dialog.h" #include "lib/film.h" #include "lib/config.h" #include "lib/util.h" @@ -536,7 +537,7 @@ private: void tools_check_for_updates () { - UpdateChecker::instance()->run (false); + UpdateChecker::instance()->run (); } void help_about () @@ -650,15 +651,18 @@ class App : public wxApp _frame->Maximize (); _frame->Show (); - UpdateChecker::instance()->StateChanged.connect (boost::bind (&App::update_checker_state_changed, this)); - ui_signaller = new wxUISignaller (this); Bind (wxEVT_IDLE, boost::bind (&App::idle, this)); Bind (wxEVT_TIMER, boost::bind (&App::check, this)); _timer.reset (new wxTimer (this)); _timer->Start (1000); - + + UpdateChecker::instance()->StateChanged.connect (boost::bind (&App::update_checker_state_changed, this)); + if (Config::instance()->check_for_updates ()) { + UpdateChecker::instance()->run (); + } + return true; } catch (exception& e) @@ -709,21 +713,19 @@ class App : public wxApp { switch (UpdateChecker::instance()->state ()) { case UpdateChecker::YES: - error_dialog ( - _frame, - wxString::Format ( - _("A new version %s of DCP-o-matic is available from http://dcpomatic.com/download"), - std_to_wx (UpdateChecker::instance()->stable()).wx_str () - ) - ); + { + UpdateDialog* dialog = new UpdateDialog (_frame, UpdateChecker::instance()->stable (), UpdateChecker::instance()->test ()); + dialog->ShowModal (); + dialog->Destroy (); break; + } case UpdateChecker::NO: - if (!UpdateChecker::instance()->startup ()) { + if (!UpdateChecker::instance()->last_emit_was_first ()) { error_dialog (_frame, _("There are no new versions of DCP-o-matic available.")); } break; case UpdateChecker::FAILED: - if (!UpdateChecker::instance()->startup ()) { + if (!UpdateChecker::instance()->last_emit_was_first ()) { error_dialog (_frame, _("The DCP-o-matic download server could not be contacted.")); } default: diff --git a/src/wx/config_dialog.cc b/src/wx/config_dialog.cc index 52c08018f..2b07dd1dc 100644 --- a/src/wx/config_dialog.cc +++ b/src/wx/config_dialog.cc @@ -135,6 +135,14 @@ ConfigDialog::make_misc_panel () add_label_to_sizer (table, _misc_panel, _("From address for KDM emails"), true); _kdm_from = new wxTextCtrl (_misc_panel, wxID_ANY); table->Add (_kdm_from, 1, wxEXPAND | wxALL); + + _check_for_updates = new wxCheckBox (_misc_panel, wxID_ANY, _("Check for updates on startup")); + table->Add (_check_for_updates, 1, wxEXPAND | wxALL); + table->AddSpacer (0); + + _check_for_test_updates = new wxCheckBox (_misc_panel, wxID_ANY, _("Check for testing updates as well as stable ones")); + table->Add (_check_for_test_updates, 1, wxEXPAND | wxALL); + table->AddSpacer (0); Config* config = Config::instance (); @@ -171,6 +179,10 @@ ConfigDialog::make_misc_panel () _mail_password->Bind (wxEVT_COMMAND_TEXT_UPDATED, boost::bind (&ConfigDialog::mail_password_changed, this)); _kdm_from->SetValue (std_to_wx (config->kdm_from ())); _kdm_from->Bind (wxEVT_COMMAND_TEXT_UPDATED, boost::bind (&ConfigDialog::kdm_from_changed, this)); + _check_for_updates->SetValue (config->check_for_updates ()); + _check_for_updates->Bind (wxEVT_COMMAND_CHECKBOX_CLICKED, boost::bind (&ConfigDialog::check_for_updates_changed, this)); + _check_for_test_updates->SetValue (config->check_for_test_updates ()); + _check_for_test_updates->Bind (wxEVT_COMMAND_CHECKBOX_CLICKED, boost::bind (&ConfigDialog::check_for_test_updates_changed, this)); } void @@ -578,3 +590,15 @@ ConfigDialog::kdm_email_changed () { Config::instance()->set_kdm_email (wx_to_std (_kdm_email->GetValue ())); } + +void +ConfigDialog::check_for_updates_changed () +{ + Config::instance()->set_check_for_updates (_check_for_updates->GetValue ()); +} + +void +ConfigDialog::check_for_test_updates_changed () +{ + Config::instance()->set_check_for_test_updates (_check_for_test_updates->GetValue ()); +} diff --git a/src/wx/config_dialog.h b/src/wx/config_dialog.h index 49b466bcb..8a17de58d 100644 --- a/src/wx/config_dialog.h +++ b/src/wx/config_dialog.h @@ -76,6 +76,9 @@ private: void make_colour_conversions_panel (); void make_kdm_email_panel (); + void check_for_updates_changed (); + void check_for_test_updates_changed (); + wxNotebook* _notebook; wxPanel* _misc_panel; wxPanel* _defaults_panel; @@ -110,6 +113,8 @@ private: wxPanel* _kdm_email_panel; wxTextCtrl* _kdm_email; wxCheckBox* _use_any_servers; + wxCheckBox* _check_for_updates; + wxCheckBox* _check_for_test_updates; EditableList<std::string, ServerDialog>* _servers_list; }; diff --git a/src/wx/update_dialog.cc b/src/wx/update_dialog.cc new file mode 100644 index 000000000..271c4174c --- /dev/null +++ b/src/wx/update_dialog.cc @@ -0,0 +1,61 @@ +/* + Copyright (C) 2012 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 + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program 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 this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +#include <wx/hyperlink.h> +#include "update_dialog.h" +#include "wx_util.h" + +using std::string; + +UpdateDialog::UpdateDialog (wxWindow* parent, string stable, string test) + : wxDialog (parent, wxID_ANY, _("Update")) +{ + wxBoxSizer* overall_sizer = new wxBoxSizer (wxVERTICAL); + + wxStaticText* message; + + if (test.empty ()) { + message = new wxStaticText (this, wxID_ANY, _("A new version of DCP-o-matic is available.")); + } else { + message = new wxStaticText (this, wxID_ANY, _("New versions of DCP-o-matic are available.")); + } + + overall_sizer->Add (message, 1, wxTOP | wxLEFT | wxRIGHT, DCPOMATIC_DIALOG_BORDER); + + wxFlexGridSizer* table = new wxFlexGridSizer (2, DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP); + + add_label_to_sizer (table, this, _("Stable version ") + std_to_wx (stable), true); + wxHyperlinkCtrl* h = new wxHyperlinkCtrl (this, wxID_ANY, "dcpomatic.com/download", "http://dcpomatic.com/download"); + table->Add (h); + + if (!test.empty ()) { + add_label_to_sizer (table, this, _("Test version ") + std_to_wx (test), true); + wxHyperlinkCtrl* h = new wxHyperlinkCtrl (this, wxID_ANY, "dcpomatic.com/test-download", "http://dcpomatic.com/test-download"); + table->Add (h); + } + + overall_sizer->Add (table, 1, wxEXPAND | wxLEFT | wxRIGHT, DCPOMATIC_DIALOG_BORDER); + + wxSizer* buttons = CreateButtonSizer (wxOK); + if (buttons) { + overall_sizer->Add (buttons, 1, wxEXPAND | wxALL); + } + + SetSizerAndFit (overall_sizer); +} diff --git a/src/wx/update_dialog.h b/src/wx/update_dialog.h new file mode 100644 index 000000000..d9c7b855d --- /dev/null +++ b/src/wx/update_dialog.h @@ -0,0 +1,27 @@ +/* + Copyright (C) 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 + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program 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 this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +#include <wx/wx.h> + +class UpdateDialog : public wxDialog +{ +public: + UpdateDialog (wxWindow *, std::string, std::string); +}; + diff --git a/src/wx/wscript b/src/wx/wscript index 26bf32bdc..9de32d39e 100644 --- a/src/wx/wscript +++ b/src/wx/wscript @@ -39,6 +39,7 @@ sources = """ timeline.cc timeline_dialog.cc timing_panel.cc + update_dialog.cc video_panel.cc wx_util.cc wx_ui_signaller.cc |
