Logo Search packages:      
Sourcecode: cadabra version File versions

help.cc

/*
      Cadabra: a field-theory motivated computer algebra system.
      Copyright (C) 2001-2009  Kasper Peeters <kasper.peeters@aei.mpg.de>

   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 3 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, see <http://www.gnu.org/licenses/>.

*/

#include "help.hh"

#include <fstream>
#include <iostream>

#ifdef __CYGWIN__
  #include <windows.h>
  #include <pcrecpp.h>
#endif

#include <gtkmm/stock.h>
#include <gtkmm/messagedialog.h>

CadabraHelp::CadabraHelp()
      : history_pos(-1), buttonbox(0), back(Gtk::Stock::GO_BACK), forward(Gtk::Stock::GO_FORWARD)
      {
      set_title("XCadabra help");
      try {
            set_icon_from_file(DESTDIR+std::string("/share/pixmaps/cadabra.png"));
            }
      catch(Glib::FileError fe) {
            std::cerr << "cannot open " << DESTDIR+std::string("/share/pixmaps/cadabra.png") << std::endl;
            }
      set_gravity(Gdk::GRAVITY_NORTH_EAST);
      set_default_size((std::min)(Gdk::Screen::get_default()->get_width()-20, 600),
                                      (std::min)(Gdk::Screen::get_default()->get_height()-20, 800));
      
      add(topbox);
      topbox.pack_start(navbox, Gtk::PACK_SHRINK);

//    actiongroup=Gtk::ActionGroup::create();
//    actiongroup->add( Gtk::Action::create("MenuFile", "_File") );
//    actiongroup->add( Gtk::Action::create("CloseWindow", Gtk::Stock::CLOSE),
//                                                sigc::mem_fun(doc, &XCadabra::on_help_close) );

//    uimanager = Gtk::UIManager::create();
//    uimanager->insert_action_group(actiongroup);
//    add_accel_group(uimanager->get_accel_group());
//    
//    Glib::ustring ui_info =
//           "<ui>"
//           "  <menubar name='MenuBar'>"
//           "    <menu action='MenuFile'>"
//           "      <menuitem action='CloseWindow'/>"
//           "    </menu>"
//           "  </menubar>"
//           "</ui>";
//    
//    uimanager->add_ui_from_string(ui_info);
//    Gtk::Widget *menubar = uimanager->get_widget("/MenuBar");
//    topbox.pack_start(*menubar, Gtk::PACK_SHRINK);

      navbox.pack_start(back, Gtk::PACK_SHRINK);
      navbox.pack_start(forward, Gtk::PACK_SHRINK);
      back.set_sensitive(false);
      forward.set_sensitive(false);
      back.signal_clicked().connect(sigc::mem_fun(*this, &CadabraHelp::on_back));
      forward.signal_clicked().connect(sigc::mem_fun(*this, &CadabraHelp::on_forward));

      topbox.add(scroll);
      scroll.set_policy(Gtk::POLICY_NEVER, Gtk::POLICY_ALWAYS);
      scroll.set_border_width(1);
      scroll.add(scrollbox);

      // Set-up the TeXView widget
      textbuf=Gtk::TextBuffer::create();
      texbuf=TeXBuffer::create(textbuf, tex_engine_help);

      texview=new TeXView(texbuf, 12);
      scrollbox.pack_start(*texview, Gtk::PACK_EXPAND_WIDGET, 0);

//    show_all();
      }

void CadabraHelp::display_help(objtype_t objtype, const std::string& objname)
      {
      if(history.size()>0 && history.back()==std::make_pair(objtype, objname)) {
             show_all();
             return; // already displaying this one
             }
      history.resize(history_pos+1);
      history.push_back(std::make_pair(objtype, objname));
      history_pos=history.size()-1;

      display_help();
      }

