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