]> git.decadent.org.uk Git - videolink.git/blobdiff - videolink.cpp
Brought up to date in preparation for version 1.2.
[videolink.git] / videolink.cpp
index ca4193370fae8d379ec326b9f5504eb9d37dfd26..112125ad2b27e47c2ab8e8ef1d3e08b76fb080cc 100644 (file)
@@ -121,6 +121,7 @@ namespace
            {".vob",     video_format_mpeg2_ps},
            {".mpeg",    video_format_mpeg2_ps},
            {".mpeg2",   video_format_mpeg2_ps},
+           {".mpg",     video_format_mpeg2_ps},
            {".voblist", video_format_vob_list}
        };
        for (std::size_t i = 0;
@@ -160,7 +161,8 @@ namespace
        add(browser_widget_);
        browser_widget_.show();
 
-       Glib::signal_idle().connect(SigC::slot(*this, &base_window::on_idle));
+       Glib::signal_idle().connect(
+           sigc::mem_fun(this, &base_window::on_idle));
     }
 
     bool base_window::on_idle()
@@ -187,7 +189,8 @@ namespace
        : base_window(frame_params),
          main_page_uri_(main_page_uri)
     {
-       signal_key_press_event().connect(SigC::slot(*this, &preview_window::on_key_press));
+       signal_key_press_event().connect(
+           sigc::mem_fun(this, &preview_window::on_key_press));
     }
 
     void preview_window::do_late_initialisation()
@@ -233,6 +236,9 @@ namespace
            {
                return pending_window_update_ || pending_req_count_;
            }
+       // Try to do as much processing as possible.  Quit if done;
+       // report and quit if an exception occurs.
+       void try_process();
        // Do as much processing as possible.  Return a flag indicating
        // whether to call again once the browser is idle.
        bool process();
@@ -276,7 +282,7 @@ namespace
          finished_(false)
     {
        browser_widget_.signal_net_state().connect(
-           SigC::slot(*this, &conversion_window::on_net_state_change));
+           sigc::mem_fun(this, &conversion_window::on_net_state_change));
 
        add_menu(main_page_uri);
     }
@@ -340,7 +346,7 @@ namespace
     {
        assert(!page_queue_.empty());
        const std::string & uri = page_queue_.front();
-       std::cout << "loading " << uri << std::endl;
+       std::cout << "INFO: Loading <" << uri << ">" << std::endl;
 
        browser_widget_.load_uri(uri);
     }
@@ -427,34 +433,7 @@ namespace
        }
 
        if (!browser_is_busy())
-       {
-           try
-           {
-               if (!process())
-               {
-                   finished_ = true;
-                   Gtk::Main::quit();
-               }
-           }
-           catch (std::exception & e)
-           {
-               std::cerr << "Fatal error";
-               if (!page_queue_.empty())
-                   std::cerr << " while processing <" << page_queue_.front()
-                             << ">";
-               std::cerr << ": " << e.what() << "\n";
-               Gtk::Main::quit();
-           }
-           catch (Glib::Exception & e)
-           {
-               std::cerr << "Fatal error";
-               if (!page_queue_.empty())
-                   std::cerr << " while processing <" << page_queue_.front()
-                             << ">";
-               std::cerr << ": " << e.what() << "\n";
-               Gtk::Main::quit();
-           }
-       }
+           try_process();
     }
 
     struct conversion_window::page_state
@@ -477,9 +456,54 @@ namespace
        link_iterator links_it, links_end;
 
        rectangle link_rect;
+       std::string link_target;
        bool link_changing;
     };
 
