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