/// // Copyright (C) 2002 - 2004, Fredrik Arnerup & Rasmus Kaj, See COPYING /// #include "window.h" #include #include #include #include #include #include #include #include "util/warning.h" #include "widget/wmisc.h" #include "widget/filesel.h" #include "widget/imagefilesel.h" #include "config.h" #include "printdialog.h" #include "propertiesdialog.h" #include "streamdialog.h" #include "pagesel.h" namespace{ typedef std::set Windows; Windows windows; // a list of all windows } FrameWindow *FrameWindow::active_window(0); FrameWindow::FrameWindow(const FrameWindow &original) : zoom_factor(original.document_view.get_zoom_factor()), document_view(original.document_view.get_document_meta(), zoom_factor.get_factor()) { constructor_common(); } // you are not supposed to call with non-empty string and non-null // document FrameWindow::FrameWindow(const Glib::ustring &filename, DocRef document) : zoom_factor(config.ZoomLevel.values.front() / 100.0), document_view(DocMeta(filename.empty() ? document : Document::create(filename, false), filename), zoom_factor.get_factor()) { constructor_common(); } void FrameWindow::constructor_common() { // key presses are forwarded to the view signal_key_press_event().connect (sigc::mem_fun(document_view, &DocumentView::on_key_press_event)); open_dialog.reset(new Filesel(*this, "Open")); save_dialog.reset(new Filesel(*this, "Save As", Gtk::FILE_CHOOSER_ACTION_SAVE)); // file filters { Gtk::FileFilter pfilter; pfilter.set_name("Passepartout Document files"); pfilter.add_pattern("*.pp"); Gtk::FileFilter afilter; afilter.set_name("All files"); afilter.add_pattern("*"); open_dialog->add_filter(pfilter); save_dialog->add_filter(pfilter); open_dialog->add_filter(afilter); save_dialog->add_filter(afilter); } print_dialog.reset(new PrintDialog(*this, document_view)); text_frame_dialog.reset(new TextFrameDialog(*this, document_view)); { // get default unit of import image dialog from config file Glib::ustring unit = config.LengthUnit.values.front(); float factor = 1; try { factor = length_units.get_factor(unit); } catch(unknown_unit_error&) { unit = Glib::ustring(); } import_dialog.reset (new ImageFilesel(*this, "Import Image", config.DefaultResolution.values.front(), unit, factor)); } pagesel = manage(new Pagesel(document_view)); // create menus and toolbar uimanager = Gtk::UIManager::create(); uimanager->insert_action_group(main_group = Gtk::ActionGroup::create()); uimanager->insert_action_group(doc_group = Gtk::ActionGroup::create()); uimanager->insert_action_group(page_group = Gtk::ActionGroup::create()); uimanager->insert_action_group(selection_group = Gtk::ActionGroup::create()); create_menus(); // defined in windowmenus.cc add_accel_group(uimanager->get_accel_group()); set_default_size(500, 700); Gtk::VBox *mainbox = manage(new Gtk::VBox()); add(*mainbox); Gtk::Toolbar *toolbar = dynamic_cast(uimanager->get_widget("/ToolBar")); toolbar->set_orientation(Gtk::ORIENTATION_VERTICAL); toolbar->set_toolbar_style(Gtk::TOOLBAR_ICONS); Gtk::HBox *hbox = manage(new Gtk::HBox(false, 0)); hbox->pack_start(*toolbar, Gtk::PACK_SHRINK, 2); Gtk::Table *table = manage(new Gtk::Table(2, 2, false)); hbox->pack_end(*table, Gtk::PACK_EXPAND_WIDGET, 0); mainbox->pack_start(*uimanager->get_widget("/MenuBar"), Gtk::PACK_SHRINK); mainbox->pack_start(*hbox); scroller = manage(new Gtk::ScrolledWindow()); table->attach(*scroller, 1, 2, 1, 2, Gtk::EXPAND | Gtk::FILL, Gtk::EXPAND | Gtk::FILL); scroller->add(document_view); scroller->set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC); cafe_opera = manage(new Gtk::Statusbar()); cafe_opera->set_has_resize_grip(false); cafe_opera->property_spacing() = double_space; cafe_opera->pack_end(*pagesel, Gtk::PACK_SHRINK, 0); Gtk::Label *page_label = manage(new Gtk::Label("P_age:", true)); page_label->set_mnemonic_widget(pagesel->get_menu()); cafe_opera->pack_end(*page_label, Gtk::PACK_SHRINK, 0); cafe_opera->pack_end(zoom_factor.get_widget(), Gtk::PACK_SHRINK, 0); Gtk::Label *zoom_label = manage(new Gtk::Label("_Zoom:", true)); zoom_label->set_mnemonic_widget(zoom_factor.get_widget()); cafe_opera->pack_end(*zoom_label, Gtk::PACK_SHRINK, 0); mainbox->pack_end(*cafe_opera, Gtk::PACK_SHRINK); zoom_factor.signal_changed.connect (sigc::mem_fun(*this, &FrameWindow::zoom_factor_changed_action)); open_dialog->signal_hide().connect (sigc::mem_fun(*this, &FrameWindow::open_dialog_done)); save_dialog->signal_hide().connect (sigc::mem_fun(*this, &FrameWindow::save_dialog_done)); import_dialog->signal_hide().connect (sigc::mem_fun(*this, &FrameWindow::import_dialog_done)); document_view.document_set_signal.connect (sigc::mem_fun(*this, &FrameWindow::on_document_changed)); Document::changed_signal.connect (sigc::mem_fun(*this, &FrameWindow::on_document_updated)); // put window in global list windows.insert(this); show_all(); active_window = this; // make sure not everything is visible and that document dependent // handlers are connected on_document_changed(); } FrameWindow::~FrameWindow() { // remove window from list windows.erase(this); // set active window active_window = 0; // don't know which one it'll be if(windows.empty()) Gtk::Main::quit(); else debug << "window count = " << windows.size() << std::endl; } void FrameWindow::set_filename(const Glib::ustring &filename) { if(!filename.empty()) { set_title(basename(filename) + " - Passepartout"); } else set_title("Passepartout"); } void FrameWindow::zoom_factor_changed_action(float factor) { document_view.set_zoom_factor(factor); } void FrameWindow::on_document_updated(DocRef document_) { DocRef document = document_view.get_document(); if(document != document_) return; on_document_changed(); } void FrameWindow::on_document_filename_changed() { DocMeta document = document_view.get_document_meta(); set_filename(document ? document.get_filename() : ""); } void FrameWindow::on_document_changed() { DocRef document = document_view.get_document(); // enable/disable stuff bool on = document; bool have_pages = on && document->get_num_of_pages() > 0; doc_group->set_sensitive(on); page_group->set_sensitive(have_pages); /// \todo when we have a selection selection_group->set_sensitive(have_pages); // We may have a new DocMeta in view, so connect to the new signal DocMeta docmeta = document_view.get_document_meta(); docmeta.changed_signal().connect (sigc::mem_fun(*this, &FrameWindow::on_document_filename_changed)); set_filename(basename(docmeta.get_filename())); } void FrameWindow::open_dialog_done() { if(!open_dialog->was_cancelled()) { if(document_view.get_document()) new FrameWindow(open_dialog->get_filename()); else { document_view.set_document (DocMeta(Document::create(open_dialog->get_filename(), false), open_dialog->get_filename())); } } } void FrameWindow::import_dialog_done() { if(!import_dialog->was_cancelled()) document_view.new_image_frame (import_dialog->get_filename(), dynamic_cast(import_dialog.get())->get_res()); } void FrameWindow::save_dialog_done() { DocMeta document = document_view.get_document_meta(); if(!save_dialog->was_cancelled() && document) { const std::string filename = save_dialog->get_filename(); document.set_filename(filename); document->save(filename); } } void FrameWindow::close() { DocRef document = document_view.get_document(); if(windows.size() > 1 || !document) { windows.erase(this); delete this; } else { DocRef null = Document::null(); document_view.set_document(DocMeta(null)); PropertiesDialog::instance().set_document(null); StreamDialog::instance().set_document(null); set_filename(""); } } void FrameWindow::save() { DocRef document = document_view.get_document(); if(!document) return; const std::string filename = document_view.get_document_meta().get_filename(); if(!filename.empty()) { document->save(filename); } else save_dialog->show(); } bool FrameWindow::on_delete_event(GdkEventAny *event) { close(); return true; } bool FrameWindow::on_focus_in_event(GdkEventFocus *event) { // the nonmodal windows are updated to reflect the content in the window // that is currently in focus active_window = this; DocRef document = document_view.get_document(); PropertiesDialog::instance().set_transient_for(*this); PropertiesDialog::instance().set_document(document); StreamDialog::instance().set_transient_for(*this); StreamDialog::instance().set_document(document); return false; } void FrameWindow::quit() { // make sure all destructors are executed while(!windows.empty()) // the destructor removes the window from the set delete *windows.begin(); Gtk::Main::quit(); }