gui/main_win.cc
author klao
Fri, 24 Mar 2006 20:27:42 +0000
changeset 2015 5e51c9eb5e83
parent 1890 4a583e07d4b8
child 2052 c54ce7a5f4e7
permissions -rw-r--r--
bootstrap: quiet option
     1 #ifdef HAVE_CONFIG_H
     2 #include <config.h>
     3 #endif
     4 
     5 #include "main_win.h"
     6 #include "guipixbufs.h"
     7 
     8 #include "gettext.h"
     9 #define _(string) gettext (string)
    10 
    11 MainWin::MainWin()
    12 {
    13   set_title ("no file");
    14   set_default_size(WIN_WIDTH,WIN_HEIGHT);
    15   add(vbox);
    16 
    17   // custom icons for the toolbar
    18   Glib::RefPtr<Gtk::IconFactory> p_icon_factory = Gtk::IconFactory::create();
    19  
    20   Glib::RefPtr<Gdk::Pixbuf> p_move_pixbuf = Gdk::Pixbuf::create_from_inline(
    21       2328, gui_icons_move);
    22   Glib::RefPtr<Gdk::Pixbuf> p_addnode_pixbuf = Gdk::Pixbuf::create_from_inline(
    23       2328, gui_icons_addnode);
    24   Glib::RefPtr<Gdk::Pixbuf> p_addlink_pixbuf = Gdk::Pixbuf::create_from_inline(
    25       2328, gui_icons_addlink);
    26   Glib::RefPtr<Gdk::Pixbuf> p_delete_pixbuf = Gdk::Pixbuf::create_from_inline(
    27       2328, gui_icons_delete);
    28   Glib::RefPtr<Gdk::Pixbuf> p_editlink_pixbuf = Gdk::Pixbuf::create_from_inline(
    29       2328, gui_icons_editlink);
    30   Glib::RefPtr<Gdk::Pixbuf> p_editnode_pixbuf = Gdk::Pixbuf::create_from_inline(
    31       2328, gui_icons_editnode);
    32   Glib::RefPtr<Gdk::Pixbuf> p_newmap_pixbuf = Gdk::Pixbuf::create_from_inline(
    33       2328, gui_icons_newmap);
    34 
    35   Gtk::IconSource move_icon_source;
    36   move_icon_source.set_pixbuf(p_move_pixbuf);
    37   Gtk::IconSet move_icon_set;
    38   move_icon_set.add_source(move_icon_source);
    39   p_icon_factory->add(Gtk::StockID("gd-move"), move_icon_set);
    40 
    41   Gtk::IconSource addnode_icon_source;
    42   addnode_icon_source.set_pixbuf(p_addnode_pixbuf);
    43   Gtk::IconSet addnode_icon_set;
    44   addnode_icon_set.add_source(addnode_icon_source);
    45   p_icon_factory->add(Gtk::StockID("gd-addnode"), addnode_icon_set);
    46 
    47   Gtk::IconSource addlink_icon_source;
    48   addlink_icon_source.set_pixbuf(p_addlink_pixbuf);
    49   Gtk::IconSet addlink_icon_set;
    50   addlink_icon_set.add_source(addlink_icon_source);
    51   p_icon_factory->add(Gtk::StockID("gd-addlink"), addlink_icon_set);
    52 
    53   Gtk::IconSource delete_icon_source;
    54   delete_icon_source.set_pixbuf(p_delete_pixbuf);
    55   Gtk::IconSet delete_icon_set;
    56   delete_icon_set.add_source(delete_icon_source);
    57   p_icon_factory->add(Gtk::StockID("gd-delete"), delete_icon_set);
    58 
    59   Gtk::IconSource editlink_icon_source;
    60   editlink_icon_source.set_pixbuf(p_editlink_pixbuf);
    61   Gtk::IconSet editlink_icon_set;
    62   editlink_icon_set.add_source(editlink_icon_source);
    63   p_icon_factory->add(Gtk::StockID("gd-editlink"), editlink_icon_set);
    64 
    65   Gtk::IconSource editnode_icon_source;
    66   editnode_icon_source.set_pixbuf(p_editnode_pixbuf);
    67   Gtk::IconSet editnode_icon_set;
    68   editnode_icon_set.add_source(editnode_icon_source);
    69   p_icon_factory->add(Gtk::StockID("gd-editnode"), editnode_icon_set);
    70 
    71   Gtk::IconSource newmap_icon_source;
    72   newmap_icon_source.set_pixbuf(p_newmap_pixbuf);
    73   Gtk::IconSet newmap_icon_set;
    74   newmap_icon_set.add_source(newmap_icon_source);
    75   p_icon_factory->add(Gtk::StockID("gd-newmap"), newmap_icon_set);
    76 
    77   p_icon_factory->add_default();
    78   
    79   ag=Gtk::ActionGroup::create();
    80 
    81   ag->add( Gtk::Action::create("FileMenu", _("_File")) );
    82   ag->add( Gtk::Action::create("FileNew", Gtk::Stock::NEW),
    83       sigc::mem_fun(*this, &MainWin::newTab));
    84   ag->add( Gtk::Action::create("FileOpen", Gtk::Stock::OPEN),
    85       sigc::mem_fun(*this, &MainWin::openFile));
    86   ag->add( Gtk::Action::create("FileClearTab", _("Clear Tab")),
    87       sigc::mem_fun(*this, &MainWin::newFile));
    88   ag->add( Gtk::Action::create("FileSave", Gtk::Stock::SAVE),
    89       sigc::mem_fun(*this, &MainWin::saveFile));
    90   ag->add( Gtk::Action::create("FileSaveAs", Gtk::Stock::SAVE_AS),
    91       sigc::mem_fun(*this, &MainWin::saveFileAs));
    92   ag->add( Gtk::Action::create("Close", Gtk::Stock::CLOSE),
    93       sigc::mem_fun(*this, &MainWin::closeTab));
    94   ag->add( Gtk::Action::create("Quit", Gtk::Stock::QUIT),
    95       sigc::mem_fun(*this, &MainWin::hide));
    96 
    97   ag->add( Gtk::Action::create("ViewMenu", _("_View")) );
    98   ag->add( Gtk::Action::create("ViewZoomIn", Gtk::Stock::ZOOM_IN),
    99       sigc::mem_fun(*this, &MainWin::zoomIn));
   100   ag->add( Gtk::Action::create("ViewZoomOut", Gtk::Stock::ZOOM_OUT),
   101       sigc::mem_fun(*this, &MainWin::zoomOut));
   102   ag->add( Gtk::Action::create("ViewZoomFit", Gtk::Stock::ZOOM_FIT),
   103       sigc::mem_fun(*this, &MainWin::zoomFit));
   104   ag->add( Gtk::Action::create("ViewZoom100", Gtk::Stock::ZOOM_100),
   105       sigc::mem_fun(*this, &MainWin::zoom100));
   106   
   107   ag->add( Gtk::Action::create("ShowMenu", _("_Show")) );
   108   ag->add( Gtk::Action::create("ShowMaps", _("_Maps")),
   109 	   sigc::mem_fun(*this, &MainWin::createMapWin));
   110 
   111   ag->add( Gtk::Action::create("AlgoMenu", _("_Algorithms")) );
   112   ag->add( Gtk::Action::create("AlgoGeneral", _("_General")),
   113 	   sigc::bind( sigc::mem_fun ( *this, &MainWin::createAlgoWin ), 0) );
   114   ag->add( Gtk::Action::create("AlgoKruskal", _("_Kruskal")),
   115 	   sigc::bind( sigc::mem_fun ( *this, &MainWin::createAlgoWin ), 1) );
   116 
   117   Gtk::RadioAction::Group tool_group;
   118   ag->add( Gtk::RadioAction::create(tool_group, "MoveItem", Gtk::StockID("gd-move"), _("Move")),
   119       sigc::bind( sigc::mem_fun ( *this, &MainWin::changeEditorialTool ), 0) );
   120   ag->add( Gtk::RadioAction::create(tool_group, "CreateNode", Gtk::StockID("gd-addnode"), _("Create node")),
   121       sigc::bind( sigc::mem_fun ( *this, &MainWin::changeEditorialTool ), 1) );
   122   ag->add( Gtk::RadioAction::create(tool_group, "CreateEdge", Gtk::StockID("gd-addlink"), _("Create edge")),
   123       sigc::bind( sigc::mem_fun ( *this, &MainWin::changeEditorialTool ), 2) );
   124   ag->add( Gtk::RadioAction::create(tool_group, "EraseItem", Gtk::StockID("gd-delete"), _("Delete")),
   125       sigc::bind( sigc::mem_fun ( *this, &MainWin::changeEditorialTool ), 3) );
   126 
   127   ag->add( Gtk::RadioAction::create(tool_group, "EditEdgeMap", Gtk::StockID("gd-editlink"), _("Edit edge map")),
   128       sigc::bind( sigc::mem_fun ( *this, &MainWin::changeEditorialTool ), 4) );
   129   ag->add( Gtk::RadioAction::create(tool_group, "EditNodeMap", Gtk::StockID("gd-editnode"), _("Edit node map")),
   130       sigc::bind( sigc::mem_fun ( *this, &MainWin::changeEditorialTool ), 5) );
   131 
   132   ag->add( Gtk::Action::create("AddMap", Gtk::StockID("gd-newmap")),
   133       sigc::mem_fun ( *this , &MainWin::createNewMapWin ) );
   134 
   135   uim=Gtk::UIManager::create();
   136   uim->insert_action_group(ag);
   137   add_accel_group(uim->get_accel_group());
   138 
   139   try
   140   {
   141 
   142     Glib::ustring ui_info =
   143       "<ui>"
   144       "  <menubar name='MenuBar'>"
   145       "    <menu action='FileMenu'>"
   146       "      <menuitem action='FileNew'/>"
   147       "      <menuitem action='FileOpen'/>"
   148       "      <menuitem action='FileClearTab'/>"
   149       "      <menuitem action='FileSave'/>"
   150       "      <menuitem action='FileSaveAs'/>"
   151       "      <menuitem action='Close'/>"
   152       "      <menuitem action='Quit'/>"
   153       "    </menu>"
   154       "    <menu action='ViewMenu'>"
   155       "      <menuitem action='ViewZoomIn' />"
   156       "      <menuitem action='ViewZoomOut' />"
   157       "      <menuitem action='ViewZoom100' />"
   158       "      <menuitem action='ViewZoomFit' />"
   159       "    </menu>"
   160       "    <menu action='ShowMenu'>"
   161       "      <menuitem action='ShowMaps'/>"
   162       "    </menu>"
   163       "    <menu action='AlgoMenu'>"
   164       "      <menuitem action='AlgoGeneral'/>"
   165       "      <menuitem action='AlgoKruskal'/>"
   166       "    </menu>"
   167       "  </menubar>"
   168       "  <toolbar name='ToolBar'>"
   169       "    <toolitem action='FileNew' />"
   170       "    <toolitem action='FileOpen' />"
   171       "    <toolitem action='FileSave' />"
   172       "    <toolitem action='Close' />"
   173       "    <separator />"
   174       "    <toolitem action='ViewZoomIn' />"
   175       "    <toolitem action='ViewZoomOut' />"
   176       "    <toolitem action='ViewZoom100' />"
   177       "    <toolitem action='ViewZoomFit' />"
   178       "    <separator />"
   179       "    <toolitem action='MoveItem' />"
   180       "    <toolitem action='CreateNode' />"
   181       "    <toolitem action='CreateEdge' />"
   182       "    <toolitem action='EraseItem' />"
   183       "    <toolitem action='EditEdgeMap' />"
   184       "    <toolitem action='EditNodeMap' />"
   185       "    <separator />"
   186       "    <toolitem action='AddMap' />"
   187       "  </toolbar>"
   188       "</ui>";
   189 
   190     uim->add_ui_from_string(ui_info);
   191 
   192   }
   193   catch(const Glib::Error& ex)
   194   {
   195     std::cerr << "building menus failed: " <<  ex.what();
   196   }
   197 
   198   Gtk::Widget* menubar = uim->get_widget("/MenuBar");
   199   if (menubar){
   200     vbox.pack_start(*menubar, Gtk::PACK_SHRINK);
   201   }
   202 
   203   Gtk::Widget* toolbar = uim->get_widget("/ToolBar");
   204   if (toolbar)
   205   {
   206     static_cast<Gtk::Toolbar*>(toolbar)->set_toolbar_style(Gtk::TOOLBAR_ICONS);
   207     vbox.pack_start(*toolbar, Gtk::PACK_SHRINK);
   208   }
   209 
   210   tooltips.set_tip(*(uim->get_widget("/ToolBar/CreateNode")),"Create Node");
   211   tooltips.enable();
   212 
   213   active_tab=-1;
   214   notebook.signal_switch_page().connect(sigc::mem_fun(*this, &MainWin::onChangeTab));
   215 
   216   active_tool = MOVE;
   217 
   218   vbox.pack_start(notebook);
   219   
   220   show_all_children();
   221 }
   222 
   223 void MainWin::set_tabtitle(std::string name)
   224 {
   225   if(strinst.find(name)==strinst.end())
   226     {
   227       tabnames[active_tab]=name;
   228       strinst[name]=1;
   229     }
   230   else
   231     {
   232       strinst[name]++;
   233       std::ostringstream o;
   234       o << strinst[name];
   235       tabnames[active_tab]=name+" - "+o.str();
   236     }
   237   set_title(tabnames[active_tab] + " - " + prog_name);
   238   notebook.set_tab_label_text((Widget&)*(tabs[active_tab]), tabnames[active_tab]);
   239   updateAlgoWinTabs();
   240 }
   241 
   242 void MainWin::readFile(const std::string & filename)
   243 {
   244   newTab();
   245   tabs[active_tab]->readFile(filename);
   246 }
   247 
   248 void MainWin::newTab()
   249 {
   250   int size=tabs.size();
   251   tabs.resize(size+1);
   252   tabnames.resize(size+1);
   253   active_tab=size;
   254   tabs[active_tab]=new NoteBookTab();
   255   tabs[active_tab]->signal_title_ch().connect(sigc::mem_fun(*this, &MainWin::set_tabtitle));
   256   tabs[active_tab]->signal_newmap_needed().connect(sigc::mem_fun(*this, &MainWin::createNewMapWinAfterSignal));
   257   tabs[active_tab]->gd_canvas->changeEditorialTool(active_tool);
   258   notebook.append_page((Gtk::Widget&)(*(tabs[active_tab])));
   259   notebook.set_current_page(size);
   260   set_tabtitle(_("unsaved file"));
   261   updateAlgoWinTabs();
   262 }
   263 
   264 void MainWin::closeTab()
   265 {
   266   if(active_tab!=-1)
   267     {
   268       if (tabs[active_tab]->mapstorage.modified)
   269 	{
   270 	  Gtk::MessageDialog mdialog(_("<b>Save changes before closing?</b>"), true, 
   271 				     Gtk::MESSAGE_WARNING, Gtk::BUTTONS_NONE);
   272 	  mdialog.add_button(_("Close file _without Saving"), Gtk::RESPONSE_REJECT);
   273 	  mdialog.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
   274 	  mdialog.add_button(Gtk::Stock::SAVE, Gtk::RESPONSE_ACCEPT);
   275 	  switch (mdialog.run())
   276 	    {
   277 	    case Gtk::RESPONSE_CANCEL:
   278 	      return;
   279 	    case Gtk::RESPONSE_REJECT:
   280 	      break;
   281 	    case Gtk::RESPONSE_ACCEPT:
   282 	      tabs[active_tab]->saveFile();
   283 	      break;
   284 	    }
   285 	}
   286       //tabs vector will be decreased with the deleted value
   287       int size=tabs.size();
   288       if(size>1)
   289 	{
   290 	  for(int i=active_tab+1;i<size;i++)
   291 	    {
   292 	      tabnames[i-1]=tabnames[i];
   293 	      tabs[i-1]=tabs[i];
   294 	    }
   295 	}
   296       //if size==1 resize will delete the only element
   297       tabs.resize(size-1);
   298       tabnames.resize(size-1);
   299 
   300       int old_active_tab=active_tab;
   301       notebook.remove_page(active_tab);
   302 
   303       //If the first tab was active, upon delete notebook
   304       //will first switch one tab upper and not lower like
   305       //in the case, when not the first tab was active.
   306       //But after deletion it will become the first tab,
   307       //and this should be registrated in tabs vector,
   308       //as well.
   309       if((old_active_tab==0)&&(size!=1))
   310 	{
   311 	  onChangeTab(NULL,0);
   312 	}
   313 
   314       //if this was the last page in notebook, there is
   315       //no active_tab now
   316       if(size==1)
   317 	{
   318 	  active_tab=-1;
   319 	}
   320 
   321       updateAlgoWinTabs();
   322     }
   323 }
   324 
   325 void MainWin::onChangeTab(GtkNotebookPage* page, guint page_num)
   326 {
   327   page=page;
   328   active_tab=page_num;
   329   tabs[active_tab]->gd_canvas->changeEditorialTool(active_tool);
   330   set_title(tabnames[active_tab]);
   331 }
   332 
   333 void MainWin::newFile()
   334 {
   335   if(active_tab!=-1)
   336     {
   337       tabs[active_tab]->newFile();
   338     }
   339 }
   340  
   341 void MainWin::openFile()
   342 {
   343   if(active_tab!=-1)
   344     {
   345       tabs[active_tab]->openFile();
   346     }
   347 }
   348  
   349 void MainWin::saveFile()
   350 {
   351   if(active_tab!=-1)
   352     {
   353       tabs[active_tab]->saveFile();
   354     }
   355 }
   356  
   357 void MainWin::saveFileAs()
   358 {
   359   if(active_tab!=-1)
   360     {
   361       tabs[active_tab]->saveFileAs();
   362     }
   363 }
   364  
   365 void MainWin::close()
   366 {
   367   if(active_tab!=-1)
   368     {
   369       tabs[active_tab]->close();
   370     }
   371 }
   372 
   373 void MainWin::zoomIn()
   374 {
   375   if(active_tab!=-1)
   376     {
   377       tabs[active_tab]->gd_canvas->zoomIn();
   378     }
   379 }
   380 
   381 void MainWin::zoomOut()
   382 {
   383   if(active_tab!=-1)
   384     {
   385       tabs[active_tab]->gd_canvas->zoomOut();
   386     }
   387 }
   388 
   389 void MainWin::zoomFit()
   390 {
   391   if(active_tab!=-1)
   392     {
   393       tabs[active_tab]->gd_canvas->zoomFit();
   394     }
   395 }
   396 
   397 void MainWin::zoom100()
   398 {
   399   if(active_tab!=-1)
   400     {
   401       tabs[active_tab]->gd_canvas->zoom100();
   402     }
   403 }
   404 
   405 void MainWin::createMapWin()
   406 {
   407   if(active_tab!=-1)
   408     {
   409       tabs[active_tab]->createMapWin(tabnames[active_tab]);
   410     }
   411 }
   412 
   413 void MainWin::createAlgoWin(int algoid)
   414 {
   415   AlgoWin * aw=new AlgoWin(algoid, tabnames);
   416   aw->signal_closing().connect(sigc::mem_fun(*this, &MainWin::deRegisterAlgoWin));
   417   aw->signal_maplist_needed().connect(sigc::mem_fun(*this, &MainWin::updateAlgoWinMaps));
   418   aw->signal_newmapwin_needed().connect(sigc::mem_fun(*this, &MainWin::createNewMapWinTabString));
   419   aws.insert(aw);
   420   aw->show();
   421 }
   422 
   423 void MainWin::updateAlgoWinTabs()
   424 {
   425   std::set< AlgoWin* >::iterator awsi=aws.begin();
   426   for(;awsi!=aws.end();awsi++)
   427     {
   428       (*awsi)->update_tablist(tabnames);
   429     }
   430 }
   431 
   432 void MainWin::updateAlgoWinMaps(AlgoWin * awp, std::string tabname)
   433 {
   434   int i=0;
   435   for(;(i<(int)tabnames.size())&&(tabnames[i]!=tabname);i++)
   436     {
   437     }
   438   awp->update_maplist(&(tabs[i]->mapstorage));
   439 }
   440 
   441 void MainWin::deRegisterAlgoWin(AlgoWin * awp)
   442 {
   443   aws.erase(awp);
   444 }
   445 
   446 void MainWin::changeEditorialTool(int tool)
   447 {
   448   active_tool=tool;
   449   if(active_tab!=-1)
   450     {
   451       tabs[active_tab]->gd_canvas->changeEditorialTool(tool);
   452     }
   453 }
   454 
   455 void MainWin::createNewMapWin()
   456 {
   457   if(active_tab!=-1)
   458     {
   459       NewMapWin * nmw=new NewMapWin(_("Create New Map - ")+tabnames[active_tab], *(tabs[active_tab]));
   460       nmw->show();
   461     }
   462 }
   463 
   464 void MainWin::createNewMapWinTabString(std::string tabname, bool itisedge)
   465 {
   466   int i=0;
   467   for(;((i<(int)tabnames.size())&&(tabnames[i]!=tabname));i++)
   468     {
   469     }
   470   createNewMapWinAfterSignal(tabs[i], itisedge);
   471 }
   472 
   473 void MainWin::createNewMapWinAfterSignal(NoteBookTab * nbt, bool itisedge)
   474 {
   475   std::vector<NoteBookTab*>::iterator nbti=tabs.begin();
   476   int i=0;
   477   for(;nbti!=tabs.end();nbti++)
   478     {
   479       if(*nbti!=nbt)
   480 	{
   481 	  i++;
   482 	}
   483       else
   484 	{
   485 	  continue;
   486 	}
   487     }
   488   NewMapWin * nmw=new NewMapWin(_("Create New Map - ")+tabnames[i], *nbt, itisedge, false);
   489   nmw->run();
   490 }