Logo Search packages:      
Sourcecode: passepartout version File versions  Download package

pagesel.cc

///
// Copyright (C) 2002 - 2004, Fredrik Arnerup & Rasmus Kaj, See COPYING
///
#include "pagesel.h"
#include "document/page.h"
#include "document/document.h"
#include "widget/wmisc.h"
#include <util/stringutil.h>
#include <util/warning.h>
#include <gtkmm/scrolledwindow.h>
#include <gtkmm/stock.h>
#include <gtkmm/arrow.h>
#include <gtkmm/label.h>

void Pagesel::page_selected_action() {
  Gtk::Menu *menu = pages.get_menu();
  Gtk::MenuItem *active_item;
  Gtk::Widget *child;
  Gtk::Label *label;
  // if active_item->get_child() returns null, then we are probably
  // try to switch to the same page as we are coming from.
  if(menu && (active_item = menu->get_active())
     && (child = active_item->get_child())
     && (label = dynamic_cast<Gtk::Label*>(child))) {
    DocRef document = document_view.get_document();
    Page *page;
    if(document && (page = document->get_page(label->get_text())))
      document_view.set_current_page_num(page->get_page_num());
  }
}

void Pagesel::next() {
  document_view.set_current_page_num(document_view.get_current_page_num() + 1);
}

void Pagesel::prev() {
  document_view.set_current_page_num(document_view.get_current_page_num() - 1);
}

void Pagesel::update() {
  int i;
  using namespace Gtk;
  using namespace Menu_Helpers;
  Gtk::Menu dummy;       // we have to change the menu and change it back
  pages.set_menu(dummy); // or else the OptionMenu widget won't notice that 
                         // the real menu has changed

  DocRef document = document_view.get_document();
  MenuList& menu_list = menu.items();
  menu_list.clear();

  set_sensitive(document && document->get_num_of_pages());
  if(!document)
      return;

  i = document->get_first_page_num();
  while(i < (document->get_first_page_num()
           + int(document->get_num_of_pages()))) {
    Glib::ustring tmp;

    // The doublesided feature is useless until we can display 
    // two pages at once, so it is disabled
    if(false // document->is_doublesided() 
       && i == document->get_first_page_num() 
       && i % 2 != 0)
      tmp = "-";
    else {
      if(document->get_page(i))
      tmp = document->get_page(i)->get_name();
      i++;
    }
    if(false) // document->is_doublesided())
      if(i < (document->get_first_page_num()
            + int(document->get_num_of_pages()))) {
      if(document->get_page(i))
        tmp += ", " + document->get_page(i)->get_name();
      i++;
      } else
      tmp += ", -";
    menu_list.push_back(MenuElem(tmp));
  }
  int index = document_view.get_current_page_num()
    - document->get_first_page_num();
  menu.set_active(index);
  left.set_sensitive(index);
  right.set_sensitive(index < (int(menu.items().size()) - 1));
  pages.set_menu(menu);
}

void Pagesel::on_realize() {
  Gtk::HBox::on_realize();
  // this fixes a problem with get_active()->get_child in
  // page_selected_action()
  update();
}

Pagesel::Pagesel(DocumentView &docview) :
  document_view(docview)
{
  document_view.current_page_num_changed_signal.connect
    (slot(*this, &Pagesel::update));
  document_view.document_changed_signal.connect
    (slot(*this, &Pagesel::update));

  left.add(*manage(new Gtk::Arrow(Gtk::ARROW_LEFT, Gtk::SHADOW_NONE)));
  right.add(*manage(new Gtk::Arrow(Gtk::ARROW_RIGHT, Gtk::SHADOW_NONE)));
  
  update();
  pages.set_menu(menu);

  pack_start(left);
  pack_start(pages);
  pack_start(right);

  left.signal_clicked().connect(slot(*this, &Pagesel::prev));
  right.signal_clicked().connect(slot(*this, &Pagesel::next));
  pages.get_menu()->signal_selection_done().connect
    (slot(*this, &Pagesel::page_selected_action));

  show_all();
}

Pagesel::~Pagesel() {
  // This is needed:
  Gtk::Menu dummy;
  pages.set_menu(dummy);
  // Is it a bug in Gtk?
}