void CadabraHelp::display_help()
      {
      show_all();

      // Add the buttons for related topics
      if(buttonbox!=0) {
             topbox.remove(*buttonbox);
             delete buttonbox;
             }
      buttonbox = new Gtk::HBox;
      topbox.pack_start(*buttonbox, Gtk::PACK_SHRINK);
      relatedlabel.set_label("See also: ");
      buttonbox->pack_start(relatedlabel, Gtk::PACK_SHRINK);

      back.set_sensitive(history.size()>1);
      forward.set_sensitive(history_pos+1<static_cast<int>(history.size()));

      std::string fname;
      std::string prefix;
#ifdef __CYGWIN__
      TCHAR path[MAX_PATH];
      GetModuleFileName(NULL, path, MAX_PATH);
        prefix=path;
      prefix=prefix.substr(0,prefix.size()
                       -std::string("xcadabra.exe").size());
      
      pcrecpp::RE(":\\\\").GlobalReplace("/", &prefix);
      pcrecpp::RE("\\\\").GlobalReplace("/", &prefix);
        prefix="/cygdrive/"+prefix+"/doc";
#else
        prefix=DESTDIR+std::string("/share/doc/cadabra");
#endif

      switch(history[history_pos].first) {
             case t_property:
                    fname=prefix+std::string("/properties/");
                    break;
             case t_algorithm:
                    fname=prefix+std::string("/algorithms/");
                    break;
             case t_texcommand:
                    fname=prefix+std::string("/reserved/");
                    break;
             default:
                    fname=prefix+std::string("/general");
                    break;
             }
      fname+=history[history_pos].second+".tex";

//    std::cout << fname << std::endl;

      std::string total, line;

      std::ifstream helpfile(fname.c_str());
      if(helpfile.is_open()==false)  {
             total = "Sorry, no help available for {\\tt "+texify(history[history_pos].second)+"}.\n\n"
                    + "{\\small (Could not open {\\tt "+texify(fname)+"}.)}";
             helpfile.open((DESTDIR+std::string("/share/doc/cadabra/general.tex")).c_str());
             if(helpfile.is_open()==false) {
                    textbuf->set_text(total);
                    texbuf->generate("","");
                    texview->image.set(texbuf->get_pixbuf());
                    return;
                    }
             }

      std::vector<std::string> seeprop, seealgo;
      while(std::getline(helpfile, line)) {
             total+=line+"\n";
             if(line.substr(0,11)=="\\cdbseeprop") 
                    seeprop.push_back(line.substr(12,line.size()-13));
             if(line.substr(0,11)=="\\cdbseealgo") 
                    seealgo.push_back(line.substr(12,line.size()-13));
             }
//    for(unsigned int i=0; i<seeprop.size(); ++i)
//           std::cerr << "see also: |::" << seeprop[i] << "|" << std::endl;
//    for(unsigned int i=0; i<seealgo.size(); ++i)
//           std::cerr << "see also: |@" << seealgo[i] << "|" << std::endl;

      textbuf->set_text(total);
      try {
             texbuf->generate("","");
             }
      catch(std::exception& ex) {
            Gtk::MessageDialog md(ex.what());
            md.set_type_hint(Gdk::WINDOW_TYPE_HINT_DIALOG);
            md.run();
            }

      texview->image.set(texbuf->get_pixbuf());

      
      for(unsigned int i=0; i<seeprop.size(); ++i) {
             Gtk::Button *tmp = new Gtk::Button("::"+seeprop[i]);
             tmp->signal_clicked().connect(sigc::bind<objtype_t, std::string>(
                                                                                sigc::mem_fun(*this, &CadabraHelp::on_help_context_link), 
                                                                                t_property,
                                                                                seeprop[i]));
             buttonbox->pack_start(*tmp, Gtk::PACK_SHRINK); // FIXME: is this leaking?
             tmp->show_all();
             }
      for(unsigned int i=0; i<seealgo.size(); ++i) {
             Gtk::Button *tmp = new Gtk::Button("@"+seealgo[i]);
             tmp->signal_clicked().connect(sigc::bind<objtype_t, std::string>(
                                                                                sigc::mem_fun(*this, &CadabraHelp::on_help_context_link), 
                                                                                t_algorithm,
                                                                                seealgo[i]));
             buttonbox->pack_start(*tmp, Gtk::PACK_SHRINK); // FIXME: is this leaking?
             tmp->show_all();
             }
      buttonbox->show_all();
      }

bool CadabraHelp::on_delete_event(GdkEventAny*)
      {
      on_help_close();
      return true;
      }

void CadabraHelp::on_back()
      {
      if(history_pos>0) {
             --history_pos;
             display_help();
             }
      }

void CadabraHelp::on_forward()
      {
      if(history_pos+1<static_cast<int>(history.size())) {
             ++history_pos;
             display_help();
             }
      }

void CadabraHelp::on_help_context_link(CadabraHelp::objtype_t objtype, std::string helpname)
      {
      display_help(objtype, helpname);
      }

void CadabraHelp::on_help_close()
      {
      hide_all();
      }

bool CadabraHelp::on_configure_event(GdkEventConfigure *cfg)
      {
      tex_engine_help.set_geometry(cfg->width-20-35);
      bool ret=Gtk::Window::on_configure_event(cfg);
      texview->image.set(texbuf->get_pixbuf());
      return ret;
      }

bool CadabraHelp::on_key_press_event(GdkEventKey* event)
      {
//    std::cerr << event->keyval << " " << event->state << std::endl;
      if(event->keyval=='w' && event->state&Gdk::CONTROL_MASK) {
             hide_all();
             return true;
             }
      return Window::on_key_press_event(event);
      }


Generated by  Doxygen 1.6.0   Back to index