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