namespace {
   class ModelColumns: public Gtk::TreeModel::ColumnRecord {
  public:
    ModelColumns()
    {add(col_name); add(col_style);}
    Gtk::TreeModelColumn<Glib::ustring> col_name;
    Gtk::TreeModelColumn<int> col_style;
  };
  const ModelColumns columns;
  const Glib::ustring no_template_string("blank page");
}

TemplatePageDialog::TemplatePageDialog(Gtk::Window &parent, 
                                       DocumentView &document_view_):
  DialogWrap("", parent), 
  document_view(document_view_)
{
  set_resizable(false);
  set_has_separator(false);

  add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
  add_button(Gtk::Stock::ADD, Gtk::RESPONSE_OK);

  Gtk::ScrolledWindow *scroller = manage(new Gtk::ScrolledWindow);
  scroller->set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
  scroller->set_shadow_type(Gtk::SHADOW_IN);
  scroller->add(page_list);

  Gtk::Label *template_label =
    manage(new Gtk::Label("Select template page:", 0));

  Gtk::Box *vbox = manage(new Gtk::VBox(false, double_space));
  vbox->set_border_width(border_width);
  Gtk::Box *template_label_box = manage(new Gtk::HBox());           
  template_label_box->pack_start(*template_label, Gtk::PACK_SHRINK);
  vbox->pack_start(*template_label_box, Gtk::PACK_SHRINK);
  vbox->pack_start(*scroller, Gtk::PACK_EXPAND_WIDGET);

  get_vbox()->pack_start(*vbox);

  get_vbox()->show_all();
  get_action_area()->show_all();

  tree_model = Gtk::ListStore::create(columns);
  page_list.set_model(tree_model);
  Gtk::CellRendererText *text_renderer = manage(new Gtk::CellRendererText());
  int col_count = page_list.append_column("Name", *text_renderer);
  Gtk::TreeViewColumn* column = page_list.get_column(col_count - 1);
  if(column) {
    column->add_attribute(text_renderer->property_text(), 
                    columns.col_name);
    column->add_attribute(text_renderer->property_style(), 
                    columns.col_style);
  }
  page_list.set_headers_visible(false);
  page_list.property_width_request() = 100;
  page_list.property_height_request() = 100;
}

void TemplatePageDialog::show_it(bool new_page_, int page_num_) {
  set_title(new_page_ ? "Add Page" : "Template Page");
  tree_model->clear();
  new_page = new_page_; page_num = page_num_;
  DocRef document = document_view.get_document();
  if(document) { 
    typedef std::list<std::string> Strings;
    Strings tmp = document->get_template_pages();
    if(tmp.empty()) {
      // if we don't have any template pages then there's no point in 
      // showing the dialog - we just create a blank page
      on_response(Gtk::RESPONSE_OK);
      return;
    }
    for(Strings::iterator i = tmp.begin(); i != tmp.end(); i++) {
      Gtk::TreeModel::Row row = *(tree_model->append());
      row[columns.col_name] = *i;
      row[columns.col_style] = Pango::STYLE_NORMAL;
    }
    Gtk::TreeModel::Row row = *(tree_model->append());
    row[columns.col_name] = no_template_string;
    row[columns.col_style] = Pango::STYLE_ITALIC;
  }
  show();
}

void TemplatePageDialog::on_response(int response_id) {
  if(response_id == Gtk::RESPONSE_OK) { // assume anything else means CANCEL
    DocRef document = document_view.get_document();
    if(new_page && document) {
      std::string page_name = "";
      Glib::RefPtr<Gtk::TreeSelection> selection = page_list.get_selection();
      Gtk::TreeModel::iterator iter = selection->get_selected();
      if(iter) {
        Gtk::TreeModel::Row row = *iter;
        page_name = Glib::ustring(row[columns.col_name]);
      }
      
      if(!page_name.empty() && page_name != no_template_string
         && document->get_template()) {
        Page *t_page = document->get_template()->get_page(page_name);
        if(!t_page) {
          // There should only be existing template pages in the list
          throw std::logic_error("Template page \""
                                 + page_name
                                 + "\" not found");
          return;
        }
        document->new_page(page_num, t_page); //problem here
      } else {
        document->new_page(page_num);
      }
      
      // go to the new page
      document_view.set_current_page_num(page_num);
    }
  }
  hide();
}

Generated by  Doxygen 1.6.0   Back to index