+    void conversion_window::try_process()
+    {
+       try
+       {
+           if (!process())
+           {
+               finished_ = true;
+               Gtk::Main::quit();
+           }
+       }
+       catch (...)
+       {
+           // Print context of exception.
+           if (!page_queue_.empty())
+           {
+               std::cerr << "ERROR: While processing page <"
+                         << page_queue_.front() << ">:\n";
+               if (page_state_.get() && !page_state_->link_target.empty())
+                   std::cerr << "ERROR: While processing link to <"
+                             << page_state_->link_target << ">:\n";
+           }
+
+           // Print exception message.
+           try
+           {
+               throw;
+           }
+           catch (std::exception & e)
+           {
+               std::cerr << "ERROR: " << e.what() << "\n";
+           }
+           catch (Glib::Exception & e)
+           {
+               std::cerr << "ERROR: " << e.what() << "\n";
+           }
+           catch (...)
+           {
+               std::cerr << "ERROR: Unknown exception\n";
+           }
+
+           Gtk::Main::quit();
+       }
+    }
+
     bool conversion_window::process()
     {
        assert(!page_queue_.empty());
@@ -498,31 +522,26 @@ namespace
        check(dom_window->GetDocument(getter_AddRefs(basic_doc)));
 
        // Start or continue processing links.
-       std::auto_ptr<page_state> state(page_state_);
-       if (!state.get())
-           state.reset(
+       if (!page_state_.get())
+           page_state_.reset(
                new page_state(
                    get_screenshot(),
                    basic_doc, frame_params_.width, frame_params_.height));
-       if (process_links(
-               state.get(),
+       if (!process_links(
+               page_state_.get(),
                basic_doc, pres_shell, pres_context, dom_window))
-       {
-           // Save iteration state for later.
-           page_state_ = state;
-       }
-       else
        {
            // We've finished work on the links so generate the
            // menu VOB.
-           quantise_rgba_pixbuf(state->diff_pixbuf,
+           quantise_rgba_pixbuf(page_state_->diff_pixbuf,
                                 dvd::button_n_colours);
            generator_.generate_menu_vob(
                resource_map_[page_queue_.front()].index,
-               state->norm_pixbuf, state->diff_pixbuf);
+               page_state_->norm_pixbuf, page_state_->diff_pixbuf);
 
            // Move on to the next page, if any, or else generate
            // the DVD filesystem.
+           page_state_.reset();
            page_queue_.pop();
            if (!page_queue_.empty())
            {
@@ -590,17 +609,17 @@ namespace
            assert(link);
            nsCOMPtr<nsIURI> uri_iface;
            check(link->GetHrefURI(getter_AddRefs(uri_iface)));
-           std::string uri_and_fragment, uri, fragment;
+           std::string uri, fragment;
            {
-               nsCString uri_and_fragment_ns;
-               check(uri_iface->GetSpec(uri_and_fragment_ns));
-               uri_and_fragment.assign(uri_and_fragment_ns.BeginReading(),
-                                       uri_and_fragment_ns.EndReading());
+               nsCString link_target_ns;
+               check(uri_iface->GetSpec(link_target_ns));
+               state->link_target.assign(link_target_ns.BeginReading(),
+                                         link_target_ns.EndReading());
 
-               std::size_t hash_pos = uri_and_fragment.find('#');
-               uri.assign(uri_and_fragment, 0, hash_pos);
+               std::size_t hash_pos = state->link_target.find('#');
+               uri.assign(state->link_target, 0, hash_pos);
                if (hash_pos != std::string::npos)
-                   fragment.assign(uri_and_fragment,
+                   fragment.assign(state->link_target,
                                    hash_pos + 1, std::string::npos);
            }
 
@@ -616,8 +635,8 @@ namespace
 
                if (state->link_rect.empty())
                {
-                   std::cerr << "Ignoring invisible link to "
-                             << uri_and_fragment << "\n";
+                   std::cerr << "WARN: Ignoring invisible link to <"
+                             << state->link_target << ">\n";
                    continue;
                }
 
@@ -631,11 +650,8 @@ namespace
                    PRBool is_file;
                    check(uri_iface->SchemeIs("file", &is_file));
                    if (!is_file)
-                   {
-                       std::cerr << "Links to video must use the file:"
-                                 << " scheme\n";
-                       continue;
-                   }
+                       throw std::runtime_error(
+                           "Link to video does not use file: scheme");
                    target = add_title(uri, format);
                    target.sub_index =
                        std::strtoul(fragment.c_str(), NULL, 10);
@@ -794,7 +810,7 @@ namespace
 
 void fatal_error(const std::string & message)
 {
-    std::cerr << "Fatal error: " << message << "\n";
+    std::cerr << "ERROR: " << message << "\n";
     Gtk::Main::quit();
 }
 
@@ -963,7 +979,7 @@ int main(int argc, char ** argv)
        {
            preview_window window(frame_params, menu_url);
            window.show();
-           window.signal_hide().connect(SigC::slot(&Gtk::Main::quit));
+           window.signal_hide().connect(sigc::ptr_fun(Gtk::Main::quit));
            Gtk::Main::run();
            return EXIT_SUCCESS;
        }
@@ -971,14 +987,14 @@ int main(int argc, char ** argv)
        {
            conversion_window window(frame_params, menu_url, output_dir, encoder);
            window.show();
-           window.signal_hide().connect(SigC::slot(&Gtk::Main::quit));
+           window.signal_hide().connect(sigc::ptr_fun(Gtk::Main::quit));
            Gtk::Main::run();
            return window.is_finished() ? EXIT_SUCCESS  : EXIT_FAILURE;
        }
     }
     catch (std::exception & e)
     {
-       std::cerr << "Fatal error: " << e.what() << "\n";
+       std::cerr << "ERROR: " << e.what() << "\n";
        return EXIT_FAILURE;
     }
 }