# HG changeset patch # User Peter Hegyi # Date 1215436239 18000 # Node ID 67188bd752db38d03af509c3acd29f95fcd6a4d3 # Parent 0e4f009eab8bff1dfe90c52eb057dd2e8578480f SVN revision 3500 made compilable with Lemon 1.0. diff -r 0e4f009eab8b -r 67188bd752db .hgignore --- a/.hgignore Mon Jun 23 11:48:43 2008 +0100 +++ b/.hgignore Mon Jul 07 08:10:39 2008 -0500 @@ -26,6 +26,24 @@ .libs/* .deps/* demo/*.eps +m4/*.m4 +ABOUT-NLS +autopackage/default.apspec +glemon +glemon.spec +guipixbufs.h +po/boldquot.sed +po/en@boldquot.header +po/en@quot.header +po/hu.gmo +po/insert-header.sin +po/Makefile.in.in +po/Makevars.template +po/POTFILES +po/quot.sed +po/remove-potcdate.sin +po/Rules-quot +po/stamp-po syntax: regexp (.*/)?\#[^/]*\#$ diff -r 0e4f009eab8b -r 67188bd752db AUTHORS --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/AUTHORS Mon Jul 07 08:10:39 2008 -0500 @@ -0,0 +1,1 @@ +To be filled diff -r 0e4f009eab8b -r 67188bd752db COPYING --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/COPYING Mon Jul 07 08:10:39 2008 -0500 @@ -0,0 +1,1 @@ +To be filled diff -r 0e4f009eab8b -r 67188bd752db Doxyfile --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Doxyfile Mon Jul 07 08:10:39 2008 -0500 @@ -0,0 +1,273 @@ +# Doxyfile 1.4.5 + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- +PROJECT_NAME = glemon +PROJECT_NUMBER = 0.1 +OUTPUT_DIRECTORY = +CREATE_SUBDIRS = NO +OUTPUT_LANGUAGE = English +USE_WINDOWS_ENCODING = NO +BRIEF_MEMBER_DESC = YES +REPEAT_BRIEF = YES +ABBREVIATE_BRIEF = "The $name class" \ + "The $name widget" \ + "The $name file" \ + is \ + provides \ + specifies \ + contains \ + represents \ + a \ + an \ + the +ALWAYS_DETAILED_SEC = NO +INLINE_INHERITED_MEMB = NO +FULL_PATH_NAMES = YES +STRIP_FROM_PATH = . +STRIP_FROM_INC_PATH = +SHORT_NAMES = NO +JAVADOC_AUTOBRIEF = NO +MULTILINE_CPP_IS_BRIEF = NO +DETAILS_AT_TOP = NO +INHERIT_DOCS = YES +SEPARATE_MEMBER_PAGES = NO +TAB_SIZE = 8 +ALIASES = +OPTIMIZE_OUTPUT_FOR_C = NO +OPTIMIZE_OUTPUT_JAVA = NO +BUILTIN_STL_SUPPORT = NO +DISTRIBUTE_GROUP_DOC = NO +SUBGROUPING = YES +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- +EXTRACT_ALL = YES +EXTRACT_PRIVATE = YES +EXTRACT_STATIC = YES +EXTRACT_LOCAL_CLASSES = YES +EXTRACT_LOCAL_METHODS = NO +HIDE_UNDOC_MEMBERS = NO +HIDE_UNDOC_CLASSES = NO +HIDE_FRIEND_COMPOUNDS = NO +HIDE_IN_BODY_DOCS = NO +INTERNAL_DOCS = NO +CASE_SENSE_NAMES = YES +HIDE_SCOPE_NAMES = NO +SHOW_INCLUDE_FILES = YES +INLINE_INFO = YES +SORT_MEMBER_DOCS = YES +SORT_BRIEF_DOCS = NO +SORT_BY_SCOPE_NAME = NO +GENERATE_TODOLIST = YES +GENERATE_TESTLIST = YES +GENERATE_BUGLIST = YES +GENERATE_DEPRECATEDLIST= YES +ENABLED_SECTIONS = +MAX_INITIALIZER_LINES = 30 +SHOW_USED_FILES = YES +SHOW_DIRECTORIES = YES +FILE_VERSION_FILTER = +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- +QUIET = NO +WARNINGS = YES +WARN_IF_UNDOCUMENTED = YES +WARN_IF_DOC_ERROR = YES +WARN_NO_PARAMDOC = NO +WARN_FORMAT = "$file:$line: $text" +WARN_LOGFILE = +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- +INPUT = . +FILE_PATTERNS = *.c \ + *.cc \ + *.cxx \ + *.cpp \ + *.c++ \ + *.d \ + *.java \ + *.ii \ + *.ixx \ + *.ipp \ + *.i++ \ + *.inl \ + *.h \ + *.hh \ + *.hxx \ + *.hpp \ + *.h++ \ + *.idl \ + *.odl \ + *.cs \ + *.php \ + *.php3 \ + *.inc \ + *.m \ + *.mm \ + *.dox \ + *.py \ + *.C \ + *.CC \ + *.C++ \ + *.II \ + *.I++ \ + *.H \ + *.HH \ + *.H++ \ + *.CS \ + *.PHP \ + *.PHP3 \ + *.M \ + *.MM \ + *.PY +RECURSIVE = NO +EXCLUDE = +EXCLUDE_SYMLINKS = NO +EXCLUDE_PATTERNS = +EXAMPLE_PATH = +EXAMPLE_PATTERNS = * +EXAMPLE_RECURSIVE = NO +IMAGE_PATH = +INPUT_FILTER = +FILTER_PATTERNS = +FILTER_SOURCE_FILES = NO +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- +SOURCE_BROWSER = YES +INLINE_SOURCES = NO +STRIP_CODE_COMMENTS = YES +REFERENCED_BY_RELATION = YES +REFERENCES_RELATION = YES +USE_HTAGS = NO +VERBATIM_HEADERS = YES +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- +ALPHABETICAL_INDEX = NO +COLS_IN_ALPHA_INDEX = 5 +IGNORE_PREFIX = +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- +GENERATE_HTML = YES +HTML_OUTPUT = html +HTML_FILE_EXTENSION = .html +HTML_HEADER = +HTML_FOOTER = +HTML_STYLESHEET = +HTML_ALIGN_MEMBERS = YES +GENERATE_HTMLHELP = NO +CHM_FILE = +HHC_LOCATION = +GENERATE_CHI = NO +BINARY_TOC = NO +TOC_EXPAND = NO +DISABLE_INDEX = NO +ENUM_VALUES_PER_LINE = 4 +GENERATE_TREEVIEW = NO +TREEVIEW_WIDTH = 250 +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- +GENERATE_LATEX = NO +LATEX_OUTPUT = latex +LATEX_CMD_NAME = latex +MAKEINDEX_CMD_NAME = makeindex +COMPACT_LATEX = NO +PAPER_TYPE = a4wide +EXTRA_PACKAGES = +LATEX_HEADER = +PDF_HYPERLINKS = NO +USE_PDFLATEX = NO +LATEX_BATCHMODE = NO +LATEX_HIDE_INDICES = NO +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- +GENERATE_RTF = NO +RTF_OUTPUT = rtf +COMPACT_RTF = NO +RTF_HYPERLINKS = NO +RTF_STYLESHEET_FILE = +RTF_EXTENSIONS_FILE = +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- +GENERATE_MAN = NO +MAN_OUTPUT = man +MAN_EXTENSION = .3 +MAN_LINKS = NO +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- +GENERATE_XML = NO +XML_OUTPUT = xml +XML_SCHEMA = +XML_DTD = +XML_PROGRAMLISTING = YES +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- +GENERATE_AUTOGEN_DEF = NO +#--------------------------------------------------------------------------- +# configuration options related to the Perl module output +#--------------------------------------------------------------------------- +GENERATE_PERLMOD = NO +PERLMOD_LATEX = NO +PERLMOD_PRETTY = YES +PERLMOD_MAKEVAR_PREFIX = +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- +ENABLE_PREPROCESSING = YES +MACRO_EXPANSION = NO +EXPAND_ONLY_PREDEF = NO +SEARCH_INCLUDES = YES +INCLUDE_PATH = +INCLUDE_FILE_PATTERNS = +PREDEFINED = +EXPAND_AS_DEFINED = +SKIP_FUNCTION_MACROS = YES +#--------------------------------------------------------------------------- +# Configuration::additions related to external references +#--------------------------------------------------------------------------- +TAGFILES = +GENERATE_TAGFILE = +ALLEXTERNALS = NO +EXTERNAL_GROUPS = YES +PERL_PATH = /usr/bin/perl +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- +CLASS_DIAGRAMS = NO +HIDE_UNDOC_RELATIONS = YES +HAVE_DOT = YES +CLASS_GRAPH = YES +COLLABORATION_GRAPH = YES +GROUP_GRAPHS = YES +UML_LOOK = NO +TEMPLATE_RELATIONS = NO +INCLUDE_GRAPH = YES +INCLUDED_BY_GRAPH = YES +CALL_GRAPH = YES +GRAPHICAL_HIERARCHY = YES +DIRECTORY_GRAPH = YES +DOT_IMAGE_FORMAT = png +DOT_PATH = +DOTFILE_DIRS = +MAX_DOT_GRAPH_WIDTH = 1024 +MAX_DOT_GRAPH_HEIGHT = 1024 +MAX_DOT_GRAPH_DEPTH = 1000 +DOT_TRANSPARENT = NO +DOT_MULTI_TARGETS = NO +GENERATE_LEGEND = YES +DOT_CLEANUP = YES +#--------------------------------------------------------------------------- +# Configuration::additions related to the search engine +#--------------------------------------------------------------------------- +SEARCHENGINE = NO diff -r 0e4f009eab8b -r 67188bd752db LICENSE --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/LICENSE Mon Jul 07 08:10:39 2008 -0500 @@ -0,0 +1,33 @@ +gLEMON code without an explicit copyright is covered by the following +copyright/license: + +Copyright (C) 2003-2006 Egervary Jeno Kombinatorikus Optimalizalasi +Kutatocsoport (Egervary Combinatorial Optimization Research Group, +EGRES). + +Permission is hereby granted, free of charge, to any person or organization +obtaining a copy of the software and accompanying documentation covered by +this license (the "Software") to use, reproduce, display, distribute, +execute, and transmit the Software, and to prepare derivative works of the +Software, and to permit third-parties to whom the Software is furnished to +do so, all subject to the following: + +The copyright notices in the Software and this entire statement, including +the above license grant, this restriction and the following disclaimer, +must be included in all copies of the Software, in whole or in part, and +all derivative works of the Software, unless such copies or derivative +works are solely in the form of machine-executable object code generated by +a source language processor. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. + +=========================================================================== +This license is a verbatim copy of the Boost Software License, Version 1.0. + + diff -r 0e4f009eab8b -r 67188bd752db Makefile.am --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Makefile.am Mon Jul 07 08:10:39 2008 -0500 @@ -0,0 +1,167 @@ +AM_CPPFLAGS = -I$(top_srcdir) -DLOCALEDIR=\""$(datadir)/locale"\" + +SUBDIRS = po m4 + +bin_PROGRAMS = glemon +BUILT_SOURCES = guipixbufs.h +CLEANFILES = guipixbufs.h + +glemon_SOURCES = \ + all_include.h \ + algobox.cc \ + algobox.h \ + algowin.cc \ + algowin.h \ + gdc-broken_edge.cc \ + graph_displayer_canvas.cc \ + graph_displayer_canvas.h \ + graph_displayer_canvas-edge.cc \ + graph_displayer_canvas-event.cc \ + graph_displayer_canvas-node.cc \ + graph_displayer_canvas-zoom.cc \ + graph-displayer.cc \ + kruskalbox.cc \ + kruskalbox.h \ + main_win.cc \ + main_win.h \ + mapstorage.cc \ + mapstorage.h \ + map_win.cc \ + map_win.h \ + mapselector.cc \ + mapselector.h \ + nbtab.h \ + nbtab.cc \ + new_map_win.cc \ + new_map_win.h \ + xymap.h \ + gui_reader.h \ + gui_reader.cc \ + gui_writer.h \ + gui_writer.cc \ + xml.h \ + guipixbufs.h \ + i18n.h \ + gettext.h \ + design_win.h \ + design_win.cc \ + dijkstrabox.h \ + dijkstrabox.cc \ + file_import_dialog.h \ + file_import_dialog.cc \ + map_value.h \ + map_value.cc \ + map_value_map.h \ + map_value_map.cc \ + save_details_widget.h \ + save_details_widget.cc \ + save_details_dialog.h \ + save_details_dialog.cc \ + io_helper.h \ + io_helper.cc \ + background_chooser_dialog.h \ + background_chooser_dialog.cc \ + eps_win.h \ + eps_win.cc + +glemon_CXXFLAGS = $(GTK_CFLAGS) $(LEMON_CFLAGS) +# glemon_LDFLAGS = $(GTK_LIBS) $(LEMON_LIBS) +glemon_LDADD = $(GTK_LIBS) $(LEMON_LIBS) $(LIBINTL) + +IMAGES = \ + icons/addlink.png \ + icons/addnode.png \ + icons/delete.png \ + icons/editlink.png \ + icons/editnode.png \ + icons/move.png \ + icons/newmap.png \ + icons/eps.png + +VARIABLES = \ + gui_icons_addlink $(srcdir)/icons/addlink.png \ + gui_icons_addnode $(srcdir)/icons/addnode.png \ + gui_icons_delete $(srcdir)/icons/delete.png \ + gui_icons_editlink $(srcdir)/icons/editlink.png \ + gui_icons_editnode $(srcdir)/icons/editnode.png \ + gui_icons_move $(srcdir)/icons/move.png \ + gui_icons_newmap $(srcdir)/icons/newmap.png \ + gui_icons_eps $(srcdir)/icons/eps.png + +guipixbufs.h: $(IMAGES) + gdk-pixbuf-csource \ + --raw --build-list $(VARIABLES) > guipixbufs.h || \ + ( rm -f guipixbufs.h && false ) + +EXTRA_DIST = \ + $(IMAGES) \ + guipixbufs.h \ + glemon.spec \ + AUTHORS \ + COPYING \ + LICENSE \ + NEWS \ + README \ + ABOUT-NLS + +MRPROPERFILES = \ + Makefile.in \ + configure \ + config.h.in \ + aclocal.m4 \ + ABOUT-NLS \ + m4/Makefile.in \ + m4/lib-link.m4 \ + m4/printf-posix.m4 \ + m4/uintmax_t.m4 \ + m4/signed.m4 \ + m4/iconv.m4 \ + m4/inttypes.m4 \ + m4/longlong.m4 \ + m4/glibc21.m4 \ + m4/inttypes_h.m4 \ + m4/codeset.m4 \ + m4/longdouble.m4 \ + m4/nls.m4 \ + m4/intmax.m4 \ + m4/lib-prefix.m4 \ + m4/glibc2.m4 \ + m4/xsize.m4 \ + m4/lcmessage.m4 \ + m4/lib-ld.m4 \ + m4/ulonglong.m4 \ + m4/wint_t.m4 \ + m4/progtest.m4 \ + m4/inttypes-pri.m4 \ + m4/stdint_h.m4 \ + m4/intdiv0.m4 \ + m4/isc-posix.m4 \ + m4/po.m4 \ + m4/size_max.m4 \ + m4/gettext.m4 \ + m4/wchar_t.m4 \ + po/Rules-quot \ + po/en@quot.header \ + po/insert-header.sin \ + po/quot.sed \ + po/en@boldquot.header \ + po/boldquot.sed \ + po/Makevars.template \ + po/remove-potcdate.sin \ + po/Makefile.in.in \ + build-aux/mkinstalldirs \ + build-aux/config.rpath \ + build-aux/depcomp \ + build-aux/missing \ + build-aux/config.guess \ + build-aux/config.sub \ + build-aux/install-sh + +mrproper: + $(MAKE) $(AM_MAKEFLAGS) maintainer-clean + -rm -f $(MRPROPERFILES) + +rpm: dist + rpmbuild -ta $(PACKAGE)-$(VERSION).tar.gz + +.PHONY: mrproper diff -r 0e4f009eab8b -r 67188bd752db NEWS --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/NEWS Mon Jul 07 08:10:39 2008 -0500 @@ -0,0 +1,1 @@ +To be filled diff -r 0e4f009eab8b -r 67188bd752db README --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/README Mon Jul 07 08:10:39 2008 -0500 @@ -0,0 +1,1 @@ +To be filled diff -r 0e4f009eab8b -r 67188bd752db algobox.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/algobox.cc Mon Jul 07 08:10:39 2008 -0500 @@ -0,0 +1,211 @@ +/* -*- C++ -*- + * + * This file is a part of LEMON, a generic C++ optimization library + * + * Copyright (C) 2003-2006 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#include +#include +#include + +enum {N_DEMO1, N_DEMO2, NODE_INPUT_NUM}; // input IDs for nodes; +enum {E_DEMO1, EDGE_INPUT_NUM}; // input IDs for arcs; + +AlgoBox::AlgoBox(std::vector tabnames) +{ + init(tabnames); +} + +void AlgoBox::init(std::vector tabnames) +{ + set_spacing(5); + + update_tablist(tabnames); + + //if active tab is changed, the map names in cbt/s have to be updated + tabcbt.signal_changed().connect(sigc::mem_fun(*this, &AlgoBox::emit_tab_change)); + + pack_start(tabcbt); + build_box(); + + show_all_children(); +}; + +void AlgoBox::update_cbt(std::vector< std::string > stringlist, Gtk::ComboBoxText & cbt) +{ + std::string actname=cbt.get_active_text(); + int prev_act=-1; + + cbt.clear(); + int actptr=0; + + std::vector< std::string >::iterator emsi=stringlist.begin(); + for(;emsi!=stringlist.end();emsi++) + { + if(actname==*emsi) + { + prev_act=actptr; + } + + cbt.append_text(*emsi); + actptr++; + } + + if(prev_act!=-1) + { + cbt.set_active(prev_act); + } + else if(actptr>0) //so there is item in the list + { + //cbt.set_active(0); + } +} + +void AlgoBox::update_tablist( std::vector< std::string > tl ) +{ + update_cbt(tl, tabcbt); + emit_tab_change(); +} + +void AlgoBox::update_maplist(MapStorage * ms) +{ + mapstorage=ms; + std::vector n_nml; + std::vector s_nml; + std::vector n_eml; + std::vector s_eml; + if(mapstorage!=NULL) + { + mapstorage->signal_node_map_ch().connect(sigc::mem_fun(*this, &AlgoBox::nodemaplist_changed)); + mapstorage->signal_arc_map_ch().connect(sigc::mem_fun(*this, &AlgoBox::arcmaplist_changed)); + n_nml=mapstorage->getNodeMapList(NUM); + s_nml=mapstorage->getNodeMapList(STR); + n_eml=mapstorage->getArcMapList(NUM); + s_eml=mapstorage->getArcMapList(STR); + } + for(int i=0;i<(int)nodemapcbts.size();i++) + { + (nodemapcbts[i])->update_list(n_nml, s_nml); + //update_cbt(nml, *(nodemapcbts[i])); + } + for(int i=0;i<(int)arcmapcbts.size();i++) + { + (arcmapcbts[i])->update_list(n_eml, s_eml); + //update_cbt(eml, *(arcmapcbts[i])); + } + signal_maplist_updated.emit(); +} + +void AlgoBox::nodemaplist_changed(std::string newmap, MapValue::Type type) +{ + for(int i=0;i<(int)nodemapcbts.size();i++) + { + (nodemapcbts[i])->append_text(newmap, type); + } +} + +void AlgoBox::arcmaplist_changed(std::string newmap, MapValue::Type type) +{ + for(int i=0;i<(int)arcmapcbts.size();i++) + { + (arcmapcbts[i])->append_text(newmap, type); + } +} + +void AlgoBox::run() +{ + std::cout << "Start algorithm." << std::endl; +} + +void AlgoBox::build_box() +{ + pack_start(*(new Gtk::HSeparator())); + + Gtk::Label * label=new Gtk::Label("Specific part for each algorithm."); + + pack_start(*label); + pack_start(*(new Gtk::HSeparator())); + + label=new Gtk::Label("Maps in chosen tab:"); + + pack_start(*label); + + for(int i=0;i empty_vector; + + MapSelector * msp=new MapSelector(empty_vector,empty_vector,"",inputname,itisarc, false, type); + + if(itisarc) + { + arcmapcbts.resize(arcmapcbts.size()+1); + arcmapcbts[arcmapcbts.size()-1]=msp; + } + else + { + nodemapcbts.resize(nodemapcbts.size()+1); + nodemapcbts[nodemapcbts.size()-1]=msp; + } + + msp->signal_newmapwin_needed().connect(sigc::mem_fun(*this, &AlgoBox::emit_new_map_signal)); + + pack_start(*msp); +} + +sigc::signal AlgoBox::signal_maplist_needed() +{ + return signal_maplist_need; +} + +void AlgoBox::emit_tab_change() +{ + std::string active_tab=tabcbt.get_active_text(); + if(active_tab!="") + { + signal_maplist_need.emit(active_tab); + } + else + { + std::vector empty_vector; + update_maplist(NULL); + } +} + +void AlgoBox::emit_new_map_signal(bool itisarc) +{ + signal_newmapwin_need.emit(tabcbt.get_active_text(), itisarc); +} diff -r 0e4f009eab8b -r 67188bd752db algobox.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/algobox.h Mon Jul 07 08:10:39 2008 -0500 @@ -0,0 +1,189 @@ +/* -*- C++ -*- + * + * This file is a part of LEMON, a generic C++ optimization library + * + * Copyright (C) 2003-2006 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#ifndef ALGOBOX_H +#define ALGOBOX_H + +class MapStorage; +class MapSelector; + +#include +#include +#include +#include "map_value.h" + +///Ancestor class of algorithm digraphical interface classes. + +///It also demonstrates, how should an algorithm digraphical interface +///work. Children of this class have the same functions and attributes, +///therefore with all of them can the holder \ref AlgoWin communicate +///in the same way. +/// +///IMPORTANT! In a child class only the following tasks are to do: +/// +///-call \ref init function with correct parameters from correctly parametrized constructor +/// +///-implement \ref build_box function +/// +///-implement \ref run function +/// +///because all other thing is automatically done in \ref init function! + +class AlgoBox : public Gtk::VBox +{ + ///Signal emitted in case of need for list of maps. + + ///If the user has selected different tab to work on + ///new maps are selected as well. These new maps should be + ///provided for \ref AlgoBox. To get these maps, \ref AlgoBox + ///emits this signal. + sigc::signal signal_maplist_need; + + ///Signal emitted in case of need for \ref NewMapWin. + + ///If user wants to create a new for an input, or output + ///it can let \ref NewMapWin popped up from here as well. + ///In that case will be this signal emitted. + sigc::signal signal_newmapwin_need; + + ///Signal emitted when maplists are updated after tab change + sigc::signal signal_maplist_updated; + + +protected: + ///Holder of tabnames. + Gtk::ComboBoxText tabcbt; + + ///Holder of widgets, in which nodemaps can be selected to work on. + std::vector nodemapcbts; + + ///Holder of widgets, in which arcmaps can be selected to work on. + std::vector arcmapcbts; + + ///Maps of selected tabs. + MapStorage * mapstorage; + +public: + ///Empty constructor called by children. + AlgoBox(){}; + + ///Constructor + + ///Calls \ref init function + ///with the provided parameters. \ref init function + ///is needed, because it is virtual, therefore the + ///functions of the proper class will be called when + ///running. + ///\param tablist list of tabs in \ref MainWin + AlgoBox(std::vector tablist); + + ///Initiates \ref AlgoBox. + + ///Creates the digraphical interface for the realized algorithm, initiates variables, connects signals. + /// + ///List of tabs in \ref MainWin is required, but no one + ///will be selected automatically. Every other + ///entry field remains empty (unselected), until a \ref NoteBookTab + ///is selected. + /// + ///It also have to bind all the signals to the correct place. + ///This function is virtual, in all type of children of + ///\ref AlgoBox the correct function willbe called. + /// + ///Therefore it is IMPORTANT that only \ref run and \ref build_box + ///has to be implemented in children of \ref AlgoBox, every other + ///thing will automatically work properly by the help of this + ///function that must be called in constructor of child!!! + virtual void init(std::vector); + + ///Signal emitted, when selected tab changes, and new list of maps required. + sigc::signal signal_maplist_needed(); + + ///Emitted if user wants to create a new map for inpuit or output. + sigc::signal signal_newmapwin_needed(){return signal_newmapwin_need;}; + + sigc::signal signal_upon_maplist_updated(){return signal_maplist_updated;}; + + ///Emits signal that requires list of maps for the recently selected \ref NoteBookTab. + void emit_tab_change(); + + ///Interface, through which \ref AlgoBox can be notified about tab addition, deletion in \ref MainWin + + ///\param tl list + ///of new tab state. + void update_tablist( std::vector< std::string > tl ); + + ///Interface, through which \ref AlgoBox can get the maps of the recently selected \ref NoteBookTab + + ///\param ms the maps + ///of the recently selected \ref NoteBookTab + void update_maplist( MapStorage * ms); + + ///Interface, through which \ref AlgoBox can be notified about nodemap addition. + + ///If new map was added to \ref MapStorage of currently selected \ref NoteBookTab + ///a signal is emitted by it. This signal is connected to this function, so \ref MapSelector s + ///in \ref nodemapcbts can be notified, and those can registrate the new map. (\ref MapSelector::append_text) + void nodemaplist_changed(std::string, MapValue::Type); + + ///Interface, through which \ref AlgoBox can be notified about arcmap addition. + + ///If new map was added to \ref MapStorage of currently selected \ref NoteBookTab + ///a signal is emitted by it. This signal is connected to this function, so \ref MapSelector s + ///in \ref arcmapcbts can be notified, and those can registrate the new map. (\ref MapSelector::append_text) + void arcmaplist_changed(std::string, MapValue::Type); + + ///Aid function to provide data for a given entry. + + ///At the moment it is only used for updating info + ///in \ref tabcbt. It clears it first, after that + ///inserts the data got from caller, and if there + ///was previously selected item it switches entry + ///to that. + ///\param tl list of entries (at the moment tabs in \ref MainWin) + ///\param cbt the entry to update (at the moment only \ref tabcbt) + void update_cbt( std::vector< std::string > tl, Gtk::ComboBoxText & cbt); + + ///Runs the ralized algorithm. + + ///Prepare the data for it + ///and after that postprocess it if necessary. + ///This is only a demo here, but in children it + ///runs the algorithm really. + virtual void run(); + + ///Creates the layout of the \ref AlgoBox + + ///Place all the entries + ///required. Run and close button is not + ///its responsibility! + virtual void build_box(); + + ///Emits \ref signal_newmapwin_need if user wants to create new input or output map. + + ///Called in case of pressing \ref MapSelector::newbut. + ///\param itisarc arc or nodemap is required. + virtual void emit_new_map_signal(bool itisarc); + + ///Aid function to make addition of \ref MapSelector easy in \ref build_box. + + ///\param label label to show in \ref MapSelector + ///\param itisarc whether arc or nodemaps stored in \ref MapSelector + void addMapSelector(std::string label, bool itisarc, MapType type = ALL); +}; +#endif //ALGOBOX_H diff -r 0e4f009eab8b -r 67188bd752db algowin.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/algowin.cc Mon Jul 07 08:10:39 2008 -0500 @@ -0,0 +1,117 @@ +/* -*- C++ -*- + * + * This file is a part of LEMON, a generic C++ optimization library + * + * Copyright (C) 2003-2006 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#include +#include +#include +#include + +sigc::signal AlgoWin::signal_closing() +{ + return signal_closed; +} + +sigc::signal AlgoWin::signal_maplist_needed() +{ + return signal_maplist_need; +} + +bool AlgoWin::closeIfEscapeIsPressed(GdkEventKey* e) +{ + if(e->keyval==GDK_Escape) + { + on_hide(); + } + return true; +} + +AlgoWin::AlgoWin(int algoid, std::vector tabnames) +{ + signal_key_press_event().connect(sigc::mem_fun(*this, &AlgoWin::closeIfEscapeIsPressed)); + + Gtk::VBox * vbox=new Gtk::VBox(); + vbox->set_spacing(5); + + Gtk::Label * label=new Gtk::Label("Select digraph:"); + + switch(algoid) + { + case 0: + ab=new AlgoBox(tabnames); + set_title("Algo Win Demo"); + break; + case 1: + ab=new KruskalBox(tabnames); + set_title("Kruskal Algorithm"); + break; + case 2: + ab=new DijkstraBox(tabnames); + set_title("Dijkstra Algorithm"); + break; + case 3: + ab=new SuurballeBox(tabnames); + set_title("Suurballe Algorithm"); + break; + default: + break; + } + ab->signal_maplist_needed().connect(sigc::mem_fun(*this, &AlgoWin::emit_tab_change)); + ab->signal_newmapwin_needed().connect(sigc::mem_fun(*this, &AlgoWin::emit_new_map_signal)); + + runbutton=new Gtk::Button("Run"); + runbutton->signal_released().connect(sigc::mem_fun(*ab,&AlgoBox::run)); + runbutton->signal_activate().connect(sigc::mem_fun(*ab,&AlgoBox::run)); + + closebutton=new Gtk::Button("Close"); + closebutton->signal_released().connect(sigc::mem_fun(*this,&AlgoWin::on_hide)); + closebutton->signal_activate().connect(sigc::mem_fun(*this,&AlgoWin::on_hide)); + + Gtk::HBox * hbox=new Gtk::HBox(); + + hbox->pack_start(*runbutton); + hbox->pack_start(*closebutton); + + vbox->pack_start(*label); + vbox->pack_start(*ab); + vbox->pack_start(*hbox); + + add(*vbox); + + show_all_children(); +}; + +void AlgoWin::update_tablist(std::vector tabnames) +{ + ab->update_tablist(tabnames); +} + +void AlgoWin::update_maplist(MapStorage * mapstorage) +{ + ab->update_maplist(mapstorage); +} + +void AlgoWin::on_hide() +{ + signal_closed.emit(this); + Gtk::Window::on_hide(); +} + +void AlgoWin::emit_tab_change(std::string newtab) +{ + signal_maplist_need.emit(this, newtab); +} diff -r 0e4f009eab8b -r 67188bd752db algowin.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/algowin.h Mon Jul 07 08:10:39 2008 -0500 @@ -0,0 +1,147 @@ +/* -*- C++ -*- + * + * This file is a part of LEMON, a generic C++ optimization library + * + * Copyright (C) 2003-2006 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#ifndef ALGOWIN_H +#define ALGOWIN_H + +#include +#include +#include + +class AlgoBox; +class MapStorage; + +///Algorithm identifiers. +enum {GENERAL, KRUSKAL, ALGO_NUM}; // algorithm IDs; + +///Window displaying digraphical interface for different algorithms. + +///This class displays a digraphical interface to set up +///and run different algorithms. Different algorithms need +///different inputs, running methods, etc. Therefore +///class \ref AlgoWin is only a holder of a base class, the so +///called AlgoBox. \ref AlgoBox is the ancestor of other +///classes. These child classes realize interfaces of different +///algorithms, but as their common ancestor is \ref AlgoBox +///the interface of them is the same. \ref AlgoWin communicates +///with these classes through this common interface. But it the +///real object to be placed in \ref AlgoWin depends on the algorithm +///which the \ref AlgoWin actually has to display. It gets the +///id of algorithm to display at initialization, and therefore it is +///able to place in itself the requested child of \ref AlgoBox +/// visualizing the appropriate algorithm. +class AlgoWin : public Gtk::Window +{ +private: + ///Algorithm specific part of \ref AlgoWin + AlgoBox * ab; + + ///Run button. + + ///If pressed, algorithm should run. + ///That is why common ancestor of different + ///algorithm realizer classes have to be. In case of + ///pressing run button a common method can be called. + Gtk::Button * runbutton; + + ///Close button. If pressed, \ref AlgoWin should close. + Gtk::Button * closebutton; + +protected: + ///Signal emitted upon close of window + + ///It is necessary, because \ref MainWin have to + ///score the opened \ref AlgoWin s, to be able to communicate + ///with them: let them know about changement in tabs, maps, etc. + ///If \ref AlgoWin is closed, \ref MainWin has to deregistrate it. + ///Therefore signal contains address of emitter \ref AlgoWin. + sigc::signal signal_closed; + + ///Signal indicating that informatino on certain maplist is required. + + ///It is just a forwarded signal from \ref AlgoBox, benefit of common ancestor + ///algorithm class. User can select the digraph (the holder \ref NoteBookTab) on + ///which the algorithm should run. But different digraphs (\ref NoteBookTab) have + ///different maps. If selected tab changes this signal is emitted by \ref AlgoBox, + ///caught and reemitted by \ref AlgoWin. + /// + ///Signal contains the address of \ref AlgoWin to let \ref MainWin know + ///where should the information needed forwarded, and the name of + ///\ref NoteBookTab, of which maps are inquired. + sigc::signal signal_maplist_need; + + ///Signal that indicates that a \ref NewMapWin should be popped up. + + ///This is a forwarded signal. If \ref AlgoBox emits a signal + ///to let a \ref NewMapWin pop up, |ref AlgoWin catch and reemit it. + /// + ///Signal contains the name of \ref NoteBookTab, in which the new map + ///should be created and a boolean that indicates whether an arc or a + ///nodemap should be created. + sigc::signal signal_newmapwin_need; + +public: + ///Close window if escape key is pressed. + bool closeIfEscapeIsPressed(GdkEventKey* e); + + ///Returns \ref signal_closed to be bindable somewhere. + sigc::signal signal_closing(); + + ///Returns \ref signal_maplist_need to be bindable somewhere. + sigc::signal signal_maplist_needed(); + + ///Returns \ref signal_newmapwin_need to be bindable somewhere. + sigc::signal signal_newmapwin_needed(){return signal_newmapwin_need;}; + + ///Forwards signal emitted by \ref AlgoBox, in which it indicates changement in selection of tabs. + void emit_tab_change(std::string); + + ///Forwards signal emitted by \ref AlgoBox, in which it indicates need for \ref NewMapWin. + void emit_new_map_signal(std::string tabname, bool itisarc){signal_newmapwin_need.emit(tabname, itisarc);}; + + ///Constructor + + ///It builds the window according to the information provided + ///by the creator. It needs the identifier of the algorithm + ///to visualize, and a list of name of \ref NoteBookTab s that can + ///be found in \ref MainWin. + ///\param algoid identifier of algorithm to show + ///\param tablist list of tabs in \ref MainWin + AlgoWin(int algoid, std::vector tablist); + + ///Forwards list of \ref NoteBookTabs toward \ref AlgoBox + + ///In case of changement in tabs in \ref MainWin + ///\ref MainWin automatically updates tablist in + ///\ref AlgoWin s. + void update_tablist(std::vector tabnames); + + ///Forwards list of requested maps toward \ref AlgoBox + + ///Upon catching the signal in which \ref AlgoBox requests + ///list of maps \ref MainWin responds + ///through this function. + void update_maplist(MapStorage *); + + ///Called when window is closing. + + ///\ref AlgoWin has to be deregistrated in \ref MainWin + ///thereforeit emits signal \ref signal_closed. + void on_hide(); +}; +#endif //ALGOWIN_H diff -r 0e4f009eab8b -r 67188bd752db all_include.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/all_include.h Mon Jul 07 08:10:39 2008 -0500 @@ -0,0 +1,73 @@ +/* -*- C++ -*- + * + * This file is a part of LEMON, a generic C++ optimization library + * + * Copyright (C) 2003-2006 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#ifndef ALL_INCLUDE_H +#define ALL_INCLUDE_H + +#include +#include + +#include + +#include +#include +#include +#include +#include + +enum {E_WIDTH, E_COLOR, E_TEXT, EDGE_PROPERTY_NUM}; // arc properties; +enum {N_RADIUS, N_COLOR, N_TEXT, NODE_PROPERTY_NUM}; // node properties; +enum {N_MAPS, E_MAPS, ARROWS, PAR, EPS_PROPERTY_NUM}; // eps properties; +enum {MOVE, CREATE_NODE, CREATE_EDGE, ERASER, MAP_EDIT, TOOL_NUM}; // tools; +#define RANGE 3 +#define WIN_WIDTH 900 +#define WIN_HEIGHT 600 +#define MIN_EDGE_WIDTH 2 +#define MAX_EDGE_WIDTH 40 +#define MIN_NODE_RADIUS 2 +#define MAX_NODE_RADIUS 80 + +#ifndef MAIN_PART +extern std::vector arc_property_strings; +extern std::vector arc_property_defaults; +extern std::vector node_property_strings; +extern std::vector node_property_defaults; +extern int longest_property_string_length; +#endif //MAIN_PART + +using namespace lemon; + +typedef lemon::dim2::Point XY; +typedef ListDigraph Digraph; +typedef Digraph::Node Node; +typedef Digraph::Arc Arc; +typedef Digraph::ArcIt ArcIt; +typedef Digraph::InArcIt InArcIt; +typedef Digraph::OutArcIt OutArcIt; +typedef Digraph::NodeIt NodeIt; + +const std::string prog_name = "LEMON Digraph Editor"; + +enum MapType +{ + NUM = 1 << 0, + STR = 1 << 1, + ALL = (1 << 0) | (1 << 1) +}; + +#endif // ALL_INCLUDE_H diff -r 0e4f009eab8b -r 67188bd752db autopackage/default.apspec.in --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/autopackage/default.apspec.in Mon Jul 07 08:10:39 2008 -0500 @@ -0,0 +1,44 @@ +# -*-shell-script-*- + +[Meta] +RootName: @lemon.cs.elte.hu/glemon:$SOFTWAREVERSION +DisplayName: glemon +ShortName: glemon +Maintainer: The LEMON Developers - http://lemon.cs.elte.hu/ +Packager: Alpar Juttner +Summary: Graphical graph and network editor for the LEMON Graph Format +SoftwareVersion: @VERSION@ +AutopackageTarget: 0.7 + +# Only uncomment InterfaceVersion if your package exposes interfaces to other software, +# for instance if it includes DSOs or python/perl modules. See the developer guide for more info, +# or ask on autopackage-dev if you don't understand interface versioning in autopackage. +# +# InterfaceVersion: 0.0 + +PackageVersion: 1 + +[Description] +Graphical graph and network editor for the LEMON Graph Format + +[BuildPrepare] +prepareBuild + +[BuildUnprepare] +unprepareBuild + +[Imports] +echo '*' | import + +[Prepare] +# Dependency checking +#require @whatever.you/need 1.0 + +[Install] +# Put your installation script here +#installExe bin/* +copyFiles * $PREFIX + +[Uninstall] +# Usually just the following line is enough to uninstall everything +uninstallFromLog diff -r 0e4f009eab8b -r 67188bd752db background_chooser_dialog.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/background_chooser_dialog.cc Mon Jul 07 08:10:39 2008 -0500 @@ -0,0 +1,52 @@ +#include +#include +#include + +BackgroundChooserDialog::BackgroundChooserDialog(MapStorage* ms) : + mapstorage(ms), + btnClear(Gtk::Stock::CLEAR) +{ + set_has_separator(false); + + Gtk::VBox* pVBox = get_vbox(); + + lblBackground.set_text("Background image file"); + lblBackground.set_use_markup(); + lblBackground.set_alignment(Gtk::ALIGN_LEFT); + lblScaling.set_text("Scaling factor"); + lblScaling.set_use_markup(); + lblScaling.set_alignment(Gtk::ALIGN_LEFT); + fcbBackground.set_width_chars(30); + fcbBackground.set_action(Gtk::FILE_CHOOSER_ACTION_OPEN); + if (mapstorage->isBackgroundSet()) + { + fcbBackground.set_filename(mapstorage->getBackgroundFilename()); + } + + fcbBackground.signal_selection_changed().connect( + sigc::mem_fun(*this, &BackgroundChooserDialog::setBackground)); + + btnClear.signal_clicked().connect( + sigc::mem_fun(*this, &BackgroundChooserDialog::clearBackground)); + + pVBox->pack_start(lblBackground, Gtk::PACK_SHRINK); + pVBox->pack_start(box, Gtk::PACK_SHRINK); + box.pack_start(fcbBackground, Gtk::PACK_EXPAND_WIDGET); + box.pack_start(btnClear, Gtk::PACK_SHRINK); + pVBox->pack_start(lblScaling, Gtk::PACK_SHRINK); + pVBox->pack_start(sbScaling, Gtk::PACK_SHRINK); + + add_button(Gtk::Stock::CLOSE, Gtk::RESPONSE_CLOSE); + + show_all_children(); +} + +void BackgroundChooserDialog::clearBackground() +{ + fcbBackground.unselect_all(); +} + +void BackgroundChooserDialog::setBackground() +{ + mapstorage->setBackground(fcbBackground.get_filename()); +} diff -r 0e4f009eab8b -r 67188bd752db background_chooser_dialog.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/background_chooser_dialog.h Mon Jul 07 08:10:39 2008 -0500 @@ -0,0 +1,27 @@ +#ifndef BACKGROUND_CHOOSER_DIALOG +#define BACKGROUND_CHOOSER_DIALOG + +#include +#include +#include +#include + +class MapStorage; + +class BackgroundChooserDialog : public Gtk::Dialog +{ + private: + MapStorage* mapstorage; + Gtk::Label lblBackground; + Gtk::Label lblScaling; + Gtk::FileChooserButton fcbBackground; + Gtk::SpinButton sbScaling; + Gtk::HBox box; + Gtk::Button btnClear; + void clearBackground(); + void setBackground(); + public: + BackgroundChooserDialog(MapStorage* ms); +}; + +#endif diff -r 0e4f009eab8b -r 67188bd752db bootstrap --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/bootstrap Mon Jul 07 08:10:39 2008 -0500 @@ -0,0 +1,85 @@ +#!/bin/bash + +quiet=0 +function quiet { [[ $quiet == 1 ]]; } + +if [[ "$1" == "-q" ]]; then + quiet=1 + shift +fi + +prev= +for option +do + if test -n "$prev" + then + eval "$prev=\$option" + prev= + continue + fi + + optarg=`expr "x$option" : 'x[^=]*=\(.*\)'` + + case $option in + + -amver | --amver) + prev=amver ;; + -amver=* | --amver=*) + amver=$optarg ;; + + -acver | --acver) + prev=acver ;; + -acver=* | --acver=*) + acver=$optarg ;; + + --help | -h) + cat << EOF +Usage: $0 [OPTION] + +Options: + -h, --help display this help and exit + --amver=VERSION use VERSION version of automake + --acver=VERSION use VERSION version of autoconf + +Expamle: + $0 --amver=1.8 --acver=2.59 +EOF + exit 0 + ;; + + *) + cat << EOF >&2 +$0: unrecognized option: $option +Try \`$0 --help' for more information. +EOF + exit 1 + ;; + + esac +done + +automake=automake +aclocal=aclocal +autoconf=autoconf +autoheader=autoheader + +if test -n "$amver" +then + automake=automake-$amver + aclocal=aclocal-$amver +fi + +if test -n "$acver" +then + autoconf=autoconf-$acver + autoheader=autoheader-$acver +fi + +set -e +quiet || set -x + +autopoint +$aclocal -I m4 +$autoconf +$autoheader +$automake --add-missing --copy --gnu diff -r 0e4f009eab8b -r 67188bd752db color.lgf --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/color.lgf Mon Jul 07 08:10:39 2008 -0500 @@ -0,0 +1,370 @@ +@nodes +coordinates_x coordinates_y label +-357 -128 1 +-298 -135 2 +-229 -140 3 +-160 -146 4 +-84 -149 5 +-3 -155 6 +76 -155 7 +155 -151 8 +229 -138 9 +298 -113 10 +362 -88 11 +433 -53 12 +447 3 13 +416 59 14 +338 69 15 +281 31 16 +217 6 17 +143 -1 18 +69 -1 19 +-7 3 20 +-73 3 21 +-137 -3 22 +-193 -26 23 +-255 -30 24 +-303 -2 25 +-348 37 26 +-355 92 27 +-335 145 28 +-299 181 29 +-229 186 30 +-164 154 31 +-104 126 32 +-46 134 33 +0 169 34 +47 197 35 +100 195 36 +141 161 37 +195 134 38 +256 146 39 +314 182 40 +370 207 41 +431 244 42 + +@arcs + label +42 41 1 +41 40 2 +40 39 3 +39 38 4 +38 37 5 +37 36 6 +36 35 7 +35 34 8 +34 33 9 +33 32 10 +32 31 11 +31 30 12 +30 29 13 +29 28 14 +28 27 15 +27 26 16 +26 25 17 +25 24 18 +24 23 19 +23 22 20 +22 21 21 +21 20 22 +20 19 23 +19 18 24 +18 17 25 +17 16 26 +16 15 27 +15 14 28 +14 13 29 +13 12 30 +12 11 31 +11 10 32 +10 9 33 +9 8 34 +8 7 35 +7 6 36 +6 5 37 +5 4 38 +4 3 39 +3 2 40 +2 1 41 + +@gui + + + 1 + + 400.5225.5 + + + + 2 + + 342194.5 + + + + 3 + + 285164 + + + + 4 + + 225.5140 + + + + 5 + + 168147.5 + + + + 6 + + 120.5178 + + + + 7 + + 73.5196 + + + + 8 + + 23.5183 + + + + 9 + + -23151.5 + + + + 10 + + -75130 + + + + 11 + + -134140 + + + + 12 + + -196.5170 + + + + 13 + + -264183.5 + + + + 14 + + -317163 + + + + 15 + + -345118.5 + + + + 16 + + -351.564.5 + + + + 17 + + -325.517.5 + + + + 18 + + -279-16 + + + + 19 + + -224-28 + + + + 20 + + -165-14.5 + + + + 21 + + -1050 + + + + 22 + + -403 + + + + 23 + + 311 + + + + 24 + + 106-1 + + + + 25 + + 1802.5 + + + + 26 + + 24918.5 + + + + 27 + + 309.550 + + + + 28 + + 37764 + + + + 29 + + 431.531 + + + + 30 + + 440-25 + + + + 31 + + 397.5-70.5 + + + + 32 + + 330-100.5 + + + + 33 + + 263.5-125.5 + + + + 34 + + 192-144.5 + + + + 35 + + 115.5-153 + + + + 36 + + 36.5-155 + + + + 37 + + -43.5-152 + + + + 38 + + -122-147.5 + + + + 39 + + -194.5-143 + + + + 40 + + -263.5-137.5 + + + + 41 + + -327.5-131.5 + + + + + + 0 + + + + 1 + label + + + 2 + + + + + + 0 + + + + 1 + label + + + 2 + + + +0.05 +40000 +20 +@end diff -r 0e4f009eab8b -r 67188bd752db configure.ac --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/configure.ac Mon Jul 07 08:10:39 2008 -0500 @@ -0,0 +1,76 @@ +dnl Process this file with autoconf to produce a configure script. + +dnl Version information. +m4_define([glemon_version_major], [0]) +m4_define([glemon_version_minor], [5]) +m4_define([glemon_version_micro], [90]) +m4_define([glemon_version_nano], []) +m4_define([glemon_version_tag], [svn]) +m4_define([glemon_svn_revision], [m4_normalize(esyscmd([svn info |grep ^Revision |cut -d ' ' -f 2]))]) +m4_define([glemon_version], [glemon_version_major().glemon_version_minor()ifelse(glemon_version_micro(), [], [], [.glemon_version_micro()])ifelse(glemon_version_nano(), [], [], [.glemon_version_nano()])ifelse(glemon_version_tag(), [], [], glemon_version_tag(), [svn], [[_]glemon_version_tag()[]glemon_svn_revision()], [[_]glemon_version_tag()])]) + +AC_PREREQ([2.59]) +AC_INIT([gLEMON], [glemon_version()], [etik-ol@cs.elte.hu], [glemon]) +AC_CONFIG_AUX_DIR([build-aux]) +AC_CONFIG_MACRO_DIR([m4]) +AM_INIT_AUTOMAKE([-Wall -Werror foreign]) +AC_CONFIG_SRCDIR([main_win.h]) +AC_CONFIG_HEADERS([config.h]) + +dnl Checks for programs. +AC_PROG_CXX +AC_PROG_CC +AM_GNU_GETTEXT_VERSION([0.14.2]) +AM_GNU_GETTEXT([external]) + +dnl Checks for libraries. +PKG_CHECK_MODULES([GTK], [libgnomecanvasmm-2.6 >= 2.6.0 gtkmm-2.4 >= 2.6]) + +AC_ARG_WITH([lemon], +AS_HELP_STRING([--with-lemon@<:@=PREFIX@:>@], [search for LEMON under PREFIX]), [], [with_lemon=no]) +if test x"$with_lemon" != x"no"; then + export PKG_CONFIG_PATH="$with_lemon/lib/pkgconfig/:$PKG_CONFIG_PATH" +fi + +PKG_CHECK_MODULES([LEMON], [lemon >= 0.6.90]) + +dnl Checks for header files. +AC_CHECK_HEADERS([libintl.h locale.h]) + +dnl Checks for typedefs, structures, and compiler characteristics. +AC_HEADER_STDBOOL +AC_C_CONST + +dnl Checks for library functions. +AC_CHECK_FUNCS([setlocale sqrt]) + +AC_CONFIG_FILES([ +Makefile +glemon.spec +autopackage/default.apspec +po/Makefile.in +m4/Makefile +]) + +AC_OUTPUT + +echo +echo '****************************** SUMMARY ******************************' +echo +echo Package version............... : $PACKAGE-$VERSION +echo +echo C++ compiler.................. : $CXX +echo C++ compiles flags............ : $CXXFLAGS +echo +echo LEMON CFLAGS.................. : $LEMON_CFLAGS +echo LEMON LIBS.................... : $LEMON_LIBS +echo +echo The packace will be installed in +echo -n ' ' +echo $prefix. +echo +echo '*********************************************************************' + +echo +echo configure complete, now type \'make\' and then \'make install\'. +echo diff -r 0e4f009eab8b -r 67188bd752db design_win.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/design_win.cc Mon Jul 07 08:10:39 2008 -0500 @@ -0,0 +1,98 @@ +/* -*- C++ -*- + * + * This file is a part of LEMON, a generic C++ optimization library + * + * Copyright (C) 2003-2006 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#include + +bool DesignWin::closeIfEscapeIsPressed(GdkEventKey* e) +{ + if(e->keyval==GDK_Escape) + { + on_hide(); + } + return true; +} + +DesignWin::DesignWin(const std::string& title, double attraction_v, double propulsation_v, int iterations_v) +{ + set_title(title); + + //mytab.signal_title_ch().connect(sigc::mem_fun(*this, &DesignWin::set_title)); + + signal_key_press_event().connect(sigc::mem_fun(*this, &DesignWin::closeIfEscapeIsPressed)); + + Gtk::VBox * vbox=new Gtk::VBox(); + vbox->set_spacing(5); + + Gtk::Label * attraction_label=new Gtk::Label("Arc elasticity: "); + Gtk::Label * propulsation_label=new Gtk::Label("Node propulsation: "); + Gtk::Label * iteration_label=new Gtk::Label("Iteration number: "); + + Gtk::Adjustment * attraction_adjustment=new Gtk::Adjustment(attraction_v, 0,1,0.01,0.1); + Gtk::Adjustment * propulsation_adjustment=new Gtk::Adjustment(propulsation_v,0,1000000,1000,10000); + Gtk::Adjustment * iteration_adjustment=new Gtk::Adjustment(iterations_v,1,20000,5,10); + + attraction = new Gtk::SpinButton(*attraction_adjustment,5,3); + propulsation = new Gtk::SpinButton(*propulsation_adjustment,5,0); + iteration = new Gtk::SpinButton(*iteration_adjustment,5,0); + + close_button=new Gtk::Button("Redesign"); + + attraction->signal_value_changed().connect(sigc::mem_fun(*this, &DesignWin::emit_attraction)); + propulsation->signal_value_changed().connect(sigc::mem_fun(*this, &DesignWin::emit_propulsation)); + iteration->signal_value_changed().connect(sigc::mem_fun(*this, &DesignWin::emit_iteration)); + close_button->signal_pressed().connect(sigc::mem_fun(*this, &DesignWin::emit_closerun)); + + table.attach(*attraction_label,0,1,0,1); + table.attach(*propulsation_label,0,1,1,2); + table.attach(*iteration_label,0,1,2,3); + table.attach(*attraction,1,2,0,1); + table.attach(*propulsation,1,2,1,2); + table.attach(*iteration,1,2,2,3); + table.attach(*close_button,0,2,3,4); + + add(table); + + show_all_children(); +}; + +void DesignWin::emit_attraction() +{ + signal_attraction_ch.emit(attraction->get_value()); +} + +void DesignWin::emit_propulsation() +{ + signal_propulsation_ch.emit(propulsation->get_value()); +} + +void DesignWin::emit_iteration() +{ + signal_iteration_ch.emit((int)iteration->get_value()); +} + +void DesignWin::set_title(std::string tabname) +{ + Gtk::Window::set_title("Design Setup - "+tabname); +} + +void DesignWin::set_data(double attr, double propuls, int it) +{ + attraction->set_value(attr); + propulsation->set_value(propuls); + iteration->set_value(it); +} diff -r 0e4f009eab8b -r 67188bd752db design_win.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/design_win.h Mon Jul 07 08:10:39 2008 -0500 @@ -0,0 +1,63 @@ +/* -*- C++ -*- + * + * This file is a part of LEMON, a generic C++ optimization library + * + * Copyright (C) 2003-2006 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#ifndef DESWIN_H +#define DESWIN_H + +#include +#include +#include + +class DesignWin : public Gtk::Window +{ +private: + Gtk::SpinButton * attraction; + Gtk::SpinButton * propulsation; + Gtk::SpinButton * iteration; + Gtk::Table table; + Gtk::Button * close_button; + + sigc::signal signal_attraction_ch; + sigc::signal signal_propulsation_ch; + sigc::signal signal_iteration_ch; + sigc::signal close_run_pr; + + void emit_attraction(); + void emit_propulsation(); + void emit_iteration(); + void emit_closerun(){close_run_pr.emit();}; + +public: + ///Close window if escape key is pressed. + bool closeIfEscapeIsPressed(GdkEventKey* e); + + ///Constructor + + ///It builds the window. + DesignWin(const std::string&, double, double, int); + + sigc::signal signal_attraction(){return signal_attraction_ch;}; + sigc::signal signal_propulsation(){return signal_propulsation_ch;}; + sigc::signal signal_iteration(){return signal_iteration_ch;}; + sigc::signal close_run(){return close_run_pr;}; + + void set_title(std::string); + + void set_data(double, double, int); +}; +#endif //DESWIN_H diff -r 0e4f009eab8b -r 67188bd752db dijkstrabox.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dijkstrabox.cc Mon Jul 07 08:10:39 2008 -0500 @@ -0,0 +1,247 @@ +/* -*- C++ -*- + * + * This file is a part of LEMON, a generic C++ optimization library + * + * Copyright (C) 2003-2006 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#include +#include +#include +#include + +#include + +//No Suurballe in Lemon 1.0 +//#include +#include + +enum {INPUT, OUTPUT, MAP_NUM}; + +DijkstraBox::DijkstraBox(std::vector t):AlgoBox() +{ + init(t); +} + +SuurballeBox::SuurballeBox(std::vector t):DijkstraBox(t) +{ + Gtk::Adjustment * adjustment=new Gtk::Adjustment(2, 1, 20, 1, 5); + num_set = new Gtk::SpinButton(*adjustment, 5,0); + + Gtk::Label * label=new Gtk::Label("No. of paths to find: "); +// hbox.pack_start(*label); +// hbox.pack_start(*num_set); +// hbox.show_all_children(); + + table.attach(*label, 0,1,2,3); + table.attach(*num_set, 1,2,2,3); + + +// pack_start(hbox); +} + +void DijkstraBox::run() +{ + if( + tabcbt.get_active_text()!="" && + (arcmapcbts[INPUT])->get_active_text()!="" && + (arcmapcbts[OUTPUT])->get_active_text()!="" && + source.get_active_text()!="" && + target.get_active_text()!="" + ) + { + const Digraph &g=mapstorage->digraph; + Node from, to; + + get_from_to(from, to, (Digraph&)g); + + std::ostringstream o; + + if(!(from==to)) + { + std::string inputmapName = arcmapcbts[INPUT]->get_active_text(); + std::string outputmapName = arcmapcbts[OUTPUT]->get_active_text(); + + MapStorage::NumericArcMap& inputmap = mapstorage->getNumericArcMap(inputmapName); + MapStorage::NumericArcMap& outputmap = mapstorage->getNumericArcMap(outputmapName); + + //zero out output map + for (ArcIt i(g); i!=INVALID; ++i) + { + outputmap[i]=0; + } + + Dijkstra dijkstra(g, inputmap); + dijkstra.run(from, to); + + if(dijkstra.reached(to)) + { + Node n=to; + int length=0; + while (n!=INVALID && n!=from) + { + Arc e=dijkstra.predArc(n); + outputmap[e]=1; + n=dijkstra.predNode(n); + length++; + } + o << "Result: " << length << " long path, with cost " << dijkstra.dist(to); + } + else + { + o << "Result: failed to find shortest path between "; + o << source.get_active_text() << " and " << target.get_active_text(); + } + resultlabel.set_text(o.str()); + + mapstorage->mapChanged(true, (arcmapcbts[OUTPUT])->get_active_text()); + // mapstorage->changeActiveMap(true, E_COLOR, + // (arcmapcbts[OUTPUT])->get_active_text()); + // mapstorage->changeActiveMap(true, E_TEXT, + // (arcmapcbts[INPUT])->get_active_text()); + } + } +} + +void SuurballeBox::run() +{ + if( + tabcbt.get_active_text()!="" && + (arcmapcbts[INPUT])->get_active_text()!="" && + (arcmapcbts[OUTPUT])->get_active_text()!="" && + source.get_active_text()!="" && + target.get_active_text()!="" + ) + { + const Digraph &g=mapstorage->digraph; + Node from, to; + + get_from_to(from, to, (Digraph&)g); + + std::ostringstream o; + + if(!(from==to)) + { + MapStorage::NumericArcMap& inputmap= + mapstorage->getNumericArcMap(arcmapcbts[INPUT]->get_active_text()); + MapStorage::NumericArcMap& outputmap= + mapstorage->getNumericArcMap(arcmapcbts[OUTPUT]->get_active_text()); + + //zero out output map + for (ArcIt i(g); i!=INVALID; ++i) + { + outputmap[i]=0; + } + + //No Suurballe in Lemon 1.0 + //Suurballe sb((Digraph&)g, inputmap, from, to); + + int found=0; + //No Suurballe in Lemon 1.0 + //found=sb.run(num_set->get_value_as_int()); + if(found) + { + for(int j=0;j path; + //No Suurballe in Lemon 1.0 + //path=sb.path(j); + for(int k=0;kmapChanged(true, (arcmapcbts[OUTPUT])->get_active_text()); + // mapstorage->changeActiveMap(true, E_COLOR, + // (arcmapcbts[OUTPUT])->get_active_text()); + // mapstorage->changeActiveMap(true, E_TEXT, + // (arcmapcbts[INPUT])->get_active_text()); + } + } +} + +void DijkstraBox::build_box() +{ + //if active tab is changed, labels of digraph nodes had to be loaded into comboboxes + //this can be done after the maps are loaded into ComboBoxes + signal_upon_maplist_updated().connect(sigc::mem_fun(*this, &DijkstraBox::maplists_updated)); + + addMapSelector("Cost map: ", true, NUM); + addMapSelector("Arcs of path here: ", true, NUM); + + Gtk::Label * source_label=new Gtk::Label("Source: "); + Gtk::Label * target_label=new Gtk::Label("Target: "); + + table.attach(*source_label, 0,1,0,1); + table.attach(*target_label, 0,1,1,2); + table.attach(source, 1,2,0,1); + table.attach(target, 1,2,1,2); + + + pack_start(table); + + resultlabel.set_text("Result: algorithm is not run yet."); + pack_start(resultlabel); +} + +void SuurballeBox::build_box() +{ +} + +void DijkstraBox::maplists_updated() +{ + if(tabcbt.get_active_text()!="") + { + source.clear(); + target.clear(); + const Digraph &g=mapstorage->digraph; + for (NodeIt i(g); i!=INVALID; ++i) + { + std::ostringstream text; + text << mapstorage->getLabel(i); + source.prepend_text(text.str()); + target.prepend_text(text.str()); + } + } +} + +void DijkstraBox::get_from_to(Node & from, Node & to, Digraph & g) +{ + int assigned=0; + for (NodeIt i(g); (i!=INVALID) && (assigned<2); ++i) + { + std::ostringstream text; + text << mapstorage->getLabel(i); + if(!(text.str().compare(source.get_active_text()))) + { + from=i; + assigned++; + } + if(!(text.str().compare(target.get_active_text()))) + { + to=i; + assigned++; + } + } +} diff -r 0e4f009eab8b -r 67188bd752db dijkstrabox.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dijkstrabox.h Mon Jul 07 08:10:39 2008 -0500 @@ -0,0 +1,91 @@ +/* -*- C++ -*- + * + * This file is a part of LEMON, a generic C++ optimization library + * + * Copyright (C) 2003-2006 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#ifndef DIJKSTRABOX_H +#define DIJKSTRABOX_H + +class AlgoBox; + +#include +#include +#include + +///Digraphical interface to run Dijkstra algorithm. + +///Child of \ref AlgoBox, +///therefore the only task to do at implementation was to +/// +///-call init function with correct parameters from correctly parametrized constructor +/// +///-implement \ref build_box function +/// +///-implement \ref run function +class DijkstraBox : public AlgoBox +{ +protected: + ///Shows result of Dijkstra algorithm + Gtk::Label resultlabel; + + + ///Table for nodeselector widgets + Gtk::Table table; + + ///Combobox for select source node + Gtk::ComboBoxText source; + + ///Combobox for select target node + Gtk::ComboBoxText target; + + ///Gets to and from node from combobox + void get_from_to(Node &, Node &, Digraph &); + +public: + ///Calls \ref AlgoBox::init function to initialize class properly, automatically. + DijkstraBox(std::vector t); + + ///Prepare, run and postprocess Dijkstra algorithm. + + ///\ref glemon works only with maps filled with double values + ///at the moment. While Dijkstra nedds a bool map as output. + ///As postprocess this bool map should be transformed to + ///double map. + virtual void run(); + + ///Builds the digraphical design of the interface. + virtual void build_box(); + + void maplists_updated(); +}; + +class SuurballeBox : public DijkstraBox +{ + ///number of paths to find + int num; + + ///Widget to set numbewr of paths to find + Gtk::SpinButton * num_set; + + ///Holder widget + Gtk::HBox hbox; + +public: + SuurballeBox(std::vector t); + void run(); + void build_box(); +}; +#endif //DIJKSTRABOX_H diff -r 0e4f009eab8b -r 67188bd752db eps_win.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eps_win.cc Mon Jul 07 08:10:39 2008 -0500 @@ -0,0 +1,110 @@ +/* -*- C++ -*- + * + * This file is a part of LEMON, a generic C++ optimization library + * + * Copyright (C) 2003-2006 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#include + +#include + +#include + +bool EpsWin::closeIfEscapeIsPressed(GdkEventKey* e) +{ + if(e->keyval==GDK_Escape) + { + hide(); + } + return true; +} + +EpsWin::EpsWin(const std::string& title, std::vector n_nml, std::vector s_nml):Gtk::Dialog(title, true, true) +{ + set_default_size(200, 50); + + set_resizable(false); + + signal_key_press_event().connect(sigc::mem_fun(*this, &EpsWin::closeIfEscapeIsPressed)); + + table=new Gtk::Table(EPS_PROPERTY_NUM, 1, false); + + std::vector labels; + labels.resize(EPS_PROPERTY_NUM); + + labels[N_MAPS]="Dump visualized nodemaps"; + labels[E_MAPS]="Dump visualizes arcmaps"; + labels[ARROWS]="Show arrows in directed digraphs"; + labels[PAR]="Indicate parallel arcs"; + + options.resize(EPS_PROPERTY_NUM); + + for(int i=0;isignal_newmapwin_needed().connect(sigc::mem_fun(*this, &EpsWin::newMapWinNeeded)); + + hbox.pack_start(*(new Gtk::Label("Filename"))); + hbox.pack_start(name); + + Gtk::VBox * vbox=get_vbox(); + + vbox->pack_start(*table); + vbox->pack_start(*mapselector); + vbox->pack_start(hbox); + + //OK button + add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL); + add_button(Gtk::Stock::OK, Gtk::RESPONSE_OK); + + show_all_children(); + +} + +bool EpsWin::on_delete_event(GdkEventAny * event) +{ + event=event; + signal_eps_close.emit(); + return true; +} + +void EpsWin::on_response(int response_id) +{ + if(response_id==Gtk::RESPONSE_OK) + { + std::vector values; + values.resize(EPS_PROPERTY_NUM); + for(int i=0;iget_active(); + } + signal_eps_details.emit(values, name.get_text(), mapselector->get_active_text()); + } + on_delete_event(NULL); +} + +void EpsWin::newMapWinNeeded(bool isitarc) +{ + signal_new_map.emit(false); +} + +void EpsWin::registerNewNodeMap(std::string newmapname, MapValue::Type type) +{ + mapselector->append_text((Glib::ustring)newmapname, type); +} diff -r 0e4f009eab8b -r 67188bd752db eps_win.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eps_win.h Mon Jul 07 08:10:39 2008 -0500 @@ -0,0 +1,109 @@ +/* -*- C++ -*- + * + * This file is a part of LEMON, a generic C++ optimization library + * + * Copyright (C) 2003-2006 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#ifndef EPS_WIN_H +#define EPS_WIN_H + +class MapSelector; + +#include +#include +#include +#include "map_value.h" + +///Digraph visualization setup window. + +///This class is responsible for creating a window, +///on which the visualization attributes can be +///assigned to maps. +class EpsWin : public Gtk::Dialog +{ +protected: + ///Designing element + Gtk::Table * table; + + ///Information holder + Gtk::Label * label; + + ///configuration + std::vector options; + + ///OK, Cancel + Gtk::Button * ok, * cancel; + + ///Container in which filename entry are organized. + Gtk::HBox hbox; + + ///Filename + Gtk::Entry name; + + MapSelector * mapselector; +public: + ///Constructor + + ///It creates the widgets shown in \ref EpsWin and + ///binds the needed signal to the correct place. + ///\param title title of window + ///\param eml arcmap list + ///\param nml nodemap list + ///\param mw the owner \ref NoteBookTab (\ref mytab) + EpsWin(const std::string& title, std::vector, std::vector); + + ///Deregistrates \ref EpsWin in its \ref NoteBookTab (\ref mytab) + virtual bool on_delete_event(GdkEventAny *); + + ///Close window if Esc key pressed. + virtual bool closeIfEscapeIsPressed(GdkEventKey*); + + ///Callback function for OK button. It creates the map. + + ///If OK is pressed this function + ///transmits the collected data to + ///appropriate functions to be able + ///to create EPS + virtual void on_response(int response_id); + + ///indicates that user is ready to export EPS file + sigc::signal, std::string, std::string > signal_eps_details; + + ///returns \ref signal_eps_details + sigc::signal, std::string, std::string > signal_eps_details_ch(){return signal_eps_details;}; + + ///indicates that the windows can be closed + sigc::signal signal_eps_close; + + ///returns \ref signal_eps_close + sigc::signal signal_eps_close_ch(){return signal_eps_close;}; + + ///indicates that the windows can be closed + sigc::signal signal_new_map; + + ///returns \ref signal_eps_close + sigc::signal signal_new_map_ch(){return signal_new_map;}; + + ///Function is called when new map is required. + void newMapWinNeeded(bool); + + ///This function inserts name of the new nodemap in the name list in \ref MapSelector s + + ///\param new_name + ///name of new map + void registerNewNodeMap(std::string new_name, MapValue::Type type); +}; + +#endif //EPS_WIN_H diff -r 0e4f009eab8b -r 67188bd752db file_import_dialog.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/file_import_dialog.cc Mon Jul 07 08:10:39 2008 -0500 @@ -0,0 +1,928 @@ +#include "file_import_dialog.h" +#include +#include +#include +#include +#include +#include + +FileImportDialog::FileImportDialog(ImportData* d) : + p_data(d) +{ + add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL); + add_button(Gtk::Stock::OK, Gtk::RESPONSE_OK); + + Gtk::VBox* pVBox = get_vbox(); + + Gtk::Notebook* nb = Gtk::manage(new Gtk::Notebook); + pVBox->pack_start(*nb, Gtk::PACK_EXPAND_WIDGET); + + Gtk::VBox* vblueMaps = Gtk::manage(new Gtk::VBox(false, 18)); + vblueMaps->set_border_width(12); + + Gtk::VBox* vbArcMaps = Gtk::manage(new Gtk::VBox(false, 18)); + vbArcMaps->set_border_width(12); + + Gtk::VBox* vbSpecMaps = Gtk::manage(new Gtk::VBox(false, 18)); + vbSpecMaps->set_border_width(12); + + nb->append_page(*vbSpecMaps, "Special Maps"); + nb->append_page(*vblueMaps, "Node Maps"); + nb->append_page(*vbArcMaps, "Arc Maps"); + + // child widgets of vbSpecMaps + { + Gtk::VBox* box1 = Gtk::manage(new Gtk::VBox(false, 6)); + vbSpecMaps->pack_start(*box1, Gtk::PACK_SHRINK); + + { + Gtk::Label* label1 = + Gtk::manage(new Gtk::Label("Node Coordinates")); + label1->set_alignment(Gtk::ALIGN_LEFT, Gtk::ALIGN_CENTER); + label1->set_use_markup(); + box1->pack_start(*label1); + + Gtk::HBox* box2 = Gtk::manage(new Gtk::HBox); + box1->pack_start(*box2); + + Gtk::Label* fill1 = Gtk::manage(new Gtk::Label(" ")); + box2->pack_start(*fill1, Gtk::PACK_SHRINK); + + Gtk::VBox* box3 = Gtk::manage(new Gtk::VBox); + box2->pack_start(*box3); + + Gtk::VBox* box13 = Gtk::manage(new Gtk::VBox); + box3->pack_start(*box13); + + rblueCoordNone.set_label("None"); + Gtk::RadioButtonGroup group = rblueCoordNone.get_group(); + box13->pack_start(rblueCoordNone); + + Gtk::VBox* box4 = Gtk::manage(new Gtk::VBox); + box3->pack_start(*box4); + + rblueCoordOneMap.set_label("One Map"); + rblueCoordOneMap.set_group(group); + box4->pack_start(rblueCoordOneMap); + + Gtk::HBox* box5 = Gtk::manage(new Gtk::HBox); + box4->pack_start(*box5); + + Gtk::Label* fill2 = Gtk::manage(new Gtk::Label(" ")); + box5->pack_start(*fill2, Gtk::PACK_SHRINK); + + Gtk::VBox* box6 = Gtk::manage(new Gtk::VBox); + box5->pack_start(*box6); + + Gtk::HBox* box7 = Gtk::manage(new Gtk::HBox); + box6->pack_start(*box7); + + Gtk::Label* label2 = Gtk::manage(new Gtk::Label("(X, Y)")); + box7->pack_start(*label2, Gtk::PACK_SHRINK, 4); + + box7->pack_start(cblueCoordOneMap, Gtk::PACK_EXPAND_WIDGET); + + + Gtk::VBox* box8 = Gtk::manage(new Gtk::VBox); + box3->pack_start(*box8); + + rblueCoordTwoMaps.set_label("Two Maps"); + rblueCoordTwoMaps.set_group(group); + box8->pack_start(rblueCoordTwoMaps); + + Gtk::HBox* box9 = Gtk::manage(new Gtk::HBox); + box8->pack_start(*box9); + + Gtk::Label* fill3 = Gtk::manage(new Gtk::Label(" ")); + box9->pack_start(*fill3, Gtk::PACK_SHRINK); + + Gtk::VBox* box10 = Gtk::manage(new Gtk::VBox); + box9->pack_start(*box10); + + Gtk::HBox* box11 = Gtk::manage(new Gtk::HBox); + box10->pack_start(*box11); + + Gtk::Label* label3 = Gtk::manage(new Gtk::Label("X")); + box11->pack_start(*label3, Gtk::PACK_SHRINK, 4); + + box11->pack_start(cblueCoordTwoMaps1, Gtk::PACK_EXPAND_WIDGET); + + Gtk::HBox* box12 = Gtk::manage(new Gtk::HBox); + box10->pack_start(*box12); + + Gtk::Label* label4 = Gtk::manage(new Gtk::Label("Y")); + box12->pack_start(*label4, Gtk::PACK_SHRINK, 4); + + box12->pack_start(cblueCoordTwoMaps2, Gtk::PACK_EXPAND_WIDGET); + + cblueCoordOneMap.signal_changed().connect( + sigc::mem_fun(*this, &FileImportDialog::onNodeCoordOneMapChanged)); + cblueCoordTwoMaps1.signal_changed().connect( + sigc::mem_fun(*this, &FileImportDialog::onNodeCoordTwoMaps1Changed)); + cblueCoordTwoMaps2.signal_changed().connect( + sigc::mem_fun(*this, &FileImportDialog::onNodeCoordTwoMaps2Changed)); + } + + { + Gtk::Label* label1 = + Gtk::manage(new Gtk::Label("Arrow Coordinates")); + label1->set_alignment(Gtk::ALIGN_LEFT, Gtk::ALIGN_CENTER); + label1->set_use_markup(); + box1->pack_start(*label1); + + Gtk::HBox* box2 = Gtk::manage(new Gtk::HBox); + box1->pack_start(*box2); + + Gtk::Label* fill1 = Gtk::manage(new Gtk::Label(" ")); + box2->pack_start(*fill1, Gtk::PACK_SHRINK); + + Gtk::VBox* box3 = Gtk::manage(new Gtk::VBox); + box2->pack_start(*box3); + + Gtk::VBox* box13 = Gtk::manage(new Gtk::VBox); + box3->pack_start(*box13); + + rbArrowCoordNone.set_label("None"); + Gtk::RadioButtonGroup group = rbArrowCoordNone.get_group(); + box13->pack_start(rbArrowCoordNone); + + Gtk::VBox* box4 = Gtk::manage(new Gtk::VBox); + box3->pack_start(*box4); + + rbArrowCoordOneMap.set_label("One Map"); + rbArrowCoordOneMap.set_group(group); + box4->pack_start(rbArrowCoordOneMap); + + Gtk::HBox* box5 = Gtk::manage(new Gtk::HBox); + box4->pack_start(*box5); + + Gtk::Label* fill2 = Gtk::manage(new Gtk::Label(" ")); + box5->pack_start(*fill2, Gtk::PACK_SHRINK); + + Gtk::VBox* box6 = Gtk::manage(new Gtk::VBox); + box5->pack_start(*box6); + + Gtk::HBox* box7 = Gtk::manage(new Gtk::HBox); + box6->pack_start(*box7); + + Gtk::Label* label2 = Gtk::manage(new Gtk::Label("(X, Y)")); + box7->pack_start(*label2, Gtk::PACK_SHRINK, 4); + + box7->pack_start(cbArrowCoordOneMap, Gtk::PACK_EXPAND_WIDGET); + + + Gtk::VBox* box8 = Gtk::manage(new Gtk::VBox); + box3->pack_start(*box8); + + rbArrowCoordTwoMaps.set_label("Two Maps"); + rbArrowCoordTwoMaps.set_group(group); + box8->pack_start(rbArrowCoordTwoMaps); + + Gtk::HBox* box9 = Gtk::manage(new Gtk::HBox); + box8->pack_start(*box9); + + Gtk::Label* fill3 = Gtk::manage(new Gtk::Label(" ")); + box9->pack_start(*fill3, Gtk::PACK_SHRINK); + + Gtk::VBox* box10 = Gtk::manage(new Gtk::VBox); + box9->pack_start(*box10); + + Gtk::HBox* box11 = Gtk::manage(new Gtk::HBox); + box10->pack_start(*box11); + + Gtk::Label* label3 = Gtk::manage(new Gtk::Label("X")); + box11->pack_start(*label3, Gtk::PACK_SHRINK, 4); + + box11->pack_start(cbArrowCoordTwoMaps1, Gtk::PACK_EXPAND_WIDGET); + + Gtk::HBox* box12 = Gtk::manage(new Gtk::HBox); + box10->pack_start(*box12); + + Gtk::Label* label4 = Gtk::manage(new Gtk::Label("Y")); + box12->pack_start(*label4, Gtk::PACK_SHRINK, 4); + + box12->pack_start(cbArrowCoordTwoMaps2, Gtk::PACK_EXPAND_WIDGET); + + cbArrowCoordOneMap.signal_changed().connect( + sigc::mem_fun(*this, &FileImportDialog::onArrowCoordOneMapChanged)); + cbArrowCoordTwoMaps1.signal_changed().connect( + sigc::mem_fun(*this, &FileImportDialog::onArrowCoordTwoMaps1Changed)); + cbArrowCoordTwoMaps2.signal_changed().connect( + sigc::mem_fun(*this, &FileImportDialog::onArrowCoordTwoMaps2Changed)); + } + } + + // child widgets of vblueMaps + { + Gtk::VBox* box1 = Gtk::manage(new Gtk::VBox(false, 6)); + vblueMaps->pack_start(*box1, Gtk::PACK_SHRINK); + + Gtk::Label* label1 = + Gtk::manage(new Gtk::Label("Element type")); + label1->set_alignment(Gtk::ALIGN_LEFT, Gtk::ALIGN_CENTER); + label1->set_use_markup(); + box1->pack_start(*label1, Gtk::PACK_SHRINK); + + Gtk::HBox* box2 = Gtk::manage(new Gtk::HBox); + box1->pack_start(*box2, Gtk::PACK_SHRINK); + + Gtk::Label* fill1 = Gtk::manage(new Gtk::Label(" ")); + box2->pack_start(*fill1, Gtk::PACK_SHRINK); + + Gtk::Frame* frame = Gtk::manage(new Gtk::Frame); + box2->pack_start(*frame, Gtk::PACK_EXPAND_WIDGET); + + Gtk::ScrolledWindow* swNodeMaps = Gtk::manage(new Gtk::ScrolledWindow); + frame->add(*swNodeMaps); + + swNodeMaps->add(twNodeMaps); + + refNodeMapStore = Gtk::ListStore::create(NodeMapColumns); + + for (std::vector::const_iterator it = + p_data->node_map_names.begin(); it != p_data->node_map_names.end(); + ++it) + { + node_tree_view_records.push_back( + tree_view_record(*it, false, false, true)); + } + + twNodeMaps.set_model(refNodeMapStore); + twNodeMaps.append_column("Name", NodeMapColumns.colName); + { + int col = twNodeMaps.append_column_editable("Numeric", + NodeMapColumns.colReadAsNumeric); + Gtk::CellRendererToggle* pRenderer = + static_cast( + twNodeMaps.get_column_cell_renderer(col-1)); + pRenderer->signal_toggled().connect( + sigc::mem_fun(*this, &FileImportDialog::onNodeMapNumericToggled)); + } + { + int col = twNodeMaps.append_column_editable("String", + NodeMapColumns.colReadAsString); + Gtk::CellRendererToggle* pRenderer = + static_cast( + twNodeMaps.get_column_cell_renderer(col-1)); + pRenderer->signal_toggled().connect( + sigc::mem_fun(*this, &FileImportDialog::onNodeMapStringToggled)); + } + + swNodeMaps->set_size_request(-1, 200); + swNodeMaps->set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC); + } + + // child widgets of vbArcMaps + { + Gtk::VBox* box1 = Gtk::manage(new Gtk::VBox(false, 6)); + vbArcMaps->pack_start(*box1, Gtk::PACK_SHRINK); + + Gtk::Label* label1 = + Gtk::manage(new Gtk::Label("Element type")); + label1->set_alignment(Gtk::ALIGN_LEFT, Gtk::ALIGN_CENTER); + label1->set_use_markup(); + box1->pack_start(*label1, Gtk::PACK_SHRINK); + + Gtk::HBox* box2 = Gtk::manage(new Gtk::HBox); + box1->pack_start(*box2, Gtk::PACK_SHRINK); + + Gtk::Label* fill1 = Gtk::manage(new Gtk::Label(" ")); + box2->pack_start(*fill1, Gtk::PACK_SHRINK); + + Gtk::Frame* frame = Gtk::manage(new Gtk::Frame); + box2->pack_start(*frame, Gtk::PACK_EXPAND_WIDGET); + + Gtk::ScrolledWindow* swArcMaps = Gtk::manage(new Gtk::ScrolledWindow); + frame->add(*swArcMaps); + + swArcMaps->add(twArcMaps); + + refArcMapStore = Gtk::ListStore::create(ArcMapColumns); + + for (std::vector::const_iterator it = + p_data->arc_map_names.begin(); it != p_data->arc_map_names.end(); + ++it) + { + arc_tree_view_records.push_back( + tree_view_record(*it, false, false, true)); + } + + twArcMaps.set_model(refArcMapStore); + twArcMaps.append_column("Name", ArcMapColumns.colName); + { + int col = twArcMaps.append_column_editable("Numeric", + ArcMapColumns.colReadAsNumeric); + Gtk::CellRendererToggle* pRenderer = + static_cast( + twArcMaps.get_column_cell_renderer(col-1)); + pRenderer->signal_toggled().connect( + sigc::mem_fun(*this, &FileImportDialog::onArcMapNumericToggled)); + } + { + int col = twArcMaps.append_column_editable("String", + ArcMapColumns.colReadAsString); + Gtk::CellRendererToggle* pRenderer = + static_cast( + twArcMaps.get_column_cell_renderer(col-1)); + pRenderer->signal_toggled().connect( + sigc::mem_fun(*this, &FileImportDialog::onArcMapStringToggled)); + } + + swArcMaps->set_size_request(-1, 200); + swArcMaps->set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC); + } + + // fill in the ComboBoxes + typedef std::vector StrVec; + for (StrVec::const_iterator it = p_data->node_map_names.begin(); + it != p_data->node_map_names.end(); ++it) + { + cblueCoordTwoMaps1.append_text(*it); + cblueCoordTwoMaps2.append_text(*it); + } + for (StrVec::const_iterator it = p_data->arc_map_names.begin(); + it != p_data->arc_map_names.end(); ++it) + { + cbArrowCoordTwoMaps1.append_text(*it); + cbArrowCoordTwoMaps2.append_text(*it); + } + for (StrVec::const_iterator it = p_data->xy_node_map_names.begin(); + it != p_data->xy_node_map_names.end(); ++it) + { + cblueCoordOneMap.append_text(*it); + } + for (StrVec::const_iterator it = p_data->xy_arc_map_names.begin(); + it != p_data->xy_arc_map_names.end(); ++it) + { + cbArrowCoordOneMap.append_text(*it); + } + + if (p_data->isXYNodeMap("coord")) + { + cblueCoordOneMap.set_active_text("coord"); + } + else if (p_data->isXYNodeMap("coords")) + { + cblueCoordOneMap.set_active_text("coords"); + } + else if (p_data->isNodeMap("coord_x") && + p_data->isNodeMap("coord_y")) + { + cblueCoordTwoMaps1.set_active_text("coord_x"); + cblueCoordTwoMaps2.set_active_text("coord_y"); + } + else if (p_data->isNodeMap("coords_x") && + p_data->isNodeMap("coords_y")) + { + cblueCoordTwoMaps1.set_active_text("coords_x"); + cblueCoordTwoMaps2.set_active_text("coords_y"); + } + else if (p_data->isNodeMap("x") && + p_data->isNodeMap("y")) + { + cblueCoordTwoMaps1.set_active_text("x"); + cblueCoordTwoMaps2.set_active_text("y"); + } + + if (p_data->isXYArcMap("arrow")) + { + cbArrowCoordOneMap.set_active_text("arrow"); + } + else if (p_data->isXYArcMap("arrows")) + { + cbArrowCoordOneMap.set_active_text("arrows"); + } + else if (p_data->isXYArcMap("midpoint")) + { + cbArrowCoordOneMap.set_active_text("midpoint"); + } + else if (p_data->isXYArcMap("midpoints")) + { + cbArrowCoordOneMap.set_active_text("midpoints"); + } + else if (p_data->isXYArcMap("mid")) + { + cbArrowCoordOneMap.set_active_text("mid"); + } + else if (p_data->isXYArcMap("mids")) + { + cbArrowCoordOneMap.set_active_text("mids"); + } + else if (p_data->isArcMap("arrow_x") && + p_data->isArcMap("arrow_y")) + { + cbArrowCoordTwoMaps1.set_active_text("arrow_x"); + cbArrowCoordTwoMaps2.set_active_text("arrow_y"); + } + else if (p_data->isArcMap("arrows_x") && + p_data->isArcMap("arrows_y")) + { + cbArrowCoordTwoMaps1.set_active_text("arrows_x"); + cbArrowCoordTwoMaps2.set_active_text("arrows_y"); + } + else if (p_data->isArcMap("midpoint_x") && + p_data->isArcMap("midpoint_y")) + { + cbArrowCoordTwoMaps1.set_active_text("midpoint_x"); + cbArrowCoordTwoMaps2.set_active_text("midpoint_y"); + } + else if (p_data->isArcMap("midpoints_x") && + p_data->isArcMap("midpoints_y")) + { + cbArrowCoordTwoMaps1.set_active_text("midpoints_x"); + cbArrowCoordTwoMaps2.set_active_text("midpoints_y"); + } + else if (p_data->isArcMap("mid_x") && + p_data->isArcMap("mid_y")) + { + cbArrowCoordTwoMaps1.set_active_text("mid_x"); + cbArrowCoordTwoMaps2.set_active_text("mid_y"); + } + else if (p_data->isArcMap("mids_x") && + p_data->isArcMap("mids_y")) + { + cbArrowCoordTwoMaps1.set_active_text("mids_x"); + cbArrowCoordTwoMaps2.set_active_text("mids_y"); + } + + { + if (cblueCoordOneMap.get_active_text() != "") + rblueCoordOneMap.set_active(); + else if (cblueCoordTwoMaps1.get_active_text() != "") + rblueCoordTwoMaps.set_active(); + else + rblueCoordNone.set_active(); + + if (cbArrowCoordOneMap.get_active_text() != "") + rbArrowCoordOneMap.set_active(); + else if (cbArrowCoordTwoMaps1.get_active_text() != "") + rbArrowCoordTwoMaps.set_active(); + else + rbArrowCoordNone.set_active(); + + onNodeCoordMapNumToggled(); + onArrowCoordMapNumToggled(); + + rblueCoordOneMap.signal_toggled().connect( + sigc::mem_fun(*this, &FileImportDialog::onNodeCoordMapNumToggled)); + rblueCoordTwoMaps.signal_toggled().connect( + sigc::mem_fun(*this, &FileImportDialog::onNodeCoordMapNumToggled)); + rbArrowCoordOneMap.signal_toggled().connect( + sigc::mem_fun(*this, &FileImportDialog::onArrowCoordMapNumToggled)); + rbArrowCoordTwoMaps.signal_toggled().connect( + sigc::mem_fun(*this, &FileImportDialog::onArrowCoordMapNumToggled)); + } + + signal_response().connect( + sigc::mem_fun(*this, &FileImportDialog::onResponse)); + + update_node_tree_view(); + update_arc_tree_view(); + + show_all_children(); +} + +void FileImportDialog::onNodeCoordMapNumToggled() +{ + if (rblueCoordOneMap.get_active()) + { + cblueCoordOneMap.get_parent()->set_sensitive(true); + cblueCoordTwoMaps1.get_parent()->set_sensitive(false); + cblueCoordTwoMaps2.get_parent()->set_sensitive(false); + + p_data->node_coord_load_from = ImportData::ONE_MAP; + } + else if (rblueCoordTwoMaps.get_active()) + { + cblueCoordOneMap.get_parent()->set_sensitive(false); + cblueCoordTwoMaps1.get_parent()->set_sensitive(true); + cblueCoordTwoMaps2.get_parent()->set_sensitive(true); + + p_data->node_coord_load_from = ImportData::TWO_MAPS; + } + else if (rblueCoordNone.get_active()) + { + cblueCoordOneMap.get_parent()->set_sensitive(false); + cblueCoordTwoMaps1.get_parent()->set_sensitive(false); + cblueCoordTwoMaps2.get_parent()->set_sensitive(false); + + p_data->node_coord_load_from = ImportData::DONT_READ; + } + update_node_tree_view(); +} + +void FileImportDialog::onArrowCoordMapNumToggled() +{ + if (rbArrowCoordOneMap.get_active()) + { + cbArrowCoordOneMap.get_parent()->set_sensitive(true); + cbArrowCoordTwoMaps1.get_parent()->set_sensitive(false); + cbArrowCoordTwoMaps2.get_parent()->set_sensitive(false); + + p_data->arrow_coord_load_from = ImportData::ONE_MAP; + } + else if (rbArrowCoordTwoMaps.get_active()) + { + cbArrowCoordOneMap.get_parent()->set_sensitive(false); + cbArrowCoordTwoMaps1.get_parent()->set_sensitive(true); + cbArrowCoordTwoMaps2.get_parent()->set_sensitive(true); + + p_data->arrow_coord_load_from = ImportData::TWO_MAPS; + } + else if (rbArrowCoordNone.get_active()) + { + cbArrowCoordOneMap.get_parent()->set_sensitive(false); + cbArrowCoordTwoMaps1.get_parent()->set_sensitive(false); + cbArrowCoordTwoMaps2.get_parent()->set_sensitive(false); + + p_data->arrow_coord_load_from = ImportData::DONT_READ; + } + update_arc_tree_view(); +} + +FileImportDialog::~FileImportDialog() +{ +} + +void FileImportDialog::onResponse(int id) +{ + if (id == Gtk::RESPONSE_OK) + { + if ((rblueCoordOneMap.get_active() && + cblueCoordOneMap.get_active_text() == "") || + (rblueCoordTwoMaps.get_active() && + (cblueCoordTwoMaps1.get_active_text() == "" || + cblueCoordTwoMaps2.get_active_text() == ""))) + { + Gtk::MessageDialog mdialog("No node map selected.", + false, Gtk::MESSAGE_ERROR); + mdialog.run(); + return; + } + else if (rblueCoordTwoMaps.get_active() && + cblueCoordTwoMaps1.get_active_text() == + cblueCoordTwoMaps2.get_active_text()) + { + Gtk::MessageDialog mdialog( + "Same node map selected for both coordinates.", + false, Gtk::MESSAGE_ERROR); + mdialog.run(); + return; + } + if ((rbArrowCoordOneMap.get_active() && + cbArrowCoordOneMap.get_active_text() == "") || + (rbArrowCoordTwoMaps.get_active() && + (cbArrowCoordTwoMaps1.get_active_text() == "" || + cbArrowCoordTwoMaps2.get_active_text() == ""))) + { + Gtk::MessageDialog mdialog("No arc map selected.", + false, Gtk::MESSAGE_ERROR); + mdialog.run(); + return; + } + else if (rbArrowCoordTwoMaps.get_active() && + cbArrowCoordTwoMaps1.get_active_text() == + cbArrowCoordTwoMaps2.get_active_text()) + { + Gtk::MessageDialog mdialog( + "Same arc map selected for both coordinates.", + false, Gtk::MESSAGE_ERROR); + mdialog.run(); + return; + } + + for (std::vector::const_iterator it = + node_tree_view_records.begin(); it != node_tree_view_records.end(); + ++it) + { + if (it->visible) + { + if (it->numeric) + p_data->numeric_node_map_names.push_back(it->name); + if (it->string) + p_data->string_node_map_names.push_back(it->name); + } + } + + for (std::vector::const_iterator it = + arc_tree_view_records.begin(); it != arc_tree_view_records.end(); + ++it) + { + if (it->visible) + { + if (it->numeric) + p_data->numeric_arc_map_names.push_back(it->name); + if (it->string) + p_data->string_arc_map_names.push_back(it->name); + } + } + } +} + +FileImportDialog::ImportData::ImportData( + const std::vector& _node_map_names, + const std::vector& _arc_map_names) : + node_map_names(_node_map_names), + arc_map_names(_arc_map_names) +{ + typedef std::vector StrVec; + { + StrVec xMaps; + StrVec yMaps; + // collect map names ending with ":x" and ":y" + for (StrVec::const_iterator it = node_map_names.begin(); + it != node_map_names.end(); ++it) + { + if ((it->length() >= 3) && + (it->substr(it->length()-2, it->length()) == ":x")) + { + xMaps.push_back(it->substr(0, it->length()-2)); + } + if ((it->length() >= 3) && + (it->substr(it->length()-2, it->length()) == ":y")) + { + yMaps.push_back(it->substr(0, it->length()-2)); + } + } + + for (StrVec::const_iterator it1 = xMaps.begin(); + it1 != xMaps.end(); ++it1) + { + for (StrVec::const_iterator it2 = yMaps.begin(); + it2 != yMaps.end(); ++it2) + { + if (*it1 == *it2) xy_node_map_names.push_back(*it1); + } + } + } + { + StrVec xMaps; + StrVec yMaps; + // collect map names ending with ":x" and ":y" + for (StrVec::const_iterator it = arc_map_names.begin(); + it != arc_map_names.end(); ++it) + { + if ((it->length() >= 3) && + (it->substr(it->length()-2, it->length()) == ":x")) + { + xMaps.push_back(it->substr(0, it->length()-2)); + } + if ((it->length() >= 3) && + (it->substr(it->length()-2, it->length()) == ":y")) + { + yMaps.push_back(it->substr(0, it->length()-2)); + } + } + + for (StrVec::const_iterator it1 = xMaps.begin(); + it1 != xMaps.end(); ++it1) + { + for (StrVec::const_iterator it2 = yMaps.begin(); + it2 != yMaps.end(); ++it2) + { + if (*it1 == *it2) xy_arc_map_names.push_back(*it1); + } + } + } +} + +FileImportDialog::ImportData::~ImportData() +{ +} + +bool FileImportDialog::ImportData::isXYNodeMap(const std::string& name) +{ + if (isNodeMap(name + ":x") && isNodeMap(name + ":y")) return true; + return false; +} + +bool FileImportDialog::ImportData::isXYArcMap(const std::string& name) +{ + if (isArcMap(name + ":x") && isArcMap(name + ":y")) return true; + return false; +} + +bool FileImportDialog::ImportData::isNodeMap(const std::string& name) +{ + if (contains(node_map_names, name)) return true; + return false; +} + +bool FileImportDialog::ImportData::isArcMap(const std::string& name) +{ + if (contains(arc_map_names, name)) return true; + return false; +} + +bool FileImportDialog::ImportData::contains(const std::vector& vec, + const std::string& str) +{ + for (std::vector::const_iterator it = vec.begin(); + it != vec.end(); ++it) + { + if (*it == str) return true; + } + return false; +} + +void FileImportDialog::onNodeCoordOneMapChanged() +{ + p_data->node_coord_one_map_name = cblueCoordOneMap.get_active_text(); + update_node_tree_view(); +} + +void FileImportDialog::onNodeCoordTwoMaps1Changed() +{ + p_data->node_coord_two_maps_1_name = cblueCoordTwoMaps1.get_active_text(); + update_node_tree_view(); +} + +void FileImportDialog::onNodeCoordTwoMaps2Changed() +{ + p_data->node_coord_two_maps_2_name = cblueCoordTwoMaps2.get_active_text(); + update_node_tree_view(); +} + +void FileImportDialog::onArrowCoordOneMapChanged() +{ + p_data->arrow_coord_one_map_name = cbArrowCoordOneMap.get_active_text(); + update_arc_tree_view(); +} + +void FileImportDialog::onArrowCoordTwoMaps1Changed() +{ + p_data->arrow_coord_two_maps_1_name = cbArrowCoordTwoMaps1.get_active_text(); + update_arc_tree_view(); +} + +void FileImportDialog::onArrowCoordTwoMaps2Changed() +{ + p_data->arrow_coord_two_maps_2_name = cbArrowCoordTwoMaps2.get_active_text(); + update_arc_tree_view(); +} + +void FileImportDialog::onNodeMapNumericToggled(const Glib::ustring& path) +{ + Gtk::TreeModel::iterator iter = refNodeMapStore->get_iter( + Gtk::TreeModel::Path(path)); + Gtk::TreeModel::Row row = *iter; + std::vector::iterator it; + for (it = node_tree_view_records.begin(); + it != node_tree_view_records.end(); ++it) + { + if (it->name == row[NodeMapColumns.colName]) break; + } + if (row[NodeMapColumns.colReadAsNumeric]) + { + row[NodeMapColumns.colReadAsString] = false; + it->string = false; + it->numeric = true; + } +} + +void FileImportDialog::onNodeMapStringToggled(const Glib::ustring& path) +{ + Gtk::TreeModel::iterator iter = refNodeMapStore->get_iter( + Gtk::TreeModel::Path(path)); + Gtk::TreeModel::Row row = *iter; + std::vector::iterator it; + for (it = node_tree_view_records.begin(); + it != node_tree_view_records.end(); ++it) + { + if (it->name == row[NodeMapColumns.colName]) break; + } + if (row[NodeMapColumns.colReadAsString]) + { + row[NodeMapColumns.colReadAsNumeric] = false; + it->string = true; + it->numeric = false; + } +} + +void FileImportDialog::update_node_tree_view() +{ + for (std::vector::iterator it = + node_tree_view_records.begin(); it != node_tree_view_records.end(); ++it) + { + it->visible = true; + } + switch (p_data->node_coord_load_from) + { + case ImportData::ONE_MAP: + for (std::vector::iterator it = + node_tree_view_records.begin(); it != + node_tree_view_records.end(); ++it) + { + if (it->name == p_data->node_coord_one_map_name) + it->visible = false; + } + break; + case ImportData::TWO_MAPS: + for (std::vector::iterator it = + node_tree_view_records.begin(); it != + node_tree_view_records.end(); ++it) + { + if ((it->name == p_data->node_coord_two_maps_1_name) || + (it->name == p_data->node_coord_two_maps_2_name)) + it->visible = false; + } + break; + case ImportData::DONT_READ: + break; + } + refNodeMapStore->clear(); + for (std::vector::iterator it = + node_tree_view_records.begin(); it != node_tree_view_records.end(); ++it) + { + if (it->visible) + { + Gtk::TreeModel::Row row = *(refNodeMapStore->append()); + row[NodeMapColumns.colName] = it->name; + row[NodeMapColumns.colReadAsNumeric] = it->numeric; + row[NodeMapColumns.colReadAsString] = it->string; + } + } +} + +void FileImportDialog::onArcMapNumericToggled(const Glib::ustring& path) +{ + Gtk::TreeModel::iterator iter = refArcMapStore->get_iter( + Gtk::TreeModel::Path(path)); + Gtk::TreeModel::Row row = *iter; + std::vector::iterator it; + for (it = arc_tree_view_records.begin(); + it != arc_tree_view_records.end(); ++it) + { + if (it->name == row[ArcMapColumns.colName]) break; + } + if (row[ArcMapColumns.colReadAsNumeric]) + { + row[ArcMapColumns.colReadAsString] = false; + it->string = false; + it->numeric = true; + } +} + +void FileImportDialog::onArcMapStringToggled(const Glib::ustring& path) +{ + Gtk::TreeModel::iterator iter = refArcMapStore->get_iter( + Gtk::TreeModel::Path(path)); + Gtk::TreeModel::Row row = *iter; + std::vector::iterator it; + for (it = arc_tree_view_records.begin(); + it != arc_tree_view_records.end(); ++it) + { + if (it->name == row[ArcMapColumns.colName]) break; + } + if (row[ArcMapColumns.colReadAsString]) + { + row[ArcMapColumns.colReadAsNumeric] = false; + it->string = true; + it->numeric = false; + } +} + +void FileImportDialog::update_arc_tree_view() +{ + for (std::vector::iterator it = + arc_tree_view_records.begin(); it != arc_tree_view_records.end(); ++it) + { + it->visible = true; + } + switch (p_data->arrow_coord_load_from) + { + case ImportData::ONE_MAP: + for (std::vector::iterator it = + arc_tree_view_records.begin(); it != + arc_tree_view_records.end(); ++it) + { + if (it->name == p_data->arrow_coord_one_map_name) + it->visible = false; + } + break; + case ImportData::TWO_MAPS: + for (std::vector::iterator it = + arc_tree_view_records.begin(); it != + arc_tree_view_records.end(); ++it) + { + if ((it->name == p_data->arrow_coord_two_maps_1_name) || + (it->name == p_data->arrow_coord_two_maps_2_name)) + it->visible = false; + } + break; + case ImportData::DONT_READ: + break; + } + refArcMapStore->clear(); + for (std::vector::iterator it = + arc_tree_view_records.begin(); it != arc_tree_view_records.end(); ++it) + { + if (it->visible) + { + Gtk::TreeModel::Row row = *(refArcMapStore->append()); + row[ArcMapColumns.colName] = it->name; + row[ArcMapColumns.colReadAsNumeric] = it->numeric; + row[ArcMapColumns.colReadAsString] = it->string; + } + } +} diff -r 0e4f009eab8b -r 67188bd752db file_import_dialog.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/file_import_dialog.h Mon Jul 07 08:10:39 2008 -0500 @@ -0,0 +1,137 @@ +#ifndef FILE_IMPORT_DIALOG +#define FILE_IMPORT_DIALOG + +#include +#include +#include +#include +#include +#include +#include +#include + +class FileImportDialog : public Gtk::Dialog +{ + public: + struct ImportData + { + ImportData( + const std::vector& _node_map_names, + const std::vector& _arc_map_names); + + ~ImportData(); + + std::vector node_map_names; + std::vector arc_map_names; + + std::vector xy_node_map_names; + std::vector xy_arc_map_names; + + bool contains( + const std::vector& vec, + const std::string& str); + + std::string node_coord_one_map_name; + std::string node_coord_two_maps_1_name; + std::string node_coord_two_maps_2_name; + std::string arrow_coord_one_map_name; + std::string arrow_coord_two_maps_1_name; + std::string arrow_coord_two_maps_2_name; + + enum ReadOpts { ONE_MAP, TWO_MAPS, DONT_READ }; + ReadOpts node_coord_load_from; + ReadOpts arrow_coord_load_from; + + bool isXYNodeMap(const std::string& name); + bool isXYArcMap(const std::string& name); + bool isNodeMap(const std::string& name); + bool isArcMap(const std::string& name); + + std::vector numeric_node_map_names; + std::vector string_node_map_names; + std::vector numeric_arc_map_names; + std::vector string_arc_map_names; + }; + + ImportData* p_data; + + Gtk::RadioButton rblueCoordNone; + Gtk::RadioButton rblueCoordOneMap; + Gtk::RadioButton rblueCoordTwoMaps; + + Gtk::RadioButton rbArrowCoordNone; + Gtk::RadioButton rbArrowCoordOneMap; + Gtk::RadioButton rbArrowCoordTwoMaps; + + Gtk::ComboBoxText cblueCoordOneMap; + Gtk::ComboBoxText cblueCoordTwoMaps1; + Gtk::ComboBoxText cblueCoordTwoMaps2; + + Gtk::ComboBoxText cbArrowCoordOneMap; + Gtk::ComboBoxText cbArrowCoordTwoMaps1; + Gtk::ComboBoxText cbArrowCoordTwoMaps2; + + void onNodeCoordMapNumToggled(); + void onArrowCoordMapNumToggled(); + + void onResponse(int id); + + void onNodeCoordOneMapChanged(); + void onNodeCoordTwoMaps1Changed(); + void onNodeCoordTwoMaps2Changed(); + + void onArrowCoordOneMapChanged(); + void onArrowCoordTwoMaps1Changed(); + void onArrowCoordTwoMaps2Changed(); + + struct MapModelColumns : public Gtk::TreeModel::ColumnRecord + { + MapModelColumns() + { + add(colName); + add(colReadAsNumeric); + add(colReadAsString); + } + Gtk::TreeModelColumn colName; + Gtk::TreeModelColumn colReadAsNumeric; + Gtk::TreeModelColumn colReadAsString; + }; + + Gtk::TreeView twNodeMaps; + MapModelColumns NodeMapColumns; + Glib::RefPtr refNodeMapStore; + void onNodeMapNumericToggled(const Glib::ustring& path); + void onNodeMapStringToggled(const Glib::ustring& path); + + Gtk::TreeView twArcMaps; + MapModelColumns ArcMapColumns; + Glib::RefPtr refArcMapStore; + void onArcMapNumericToggled(const Glib::ustring& path); + void onArcMapStringToggled(const Glib::ustring& path); + + struct tree_view_record + { + tree_view_record(const std::string& _name, bool _numeric, bool _string, + bool _visible) : + name(_name), + numeric(_numeric), + string(_string), + visible(_visible) {} + std::string name; + bool numeric; + bool string; + bool visible; + }; + + std::vector node_tree_view_records; + void update_node_tree_view(); + + std::vector arc_tree_view_records; + void update_arc_tree_view(); + + public: + FileImportDialog(ImportData* d); + ~FileImportDialog(); +}; + +#endif diff -r 0e4f009eab8b -r 67188bd752db gdc-broken_edge.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gdc-broken_edge.cc Mon Jul 07 08:10:39 2008 -0500 @@ -0,0 +1,260 @@ +/* -*- C++ -*- + * + * This file is a part of LEMON, a generic C++ optimization library + * + * Copyright (C) 2003-2006 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#include +#include +#include +#include + +DigraphDisplayerCanvas::ArcBase::ArcBase(Gnome::Canvas::Group& _group, Arc _arc, DigraphDisplayerCanvas& _canvas) : + Gnome::Canvas::Group(_group), arc(_arc), canvas(_canvas), arrow(*this) +{ + arrow.property_fill_color().set_value("red"); + arrow.lower_to_bottom(); + lower_to_bottom(); +} + +DigraphDisplayerCanvas::ArcBase::~ArcBase() +{ +} + +void DigraphDisplayerCanvas::ArcBase::drawArrow(XY unit_vector_in_dir) +{ + MapStorage& ms = *canvas.mytab.mapstorage; + XY center(ms.getArrowCoords(arc)); + XY unit_norm_vector(0-unit_vector_in_dir.y, unit_vector_in_dir.x); + + // /\ // top + // / \ // + // - - // c(enter)l(eft), ccl, ccr, cr + // || // + // || // b(ottom)l, br + + double size=3; + + XY bl (center - unit_vector_in_dir * 3 * size + unit_norm_vector * size ); + XY br (center - unit_vector_in_dir * 3 * size - unit_norm_vector * size ); + XY ccl(center + unit_vector_in_dir * size + unit_norm_vector * size ); + XY ccr(center + unit_vector_in_dir * size - unit_norm_vector * size ); + XY cl (center + unit_vector_in_dir * size + unit_norm_vector * 2 * size ); + XY cr (center + unit_vector_in_dir * size - unit_norm_vector * 2 * size ); + XY top(center + unit_vector_in_dir * 3 * size); + + Gnome::Canvas::Points arrow_points; + arrow_points.push_back(Gnome::Art::Point( bl.x , bl.y ) ); + arrow_points.push_back(Gnome::Art::Point( br.x , br.y ) ); + arrow_points.push_back(Gnome::Art::Point( ccr.x, ccr.y ) ); + arrow_points.push_back(Gnome::Art::Point( cr.x , cr.y ) ); + arrow_points.push_back(Gnome::Art::Point( top.x, top.y ) ); + arrow_points.push_back(Gnome::Art::Point( cl.x , cl.y ) ); + arrow_points.push_back(Gnome::Art::Point( ccl.x, ccl.y ) ); + + arrow.property_points().set_value(arrow_points); +} + +DigraphDisplayerCanvas::BrokenArc::BrokenArc(Gnome::Canvas::Group & g, + Arc _arc, DigraphDisplayerCanvas & gc) : ArcBase(g, _arc, gc), + isbutton(false), line(*this) +{ + arrow.signal_event().connect(sigc::mem_fun(*this, &DigraphDisplayerCanvas::BrokenArc::arcFormerEventHandler)); + + line.property_fill_color().set_value("green"); + line.property_width_units().set_value(10); + line.lower_to_bottom(); + + draw(); +} + +DigraphDisplayerCanvas::BrokenArc::~BrokenArc() +{ +} + +void DigraphDisplayerCanvas::BrokenArc::draw() +{ + MapStorage& ms = *canvas.mytab.mapstorage; + + //calculating coordinates of the direction indicator arrow + XY head(ms.getNodeCoords(ms.digraph.target(arc))); + XY center(ms.getArrowCoords(arc)); + + XY unit_vector_in_dir(head-center); + double length=sqrt( unit_vector_in_dir.normSquare() ); + + if(length!=0) + { + unit_vector_in_dir/=length; + } + + // update the arrow + drawArrow(unit_vector_in_dir); + + // update the arc + Gnome::Canvas::Points points; + Node source = ms.digraph.source(arc); + Node target = ms.digraph.target(arc); + points.push_back(Gnome::Art::Point(ms.getNodeCoords(source).x, + ms.getNodeCoords(source).y)); + points.push_back(Gnome::Art::Point(ms.getArrowCoords(arc).x, + ms.getArrowCoords(arc).y)); + points.push_back(Gnome::Art::Point(ms.getNodeCoords(target).x, + ms.getNodeCoords(target).y)); + line.property_points().set_value(points); +} + +bool DigraphDisplayerCanvas::BrokenArc::arcFormerEventHandler(GdkEvent* e) +{ + switch(e->type) + { + case GDK_BUTTON_PRESS: + //we mark the location of the event to be able to calculate parameters + //of dragging + if(canvas.getActualTool()!=CREATE_NODE) + { + canvas.toggleArcActivity(this, true); + clicked_x=e->button.x; + clicked_y=e->button.y; + isbutton=true; + } + break; + case GDK_BUTTON_RELEASE: + if(canvas.getActualTool()!=CREATE_NODE) + { + canvas.toggleArcActivity(this, false); + isbutton=false; + } + break; + case GDK_MOTION_NOTIFY: + //we only have to do sg. if the mouse button is pressed + if(isbutton) + { + //new coordinates will be the old values, + //because the item will be moved to the + //new coordinate therefore the new movement + //has to be calculated from here + + double dx=e->motion.x-clicked_x; + double dy=e->motion.y-clicked_y; + + Gnome::Canvas::Points points_new; + + canvas.mytab.mapstorage->setArrowCoords(arc, canvas.mytab.mapstorage->getArrowCoords(arc) + XY(dx, dy)); + + draw(); + canvas.textReposition(canvas.mytab.mapstorage->getArrowCoords(arc)); + + clicked_x=e->motion.x; + clicked_y=e->motion.y; + + } + default: break; + } + + return true; +} + +void DigraphDisplayerCanvas::BrokenArc::setLineWidth(int w) +{ + line.property_width_units().set_value(w); +} + +void DigraphDisplayerCanvas::BrokenArc::setFillColor(Gdk::Color c) +{ + line.property_fill_color_gdk().set_value(c); +} + +DigraphDisplayerCanvas::LoopArc::LoopArc(Gnome::Canvas::Group& _group, + Arc _arc, DigraphDisplayerCanvas& _canvas) : + ArcBase(_group, _arc, _canvas), line(*this), isbutton(false) +{ + arrow.signal_event().connect(sigc::mem_fun(*this, &DigraphDisplayerCanvas::LoopArc::arcFormerEventHandler)); + + line.property_outline_color().set_value("green"); + line.property_width_units().set_value(10); + line.lower_to_bottom(); + + draw(); +} + +DigraphDisplayerCanvas::LoopArc::~LoopArc() +{ +} + +void DigraphDisplayerCanvas::LoopArc::draw() +{ + MapStorage& ms = *canvas.mytab.mapstorage; + + Node node = ms.digraph.source(arc); + XY center = (ms.getNodeCoords(node) + ms.getArrowCoords(arc)) / 2.0; + + XY unit_vector_in_dir(rot90(center - ms.getArrowCoords(arc))); + double length = sqrt(unit_vector_in_dir.normSquare()); + unit_vector_in_dir /= length; + + drawArrow(unit_vector_in_dir); + + double radius = + sqrt((ms.getArrowCoords(arc) - ms.getNodeCoords(node)).normSquare()) / 2.0; + + XY p1 = center + XY(-radius, radius); + XY p2 = center + XY( radius, -radius); + line.property_x1().set_value(p1.x); + line.property_y1().set_value(p1.y); + line.property_x2().set_value(p2.x); + line.property_y2().set_value(p2.y); +} + +void DigraphDisplayerCanvas::LoopArc::setLineWidth(int w) +{ + line.property_width_units().set_value(w); +} + +void DigraphDisplayerCanvas::LoopArc::setFillColor(Gdk::Color c) +{ + line.property_outline_color_gdk().set_value(c); +} + +bool DigraphDisplayerCanvas::LoopArc::arcFormerEventHandler(GdkEvent* e) +{ + switch(e->type) + { + case GDK_BUTTON_PRESS: + if(canvas.getActualTool()!=CREATE_NODE) + { + canvas.toggleArcActivity(this, true); + isbutton=true; + } + break; + case GDK_BUTTON_RELEASE: + if(canvas.getActualTool()!=CREATE_NODE) + { + canvas.toggleArcActivity(this, false); + isbutton=false; + } + break; + case GDK_MOTION_NOTIFY: + if(isbutton) + { + canvas.mytab.mapstorage->setArrowCoords(arc, XY(e->motion.x, e->motion.y)); + + draw(); + canvas.textReposition(canvas.mytab.mapstorage->getArrowCoords(arc)); + } + default: break; + } + return true; +} diff -r 0e4f009eab8b -r 67188bd752db gettext.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gettext.h Mon Jul 07 08:10:39 2008 -0500 @@ -0,0 +1,79 @@ +/* Convenience header for conditional use of GNU . + Copyright (C) 1995-1998, 2000-2002, 2004 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU Library General Public License as published + by the Free Software Foundation; either version 2, 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + USA. */ + +#ifndef _LIBGETTEXT_H +#define _LIBGETTEXT_H 1 + +/* NLS can be disabled through the configure --disable-nls option. */ +#if ENABLE_NLS + +/* Get declarations of GNU message catalog functions. */ +# include + +#else + +/* Solaris /usr/include/locale.h includes /usr/include/libintl.h, which + chokes if dcgettext is defined as a macro. So include it now, to make + later inclusions of a NOP. We don't include + as well because people using "gettext.h" will not include , + and also including would fail on SunOS 4, whereas + is OK. */ +#if defined(__sun) +# include +#endif + +/* Many header files from the libstdc++ coming with g++ 3.3 or newer include + , which chokes if dcgettext is defined as a macro. So include + it now, to make later inclusions of a NOP. */ +#if defined(__cplusplus) && defined(__GNUG__) && (__GNUC__ >= 3) +# include +# if (__GLIBC__ >= 2) || _GLIBCXX_HAVE_LIBINTL_H +# include +# endif +#endif + +/* Disabled NLS. + The casts to 'const char *' serve the purpose of producing warnings + for invalid uses of the value returned from these functions. + On pre-ANSI systems without 'const', the config.h file is supposed to + contain "#define const". */ +# define gettext(Msgid) ((const char *) (Msgid)) +# define dgettext(Domainname, Msgid) ((const char *) (Msgid)) +# define dcgettext(Domainname, Msgid, Category) ((const char *) (Msgid)) +# define ngettext(Msgid1, Msgid2, N) \ + ((N) == 1 ? (const char *) (Msgid1) : (const char *) (Msgid2)) +# define dngettext(Domainname, Msgid1, Msgid2, N) \ + ((N) == 1 ? (const char *) (Msgid1) : (const char *) (Msgid2)) +# define dcngettext(Domainname, Msgid1, Msgid2, N, Category) \ + ((N) == 1 ? (const char *) (Msgid1) : (const char *) (Msgid2)) +# define textdomain(Domainname) ((const char *) (Domainname)) +# define bindtextdomain(Domainname, Dirname) ((const char *) (Dirname)) +# define bind_textdomain_codeset(Domainname, Codeset) ((const char *) (Codeset)) + +#endif + +/* A pseudo function call that serves as a marker for the automated + extraction of messages, but does not call gettext(). The run-time + translation is done at a different place in the code. + The argument, String, should be a literal string. Concatenated strings + and other string expressions won't work. + The macro's expansion is not parenthesized, so that it is suitable as + initializer for static 'char[]' or 'const char[]' variables. */ +#define gettext_noop(String) String + +#endif /* _LIBGETTEXT_H */ diff -r 0e4f009eab8b -r 67188bd752db glemon.spec.in --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/glemon.spec.in Mon Jul 07 08:10:39 2008 -0500 @@ -0,0 +1,42 @@ +Summary: A graph editor for the LEMON Graph Format +Name: @PACKAGE_TARNAME@ +Version: @PACKAGE_VERSION@ +Release: 1 +License: Boost +URL: http://lemon.cs.elte.hu +Source0: %{name}-%{version}.tar.gz +Group: Development/Libraries +BuildRoot: %{_tmppath}/%{name}-root +Requires: lemon +Requires: gtkmm24 >= 2.6 +Requires: libgnomecanvasmm >= 2.6.0 +BuildRequires: lemon-devel +BuildRequires: gtkmm24-devel >= 2.6 +BuildRequires: libgnomecanvasmm-devel >= 2.6.0 + +%description +glemon is a graphical editor for the LEMON Graph Format (.lgf) + +%prep +%setup -q + +%build +%configure +make + +%install +rm -rf $RPM_BUILD_ROOT +make DESTDIR=$RPM_BUILD_ROOT install + +%clean +rm -rf $RPM_BUILD_ROOT + +%post -p /sbin/ldconfig + +%postun -p /sbin/ldconfig + +%files +%defattr(-,root,root) +%{_bindir}/glemon +%{_datadir}/locale +%doc AUTHORS COPYING LICENSE NEWS README diff -r 0e4f009eab8b -r 67188bd752db graph-displayer.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graph-displayer.cc Mon Jul 07 08:10:39 2008 -0500 @@ -0,0 +1,115 @@ +/* -*- C++ -*- + * + * This file is a part of LEMON, a generic C++ optimization library + * + * Copyright (C) 2003-2006 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include "all_include.h" +#include "main_win.h" +#include +#include + +#include + +#define MAIN_PART + +std::vector arc_property_strings; +std::vector arc_property_defaults; +std::vector node_property_strings; +std::vector node_property_defaults; +int longest_property_string_length; + +int main(int argc, char *argv[]) +{ + setlocale(LC_ALL, ""); + bindtextdomain(PACKAGE, LOCALEDIR); + bind_textdomain_codeset(PACKAGE, "UTF-8"); + textdomain(PACKAGE); + + //initializing + + arc_property_strings.resize(EDGE_PROPERTY_NUM); + arc_property_strings[E_WIDTH]="Arc Width"; + arc_property_strings[E_COLOR]="Arc Color"; + arc_property_strings[E_TEXT]="Arc Text"; + + arc_property_defaults.resize(EDGE_PROPERTY_NUM); + arc_property_defaults[E_WIDTH]=10.0; + arc_property_defaults[E_COLOR]=100; + arc_property_defaults[E_TEXT]=0; + + node_property_strings.resize(NODE_PROPERTY_NUM); + node_property_strings[N_RADIUS]="Node Radius"; + node_property_strings[N_COLOR]="Node Color"; + node_property_strings[N_TEXT]="Node Text"; + + node_property_defaults.resize(NODE_PROPERTY_NUM); + node_property_defaults[N_RADIUS]=20.0; + node_property_defaults[N_COLOR]=100; + node_property_defaults[N_TEXT]=0; + + longest_property_string_length=0; + for(int i=0;ilongest_property_string_length) + { + longest_property_string_length=j; + } + } + for(int i=0;ilongest_property_string_length) + { + longest_property_string_length=j; + } + } + + + //initializing GUI + + Gnome::Canvas::init(); + Gtk::Main app(argc, argv); + + MainWin mytab; + +// if ((argc == 2) && (Glib::file_test(argv[1], Glib::FILE_TEST_IS_REGULAR))) +// { +// mytab.readFile(argv[1]); +// } + if(argc>=2) + { + for(int i=1;i +#include +#include +#include + +const int minimum_arc_width=0; + +int DigraphDisplayerCanvas::resetArcWidth (Arc arc) +{ + MapStorage& ms = *mytab.mapstorage; + double min, max; + + min=arc_property_defaults[E_WIDTH]; + max=arc_property_defaults[E_WIDTH]; + Digraph::ArcMap actual_map(ms.digraph,arc_property_defaults[E_WIDTH]); + + if(arc==INVALID) + { + for (ArcIt i(ms.digraph); i!=INVALID; ++i) + { + double v=fabs(actual_map[i]); + int w; + if(min==max) + { + w=(int)(arc_property_defaults[E_WIDTH]); + } + else + { + w=(int)(MIN_EDGE_WIDTH+(v-min)/(max-min)*(MAX_EDGE_WIDTH-MIN_EDGE_WIDTH)); + } + if(zoomtrack) + { + double actual_ppu=get_pixels_per_unit(); + w=(int)(w/actual_ppu*fixed_zoom_factor); + } + arcsmap[i]->setLineWidth(w); + } + } + else + { + int w=(int)actual_map[arc]; + if(w>=0) + { + arcsmap[arc]->setLineWidth(w); + } + } + return 0; +} + + +int DigraphDisplayerCanvas::changeArcWidth (std::string mapname, Arc arc) +{ + MapStorage& ms = *mytab.mapstorage; + double min, max; + + { + ArcIt e(ms.digraph); + min = max = ms.get(mapname, e); + for (; e != INVALID; ++e) + { + if (static_cast(ms.get(mapname, e)) > max) + max = ms.get(mapname, e); + if (static_cast(ms.get(mapname, e)) < min) + min = ms.get(mapname, e); + } + } + + if(arc==INVALID) + { + for (ArcIt i(ms.digraph); i!=INVALID; ++i) + { + double v=ms.get(mapname, i); + int w; + if(autoscale) + { + if(min==max) + { + w=(int)(arc_property_defaults[E_WIDTH]); + } + else + { + w=(int)(minimum_arc_width+(v-min)/(max-min)*(arc_width-minimum_arc_width)); + } + } + else + { + w=(int)(v*arc_width); + } + if(w<0) + { + arcsmap[i]->hide(); + } + else + { + arcsmap[i]->show(); + if(wsetLineWidth(w); + } + } + } + else + { + int w=(int)ms.get(mapname, arc); + if(w>=0) + { + arcsmap[arc]->setLineWidth(w); + } + } + return 0; +}; + +int DigraphDisplayerCanvas::changeArcColor (std::string mapname, Arc arc) +{ + MapStorage& ms = *mytab.mapstorage; + + //function maps the range of the maximum and + //the minimum of the nodemap to the range of + //green in RGB + + double max, min; + + { + ArcIt e(ms.digraph); + min = max = ms.get(mapname, e); + for (; e != INVALID; ++e) + { + if (static_cast(ms.get(mapname, e)) > max) + max = ms.get(mapname, e); + if (static_cast(ms.get(mapname, e)) < min) + min = ms.get(mapname, e); + } + } + + if(arc==INVALID) + { + for (ArcIt i(ms.digraph); i!=INVALID; ++i) + { + double w=ms.get(mapname, i); + + Gdk::Color color; + if(max!=min) + { + color=rainbowColorCounter(min, max, w); + } + else + { + color.set_rgb_p (0, 1, 0); + } + arcsmap[i]->setFillColor(color); + } + } + else + { + Gdk::Color color; + + double w=ms.get(mapname, arc); + + if(max!=min) + { + color=rainbowColorCounter(min, max, w); + } + else + { + color.set_rgb_p (0, 1, 0); + } + + arcsmap[arc]->setFillColor(color); + } + return 0; +}; + +int DigraphDisplayerCanvas::resetArcColor (Arc arc) +{ + MapStorage& ms = *mytab.mapstorage; + + //function maps the range of the maximum and + //the minimum of the nodemap to the range of + //green in RGB + Digraph::ArcMap actual_map(ms.digraph,arc_property_defaults[E_COLOR]); + + double max, min; + + max=arc_property_defaults[E_COLOR]; + min=arc_property_defaults[E_COLOR]; + + if(arc==INVALID) + { + for (ArcIt i(ms.digraph); i!=INVALID; ++i) + { + double w=actual_map[i]; + + Gdk::Color color; + if(max!=min) + { + color.set_rgb_p (0, 100*(w-min)/(max-min), 0); + } + else + { + color.set_rgb_p (0, 100, 0); + } + arcsmap[i]->setFillColor(color); + } + } + else + { + Gdk::Color color; + + double w=actual_map[arc]; + + if(max!=min) + { + color.set_rgb_p (0, 100*(w-min)/(max-min), 0); + } + else + { + color.set_rgb_p (0, 100, 0); + } + + arcsmap[arc]->setFillColor(color); + } + return 0; +}; + +int DigraphDisplayerCanvas::changeArcText (std::string mapname, Arc arc) +{ + MapStorage& ms = *mytab.mapstorage; + + //the number in the map will be written on the arc + //EXCEPT when the name of the map is Default, because + //in that case empty string will be written, because + //that is the deleter map + + if(arc==INVALID) + { + for (ArcIt i(ms.digraph); i!=INVALID; ++i) + { + arcmap_to_edit=mapname; + + arctextmap[i]->property_text().set_value( + static_cast(ms.get(mapname, i))); + } + + } + else + { + arctextmap[arc]->property_text().set_value( + static_cast(ms.get(mapname, arc))); + } + + return 0; +}; + +int DigraphDisplayerCanvas::resetArcText (Arc arc) +{ + MapStorage& ms = *mytab.mapstorage; + + //the number in the map will be written on the arc + //EXCEPT when the name of the map is Default, because + //in that case empty string will be written, because + //that is the deleter map + + if(arc==INVALID) + { + for (ArcIt i(ms.digraph); i!=INVALID; ++i) + { + arcmap_to_edit=""; + arctextmap[i]->property_text().set_value(""); + } + } + else + { + arctextmap[arc]->property_text().set_value(""); + } + + return 0; +}; diff -r 0e4f009eab8b -r 67188bd752db graph_displayer_canvas-event.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graph_displayer_canvas-event.cc Mon Jul 07 08:10:39 2008 -0500 @@ -0,0 +1,967 @@ +/* -*- C++ -*- + * + * This file is a part of LEMON, a generic C++ optimization library + * + * Copyright (C) 2003-2006 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#include +#include +#include +#include +#include + +bool DigraphDisplayerCanvas::on_expose_event(GdkEventExpose *event) +{ + Gnome::Canvas::CanvasAA::on_expose_event(event); + //usleep(10000); + //rezoom(); + return true; +} + +void DigraphDisplayerCanvas::changeEditorialTool(int newtool) +{ + if(actual_tool!=newtool) + { + + actual_handler.disconnect(); + + switch(actual_tool) + { + case CREATE_EDGE: + { + GdkEvent * generated=new GdkEvent(); + generated->type=GDK_BUTTON_RELEASE; + generated->button.button=3; + createArcEventHandler(generated); + break; + } + case MAP_EDIT: + { + break; + } + default: + break; + } + + active_item=NULL; + target_item=NULL; + active_arc=INVALID; + active_node=INVALID; + + + actual_tool=newtool; + + switch(newtool) + { + case MOVE: + actual_handler=signal_event().connect(sigc::mem_fun(*this, &DigraphDisplayerCanvas::moveEventHandler), false); + break; + + case CREATE_NODE: + actual_handler=signal_event().connect(sigc::mem_fun(*this, &DigraphDisplayerCanvas::createNodeEventHandler), false); + break; + + case CREATE_EDGE: + actual_handler=signal_event().connect(sigc::mem_fun(*this, &DigraphDisplayerCanvas::createArcEventHandler), false); + break; + + case ERASER: + actual_handler=signal_event().connect(sigc::mem_fun(*this, &DigraphDisplayerCanvas::eraserEventHandler), false); + break; + + case MAP_EDIT: + grab_focus(); + actual_handler=signal_event().connect(sigc::mem_fun(*this, &DigraphDisplayerCanvas::mapEditEventHandler), false); + break; + + default: + break; + } + } +} + +int DigraphDisplayerCanvas::getActualTool() +{ + return actual_tool; +} + +bool DigraphDisplayerCanvas::scrollEventHandler(GdkEvent* e) +{ + bool handled=false; + if(e->type==GDK_SCROLL) + { + + //pointer shows this win point before zoom + XY win_coord(((GdkEventScroll*)e)->x, ((GdkEventScroll*)e)->y); + + //the original scroll settings + int scroll_offset_x, scroll_offset_y; + get_scroll_offsets(scroll_offset_x, scroll_offset_y); + + //pointer shows this canvas point before zoom + XY canvas_coord; + window_to_world(win_coord.x, win_coord.y, canvas_coord.x, canvas_coord.y); + + if(((GdkEventScroll*)e)->direction) //IN + { + zoomIn(); + } + else + { + zoomOut(); + } + + //pointer shows this window point after zoom + XY post_win_coord; + world_to_window(canvas_coord.x, canvas_coord.y, post_win_coord.x, post_win_coord.y); + + //we have to add the difference between new and old window point to original scroll offset + scroll_to(scroll_offset_x+(int)(post_win_coord.x-win_coord.x),scroll_offset_y+(int)(post_win_coord.y-win_coord.y)); + + //no other eventhandler is needed + handled=true; + } + return handled; +} + +bool DigraphDisplayerCanvas::moveEventHandler(GdkEvent* e) +{ + MapStorage& ms = *mytab.mapstorage; + + static Gnome::Canvas::Text *coord_text = 0; + switch(e->type) + { + case GDK_BUTTON_PRESS: + //we mark the location of the event to be able to calculate parameters of dragging + window_to_world (e->button.x, e->button.y, clicked_x, clicked_y); + + active_item=(get_item_at(clicked_x, clicked_y)); + active_node=INVALID; + for (NodeIt i(ms.digraph); i!=INVALID; ++i) + { + if(nodesmap[i]==active_item) + { + active_node=i; + } + } + isbutton=e->button.button; + break; + case GDK_BUTTON_RELEASE: + if (coord_text) + { + delete coord_text; + coord_text = 0; + } + isbutton=0; + active_item=NULL; + active_node=INVALID; + break; + case GDK_MOTION_NOTIFY: + //we only have to do sg. if the mouse button is pressed AND the click was on a node that was found in the set of nodes + if(active_node!=INVALID) + { + ms.setModified(); + + //new coordinates will be the old values, + //because the item will be moved to the + //new coordinate therefore the new movement + //has to be calculated from here + + double new_x, new_y; + + window_to_world (e->motion.x, e->motion.y, new_x, new_y); + + double dx=new_x-clicked_x; + double dy=new_y-clicked_y; + + moveNode(dx, dy); + + clicked_x=new_x; + clicked_y=new_y; + + // reposition the coordinates text + std::ostringstream ostr; + ostr << "(" << + ms.getNodeCoords(active_node).x << ", " << + ms.getNodeCoords(active_node).y << ")"; + double radius = + (nodesmap[active_node]->property_x2().get_value() - + nodesmap[active_node]->property_x1().get_value()) / 2.0; + if (coord_text) + { + coord_text->property_text().set_value(ostr.str()); + coord_text->property_x().set_value( + ms.getNodeCoords(active_node).x + radius); + coord_text->property_y().set_value( + ms.getNodeCoords(active_node).y - radius); + } + else + { + coord_text = new Gnome::Canvas::Text( + displayed_graph, + ms.getNodeCoords(active_node).x + radius, + ms.getNodeCoords(active_node).y - radius, + ostr.str()); + coord_text->property_fill_color().set_value("black"); + coord_text->property_anchor().set_value(Gtk::ANCHOR_SOUTH_WEST); + } + + + } + default: break; + } + + return false; +} + +XY DigraphDisplayerCanvas::calcArrowPos(XY moved_node_1, XY moved_node_2, XY fix_node, XY old_arrow_pos, int move_code) +{ + switch(move_code) + { + case 1: + return XY((moved_node_2.x + fix_node.x) / 2.0, (moved_node_2.y + fix_node.y) / 2.0); + break; + case 2: + return old_arrow_pos; + break; + case 3: + { + ////////////////////////////////////////////////////////////////////////////////////////////////////// + /////////// keeps shape-with scalar multiplication - version 2. + ////////////////////////////////////////////////////////////////////////////////////////////////////// + + //old vector from one to the other node - a + XY a_v(moved_node_1.x-fix_node.x,moved_node_1.y-fix_node.y); + //new vector from one to the other node - b + XY b_v(moved_node_2.x-fix_node.x,moved_node_2.y-fix_node.y); + + double absa=sqrt(a_v.normSquare()); + double absb=sqrt(b_v.normSquare()); + + if ((absa == 0.0) || (absb == 0.0)) + { + return old_arrow_pos; + } + else + { + //old vector from one node to the breakpoint - c + XY c_v(old_arrow_pos.x-fix_node.x,old_arrow_pos.y-fix_node.y); + + //unit vector with the same direction to a_v + XY a_v_u(a_v.x/absa,a_v.y/absa); + + //normal vector of unit vector with the same direction to a_v + XY a_v_u_n(((-1)*a_v_u.y),a_v_u.x); + + //unit vector with the same direction to b_v + XY b_v_u(b_v.x/absb,b_v.y/absb); + + //normal vector of unit vector with the same direction to b_v + XY b_v_u_n(((-1)*b_v_u.y),b_v_u.x); + + //vector c in a_v_u and a_v_u_n co-ordinate system + XY c_a(c_v*a_v_u,c_v*a_v_u_n); + + //new vector from one node to the breakpoint - d - we have to calculate this one + XY d_v=absb/absa*(c_a.x*b_v_u+c_a.y*b_v_u_n); + + return XY(d_v.x+fix_node.x,d_v.y+fix_node.y); + } + break; + } + default: + break; + } +} + + +bool DigraphDisplayerCanvas::createNodeEventHandler(GdkEvent* e) +{ + MapStorage& ms = *mytab.mapstorage; + + switch(e->type) + { + //move the new node + case GDK_MOTION_NOTIFY: + { + GdkEvent * generated=new GdkEvent(); + generated->motion.x=e->motion.x; + generated->motion.y=e->motion.y; + generated->type=GDK_MOTION_NOTIFY; + moveEventHandler(generated); + break; + } + + case GDK_BUTTON_RELEASE: + ms.setModified(); + + is_drawn=true; + + isbutton=1; + + window_to_world (e->button.x, e->button.y, clicked_x, clicked_y); + + active_node = ms.addNode(XY(clicked_x, clicked_y)); + + nodesmap[active_node]=new Gnome::Canvas::Ellipse(displayed_graph, + clicked_x-20, clicked_y-20, clicked_x+20, clicked_y+20); + active_item=(Gnome::Canvas::Item *)(nodesmap[active_node]); + *(nodesmap[active_node]) << + Gnome::Canvas::Properties::fill_color("blue"); + *(nodesmap[active_node]) << + Gnome::Canvas::Properties::outline_color("black"); + active_item->raise_to_top(); + + (nodesmap[active_node])->show(); + + nodetextmap[active_node]=new Gnome::Canvas::Text(displayed_graph, + clicked_x+node_property_defaults[N_RADIUS]+5, + clicked_y+node_property_defaults[N_RADIUS]+5, ""); + nodetextmap[active_node]->property_fill_color().set_value("darkblue"); + nodetextmap[active_node]->raise_to_top(); + + // mapwin.updateNode(active_node); + propertyUpdate(active_node); + + isbutton=0; + target_item=NULL; + active_item=NULL; + active_node=INVALID; + break; + default: + break; + } + return false; +} + +bool DigraphDisplayerCanvas::createArcEventHandler(GdkEvent* e) +{ + MapStorage& ms = *mytab.mapstorage; + + switch(e->type) + { + case GDK_BUTTON_PRESS: + //in arc creation right button has special meaning + if(e->button.button!=3) + { + //there is not yet selected node + if(active_node==INVALID) + { + //we mark the location of the event to be able to calculate parameters of dragging + + window_to_world (e->button.x, e->button.y, clicked_x, clicked_y); + + active_item=(get_item_at(clicked_x, clicked_y)); + active_node=INVALID; + for (NodeIt i(ms.digraph); i!=INVALID; ++i) + { + if(nodesmap[i]==active_item) + { + active_node=i; + } + } + //the clicked item is really a node + if(active_node!=INVALID) + { + *(nodesmap[active_node]) << Gnome::Canvas::Properties::fill_color("red"); + isbutton=1; + } + //clicked item was not a node. It could be e.g. arc. + else + { + active_item=NULL; + } + } + //we only have to do sg. if the mouse button + // is pressed already once AND the click was + // on a node that was found in the set of + //nodes, and now we only search for the second + //node + else + { + window_to_world (e->button.x, e->button.y, clicked_x, clicked_y); + target_item=(get_item_at(clicked_x, clicked_y)); + Node target_node=INVALID; + for (NodeIt i(ms.digraph); i!=INVALID; ++i) + { + if(nodesmap[i]==target_item) + { + target_node=i; + } + } + //the clicked item is a node, the arc can be drawn + if(target_node!=INVALID) + { + ms.setModified(); + + *(nodesmap[target_node]) << + Gnome::Canvas::Properties::fill_color("red"); + + active_arc = ms.addArc(active_node, target_node); + + if(target_node!=active_node) + { + arcsmap[active_arc]=new BrokenArc(displayed_graph, active_arc, *this); + } + else + { + arcsmap[active_arc]=new LoopArc(displayed_graph, active_arc, *this); + } + + //initializing arc-text as well, to empty string + XY text_pos=ms.getArrowCoords(active_arc); + text_pos+=(XY(10,10)); + + arctextmap[active_arc]=new Gnome::Canvas::Text(displayed_graph, + text_pos.x, text_pos.y, ""); + arctextmap[active_arc]->property_fill_color().set_value( + "darkgreen"); + arctextmap[active_arc]->raise_to_top(); + + propertyUpdate(active_arc); + } + //clicked item was not a node. it could be an e.g. arc. we do not + //deal with it furthermore. + else + { + target_item=NULL; + } + } + } + break; + case GDK_BUTTON_RELEASE: + isbutton=0; + //we clear settings in two cases + //1: the arc is ready (target_item has valid value) + //2: the arc creation is cancelled with right button + if((target_item)||(e->button.button==3)) + { + if(active_item) + { + propertyUpdate(active_node,N_COLOR); + active_item=NULL; + } + if(target_item) + { + propertyUpdate(ms.digraph.target(active_arc),N_COLOR); + target_item=NULL; + } + active_node=INVALID; + active_arc=INVALID; + } + break; + default: + break; + } + return false; +} + +bool DigraphDisplayerCanvas::eraserEventHandler(GdkEvent* e) +{ + MapStorage& ms = *mytab.mapstorage; + + switch(e->type) + { + case GDK_BUTTON_PRESS: + //finding the clicked items + window_to_world (e->button.x, e->button.y, clicked_x, clicked_y); + active_item=(get_item_at(clicked_x, clicked_y)); + active_node=INVALID; + active_arc=INVALID; + //was it a node? + for (NodeIt i(ms.digraph); i!=INVALID; ++i) + { + if(nodesmap[i]==active_item) + { + active_node=i; + } + } + //or was it an arc? + if(active_node==INVALID) + { + for (ArcIt i(ms.digraph); i!=INVALID; ++i) + { + if(arcsmap[i]->getLine()==active_item) + { + active_arc=i; + } + } + } + + // return if the clicked object is neither an arc nor a node + if (active_arc == INVALID) return false; + + //recolor activated item + if(active_item) + { + *active_item << Gnome::Canvas::Properties::fill_color("red"); + } + break; + + case GDK_BUTTON_RELEASE: + window_to_world (e->button.x, e->button.y, clicked_x, clicked_y); + if(active_item) + { + //the cursor was not moved since pressing it + if( active_item == ( get_item_at (clicked_x, clicked_y) ) ) + { + //a node was found + if(active_node!=INVALID) + { + ms.setModified(); + + std::set arcs_to_delete; + + for(OutArcIt e(ms.digraph,active_node);e!=INVALID;++e) + { + arcs_to_delete.insert(e); + } + + for(InArcIt e(ms.digraph,active_node);e!=INVALID;++e) + { + arcs_to_delete.insert(e); + } + + //deleting collected arcs + for(std::set::iterator + arc_set_it=arcs_to_delete.begin(); + arc_set_it!=arcs_to_delete.end(); + ++arc_set_it) + { + deleteItem(*arc_set_it); + } + deleteItem(active_node); + } + //a simple arc was chosen + else if (active_arc != INVALID) + { + deleteItem(active_arc); + } + } + //pointer was moved, deletion is cancelled + else + { + if(active_node!=INVALID) + { + *active_item << Gnome::Canvas::Properties::fill_color("blue"); + } + else if (active_arc != INVALID) + { + *active_item << Gnome::Canvas::Properties::fill_color("green"); + } + } + } + //reseting datas + active_item=NULL; + active_arc=INVALID; + active_node=INVALID; + break; + + case GDK_MOTION_NOTIFY: + break; + + default: + break; + } + return false; +} + +bool DigraphDisplayerCanvas::mapEditEventHandler(GdkEvent* e) +{ + MapStorage& ms = *mytab.mapstorage; + + if(actual_tool==MAP_EDIT) + { + switch(e->type) + { + case GDK_BUTTON_PRESS: + { + //for determine, whether it was an arc + Arc clicked_arc=INVALID; + //for determine, whether it was a node + Node clicked_node=INVALID; + + window_to_world (e->button.x, e->button.y, clicked_x, clicked_y); + active_item=(get_item_at(clicked_x, clicked_y)); + + //find the activated item between text of nodes + for (NodeIt i(ms.digraph); i!=INVALID; ++i) + { + //at the same time only one can be active + if(nodetextmap[i]==active_item) + { + clicked_node=i; + } + } + + //if there was not, search for it between nodes + if(clicked_node==INVALID) + { + for (NodeIt i(ms.digraph); i!=INVALID; ++i) + { + //at the same time only one can be active + if(nodesmap[i]==active_item) + { + clicked_node=i; + } + } + } + + if(clicked_node==INVALID) + { + //find the activated item between texts + for (ArcIt i(ms.digraph); i!=INVALID; ++i) + { + //at the same time only one can be active + if(arctextmap[i]==active_item) + { + clicked_arc=i; + } + } + + //if it was not between texts, search for it between arcs + if(clicked_arc==INVALID) + { + for (ArcIt i(ms.digraph); i!=INVALID; ++i) + { + //at the same time only one can be active + if((arcsmap[i]->getLine())==active_item) + { + clicked_arc=i; + } + } + } + } + + //if it was really a node... + if(clicked_node!=INVALID) + { + // the id map is not editable + if (nodemap_to_edit == "label") return 0; + + //and there is activated map + if(nodetextmap[clicked_node]->property_text().get_value()!="") + { + //activate the general variable for it + active_node=clicked_node; + + //create a dialog + Gtk::Dialog dialog("Edit value", true); + dialog.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL); + dialog.add_button(Gtk::Stock::OK, Gtk::RESPONSE_ACCEPT); + Gtk::VBox* vbox = dialog.get_vbox(); + + /* + Gtk::SpinButton spin(0.0, 4); + spin.set_increments(1.0, 10.0); + spin.set_range(-1000000.0, 1000000.0); + spin.set_numeric(true); + spin.set_value(atof(nodetextmap[active_node]->property_text().get_value().c_str())); + vbox->add(spin); + spin.show(); + */ + Gtk::Entry entry; + entry.set_text(nodetextmap[active_node]->property_text().get_value()); + vbox->add(entry); + entry.show(); + + switch (dialog.run()) + { + case Gtk::RESPONSE_NONE: + case Gtk::RESPONSE_CANCEL: + break; + case Gtk::RESPONSE_ACCEPT: + switch (ms.getNodeMapElementType(nodemap_to_edit)) + { + case MapValue::NUMERIC: + ms.set(nodemap_to_edit, active_node, + atof(entry.get_text().c_str())); + break; + case MapValue::STRING: + ms.set(nodemap_to_edit, active_node, + static_cast(entry.get_text())); + break; + } + nodetextmap[active_node]->property_text().set_value( + static_cast(ms.get(nodemap_to_edit, active_node))); + + //mapwin.updateNode(active_node); + //mapwin.updateNode(Node(INVALID)); + propertyUpdate(Node(INVALID)); + } + } + } + else + //if it was really an arc... + if(clicked_arc!=INVALID) + { + // the id map is not editable + if (arcmap_to_edit == "label") return 0; + + //and there is activated map + if(arctextmap[clicked_arc]->property_text().get_value()!="") + { + //activate the general variable for it + active_arc=clicked_arc; + + //create a dialog + Gtk::Dialog dialog("Edit value", true); + dialog.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL); + dialog.add_button(Gtk::Stock::OK, Gtk::RESPONSE_ACCEPT); + Gtk::VBox* vbox = dialog.get_vbox(); + + /* + Gtk::SpinButton spin(0.0, 4); + spin.set_increments(1.0, 10.0); + spin.set_range(-1000000.0, 1000000.0); + spin.set_numeric(true); + spin.set_value(atof(arctextmap[active_arc]->property_text().get_value().c_str())); + vbox->add(spin); + spin.show(); + */ + Gtk::Entry entry; + entry.set_text(arctextmap[active_arc]->property_text().get_value()); + vbox->add(entry); + entry.show(); + + std::cout << arcmap_to_edit << std::endl; + switch (dialog.run()) + { + case Gtk::RESPONSE_NONE: + case Gtk::RESPONSE_CANCEL: + break; + case Gtk::RESPONSE_ACCEPT: + switch (ms.getArcMapElementType(arcmap_to_edit)) + { + case MapValue::NUMERIC: + ms.set(arcmap_to_edit, active_arc, + atof(entry.get_text().c_str())); + break; + case MapValue::STRING: + ms.set(arcmap_to_edit, active_arc, + static_cast(entry.get_text())); + break; + } + arctextmap[active_arc]->property_text().set_value( + static_cast(ms.get(arcmap_to_edit, active_arc))); + + //mapwin.updateArc(active_arc); + // mapwin.updateArc(Arc(INVALID)); + propertyUpdate(Arc(INVALID)); + } + } + } + break; + } + default: + break; + } + } + return false; +} + +void DigraphDisplayerCanvas::deleteItem(Node node_to_delete) +{ + delete(nodetextmap[node_to_delete]); + delete(nodesmap[node_to_delete]); + mytab.mapstorage->digraph.erase(node_to_delete); +} + +void DigraphDisplayerCanvas::deleteItem(Arc arc_to_delete) +{ + delete(arctextmap[arc_to_delete]); + delete(arcsmap[arc_to_delete]); + mytab.mapstorage->digraph.erase(arc_to_delete); +} + +void DigraphDisplayerCanvas::textReposition(XY new_place) +{ + new_place+=(XY(10,10)); + arctextmap[forming_arc]->property_x().set_value(new_place.x); + arctextmap[forming_arc]->property_y().set_value(new_place.y); +} + +void DigraphDisplayerCanvas::toggleArcActivity(ArcBase* active_bre, bool on) +{ + if(on) + { + if(forming_arc!=INVALID) + { + std::cerr << "ERROR!!!! Valid arc found!" << std::endl; + } + else + { + for (ArcIt i(mytab.mapstorage->digraph); i!=INVALID; ++i) + { + if(arcsmap[i]==active_bre) + { + forming_arc=i; + } + } + } + } + else + { + if(forming_arc!=INVALID) + { + forming_arc=INVALID; + } + else + { + std::cerr << "ERROR!!!! Invalid arc found!" << std::endl; + } + } +} + +void DigraphDisplayerCanvas::moveNode(double dx, double dy, Gnome::Canvas::Item * item, Node node) +{ + MapStorage& ms = *mytab.mapstorage; + + Gnome::Canvas::Item * moved_item=item; + Node moved_node=node; + + if(item==NULL && node==INVALID) + { + moved_item=active_item; + moved_node=active_node; + } + else + { + isbutton=1; + } + + //repositioning node and its text + moved_item->move(dx, dy); + nodetextmap[moved_node]->move(dx, dy); + + // the new coordinates of the centre of the node + double coord_x = dx + ms.getNodeCoords(moved_node).x; + double coord_y = dy + ms.getNodeCoords(moved_node).y; + + // write back the new coordinates to the coords map + ms.setNodeCoords(moved_node, XY(coord_x, coord_y)); + + //all the arcs connected to the moved point has to be redrawn + for(OutArcIt ei(ms.digraph,moved_node);ei!=INVALID;++ei) + { + XY arrow_pos; + + if (ms.digraph.source(ei) == ms.digraph.target(ei)) + { + arrow_pos = ms.getArrowCoords(ei) + XY(dx, dy); + } + else + { + XY moved_node_1(coord_x - dx, coord_y - dy); + XY moved_node_2(coord_x, coord_y); + Node target = ms.digraph.target(ei); + XY fix_node = ms.getNodeCoords(target); + XY old_arrow_pos(ms.getArrowCoords(ei)); + + arrow_pos = calcArrowPos(moved_node_1, moved_node_2, fix_node, old_arrow_pos, isbutton); + } + + ms.setArrowCoords(ei, arrow_pos); + arcsmap[ei]->draw(); + + //reposition of arctext + XY text_pos=ms.getArrowCoords(ei); + text_pos+=(XY(10,10)); + arctextmap[ei]->property_x().set_value(text_pos.x); + arctextmap[ei]->property_y().set_value(text_pos.y); + } + + for(InArcIt ei(ms.digraph,moved_node);ei!=INVALID;++ei) + { + if (ms.digraph.source(ei) != ms.digraph.target(ei)) + { + XY moved_node_1(coord_x - dx, coord_y - dy); + XY moved_node_2(coord_x, coord_y); + Node source = ms.digraph.source(ei); + XY fix_node = ms.getNodeCoords(source); + XY old_arrow_pos(ms.getArrowCoords(ei)); + + XY arrow_pos; + arrow_pos = calcArrowPos(moved_node_1, moved_node_2, fix_node, old_arrow_pos, isbutton); + + ms.setArrowCoords(ei, arrow_pos); + arcsmap[ei]->draw(); + + //reposition of arctext + XY text_pos=ms.getArrowCoords(ei); + text_pos+=(XY(10,10)); + arctextmap[ei]->property_x().set_value(text_pos.x); + arctextmap[ei]->property_y().set_value(text_pos.y); + } + } +} + +Gdk::Color DigraphDisplayerCanvas::rainbowColorCounter(double min, double max, double w) +{ + Gdk::Color color; + + double pos=(w-min)/(max-min); + int phase=0; + + //rainbow transitions contain 6 phase + //in each phase only one color is changed + //first we determine the phase, in which + //the actual value belongs to + for (int i=0;i<=5;i++) + { + if(((double)i/6 +#include +#include +#include + +const int minimum_node_radius=5; + +int DigraphDisplayerCanvas::changeNodeRadius (std::string mapname, Node node) +{ + MapStorage& ms = *mytab.mapstorage; + + double min, max; + + { + NodeIt n(ms.digraph); + min = max = ms.get(mapname, n); + for (; n != INVALID; ++n) + { + if (static_cast(ms.get(mapname, n)) > max) + max = ms.get(mapname, n); + if (static_cast(ms.get(mapname, n)) < min) + min = ms.get(mapname, n); + } + } + + if(node==INVALID) + { + for (NodeIt i(ms.digraph); i!=INVALID; ++i) + { + double v=fabs(ms.get(mapname,i)); + int w; + if(autoscale) + { + if(min==max) + { + w=(int)(node_property_defaults[N_RADIUS]); + } + else + { + w=(int)(minimum_node_radius+(v-min)/(max-min)*(radius_size-minimum_node_radius)); + } + } + else + { + w=(int)(v*radius_size); + } + + if(w=0) + { + double x1, y1, x2, y2; + x1=nodesmap[i]->property_x1().get_value(); + x2=nodesmap[i]->property_x2().get_value(); + y1=nodesmap[i]->property_y1().get_value(); + y2=nodesmap[i]->property_y2().get_value(); + nodesmap[i]->property_x1().set_value((x1+x2)/2-w); + nodesmap[i]->property_x2().set_value((x1+x2)/2+w); + nodesmap[i]->property_y1().set_value((y1+y2)/2-w); + nodesmap[i]->property_y2().set_value((y1+y2)/2+w); + } + } + } + else + { + //I think only new nodes use this case + //that has no own value, only the default one + //int w=(int)(*actual_map)[node]; + int w=(int)(node_property_defaults[N_RADIUS]); + if(w>=0) + { + double x1, y1, x2, y2; + x1=nodesmap[node]->property_x1().get_value(); + x2=nodesmap[node]->property_x2().get_value(); + y1=nodesmap[node]->property_y1().get_value(); + y2=nodesmap[node]->property_y2().get_value(); + nodesmap[node]->property_x1().set_value((x1+x2)/2-w); + nodesmap[node]->property_x2().set_value((x1+x2)/2+w); + nodesmap[node]->property_y1().set_value((y1+y2)/2-w); + nodesmap[node]->property_y2().set_value((y1+y2)/2+w); + } + } + return 0; +}; + +int DigraphDisplayerCanvas::resetNodeRadius (Node node) +{ + MapStorage& ms = *mytab.mapstorage; + + double min, max; + min=node_property_defaults[N_RADIUS]; + max=node_property_defaults[N_RADIUS]; + Digraph::NodeMap actual_map(ms.digraph,node_property_defaults[N_RADIUS]); + + if(node==INVALID) + { + for (NodeIt i(ms.digraph); i!=INVALID; ++i) + { + double v=fabs(actual_map[i]); + int w; + if(min==max) + { + w=(int)(node_property_defaults[N_RADIUS]); + } + else + { + w=(int)(MIN_NODE_RADIUS+(v-min)/(max-min)*(MAX_NODE_RADIUS-MIN_NODE_RADIUS)); + } + if(zoomtrack) + { + double actual_ppu=get_pixels_per_unit(); + w=(int)(w/actual_ppu*fixed_zoom_factor); + } + if(w>=0) + { + double x1, y1, x2, y2; + x1=nodesmap[i]->property_x1().get_value(); + x2=nodesmap[i]->property_x2().get_value(); + y1=nodesmap[i]->property_y1().get_value(); + y2=nodesmap[i]->property_y2().get_value(); + nodesmap[i]->property_x1().set_value((x1+x2)/2-w); + nodesmap[i]->property_x2().set_value((x1+x2)/2+w); + nodesmap[i]->property_y1().set_value((y1+y2)/2-w); + nodesmap[i]->property_y2().set_value((y1+y2)/2+w); + } + } + } + else + { + //I think only new nodes use this case +// int w=(int)actual_map[node]; + int w=(int)(node_property_defaults[N_RADIUS]); + if(w>=0) + { + double x1, y1, x2, y2; + x1=nodesmap[node]->property_x1().get_value(); + x2=nodesmap[node]->property_x2().get_value(); + y1=nodesmap[node]->property_y1().get_value(); + y2=nodesmap[node]->property_y2().get_value(); + nodesmap[node]->property_x1().set_value((x1+x2)/2-w); + nodesmap[node]->property_x2().set_value((x1+x2)/2+w); + nodesmap[node]->property_y1().set_value((y1+y2)/2-w); + nodesmap[node]->property_y2().set_value((y1+y2)/2+w); + } + } + return 0; +}; + +int DigraphDisplayerCanvas::changeNodeColor (std::string mapname, Node node) +{ + MapStorage& ms = *mytab.mapstorage; + + //function maps the range of the maximum and + //the minimum of the nodemap to the range of + //green in RGB + + double max, min; + + { + NodeIt n(ms.digraph); + min = max = ms.get(mapname, n); + for (; n != INVALID; ++n) + { + if (static_cast(ms.get(mapname, n)) > max) + max = ms.get(mapname, n); + if (static_cast(ms.get(mapname, n)) < min) + min = ms.get(mapname, n); + } + } + + if(node==INVALID) + { + + for (NodeIt i(ms.digraph); i!=INVALID; ++i) + { + Gdk::Color color; + + double w=ms.get(mapname, i); + + if(max!=min) + { + color=rainbowColorCounter(min, max, w); + } + else + { + color.set_rgb_p (0, 0, 1); + } + + nodesmap[i]->property_fill_color_gdk().set_value(color); + } + } + else + { + Gdk::Color color; + + double w=ms.get(mapname, node); + + if(max!=min) + { + color=rainbowColorCounter(min, max, w); + } + else + { + color.set_rgb_p (0, 0, 1); + } + + nodesmap[node]->property_fill_color_gdk().set_value(color); + } + return 0; +}; + +int DigraphDisplayerCanvas::resetNodeColor (Node node) +{ + MapStorage& ms = *mytab.mapstorage; + + //function maps the range of the maximum and + //the minimum of the nodemap to the range of + //green in RGB + + Digraph::NodeMap actual_map(ms.digraph,node_property_defaults[N_COLOR]); + + double max, min; + + max=node_property_defaults[N_COLOR]; + min=node_property_defaults[N_COLOR]; + + if(node==INVALID) + { + + for (NodeIt i(ms.digraph); i!=INVALID; ++i) + { + Gdk::Color color; + + double w=actual_map[i]; + + if(max!=min) + { + color.set_rgb_p (0, 0, 100*(w-min)/(max-min)); + } + else + { + color.set_rgb_p (0, 0, 100); + } + + nodesmap[i]->property_fill_color_gdk().set_value(color); + } + } + else + { + Gdk::Color color; + + double w=actual_map[node]; + + if(max!=min) + { + color.set_rgb_p (0, 0, 100*(w-min)/(max-min)); + } + else + { + color.set_rgb_p (0, 0, 100); + } + + nodesmap[node]->property_fill_color_gdk().set_value(color); + } + return 0; +}; + +int DigraphDisplayerCanvas::changeNodeText (std::string mapname, Node node) +{ + MapStorage& ms = *mytab.mapstorage; + + //the number in the map will be written on the node + //EXCEPT when the name of the map is Text, because + //in that case empty string will be written, because + //that is the deleter map + + if(node==INVALID) + { + for (NodeIt i(ms.digraph); i!=INVALID; ++i) + { + nodemap_to_edit=mapname; + + nodetextmap[i]->property_text().set_value( + static_cast(ms.get(mapname, i))); + } + } + else + { + nodetextmap[node]->property_text().set_value( + static_cast(ms.get(mapname, node))); + } + return 0; +}; + +int DigraphDisplayerCanvas::resetNodeText (Node node) +{ + MapStorage& ms = *mytab.mapstorage; + + //the number in the map will be written on the node + //EXCEPT when the name of the map is Text, because + //in that case empty string will be written, because + //that is the deleter map + + if(node==INVALID) + { + for (NodeIt i(ms.digraph); i!=INVALID; ++i) + { + nodemap_to_edit=""; + nodetextmap[i]->property_text().set_value(""); + } + } + else + { + nodetextmap[node]->property_text().set_value(""); + } + return 0; +}; diff -r 0e4f009eab8b -r 67188bd752db graph_displayer_canvas-zoom.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graph_displayer_canvas-zoom.cc Mon Jul 07 08:10:39 2008 -0500 @@ -0,0 +1,90 @@ +/* -*- C++ -*- + * + * This file is a part of LEMON, a generic C++ optimization library + * + * Copyright (C) 2003-2006 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#include +#include + +void DigraphDisplayerCanvas::zoomIn() +{ + set_pixels_per_unit( + (1.0 + (double) zoom_step / 100.0) * get_pixels_per_unit()); + if(zoomtrack) + { + propertyChange(false, N_RADIUS); + propertyChange(true, E_WIDTH); + } +} + +void DigraphDisplayerCanvas::zoomOut() +{ + set_pixels_per_unit( + (1.0 - (double) zoom_step / 100.0) * get_pixels_per_unit()); + if(zoomtrack) + { + propertyChange(true, E_WIDTH); + propertyChange(false, N_RADIUS); + } +} + +void DigraphDisplayerCanvas::zoomFit() +{ + updateScrollRegion(); + + // get the height and width of the canvas + Gtk::Allocation a = get_allocation(); + int aw = a.get_width(); + int ah = a.get_height(); + + // get the bounding box of the digraph + update_now(); + double x1, y1, x2, y2; + root()->get_bounds(x1, y1, x2, y2); + + // fit the digraph to the window + double ppu1 = (double) aw / fabs(x2 - x1); + double ppu2 = (double) ah / fabs(y2 - y1); + set_pixels_per_unit((ppu1 < ppu2) ? ppu1 : ppu2); + + if(zoomtrack) + { + propertyChange(true, E_WIDTH); + propertyChange(false, N_RADIUS); + } +} + +void DigraphDisplayerCanvas::zoom100() +{ + updateScrollRegion(); + set_pixels_per_unit(1.0); + + if(zoomtrack) + { + propertyChange(true, E_WIDTH); + propertyChange(false, N_RADIUS); + } +} + +void DigraphDisplayerCanvas::updateScrollRegion() +{ + // get_bounds() yields something sane only when no updates are pending + // and it returns a sufficient, not an exact bounding box + update_now(); + double x1, y1, x2, y2; + root()->get_bounds(x1, y1, x2, y2); + set_scroll_region(x1, y1, x2, y2); +} diff -r 0e4f009eab8b -r 67188bd752db graph_displayer_canvas.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graph_displayer_canvas.cc Mon Jul 07 08:10:39 2008 -0500 @@ -0,0 +1,461 @@ +/* -*- C++ -*- + * + * This file is a part of LEMON, a generic C++ optimization library + * + * Copyright (C) 2003-2006 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#include +#include +#include +#include +#include + +DigraphDisplayerCanvas::DigraphDisplayerCanvas(NoteBookTab & mainw) : + nodesmap(mainw.mapstorage->digraph), arcsmap(mainw.mapstorage->digraph), arctextmap(mainw.mapstorage->digraph), + nodetextmap(mainw.mapstorage->digraph), displayed_graph(*(root()), 0, 0), + isbutton(0), active_item(NULL), target_item(NULL), nodemap_to_edit(""), + arcmap_to_edit(""), autoscale(true), zoomtrack(false), radius_size(20), arc_width(10), + was_redesigned(false), is_drawn(false), mytab(mainw), + background_set(false) +{ + //add mouse scroll event handler - it won't be changed, it handles zoom + signal_event().connect(sigc::mem_fun(*this, &DigraphDisplayerCanvas::scrollEventHandler), false); + + //base event handler is move tool + actual_handler=signal_event().connect(sigc::mem_fun(*this, &DigraphDisplayerCanvas::moveEventHandler), false); + actual_tool=MOVE; + + + active_node=INVALID; + active_arc=INVALID; + forming_arc=INVALID; + + setBackground(); +} + +void DigraphDisplayerCanvas::setBackground() +{ + if (background_set) + { + delete background; + } + if (mytab.mapstorage->isBackgroundSet()) + { + background_set = true; + refBackground = Gdk::Pixbuf::create_from_file( + mytab.mapstorage->getBackgroundFilename()); + background = new Gnome::Canvas::Pixbuf( + *(root()), + 0.0 - refBackground->get_width() / 2.0, + 0.0 - refBackground->get_height() / 2.0, + refBackground); + background->lower_to_bottom(); + } + else + { + background_set = false; + } +} + +DigraphDisplayerCanvas::~DigraphDisplayerCanvas() +{ + for (NodeIt n((mytab.mapstorage)->digraph); n != INVALID; ++n) + { + delete nodesmap[n]; + delete nodetextmap[n]; + } + + for (ArcIt e((mytab.mapstorage)->digraph); e != INVALID; ++e) + { + delete arcsmap[e]; + delete arctextmap[e]; + } +} + +void DigraphDisplayerCanvas::propertyChange(bool itisarc, int prop) +{ + if(itisarc) + { + propertyUpdate(Arc(INVALID), prop); + } + else + { + propertyUpdate(Node(INVALID), prop); + } +} + +void DigraphDisplayerCanvas::propertyUpdate(Arc arc) +{ + for(int i=0;i nodemaps = mytab.mapstorage->getNodeMapList(); + bool found = false; + for (std::vector::const_iterator it = nodemaps.begin(); + it != nodemaps.end(); ++it) + { + if (*it == mapname) + { + found = true; + break; + } + } + if (found) + { + switch(prop) + { + case N_RADIUS: + changeNodeRadius(mapname, node); + break; + case N_COLOR: + changeNodeColor(mapname, node); + break; + case N_TEXT: + changeNodeText(mapname, node); + break; + default: + std::cerr<<"Error\n"; + } + } + } + else //mapname=="" + { + Node node=INVALID; + switch(prop) + { + case N_RADIUS: + resetNodeRadius(node); + break; + case N_COLOR: + resetNodeColor(node); + break; + case N_TEXT: + resetNodeText(node); + break; + default: + std::cerr<<"Error\n"; + } + } + } +} + +void DigraphDisplayerCanvas::propertyUpdate(Arc arc, int prop) +{ + std::string mapname=mytab.getActiveArcMap(prop); + + if(is_drawn) + { + if(mapname!="") + { + std::vector arcmaps = mytab.mapstorage->getArcMapList(); + bool found = false; + for (std::vector::const_iterator it = arcmaps.begin(); + it != arcmaps.end(); ++it) + { + if (*it == mapname) + { + found = true; + break; + } + } + if (found) + { + switch(prop) + { + case E_WIDTH: + changeArcWidth(mapname, arc); + break; + case E_COLOR: + changeArcColor(mapname, arc); + break; + case E_TEXT: + changeArcText(mapname, arc); + break; + default: + std::cerr<<"Error\n"; + } + } + } + else //mapname=="" + { + switch(prop) + { + case E_WIDTH: + resetArcWidth(arc); + break; + case E_COLOR: + resetArcColor(arc); + break; + case E_TEXT: + resetArcText(arc); + break; + default: + std::cerr<<"Error\n"; + } + } + } +} + +void DigraphDisplayerCanvas::drawDigraph() +{ + //first arcs are drawn, to hide joining with nodes later + + for (ArcIt i((mytab.mapstorage)->digraph); i!=INVALID; ++i) + { + if (mytab.mapstorage->digraph.source(i) == mytab.mapstorage->digraph.target(i)) + { + arcsmap[i]=new LoopArc(displayed_graph, i, *this); + } + else + { + arcsmap[i]=new BrokenArc(displayed_graph, i, *this); + } + //initializing arc-text as well, to empty string + + XY text_pos=mytab.mapstorage->getArrowCoords(i); + text_pos+=(XY(10,10)); + + arctextmap[i]=new Gnome::Canvas::Text(displayed_graph, text_pos.x, text_pos.y, ""); + arctextmap[i]->property_fill_color().set_value("darkgreen"); + arctextmap[i]->signal_event().connect(sigc::mem_fun(*this, &DigraphDisplayerCanvas::mapEditEventHandler), false); + arctextmap[i]->raise_to_top(); + } + + //afterwards nodes come to be drawn + + for (NodeIt i((mytab.mapstorage)->digraph); i!=INVALID; ++i) + { + //drawing bule nodes, with black line around them + + nodesmap[i]=new Gnome::Canvas::Ellipse( + displayed_graph, + mytab.mapstorage->getNodeCoords(i).x-20, + mytab.mapstorage->getNodeCoords(i).y-20, + mytab.mapstorage->getNodeCoords(i).x+20, + mytab.mapstorage->getNodeCoords(i).y+20); + *(nodesmap[i]) << Gnome::Canvas::Properties::fill_color("blue"); + *(nodesmap[i]) << Gnome::Canvas::Properties::outline_color("black"); + nodesmap[i]->raise_to_top(); + + //initializing arc-text as well, to empty string + + XY text_pos( + (mytab.mapstorage->getNodeCoords(i).x+node_property_defaults[N_RADIUS]+5), + (mytab.mapstorage->getNodeCoords(i).y+node_property_defaults[N_RADIUS]+5)); + + nodetextmap[i]=new Gnome::Canvas::Text(displayed_graph, + text_pos.x, text_pos.y, ""); + nodetextmap[i]->property_fill_color().set_value("darkblue"); + nodetextmap[i]->signal_event().connect(sigc::mem_fun(*this, &DigraphDisplayerCanvas::mapEditEventHandler), false); + nodetextmap[i]->raise_to_top(); + } + + is_drawn=true; + + //upon drawing digraph + //properties have to + //be set in as well + for(int i=0;idigraph); n != INVALID; ++n) + { + delete nodesmap[n]; + delete nodetextmap[n]; + } + + for (ArcIt e((mytab.mapstorage)->digraph); e != INVALID; ++e) + { + delete arcsmap[e]; + delete arctextmap[e]; + } + + is_drawn=false; +} + +void DigraphDisplayerCanvas::setView(bool autoscale_p, bool zoomtrack_p, double width_p, double radius_p) +{ + autoscale=autoscale_p; + arc_width=width_p; + radius_size=radius_p; + + if((!zoomtrack) && zoomtrack_p) + { + fixed_zoom_factor=get_pixels_per_unit(); + } + + zoomtrack=zoomtrack_p; + + propertyChange(false, N_RADIUS); + propertyChange(true, E_WIDTH); +} + +void DigraphDisplayerCanvas::getView(bool & autoscale_p, bool & zoomtrack_p, double& width_p, double& radius_p) +{ + autoscale_p=autoscale; + zoomtrack_p=zoomtrack; + width_p=arc_width; + radius_p=radius_size; +} + +void DigraphDisplayerCanvas::reDesignDigraph() +{ + MapStorage& ms = *mytab.mapstorage; + NodeIt firstnode(ms.digraph); + //is it not an empty digraph? + if(firstnode!=INVALID) + { + double max_coord=50000; + double min_dist=20; + double init_vector_length=25; + + if(!was_redesigned) + { + NodeIt i(ms.digraph); + + dim2::Point init(init_vector_length*rnd(), + init_vector_length*rnd()); + moveNode(init.x, init.y, nodesmap[i], i); + was_redesigned=true; + } + + double attraction; + double propulsation; + int iterations; + + ms.get_design_data(attraction, propulsation, iterations); + + //iteration counter + for(int l=0;l x(ms.digraph); + Digraph::NodeMap y(ms.digraph); + XYMap > actual_forces; + actual_forces.setXMap(x); + actual_forces.setYMap(y); + + //count actual force for each nodes + for (NodeIt i(ms.digraph); i!=INVALID; ++i) + { + //propulsation of nodes + for (NodeIt j(ms.digraph); j!=INVALID; ++j) + { + if(i!=j) + { + lemon::dim2::Point delta = + (ms.getNodeCoords(i)- + ms.getNodeCoords(j)); + + const double length_sqr=std::max(delta.normSquare(),min_dist); + + //normalize vector + delta/=sqrt(length_sqr); + + //calculating propulsation strength + //greater distance menas smaller propulsation strength + delta*=propulsation/length_sqr; + + actual_forces.set(i,(actual_forces[i]+delta)); + } + } + //attraction of nodes, to which actual node is bound + for(OutArcIt ei(ms.digraph,i);ei!=INVALID;++ei) + { + lemon::dim2::Point delta = + (ms.getNodeCoords(i)- + ms.getNodeCoords(ms.digraph.target(ei))); + + //calculating attraction strength + //greater distance means greater strength + delta*=attraction; + + actual_forces.set(i,actual_forces[i]-delta); + } + for(InArcIt ei(ms.digraph,i);ei!=INVALID;++ei) + { + lemon::dim2::Point delta = + (ms.getNodeCoords(i)- + ms.getNodeCoords(ms.digraph.source(ei))); + + //calculating attraction strength + //greater distance means greater strength + delta*=attraction; + + actual_forces.set(i,actual_forces[i]-delta); + } + } + for (NodeIt i(ms.digraph); i!=INVALID; ++i) + { + if((ms.getNodeCoords(i).x)+actual_forces[i].x>max_coord) + { + actual_forces[i].x=max_coord-(ms.getNodeCoords(i).x); + std::cout << "Correction! " << ((ms.getNodeCoords(i).x)+actual_forces[i].x) << std::endl; + } + else if((ms.getNodeCoords(i).x)+actual_forces[i].x<(0-max_coord)) + { + actual_forces[i].x=0-max_coord-(ms.getNodeCoords(i).x); + std::cout << "Correction! " << ((ms.getNodeCoords(i).x)+actual_forces[i].x) << std::endl; + } + if((ms.getNodeCoords(i).y)+actual_forces[i].y>max_coord) + { + actual_forces[i].y=max_coord-(ms.getNodeCoords(i).y); + std::cout << "Correction! " << ((ms.getNodeCoords(i).y)+actual_forces[i].y) << std::endl; + } + else if((ms.getNodeCoords(i).y)+actual_forces[i].y<(0-max_coord)) + { + actual_forces[i].y=0-max_coord-(ms.getNodeCoords(i).y); + std::cout << "Correction! " << ((ms.getNodeCoords(i).y)+actual_forces[i].y) << std::endl; + } + moveNode(actual_forces[i].x, actual_forces[i].y, nodesmap[i], i); + } + } + } +} + diff -r 0e4f009eab8b -r 67188bd752db graph_displayer_canvas.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graph_displayer_canvas.h Mon Jul 07 08:10:39 2008 -0500 @@ -0,0 +1,452 @@ +/* -*- C++ -*- + * + * This file is a part of LEMON, a generic C++ optimization library + * + * Copyright (C) 2003-2006 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#ifndef GRAPH_DISPLAYER_CANVAS_H +#define GRAPH_DISPLAYER_CANVAS_H + +class NoteBookTab; + +#include "all_include.h" +#include +#include + +///This class is the canvas, on which the digraph can be drawn. +class DigraphDisplayerCanvas : public Gnome::Canvas::CanvasAA +{ + friend class BrokenArc; + friend class LoopArc; + + class ArcBase : public Gnome::Canvas::Group + { + protected: + ///Reference to the canvas, on which the digraph is drawn. + + ///It is needed, because some datas needed from + ///digraph can be accessed by this or should be sent + ///as parameter, but it would be complicated + DigraphDisplayerCanvas& canvas; + + ///The arc that the class displays. + + ///It is needed, because some datas needed from + ///digraph can be accessed by this or should be sent + ///as parameter, but it would be complicated + Arc arc; + + Gnome::Canvas::Polygon arrow; + + void drawArrow(XY); + public: + ArcBase(Gnome::Canvas::Group&, Arc, DigraphDisplayerCanvas&); + virtual ~ArcBase(); + virtual void draw() = 0; + virtual void setLineWidth(int) = 0; + virtual void setFillColor(Gdk::Color) = 0; + virtual Gnome::Canvas::Item * getLine() = 0; + }; + + ///Arc displayer class + + ///This class is responsible for displaying arcs in digraph. + ///The displayed arc is broken in the middle. The + ///aim of this is to be able to indicate direction of arcs + ///and to be able to display more then one arcs between the + ///same source and target + class BrokenArc : public ArcBase + { + private: + Gnome::Canvas::Line line; + + ///Indicates whether the button of mouse is pressed or not at the moment. + bool isbutton; + + ///At this location was the mousebutton pressed. Horizontal component. + + ///It helps to calculate the + ///distance of dragging. + double clicked_x; + + ///At this location was the mousebutton pressed. Vertical component. + + ///It helps to calculate the + ///distance of dragging. + double clicked_y; + + ///event handler for forming broken arcs + + ///\param event the + ///event to handle + bool arcFormerEventHandler(GdkEvent* event); + + public: + ///Constructor of broken arc class. + + ///\param g the group to which the arc belongs + ///\param _arc the represented arc + ///\param gc the canvas + BrokenArc(Gnome::Canvas::Group&, Arc, DigraphDisplayerCanvas&); + + ///Destructor of broken arc class + + ///Frees up + ///reserved memory + ~BrokenArc(); + + ///The function that draws the arc based on collected data + void draw(); + + void setLineWidth(int); + void setFillColor(Gdk::Color); + + Gnome::Canvas::Item * getLine() { return (Gnome::Canvas::Item *)(&line); }; + }; + + class LoopArc : public ArcBase + { + private: + Gnome::Canvas::Ellipse line; + bool arcFormerEventHandler(GdkEvent* e); + bool isbutton; + public: + LoopArc(Gnome::Canvas::Group&, Arc, DigraphDisplayerCanvas&); + ~LoopArc(); + void draw(); + void setLineWidth(int); + void setFillColor(Gdk::Color); + Gnome::Canvas::Item * getLine() { return (Gnome::Canvas::Item *)(&line); }; + }; + + ///Type of canvas, on which the digraph is drawn + typedef Gnome::Canvas::CanvasAA Parent; + +public: + ///Constructor + + ///\param nbt the tab of the window, in which the digraph is displayed + DigraphDisplayerCanvas(NoteBookTab & nbt); + + ///destructor of the class + virtual ~DigraphDisplayerCanvas(); + + ///Returns a color of the rainbow based on a map value and the min and max value of the given map + + ///min and max is purple, between them there is a linear assign + Gdk::Color rainbowColorCounter(double, double, double); + + ///Changes the width of arc(s) according to the given map. + + ///\param mapname is the name of the map which contains the values to be set + ///\param arc if it is given, only the width of the given arc will be set, instead of all of them. + int changeArcWidth (std::string mapname, Arc arc=INVALID); + + ///Resets width of arc(s) to the default value + + ///\param arc if it is given, only the width of the + ///given arc will be reset, instead of all of them. + int resetArcWidth (Arc arc=INVALID); + + ///Changes the color of arc(s) according to the given map. + + ///\param mapname is the name of the map which contains the new values + ///\param arc if it is given, only the color of the given arc will be set, instead of all of them. + int changeArcColor (std::string mapname, Arc arc=INVALID); + + ///Resets color of arc(s) to the default value + + ///\param arc if it is given, only the color of the + ///given arc will be reset, instead of all of them. + int resetArcColor (Arc arc=INVALID); + + ///Changes the label of arc(s) according to the given map. + + ///\param mapname is the name of the map which contains the new values + ///\param arc if it is given, only the label of the given arc will be set, instead of all of them. + int changeArcText (std::string mapname, Arc arc=INVALID); + + ///Resets label of arc(s) to the default value + + ///\param arc if it is given, only the color of the + ///given arc will be reset, instead of all of them. + int resetArcText (Arc arc=INVALID); + + ///Changes the radius of node(s) according to the given map. + + ///\param mapname is the name of the map which contains the new values + ///\param node if it is given, only the radius of the given node will be set, instead of all of them. + int changeNodeRadius (std::string mapname, Node node=INVALID); + + ///Resets radius of node(s) to the default value + + ///\param node if it is given, only the radius of the + ///given node will be reset, instead of all of them. + int resetNodeRadius (Node node=INVALID); + + ///Changes the color of node(s) according to the given map. + + ///\param mapname is the name of the map which contains the new values + ///\param node if it is given, only the color of the given node will be set, instead of all of them. + int changeNodeColor (std::string mapname, Node node=INVALID); + + ///Resets color of node(s) to the default value + + ///\param node if it is given, only the color of the + ///given node will be reset, instead of all of them. + int resetNodeColor (Node node=INVALID); + + ///Changes the label of node(s) according to the given map. + + ///\param mapname is the name of the map which contains the new values + ///\param node if it is given, only the label of the given node will be set, instead of all of them. + int changeNodeText (std::string mapname, Node node=INVALID); + + ///Resets label of node(s) to the default value + + ///\param node if it is given, only the label of the + ///given node will be reset, instead of all of them. + int resetNodeText (Node node=INVALID); + + ///This function is called, when any of the displayed attributes have to be updated, or changed + + ///\param itisarc if true, arc property has to be changed, else node property + ///\param prop the id of property that has to changed or updated + void propertyChange(bool itisarc, int prop); + + ///updates the given property + + ///\param arc if it is not INVALID, only the property of the given arc will be updated, instead of all of them + ///\param prop the property to update + void propertyUpdate(Arc arc, int prop); + + ///updates the given property + + ///\param node if it is not INVALID, only the property of the given node will be updated, instead of all of them + ///\param prop the property to update + void propertyUpdate(Node node, int prop); + + ///updates all the property for the given arc + void propertyUpdate(Arc); + + ///updates all the property for the given node + void propertyUpdate(Node); + + ///Callback for 'ViewZoomIn' action. + virtual void zoomIn(); + ///Callback for 'ViewZoomOut' action. + virtual void zoomOut(); + ///Callback for 'ViewZoomFit' action. + virtual void zoomFit(); + ///Callback for 'ViewZoom100' action. + virtual void zoom100(); + ///Sets the scroll region of the convas to the bounding box of the digraph. + void updateScrollRegion(); + + ///This function changes the tool in the digraph-editor's hand + void changeEditorialTool(int); + +protected: + + //maximizing, minimizing, restoring window, etc. + virtual bool on_expose_event(GdkEventExpose *); + +private: + + ///This function is responsible for the correct + ///reaction of any action happened in the territory + ///of the canvas + ///DEPRECATED!!!! + bool eventHandler(GdkEvent* e, Node n); + + ///actual event handler + /// + ///Actual event handler should be stored, to be able to disconnect it and later reconnect it. + sigc::connection actual_handler; + + ///event handler for the case when move-tool is active + bool moveEventHandler(GdkEvent*); + ///event handler for the case when create_node-tool is active + bool createNodeEventHandler(GdkEvent*); + ///event handler for the case when create_arc-tool is active + bool createArcEventHandler(GdkEvent*); + ///event handler for the case when eraser-tool is active + bool eraserEventHandler(GdkEvent*); + ///event handler for the case when map editor tool is active + bool mapEditEventHandler(GdkEvent*); + ///event handler for the case when user scrolls the mouse + bool scrollEventHandler(GdkEvent*); + +private: + ///moves node according to the given parameters + void moveNode(double, double, Gnome::Canvas::Item * item=NULL, Node node=INVALID); + +public: + ///Moves the text to new place + void textReposition(XY); + + ///Activates an arc belonging to an ArcBase + + ///After we have activated an arc this way, + ///the GDC object will know, which arc is under forming + ///therefore it can redraw the necessary elements on the canvas, + ///for example the text belonging to the \ref ArcBase can be + ///redrawn (\ref textReposition). + void toggleArcActivity(ArcBase*, bool); + +public: + + ///Returns the actual tool in hand + int getActualTool(); + + ///Sets node representation settings + void setView(bool, bool, double, double); + + ///Gets node representation settings + void getView(bool &, bool &, double&, double&); + + ///draws the digraph + + ///Called when opening a file. + void drawDigraph(); + + ///Clears the canvas + + ///It achieves this by deleting all data + ///structure used to help handle the displayed digraph. + void clear(); + + ///creates a new Nodemap + + ///\param init initial value of the map + ///\param mapname name of new map + int addNewNodeMap(double init,std::string mapname); + ///creates a new Arcmap + + ///\param init initial value of the map + ///\param mapname name of new map + int addNewArcMap(double init,std::string mapname); + + void reDesignDigraph(); + + ///Show whether the digraph is already drawn. + bool is_drawn; + +private: + ///Deletes the given element. + void deleteItem(Node); + ///Deletes the given element. + void deleteItem(Arc); + +private: + + ///Map of nodes of digraph + Digraph::NodeMap nodesmap; + + ///Map of arcs of digraph + Digraph::ArcMap arcsmap; + + ///Map of texts to write on arcs + Digraph::ArcMap arctextmap; + + ///Map of texts to write on nodes + Digraph::NodeMap nodetextmap; + + ///Group of digraphical elements of displayed_graph + Gnome::Canvas::Group displayed_graph; + +private: + ///Indicates whether the button of mouse is pressed or not + int isbutton; + + ///Stores the actual tool in hand + int actual_tool; + + ///At this location was the mousebutton pressed. + ///It helps to calculate the distance of dragging. + double clicked_x, clicked_y; + + ///Remembers which Gnome::Canvas::Item was pressed. + + ///this variable is needed, to work on it after selection + Gnome::Canvas::Item * active_item; + + ///Remembers which Gnome::Canvas::Item was pressed. + + ///this variable is used at arc creation, it will + ///be the secondly selected node. No local variable + ///can be used for this purpose inside the function, + ///because the node selected by button press, and + ///the arc is created by button release. Both of + ///them is different function call. + Gnome::Canvas::Item * target_item; + + ///selected node (for any editing) + Node active_node; + + ///selected arc (for any editing) + Arc active_arc; + + ///the arc that is selected by clicking on the red arrow in the middle of it + + ///This arc is stored only for the purpose of reshape it. + ///That is why it is selected in a different manner. + Arc forming_arc; + + ///Map displayed by label can be edited. + std::string nodemap_to_edit; + + ///Map displayed by label can be edited. + std::string arcmap_to_edit; + + static const int zoom_step = 5; + + ///Is node radius autoscaled + bool autoscale; + + ///Should we track zoomfactor changes + bool zoomtrack; + + ///to store the zoom factor when it was "fixed" + double fixed_zoom_factor; + + ///Node radius size + double radius_size; + + ///Arc width + double arc_width; + + ///Was redesign run on this digraph already? + /// + ///If not, the layout will be modified randomly + ///to avoid frozen layout because of wrong + ///initial state + bool was_redesigned; + +private: + + ///reference to the container, in which the canvas is + NoteBookTab & mytab; + + XY calcArrowPos(XY, XY, XY, XY, int); + + bool background_set; + Glib::RefPtr refBackground; + Gnome::Canvas::Pixbuf *background; +public: + void setBackground(); +}; + +#endif //GRAPH_DISPLAYER_CANVAS_H diff -r 0e4f009eab8b -r 67188bd752db graphocska.lgf --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graphocska.lgf Mon Jul 07 08:10:39 2008 -0500 @@ -0,0 +1,39 @@ +@nodes +label coordinates_x coordinates_y data +1 230 -80 1.123 +2 230 100 3.234 +3 120 -80 5.345 +4 120 100 7.456 +5 20 100 9.567 +6 20 -80 11.678 +7 -40 10 13.789 +8 -100 100 15.890 +9 -100 10 17.901 +10 -100 -80 19.012 +11 -200 -80 21.000 +12 -200 10 23.001 +13 -200 100 25.003 +14 -300 100 27.004 +15 -300 -80 29.9999 + +@arcs + label map1 map2 map3 map4 +15 14 1 21 111 231 3 +14 13 2 22 112 232 6 +13 12 3 23 113 233 9 +13 8 4 24 114 234 12 +12 11 5 25 115 235 15 +12 9 6 26 116 236 18 +11 10 7 27 117 237 21 +10 9 8 28 118 238 24 +10 7 9 29 119 239 27 +9 8 10 30 120 230 30 +7 6 11 31 121 241 33 +6 5 12 32 122 242 36 +6 3 13 33 123 243 39 +5 4 14 34 124 244 42 +4 3 15 35 125 245 45 +3 2 16 36 126 246 48 +2 1 17 37 127 247 51 + +@end \ No newline at end of file diff -r 0e4f009eab8b -r 67188bd752db gui_reader.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gui_reader.cc Mon Jul 07 08:10:39 2008 -0500 @@ -0,0 +1,194 @@ +/* -*- C++ -*- + * + * This file is a part of LEMON, a generic C++ optimization library + * + * Copyright (C) 2003-2006 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#include +#include + +#include +#include "io_helper.h" +#include +#include + +// bool GuiReader::header(const std::string& line) +// { +// std::istringstream ls(line); +// std::string head; +// ls >> head; +// return head == "@gui"; +// } + +//void GuiReader::read(std::istream& is) +void GuiReader::operator()(std::istream& is, int& ln) +{ + using std::vector; + using std::string; + using std::pair; + using std::make_pair; + using std::string; + using std::map; + + XmlIo x(is); + + { x("main_node_map_names", gui_data.main_node_map_names); } + { x("gui_node_map_names", gui_data.gui_node_map_names); } + + { x("node_map_types", gui_data.node_map_types); } + + { x("main_arc_map_names", gui_data.main_arc_map_names); } + { x("gui_arc_map_names", gui_data.gui_arc_map_names); } + + { x("arc_map_types", gui_data.arc_map_types); } + + for (vector::const_iterator it = gui_data.gui_node_map_names.begin(); + it != gui_data.gui_node_map_names.end(); ++it) + { + MapValue::Type type = gui_data.node_map_types[*it]; + switch (type) + { + case MapValue::NUMERIC: + { + map* p_map_data = + new map; + gui_data.numeric_node_maps[*it] = p_map_data; + { x(*it, *p_map_data); } + } + break; + case MapValue::STRING: + { + map* p_map_data = + new map; + gui_data.string_node_maps[*it] = p_map_data; + { x(*it, *p_map_data); } + } + break; + } + } + + for (vector::const_iterator it = gui_data.gui_arc_map_names.begin(); + it != gui_data.gui_arc_map_names.end(); ++it) + { + MapValue::Type type = gui_data.arc_map_types[*it]; + switch (type) + { + case MapValue::NUMERIC: + { + map* p_map_data = + new map; + gui_data.numeric_arc_maps[*it] = p_map_data; + { x(*it, *p_map_data); } + } + break; + case MapValue::STRING: + { + map* p_map_data = + new map; + gui_data.string_arc_maps[*it] = p_map_data; + { x(*it, *p_map_data); } + } + break; + } + } + + { + std::string node_coords_save_dest; + { x("node_coords_save_dest", node_coords_save_dest); } + if (node_coords_save_dest == "gui_sect") + { + // read the node coorinates + gui_data.node_coords_save_dest = MapStorage::SpecMapSaveOpts::GUI_SECT; + { x("node_coord_map", gui_data.node_coord_map); } + } + else if (node_coords_save_dest == "nodeset_sect_1_map") + { + gui_data.node_coords_save_dest = MapStorage::SpecMapSaveOpts::NESET_SECT; + gui_data.node_coords_save_map_num = MapStorage::SpecMapSaveOpts::ONE_MAP; + { x("map_name", gui_data.node_coords_one_map_name); } + } + else if (node_coords_save_dest == "nodeset_sect_2_maps") + { + gui_data.node_coords_save_dest = MapStorage::SpecMapSaveOpts::NESET_SECT; + gui_data.node_coords_save_map_num = MapStorage::SpecMapSaveOpts::TWO_MAPS; + { x("map1_name", gui_data.node_coords_two_maps_1_name); } + { x("map2_name", gui_data.node_coords_two_maps_2_name); } + } + } + + { + std::string arrow_coords_save_dest; + { x("arrow_coords_save_dest", arrow_coords_save_dest); } + if (arrow_coords_save_dest == "gui_sect") + { + // read the arrow coorinates + gui_data.arrow_coords_save_dest = MapStorage::SpecMapSaveOpts::GUI_SECT; + { x("arrow_coord_map", gui_data.arrow_coord_map); } + } + else if (arrow_coords_save_dest == "arcset_sect_1_map") + { + gui_data.arrow_coords_save_dest = MapStorage::SpecMapSaveOpts::NESET_SECT; + gui_data.arrow_coords_save_map_num = MapStorage::SpecMapSaveOpts::ONE_MAP; + { x("map_name", gui_data.arrow_coords_one_map_name); } + } + else if (arrow_coords_save_dest == "arcset_sect_2_maps") + { + gui_data.arrow_coords_save_dest = MapStorage::SpecMapSaveOpts::NESET_SECT; + gui_data.arrow_coords_save_map_num = MapStorage::SpecMapSaveOpts::TWO_MAPS; + { x("map1_name", gui_data.arrow_coords_two_maps_1_name); } + { x("map2_name", gui_data.arrow_coords_two_maps_2_name); } + } + } + + + + std::map nm; + x("active_nodemaps", nm); + + for(int i=0;ichangeActiveMap(false, i, nm[i]); + } + + std::map em; + x("active_arcmaps", em); + for(int i=0;ichangeActiveMap(true, i, em[i]); + } + + double attraction; + double propulsation; + int iteration; + + x("redesign-attraction", attraction); + x("redesign-propulsation", propulsation); + x("redesign-iteration", iteration); + + mapstorage->set_attraction(attraction); + mapstorage->set_propulsation(propulsation); + mapstorage->set_iteration(iteration); + + mapstorage->redesign_data_changed(); +} + +//GuiReader::GuiReader(LemonReader& reader, MapStorage* _mapstorage, +GuiReader::GuiReader(MapStorage* _mapstorage, + MapStorage::GUISectData& _gui_data) : + //Parent(reader), + mapstorage(_mapstorage), + gui_data(_gui_data) +{ +} diff -r 0e4f009eab8b -r 67188bd752db gui_reader.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gui_reader.h Mon Jul 07 08:10:39 2008 -0500 @@ -0,0 +1,36 @@ +/* -*- C++ -*- + * + * This file is a part of LEMON, a generic C++ optimization library + * + * Copyright (C) 2003-2006 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#ifndef GUI_READER_H +#define GUI_READER_H + +#include +#include "mapstorage.h" + +class GuiReader +{ + private: + MapStorage* mapstorage; + MapStorage::GUISectData& gui_data; + + public: + void operator()(std::istream&, int&); + GuiReader(MapStorage*, MapStorage::GUISectData&); +}; + +#endif diff -r 0e4f009eab8b -r 67188bd752db gui_writer.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gui_writer.cc Mon Jul 07 08:10:39 2008 -0500 @@ -0,0 +1,281 @@ +/* -*- C++ -*- + * + * This file is a part of LEMON, a generic C++ optimization library + * + * Copyright (C) 2003-2006 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#include "gui_writer.h" +#include "io_helper.h" +#include "mapstorage.h" +#include "xml.h" +#include +#include + +#include +#include + +// std::string GuiWriter::header() +// { +// return "@gui"; +// } + +void GuiWriter::write(std::ostream& os) +{ + using std::vector; + using std::string; + using std::map; + using std::string; + + os << "@gui" << std::endl; + + XmlIo x(os); + + vector all_node_map_names = mapstorage->getNodeMapList(); + // name of the maps saved to the nodeset section + vector main_node_map_names; + // name of the maps saved to the gui section + vector gui_node_map_names; + + for (vector::const_iterator it = all_node_map_names.begin(); + it != all_node_map_names.end(); ++it) + { + if (mapstorage->getNodeMapSaveDest(*it) == MapStorage::NESET_SECT) + main_node_map_names.push_back(*it); + else if (mapstorage->getNodeMapSaveDest(*it) == MapStorage::GUI_SECT) + gui_node_map_names.push_back(*it); + } + + { x("main_node_map_names", main_node_map_names); } + { x("gui_node_map_names", gui_node_map_names); } + + map node_map_types; + for (vector::const_iterator it = main_node_map_names.begin(); + it != main_node_map_names.end(); ++it) + { + node_map_types[*it] = mapstorage->getNodeMapElementType(*it); + } + for (vector::const_iterator it = gui_node_map_names.begin(); + it != gui_node_map_names.end(); ++it) + { + node_map_types[*it] = mapstorage->getNodeMapElementType(*it); + } + + { x("node_map_types", node_map_types); } + + + vector all_arc_map_names = mapstorage->getArcMapList(); + // name of the maps saved to the arcset section + vector main_arc_map_names; + // name of the maps saved to the gui section + vector gui_arc_map_names; + + for (vector::const_iterator it = all_arc_map_names.begin(); + it != all_arc_map_names.end(); ++it) + { + if (mapstorage->getArcMapSaveDest(*it) == MapStorage::NESET_SECT) + main_arc_map_names.push_back(*it); + if (mapstorage->getArcMapSaveDest(*it) == MapStorage::GUI_SECT) + gui_arc_map_names.push_back(*it); + } + + { x("main_arc_map_names", main_arc_map_names); } + { x("gui_arc_map_names", gui_arc_map_names); } + + map arc_map_types; + for (vector::const_iterator it = main_arc_map_names.begin(); + it != main_arc_map_names.end(); ++it) + { + arc_map_types[*it] = mapstorage->getArcMapElementType(*it); + } + for (vector::const_iterator it = gui_arc_map_names.begin(); + it != gui_arc_map_names.end(); ++it) + { + arc_map_types[*it] = mapstorage->getArcMapElementType(*it); + } + + { x("arc_map_types", arc_map_types); } + + // write the gui node maps + for (vector::const_iterator it = gui_node_map_names.begin(); + it != gui_node_map_names.end(); ++it) + { + MapValue::Type type = mapstorage->getNodeMapElementType(*it); + const MapStorage::NodeLabelMap& labels = mapstorage->getNodeLabelMap(); + switch (type) + { + case MapValue::NUMERIC: + { + std::map map_data; + MapStorage::NumericNodeMap& map = + mapstorage->getNumericNodeMap(*it); + for (NodeIt n(mapstorage->getDigraph()); n != INVALID; ++n) + { + map_data[labels[n]] = map[n]; + } + { x(*it, map_data); } + } + break; + case MapValue::STRING: + { + std::map map_data; + MapStorage::StringNodeMap& map = + mapstorage->getStringNodeMap(*it); + for (NodeIt n(mapstorage->getDigraph()); n != INVALID; ++n) + { + map_data[labels[n]] = map[n]; + } + { x(*it, map_data); } + } + break; + } + } + + // write the gui arc maps + for (vector::const_iterator it = gui_arc_map_names.begin(); + it != gui_arc_map_names.end(); ++it) + { + MapValue::Type type = mapstorage->getArcMapElementType(*it); + const MapStorage::ArcLabelMap& labels = mapstorage->getArcLabelMap(); + switch (type) + { + case MapValue::NUMERIC: + { + std::map map_data; + MapStorage::NumericArcMap& map = + mapstorage->getNumericArcMap(*it); + for (ArcIt e(mapstorage->getDigraph()); e != INVALID; ++e) + { + map_data[labels[e]] = map[e]; + } + { x(*it, map_data); } + } + break; + case MapValue::STRING: + { + std::map map_data; + MapStorage::StringArcMap& map = + mapstorage->getStringArcMap(*it); + for (ArcIt e(mapstorage->getDigraph()); e != INVALID; ++e) + { + map_data[labels[e]] = map[e]; + } + { x(*it, map_data); } + } + break; + } + } + + { + switch (mapstorage->getNodeCoordsSaveDest()) + { + case MapStorage::SpecMapSaveOpts::GUI_SECT: + { x("node_coords_save_dest", string("gui_sect")); } + // write the node coorinates + { + const MapStorage::NodeLabelMap& labels = + mapstorage->getNodeLabelMap(); + std::map node_coord_map; + MapStorage::NodeCoordMap& map = mapstorage->getNodeCoordMap(); + for (NodeIt n(mapstorage->getDigraph()); n != INVALID; ++n) + { + node_coord_map[labels[n]] = map[n]; + } + { x("node_coord_map", node_coord_map); } + } + break; + case MapStorage::SpecMapSaveOpts::NESET_SECT: + switch (mapstorage->getNodeCoordsSaveMapNum()) + { + case MapStorage::SpecMapSaveOpts::ONE_MAP: + { x("node_coords_save_dest", string("nodeset_sect_1_map")); } + { x("map_name", mapstorage->getNodeCoordsOneMapName()); } + break; + case MapStorage::SpecMapSaveOpts::TWO_MAPS: + { x("node_coords_save_dest", string("nodeset_sect_2_maps")); } + { x("map1_name", mapstorage->getNodeCoordsTwoMaps1Name()); } + { x("map2_name", mapstorage->getNodeCoordsTwoMaps2Name()); } + break; + } + break; + } + } + + { + switch (mapstorage->getArrowCoordsSaveDest()) + { + case MapStorage::SpecMapSaveOpts::GUI_SECT: + { x("arrow_coords_save_dest", string("gui_sect")); } + // write the arrow coorinates + { + const MapStorage::ArcLabelMap& labels = + mapstorage->getArcLabelMap(); + std::map arrow_coord_map; + MapStorage::ArrowCoordMap& map = mapstorage->getArrowCoordMap(); + for (ArcIt e(mapstorage->getDigraph()); e != INVALID; ++e) + { + arrow_coord_map[labels[e]] = map[e]; + } + { x("arrow_coord_map", arrow_coord_map); } + } + break; + case MapStorage::SpecMapSaveOpts::NESET_SECT: + switch (mapstorage->getArrowCoordsSaveMapNum()) + { + case MapStorage::SpecMapSaveOpts::ONE_MAP: + { x("arrow_coords_save_dest", string("arcset_sect_1_map")); } + { x("map_name", mapstorage->getArrowCoordsOneMapName()); } + break; + case MapStorage::SpecMapSaveOpts::TWO_MAPS: + { x("arrow_coords_save_dest", string("arcset_sect_2_maps")); } + { x("map1_name", mapstorage->getArrowCoordsTwoMaps1Name()); } + { x("map2_name", mapstorage->getArrowCoordsTwoMaps2Name()); } + break; + } + break; + } + } + + + std::map nm; + for(int i=0;iactive_nodemaps[i]; + } + { x("active_nodemaps", nm); } + + std::map em; + for(int i=0;iactive_arcmaps[i]; + } + { x("active_arcmaps", em); } + + double attraction; + double propulsation; + int iteration; + + mapstorage->get_design_data(attraction, propulsation, iteration); + + { x("redesign-attraction", attraction); } + { x("redesign-propulsation", propulsation); } + { x("redesign-iteration", iteration); } +} + +//GuiWriter::GuiWriter(LemonWriter& writer, MapStorage* ms) : +GuiWriter::GuiWriter(MapStorage* ms) : + //Parent(writer), + mapstorage(ms) +{ +} diff -r 0e4f009eab8b -r 67188bd752db gui_writer.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gui_writer.h Mon Jul 07 08:10:39 2008 -0500 @@ -0,0 +1,35 @@ +/* -*- C++ -*- + * + * This file is a part of LEMON, a generic C++ optimization library + * + * Copyright (C) 2003-2006 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#ifndef GUI_WRITER_H +#define GUI_WRITER_H + +#include + +class MapStorage; + +class GuiWriter +{ + private: + MapStorage* mapstorage; + public: + virtual void write(std::ostream&); + GuiWriter(MapStorage*); +}; + +#endif diff -r 0e4f009eab8b -r 67188bd752db i18n.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/i18n.h Mon Jul 07 08:10:39 2008 -0500 @@ -0,0 +1,7 @@ +#ifndef I18N_H +#define I18N_H + +#include "gettext.h" +#define _(string) gettext (string) + +#endif diff -r 0e4f009eab8b -r 67188bd752db icons/addlink.png Binary file icons/addlink.png has changed diff -r 0e4f009eab8b -r 67188bd752db icons/addnode.png Binary file icons/addnode.png has changed diff -r 0e4f009eab8b -r 67188bd752db icons/delete.png Binary file icons/delete.png has changed diff -r 0e4f009eab8b -r 67188bd752db icons/editlink.png Binary file icons/editlink.png has changed diff -r 0e4f009eab8b -r 67188bd752db icons/editnode.png Binary file icons/editnode.png has changed diff -r 0e4f009eab8b -r 67188bd752db icons/eps.png Binary file icons/eps.png has changed diff -r 0e4f009eab8b -r 67188bd752db icons/move.png Binary file icons/move.png has changed diff -r 0e4f009eab8b -r 67188bd752db icons/newmap.png Binary file icons/newmap.png has changed diff -r 0e4f009eab8b -r 67188bd752db io_helper.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/io_helper.cc Mon Jul 07 08:10:39 2008 -0500 @@ -0,0 +1,34 @@ +#include "io_helper.h" + +namespace lemon { + void xml(XmlIo &x, MapValue::Type& v) + { + if(x.write()) { + switch (v) + { + case MapValue::NUMERIC: + { x("type", std::string("numeric")); } + break; + case MapValue::STRING: + { x("type", std::string("string")); } + break; + } + } + else { + std::string type; + { x("type", type); } + if (type == "numeric") + { + v = MapValue::NUMERIC; + } + else if (type == "string") + { + v = MapValue::STRING; + } + else + { + throw DataFormatError("Bad format"); + } + } + } +}; diff -r 0e4f009eab8b -r 67188bd752db io_helper.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/io_helper.h Mon Jul 07 08:10:39 2008 -0500 @@ -0,0 +1,11 @@ +#ifndef IO_HELPER +#define IO_HELPER + +#include "xml.h" +#include "map_value.h" + +namespace lemon { + void xml(XmlIo &x, MapValue::Type& v); +}; + +#endif diff -r 0e4f009eab8b -r 67188bd752db kruskalbox.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/kruskalbox.cc Mon Jul 07 08:10:39 2008 -0500 @@ -0,0 +1,83 @@ +/* -*- C++ -*- + * + * This file is a part of LEMON, a generic C++ optimization library + * + * Copyright (C) 2003-2006 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#include + +#include +#include +#include +#include + +enum {INPUT, OUTPUT, MAP_NUM}; + +KruskalBox::KruskalBox(std::vector t):AlgoBox() +{ + init(t); +} + +void KruskalBox::run() +{ + if( + tabcbt.get_active_text()!="" && + (arcmapcbts[INPUT])->get_active_text()!="" && + (arcmapcbts[OUTPUT])->get_active_text()!="" + ) + { + + const Digraph &g=mapstorage->getDigraph(); + std::string input_map_name = arcmapcbts[INPUT]->get_active_text(); + Digraph::ArcMap outputmap(g); + const MapStorage::NumericArcMap& inputmap= + mapstorage->getNumericArcMap(input_map_name); + double res=kruskal(g, inputmap, outputmap); + + for (ArcIt i(g); i!=INVALID; ++i) + { + if(outputmap[i]) + { + mapstorage->set(arcmapcbts[OUTPUT]->get_active_text(), i, 1.0); + } + else + { + mapstorage->set(arcmapcbts[OUTPUT]->get_active_text(), i, 0.0); + } + } + + std::ostringstream o; + o << "Result: " << res; + resultlabel.set_text(o.str()); + + mapstorage->mapChanged(true, (arcmapcbts[OUTPUT])->get_active_text()); + // mapstorage->changeActiveMap(true, E_COLOR, + // (arcmapcbts[OUTPUT])->get_active_text()); + // mapstorage->changeActiveMap(true, E_TEXT, + // (arcmapcbts[INPUT])->get_active_text()); + + } +} + +void KruskalBox::build_box() +{ + std::vector empty_vector; + + addMapSelector("Arccosts: ", true, NUM); + addMapSelector("Arcs of tree here: ", true, NUM); + + resultlabel.set_text("Result: algorithm is not run yet."); + pack_start(resultlabel); +} diff -r 0e4f009eab8b -r 67188bd752db kruskalbox.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/kruskalbox.h Mon Jul 07 08:10:39 2008 -0500 @@ -0,0 +1,58 @@ +/* -*- C++ -*- + * + * This file is a part of LEMON, a generic C++ optimization library + * + * Copyright (C) 2003-2006 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#ifndef KRUSKALBOX_H +#define KRUSKALBOX_H + +class AlgoBox; + +#include +#include +#include + +///Digraphical interface to run Kruskal algorithm. + +///Child of \ref AlgoBox, +///therefore the only task to do at implementation was to +/// +///-call init function with correct parameters from correctly parametrized constructor +/// +///-implement \ref build_box function +/// +///-implement \ref run function +class KruskalBox : public AlgoBox +{ + ///Shows result of Kruskal algorithm + Gtk::Label resultlabel; + +public: + ///Calls \ref AlgoBox::init function to initialize class properly, automatically. + KruskalBox(std::vector t); + + ///Prepare, run and postprocess Kruskal algorithm. + + ///\ref glemon works only with maps filled with double values + ///at the moment. While Kruskal nedds a bool map as output. + ///As postprocess this bool map should be transformed to + ///double map. + void run(); + + ///Builds the digraphical design of the interface. + void build_box(); +}; +#endif //KRUSKALBOX_H diff -r 0e4f009eab8b -r 67188bd752db m4/Makefile.am --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/m4/Makefile.am Mon Jul 07 08:10:39 2008 -0500 @@ -0,0 +1,30 @@ +EXTRA_DIST = \ + codeset.m4 \ + gettext.m4 \ + glibc21.m4 \ + glibc2.m4 \ + iconv.m4 \ + intdiv0.m4 \ + intmax.m4 \ + inttypes_h.m4 \ + inttypes.m4 \ + inttypes-pri.m4 \ + isc-posix.m4 \ + lcmessage.m4 \ + lib-ld.m4 \ + lib-link.m4 \ + lib-prefix.m4 \ + longdouble.m4 \ + longlong.m4 \ + nls.m4 \ + po.m4 \ + printf-posix.m4 \ + progtest.m4 \ + signed.m4 \ + size_max.m4 \ + stdint_h.m4 \ + uintmax_t.m4 \ + ulonglong.m4 \ + wchar_t.m4 \ + wint_t.m4 \ + xsize.m4 diff -r 0e4f009eab8b -r 67188bd752db main_win.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main_win.cc Mon Jul 07 08:10:39 2008 -0500 @@ -0,0 +1,657 @@ +/* -*- C++ -*- + * + * This file is a part of LEMON, a generic C++ optimization library + * + * Copyright (C) 2003-2006 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include "main_win.h" +#include "guipixbufs.h" +#include "save_details_dialog.h" +#include "background_chooser_dialog.h" + +#include +#include +#include +#include +#include + +#include "i18n.h" + +MainWin::MainWin() +{ + set_title ("no file"); + set_default_size(WIN_WIDTH,WIN_HEIGHT); + //add(vbox); + add(table); + + // custom icons for the toolbar + Glib::RefPtr p_icon_factory = Gtk::IconFactory::create(); + + Glib::RefPtr p_move_pixbuf = Gdk::Pixbuf::create_from_inline( + 2328, gui_icons_move); + Glib::RefPtr p_addnode_pixbuf = Gdk::Pixbuf::create_from_inline( + 2328, gui_icons_addnode); + Glib::RefPtr p_addlink_pixbuf = Gdk::Pixbuf::create_from_inline( + 2328, gui_icons_addlink); + Glib::RefPtr p_delete_pixbuf = Gdk::Pixbuf::create_from_inline( + 2328, gui_icons_delete); + Glib::RefPtr p_editlink_pixbuf = Gdk::Pixbuf::create_from_inline( + 2328, gui_icons_editlink); + Glib::RefPtr p_newmap_pixbuf = Gdk::Pixbuf::create_from_inline( + 2328, gui_icons_newmap); + Glib::RefPtr p_eps_pixbuf = Gdk::Pixbuf::create_from_inline( + 2328, gui_icons_eps); + + Gtk::IconSource move_icon_source; + move_icon_source.set_pixbuf(p_move_pixbuf); + Gtk::IconSet move_icon_set; + move_icon_set.add_source(move_icon_source); + p_icon_factory->add(Gtk::StockID("gd-move"), move_icon_set); + + Gtk::IconSource addnode_icon_source; + addnode_icon_source.set_pixbuf(p_addnode_pixbuf); + Gtk::IconSet addnode_icon_set; + addnode_icon_set.add_source(addnode_icon_source); + p_icon_factory->add(Gtk::StockID("gd-addnode"), addnode_icon_set); + + Gtk::IconSource addlink_icon_source; + addlink_icon_source.set_pixbuf(p_addlink_pixbuf); + Gtk::IconSet addlink_icon_set; + addlink_icon_set.add_source(addlink_icon_source); + p_icon_factory->add(Gtk::StockID("gd-addlink"), addlink_icon_set); + + Gtk::IconSource delete_icon_source; + delete_icon_source.set_pixbuf(p_delete_pixbuf); + Gtk::IconSet delete_icon_set; + delete_icon_set.add_source(delete_icon_source); + p_icon_factory->add(Gtk::StockID("gd-delete"), delete_icon_set); + + Gtk::IconSource editlink_icon_source; + editlink_icon_source.set_pixbuf(p_editlink_pixbuf); + Gtk::IconSet editlink_icon_set; + editlink_icon_set.add_source(editlink_icon_source); + p_icon_factory->add(Gtk::StockID("gd-editlink"), editlink_icon_set); + + Gtk::IconSource newmap_icon_source; + newmap_icon_source.set_pixbuf(p_newmap_pixbuf); + Gtk::IconSet newmap_icon_set; + newmap_icon_set.add_source(newmap_icon_source); + p_icon_factory->add(Gtk::StockID("gd-newmap"), newmap_icon_set); + + Gtk::IconSource eps_icon_source; + eps_icon_source.set_pixbuf(p_eps_pixbuf); + Gtk::IconSet eps_icon_set; + eps_icon_set.add_source(eps_icon_source); + p_icon_factory->add(Gtk::StockID("gd-eps"), eps_icon_set); + + p_icon_factory->add_default(); + + ag=Gtk::ActionGroup::create(); + + ag->add( Gtk::Action::create("FileMenu", _("_File")) ); + ag->add( Gtk::Action::create("FileNew", Gtk::Stock::NEW), + sigc::mem_fun(*this, &MainWin::newTab)); + ag->add( Gtk::Action::create("FileOpen", Gtk::Stock::OPEN), + sigc::mem_fun(*this, &MainWin::openFile)); + ag->add( Gtk::Action::create("FileClearTab", _("Clear Tab")), + sigc::mem_fun(*this, &MainWin::newFile)); + ag->add( Gtk::Action::create("FileSave", Gtk::Stock::SAVE), + sigc::mem_fun(*this, &MainWin::saveFile)); + ag->add( Gtk::Action::create("FileSaveAs", Gtk::Stock::SAVE_AS), + sigc::mem_fun(*this, &MainWin::saveFileAs)); + ag->add( Gtk::Action::create("SaveDetails", _("Save _Details...")), + sigc::mem_fun(*this, &MainWin::createSaveDetailsDialog)); + ag->add( Gtk::Action::create("Close", Gtk::Stock::CLOSE), + sigc::mem_fun(*this, &MainWin::closeTab)); + ag->add( Gtk::Action::create("Quit", Gtk::Stock::QUIT), + sigc::mem_fun(*this, &MainWin::hide)); + + ag->add( Gtk::Action::create("ViewMenu", _("_View")) ); + ag->add( Gtk::Action::create("ViewZoomIn", Gtk::Stock::ZOOM_IN), + sigc::mem_fun(*this, &MainWin::zoomIn)); + ag->add( Gtk::Action::create("ViewZoomOut", Gtk::Stock::ZOOM_OUT), + sigc::mem_fun(*this, &MainWin::zoomOut)); + ag->add( Gtk::Action::create("ViewZoomFit", Gtk::Stock::ZOOM_FIT), + sigc::mem_fun(*this, &MainWin::zoomFit)); + ag->add( Gtk::Action::create("ViewZoom100", Gtk::Stock::ZOOM_100), + sigc::mem_fun(*this, &MainWin::zoom100)); + ag->add( Gtk::Action::create("SetBackground", _("Set Background...")), + sigc::mem_fun(*this, &MainWin::createBackgroundChooser)); + + ag->add( Gtk::Action::create("ShowMenu", _("_Show")) ); + ag->add( Gtk::Action::create("ShowMaps", _("_Maps")), + sigc::mem_fun(*this, &MainWin::createMapWin)); + ag->add( Gtk::Action::create("ShowDesign", _("_Design")), + sigc::mem_fun(*this, &MainWin::createDesignWin)); + + ag->add( Gtk::Action::create("AlgoMenu", _("_Algorithms")) ); + ag->add( Gtk::Action::create("AlgoGeneral", _("_General")), + sigc::bind( sigc::mem_fun ( *this, &MainWin::createAlgoWin ), 0) ); + ag->add( Gtk::Action::create("AlgoKruskal", _("_Kruskal")), + sigc::bind( sigc::mem_fun ( *this, &MainWin::createAlgoWin ), 1) ); + ag->add( Gtk::Action::create("AlgoDijkstra", _("_Dijkstra")), + sigc::bind( sigc::mem_fun ( *this, &MainWin::createAlgoWin ), 2) ); + ag->add( Gtk::Action::create("AlgoSuurballe", _("_Suurballe")), + sigc::bind( sigc::mem_fun ( *this, &MainWin::createAlgoWin ), 3) ); + + Gtk::RadioAction::Group tool_group; + ag->add( Gtk::RadioAction::create(tool_group, "MoveItem", Gtk::StockID("gd-move"), _("Move")), + sigc::bind( sigc::mem_fun ( *this, &MainWin::changeEditorialTool ), 0) ); + ag->add( Gtk::RadioAction::create(tool_group, "CreateNode", Gtk::StockID("gd-addnode"), _("Create node")), + sigc::bind( sigc::mem_fun ( *this, &MainWin::changeEditorialTool ), 1) ); + ag->add( Gtk::RadioAction::create(tool_group, "CreateArc", Gtk::StockID("gd-addlink"), _("Create arc")), + sigc::bind( sigc::mem_fun ( *this, &MainWin::changeEditorialTool ), 2) ); + ag->add( Gtk::RadioAction::create(tool_group, "EraseItem", Gtk::StockID("gd-delete"), _("Delete")), + sigc::bind( sigc::mem_fun ( *this, &MainWin::changeEditorialTool ), 3) ); + + ag->add( Gtk::RadioAction::create(tool_group, "EditArcMap", Gtk::StockID("gd-editlink"), _("Edit arc map")), + sigc::bind( sigc::mem_fun ( *this, &MainWin::changeEditorialTool ), 4) ); + + ag->add( Gtk::Action::create("AddMap", Gtk::StockID("gd-newmap"), "New map"), + sigc::mem_fun ( *this , &MainWin::createNewMapWin ) ); + + ag->add( Gtk::Action::create("DesignDigraph", Gtk::Stock::REFRESH), + sigc::mem_fun ( *this , &MainWin::reDesignDigraph ) ); + + ag->add( Gtk::Action::create("Eps", Gtk::StockID("gd-eps"), "Export to EPS"), + sigc::mem_fun ( *this , &MainWin::exportToEPS ) ); + + uim=Gtk::UIManager::create(); + uim->insert_action_group(ag); + add_accel_group(uim->get_accel_group()); + + try + { + + Glib::ustring ui_info = + "" + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + ""; + + uim->add_ui_from_string(ui_info); + + } + catch(const Glib::Error& ex) + { + std::cerr << "building menus failed: " << ex.what(); + } + + Gtk::Widget* menubar = uim->get_widget("/MenuBar"); + if (menubar){ + //vbox.pack_start(*menubar, Gtk::PACK_SHRINK); + table.attach(*menubar, 0, 1, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::SHRINK); + } + + Gtk::Widget* toolbar = uim->get_widget("/ToolBar"); + if (toolbar) + { + static_cast(toolbar)->set_toolbar_style(Gtk::TOOLBAR_ICONS); + static_cast(toolbar)->set_tooltips(true); + //hbox.pack_start(*toolbar, Gtk::PACK_EXPAND_WIDGET); + + table.attach(*toolbar, 0, 1, 1, 2, Gtk::EXPAND|Gtk::FILL, Gtk::SHRINK); + + } + + table2.set_row_spacings(10); + table2.set_col_spacings(5); + + auto_scale = Gtk::manage(new Gtk::CheckButton("Autoscale")); + auto_scale->set_active(false); + auto_scale->signal_toggled().connect(sigc::mem_fun(*this, &MainWin::nodeViewChanged)); + table2.attach(*auto_scale, 0,2,0,1); + + Gtk::Label * width_label=Gtk::manage(new Gtk::Label("Arc Width:")); + table2.attach(*width_label, 0,1,1,2); + + Gtk::Adjustment * adjustment_width=Gtk::manage(new Gtk::Adjustment(20, 1, 200, 5, 10)); + + arc_width = Gtk::manage(new Gtk::SpinButton(*adjustment_width, 5,0)); + arc_width->signal_value_changed().connect(sigc::mem_fun(*this, &MainWin::nodeViewChanged)); + table2.attach(*arc_width, 1,2,1,2); + + Gtk::Label * radius_label= Gtk::manage(new Gtk::Label("Node Radius:")); + table2.attach(*radius_label, 2,3,1,2); + + Gtk::Adjustment * adjustment_radius=Gtk::manage(new Gtk::Adjustment(20, 0, 500, 5, 10)); + + radius_size = Gtk::manage(new Gtk::SpinButton(*adjustment_radius, 5,0)); + radius_size->signal_value_changed().connect(sigc::mem_fun(*this, &MainWin::nodeViewChanged)); + table2.attach(*radius_size, 3,4,1,2); + + zoom_track = Gtk::manage(new Gtk::CheckButton("Zoom tracking")); + zoom_track->set_active(false); + zoom_track->signal_toggled().connect(sigc::mem_fun(*this, &MainWin::nodeViewChanged)); + table2.attach(*zoom_track, 2,4,0,1); + + + table.attach(table2, 1, 2, 0, 2, Gtk::SHRINK, Gtk::SHRINK); + + tooltips=Gtk::manage(new Gtk::Tooltips()); + if(tooltips) + { + tooltips->set_tip(*zoom_track, "If on, arc widths and node radiuses are constant, independent from zooming"); + tooltips->set_tip(*auto_scale, "If on, glemon automatically determines the size of arcs and nodes"); + tooltips->set_tip(*radius_size, "Sets maximum node radius, if auto-scale is off"); + tooltips->set_tip(*arc_width, "Sets maximum arc width, if auto-scale is off"); + + static_cast(uim->get_widget("/ToolBar/FileNew"))->set_tooltip(*tooltips, "Inserts new tab"); + static_cast(uim->get_widget("/ToolBar/FileOpen"))->set_tooltip(*tooltips, "Lets you open a file"); + static_cast(uim->get_widget("/ToolBar/FileSave"))->set_tooltip(*tooltips, "Saves the digraph on the active tab"); + static_cast(uim->get_widget("/ToolBar/Close"))->set_tooltip(*tooltips, "Closes the active tab"); + static_cast(uim->get_widget("/ToolBar/ViewZoomIn"))->set_tooltip(*tooltips, "Zoom in the digraph"); + static_cast(uim->get_widget("/ToolBar/ViewZoomOut"))->set_tooltip(*tooltips, "Zoom out the digraph"); + static_cast(uim->get_widget("/ToolBar/ViewZoom100"))->set_tooltip(*tooltips, "Shows actual size of digraph"); + static_cast(uim->get_widget("/ToolBar/ViewZoomFit"))->set_tooltip(*tooltips, "Fits digraph into window"); + static_cast(uim->get_widget("/ToolBar/MoveItem"))->set_tooltip(*tooltips, "Moves the clicked item (arc/node)"); + static_cast(uim->get_widget("/ToolBar/CreateNode"))->set_tooltip(*tooltips, "Adds new node"); + static_cast(uim->get_widget("/ToolBar/CreateArc"))->set_tooltip(*tooltips, "Lets you create new arc"); + static_cast(uim->get_widget("/ToolBar/EraseItem"))->set_tooltip(*tooltips, "Erases the clicked item (arc/node)"); + static_cast(uim->get_widget("/ToolBar/EditArcMap"))->set_tooltip(*tooltips, "Lets you edit the values written on the items"); + static_cast(uim->get_widget("/ToolBar/AddMap"))->set_tooltip(*tooltips, "Adds arc/nodemap"); + static_cast(uim->get_widget("/ToolBar/DesignDigraph"))->set_tooltip(*tooltips, "Redesigns your digraph, supposing elastic arcs and propulsation of nodes."); + + tooltips->enable(); + } + + active_tab=-1; + notebook.signal_switch_page().connect(sigc::mem_fun(*this, &MainWin::onChangeTab)); + + active_tool = MOVE; + + table.attach(notebook,0,2,2,3, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL); + + show_all_children(); +} + +MainWin::~MainWin() +{ +} + +void MainWin::set_tabtitle(std::string name) +{ + if(strinst.find(name)==strinst.end()) + { + tabnames[active_tab]=name; + strinst[name]=1; + } + else + { + strinst[name]++; + std::ostringstream o; + o << strinst[name]; + tabnames[active_tab]=name+" - "+o.str(); + } + set_title(tabnames[active_tab] + " - " + prog_name); + notebook.set_tab_label_text((Widget&)*(tabs[active_tab]), tabnames[active_tab]); + updateAlgoWinTabs(); +} + +void MainWin::readFile(const std::string & filename) +{ + newTab(); + tabs[active_tab]->readFile(filename); +} + +void MainWin::newTab() +{ + int size=tabs.size(); + tabs.resize(size+1); + tabnames.resize(size+1); + active_tab=size; + tabs[active_tab]=Gtk::manage(new NoteBookTab()); + tabs[active_tab]->signal_title_ch().connect(sigc::mem_fun(*this, &MainWin::set_tabtitle)); + tabs[active_tab]->signal_newmap_needed().connect(sigc::mem_fun(*this, &MainWin::createNewMapWinAfterSignal)); + tabs[active_tab]->gd_canvas->changeEditorialTool(active_tool); + notebook.append_page((Gtk::Widget&)(*(tabs[active_tab]))); + notebook.set_current_page(size); + set_tabtitle(_("unsaved file")); + updateAlgoWinTabs(); +} + +void MainWin::closeTab() +{ + if(active_tab!=-1) + { + if (tabs[active_tab]->mapstorage->getModified()) + { + Gtk::MessageDialog mdialog(_("Save changes before closing?"), true, + Gtk::MESSAGE_WARNING, Gtk::BUTTONS_NONE); + mdialog.add_button(_("Close file _without Saving"), Gtk::RESPONSE_REJECT); + mdialog.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL); + mdialog.add_button(Gtk::Stock::SAVE, Gtk::RESPONSE_ACCEPT); + switch (mdialog.run()) + { + case Gtk::RESPONSE_CANCEL: + return; + case Gtk::RESPONSE_REJECT: + break; + case Gtk::RESPONSE_ACCEPT: + tabs[active_tab]->saveFile(); + break; + } + } + //tabs vector will be decreased with the deleted value + int size=tabs.size(); + if(size>1) + { + for(int i=active_tab+1;igd_canvas->changeEditorialTool(active_tool); + set_title(tabnames[active_tab]); + bool autoscale; + bool zoomtrack; + double width; + double radius; + tabs[active_tab]->getView(autoscale, zoomtrack, width, radius); + arc_width->set_value(width); + radius_size->set_value(radius); + zoom_track->set_active(zoomtrack); + auto_scale->set_active(autoscale); + +} + +void MainWin::newFile() +{ + if(active_tab!=-1) + { + tabs[active_tab]->newFile(); + } +} + +void MainWin::openFile() +{ + if(active_tab==-1) + { + newTab(); + } + tabs[active_tab]->openFile(); +} + +void MainWin::saveFile() +{ + if(active_tab!=-1) + { + tabs[active_tab]->saveFile(); + } +} + +void MainWin::saveFileAs() +{ + if(active_tab!=-1) + { + tabs[active_tab]->saveFileAs(); + } +} + +void MainWin::close() +{ + if(active_tab!=-1) + { + tabs[active_tab]->close(); + } +} + +void MainWin::zoomIn() +{ + if(active_tab!=-1) + { + tabs[active_tab]->gd_canvas->zoomIn(); + } +} + +void MainWin::zoomOut() +{ + if(active_tab!=-1) + { + tabs[active_tab]->gd_canvas->zoomOut(); + } +} + +void MainWin::zoomFit() +{ + if(active_tab!=-1) + { + tabs[active_tab]->gd_canvas->zoomFit(); + } +} + +void MainWin::zoom100() +{ + if(active_tab!=-1) + { + tabs[active_tab]->gd_canvas->zoom100(); + } +} + +void MainWin::createMapWin() +{ + if(active_tab!=-1) + { + tabs[active_tab]->createMapWin(tabnames[active_tab]); + } +} + +void MainWin::createDesignWin() +{ + if(active_tab!=-1) + { + tabs[active_tab]->createDesignWin(tabnames[active_tab]); + } +} + +void MainWin::createAlgoWin(int algoid) +{ + AlgoWin * aw=Gtk::manage(new AlgoWin(algoid, tabnames)); + aw->signal_closing().connect(sigc::mem_fun(*this, &MainWin::deRegisterAlgoWin)); + aw->signal_maplist_needed().connect(sigc::mem_fun(*this, &MainWin::updateAlgoWinMaps)); + aw->signal_newmapwin_needed().connect(sigc::mem_fun(*this, &MainWin::createNewMapWinTabString)); + aws.insert(aw); + aw->show(); +} + +void MainWin::updateAlgoWinTabs() +{ + std::set< AlgoWin* >::iterator awsi=aws.begin(); + for(;awsi!=aws.end();awsi++) + { + (*awsi)->update_tablist(tabnames); + } +} + +void MainWin::updateAlgoWinMaps(AlgoWin * awp, std::string tabname) +{ + int i=0; + for(;(i<(int)tabnames.size())&&(tabnames[i]!=tabname);i++) + { + } + awp->update_maplist(tabs[i]->mapstorage); +} + +void MainWin::deRegisterAlgoWin(AlgoWin * awp) +{ + aws.erase(awp); +} + +void MainWin::changeEditorialTool(int tool) +{ + active_tool=tool; + if(active_tab!=-1) + { + tabs[active_tab]->gd_canvas->changeEditorialTool(tool); + } +} + +void MainWin::createNewMapWin() +{ + if(active_tab!=-1) + { + NewMapWin * nmw=Gtk::manage(new NewMapWin(_("Create New Map - ")+tabnames[active_tab], *(tabs[active_tab]))); + nmw->show(); + } +} + +void MainWin::createNewMapWinTabString(std::string tabname, bool itisarc) +{ + int i=0; + for(;((i<(int)tabnames.size())&&(tabnames[i]!=tabname));i++) + { + } + createNewMapWinAfterSignal(tabs[i], itisarc); +} + +void MainWin::createNewMapWinAfterSignal(NoteBookTab * nbt, bool itisarc) +{ + std::vector::iterator nbti=tabs.begin(); + int i=0; + for(;nbti!=tabs.end();nbti++) + { + if(*nbti!=nbt) + { + i++; + } + else + { + continue; + } + } + NewMapWin * nmw=Gtk::manage(new NewMapWin(_("Create New Map - ")+tabnames[i], *nbt, itisarc, false)); + nmw->run(); +} + + +void MainWin::nodeViewChanged() +{ + double width=arc_width->get_value(); + double radius=radius_size->get_value(); + bool zoomtrack=zoom_track->get_active(); + bool autoscale=auto_scale->get_active(); + tabs[active_tab]->setView(autoscale, zoomtrack, width, radius); +} + +void MainWin::reDesignDigraph() +{ + tabs[active_tab]->reDesignDigraph(); +} + +void MainWin::createSaveDetailsDialog() +{ + SaveDetailsDialog dialog(tabs[active_tab]->mapstorage); + dialog.run(); +} + +void MainWin::exportToEPS() +{ + if(active_tab!=-1) + { + tabs[active_tab]->createExportToEPSWin(tabnames[active_tab]); + } +} + +void MainWin::createBackgroundChooser() +{ + BackgroundChooserDialog dialog(tabs[active_tab]->mapstorage); + dialog.run(); +} diff -r 0e4f009eab8b -r 67188bd752db main_win.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main_win.h Mon Jul 07 08:10:39 2008 -0500 @@ -0,0 +1,273 @@ +/* -*- C++ -*- + * + * This file is a part of LEMON, a generic C++ optimization library + * + * Copyright (C) 2003-2006 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#ifndef MAIN_WIN_H +#define MAIN_WIN_H + +#include "all_include.h" +#include +#include +#include + +class AlgoWin; +class NoteBookTab; + +///This class is the main window of GUI. + +///It has menus, and a notebook. Notebook has different pages, +///the so called tabs (\ref NoteBookTab). Each \ref NoteBookTab contains a canvas on which digraphs can be drawn. +///To manage creation and close of tabs and tabswitching is the task of MainWin. +class MainWin : public Gtk::Window +{ + ///Container in which the menus and the notebook is. + //Gtk::VBox vbox; + Gtk::Table table; + Gtk::Table table2; + + ///Container in which the toolbar and the node parametrizer is. + Gtk::HBox hbox; + + ///Should nodes be autoscaled or not? + Gtk::CheckButton * auto_scale; + + ///Should node size track zoom factor? + Gtk::CheckButton * zoom_track; + + ///Minimum and maximum node radius entry + Gtk::SpinButton * radius_size, * arc_width; + + ///The notebook that has tabs (\ref NoteBookTab) with different digraphs. + Gtk::Notebook notebook; + + ///The tool selected to manipulate digraph. + + ///It has to be stored, because in case of tabswitching + ///the correct tool has to be set for the actual digraph. + int active_tool; + + ///The number of active tab in the notebook. + int active_tab; + + ///Vector of existing tabs in the notebook. + std::vector tabs; + + ///Vector of the name of tabs. + + ///All \ref NoteBookTab has a name that is stored here. The index of the name + ///is the same as the index of the \ref NoteBookTab in \ref tabs. + std::vector tabnames; + + ///Counter of occurence of the same file names. + + ///If a file is opened more than once we have to score + ///the occurences to let the titles on tabs different. + ///If more than one occurence is present, from the second + ///one near the filename the number of the occurence appear. + std::map strinst; + + ///Set of opened \ref AlgoWin s. + + ///More than one \refAlgoWin can be opened. We have to + ///communicate with them in case of new \ref NoteBookTab creation, + ///\ref NoteBookTab close, or map change. Therefore we have to score + ///their occurences. + std::set< AlgoWin* > aws; + +public: + + ///Constructor of the \ref MainWin. + + ///It creates the menus, the toolbar and the notebook in which + ///\ref NoteBookTab s take place. \ref NoteBookTab s are the + ///holder of the canvases on which the digraphs are drawn. + MainWin(); + + ~MainWin(); + ///Sets title of tabs. + + ///It alse registrates it in \ref tabnames. If more than one + ///occurence is in the notebook of the same file it has to + ///extend tabname with the number of occurence. + void set_tabtitle(std::string); + + ///ActionGroup for menu + Glib::RefPtr ag; + + ///UIManager for menu + Glib::RefPtr uim; + + ///Creates a new \ref NoteBookTab and opens the given file. + + ///It is called only with command line parameters at stratup. + void readFile(const std::string &); + + ///Tooltips + Gtk::Tooltips * tooltips; + + //Call-backs of buttons + + ///Callback for 'FileNew' action. + virtual void newFile(); + ///Callback for 'FileOpen' action. + virtual void openFile(); + ///Callback for 'FileSave' action. + virtual void saveFile(); + ///Callback for 'FileSaveAs' action. + virtual void saveFileAs(); + ///Callback for 'Close' action. + virtual void close(); + + //Toolbar + + ///Callback for 'zoomIn' action. + + ///It calls the appropriate function in + ///\ref DigraphDisplayerCanvas + virtual void zoomIn(); + ///Callback for 'zoomOut' action. + + ///It calls the appropriate function in + ///\ref DigraphDisplayerCanvas + virtual void zoomOut(); + ///Callback for 'zoomFit' action. + + ///It calls the appropriate function in + ///\ref DigraphDisplayerCanvas + virtual void zoomFit(); + ///Callback for 'zoom100' action. + + ///It calls the appropriate function in + ///\ref DigraphDisplayerCanvas + virtual void zoom100(); + + ///Callback for Show Maps menupoint. + + ///It calls the appropriate function in + ///\ref NoteBookTab + virtual void createMapWin(); + + ///Callback for Show Design menupoint. + + ///It calls the appropriate function in + ///\ref NoteBookTab + virtual void createDesignWin(); + + ///Pops up an Algorithm window. + + ///It not only creates but registrates the newly created \ref AlgoWin. + ///It is necessary, because in case of changement between tabs or maps + ///we have to communicate with it. Signals are also have to be connected + ///to it, because \ref AlgoWin emits signals if it needs anything (maplist, deregistration). + ///\param algo type of the algorithm to run. + virtual void createAlgoWin(int algo); + + ///Deregisters AlgoWin + + ///This is the function connected to the closing signal of \ref AlgoWin. + ///It only deletes the sender \ref AlgoWin from \ref aws. This function + ///is called only by the closing \ref AlgoWin itself. + ///\param aw the \ref AlgoWin to delete. + virtual void deRegisterAlgoWin(AlgoWin * aw); + + ///Updates list of tabs in all of the \ref AlgoWin + + ///When \ref NoteBookTab inserted somewhere or closed one tablist in all \ref AlgoWin + ///have to be updated. That is why we score all the opened \ref AlgoWin. + ///During update \ref tabnames will be passed to each \ref AlgoWin. + virtual void updateAlgoWinTabs(); + + ///Refresh list of maps in the AlgoWin that requested it. + + ///In an \ref AlgoWin there is a ComboBoxText, in which + ///a \ref NoteBookTab can be chosen that contains the digraph and the maps, + ///on which we would like to run algorithms. If we change the + ///tab the available maps also have to be updated, because + ///in the different tabs different maps are available. Therefore + ///on tab change the \ref AlgoWin emits a signal that contains itself + ///so that the appropriate maps can be sent to it. For the sake of simplicity + ///the program answers this call with the mapstorage of the newly selected tab. + ///\param aw the caller \ref AlgoWin + ///\param tabname the newly selected tab in the \ref AlgoWin + virtual void updateAlgoWinMaps(AlgoWin * aw, std::string tabname); + + ///Registrates the new digraph-editor tool in hand. + + ///The editor-tool in hand is global, it is the same for all tab + ///at the same time. Therefore the active tool has to be scored here (\ref active_tool). + ///This function is the callback function of the editor-tool buttons. It sets \ref active_tool + ///to the correct value. + ///\param tool the newly selected digraph-editor tool (See all_include.h) + virtual void changeEditorialTool(int tool); + + ///Pops up a \ref NewMapWin dialog after requested by a \ref MapWin + + ///Each tab can pop-up a \ref MapWin. In \ref MapWin new tab can be created. + ///In this case \ref NoteBookTab emits a signal. This function is connected to that signal. + ///It sends the caller \ref NoteBookTab and whether an arcmap or a nodemap should be created. + ///Caller \ref NoteBookTab is necessary for the window to be able to place the new map in its + ///correct place. + ///\param nbt the caller tab + ///\param itisarc true if arcmap has to be created, false if nodemap + virtual void createNewMapWinAfterSignal(NoteBookTab * nbt, bool itisarc); + + ///Pops up a \ref NewMapWin dialog after requested by an \ref AlgoWin + + ///\ref AlgoWin can also can request a \ref NewMapWin to pop-up. + ///It emits a signal in this case. This function is bound to that signal. + ///The signal contains the name of \ref NoteBookTab in which the new map has to be + ///placed and whether the new map is an arcmap or a nodemap. + ///\ref tabname the tab in which the new map has to be placed + ///\ref itisarc true if the new map will be arc map, false if it will be nodemap + virtual void createNewMapWinTabString(std::string tabname, bool itisarc); + + ///Pops up a \ref NewMapWin dialog if button on \ref MainWin has been pressed. + + ///In this case a general \ref NewMapWin will be popped up. This means that + ///both arc and nodemap can be created by it. The new map will be placed in + ///\MapStorage of the actual selected \ref NoteBookTab. + virtual void createNewMapWin(); + + //Notebook handlers + ///Callback for 'FileNewTab' action. + virtual void newTab(); + + ///Callback for 'FileCloseTab' action. + + ///It closes the actual \ref NoteBookTab and registrates this event: + ///data is shifted to the correct places in vectors. + virtual void closeTab(); + + ///Tabswitching handler + + ///Sets the variables that have to store the actual state, and it + ///updates the title of window to the actually selected \ref NoteBookTab. + virtual void onChangeTab(GtkNotebookPage*, guint); + + virtual void nodeViewChanged(); + + virtual void reDesignDigraph(); + + /// Pops up a SaveDetailsDialog. + void createSaveDetailsDialog(); + + virtual void exportToEPS(); + + void createBackgroundChooser(); +}; + +#endif //MAIN_WIN_H diff -r 0e4f009eab8b -r 67188bd752db map_value.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/map_value.cc Mon Jul 07 08:10:39 2008 -0500 @@ -0,0 +1,153 @@ +#include "map_value.h" +#include +#include + +MapValue::MapValue() +{ + //std::cout << __PRETTY_FUNCTION__ << std::endl; + has_value = false; +} + +MapValue::MapValue(double d) +{ + //std::cout << __PRETTY_FUNCTION__ << std::endl; + p_value = new double(d); + type = NUMERIC; + has_value = true; +} + +MapValue::MapValue(std::string str) +{ + //std::cout << __PRETTY_FUNCTION__ << std::endl; + p_value = new std::string(str); + type = STRING; + has_value = true; +} + +MapValue::MapValue(const char* str) +{ + //std::cout << __PRETTY_FUNCTION__ << std::endl; + p_value = new std::string(str); + type = STRING; + has_value = true; +} + +MapValue::operator double() const +{ + //std::cout << __PRETTY_FUNCTION__ << std::endl; + if (!has_value) throw IllegalOperation(); + if (type == NUMERIC) + return *(static_cast(p_value)); + else + throw IllegalOperation(); +} + +MapValue::operator std::string() const +{ + //std::cout << __PRETTY_FUNCTION__ << std::endl; + if (!has_value) throw IllegalOperation(); + std::string ret; + switch (type) + { + case NUMERIC: + { + double d = *(static_cast(p_value)); + std::ostringstream ostr; + ostr << d; + ret = ostr.str(); + } + break; + case STRING: + ret = *(static_cast(p_value)); + break; + } + return ret; +} + +MapValue::MapValue(const MapValue& v) +{ + //std::cout << __PRETTY_FUNCTION__ << std::endl; + if (!v.has_value) throw IllegalOperation(); + has_value = true; + type = v.type; + switch (v.type) + { + case NUMERIC: + p_value = new double(*(static_cast(v.p_value))); + break; + case STRING: + p_value = new std::string(*(static_cast(v.p_value))); + break; + } +} + +MapValue& MapValue::operator=(const MapValue& v) +{ + //std::cout << __PRETTY_FUNCTION__ << std::endl; + if (&v != this) + { + if (!v.has_value) throw IllegalOperation(); + clear(); + has_value = true; + type = v.type; + switch (v.type) + { + case NUMERIC: + p_value = new double(*(static_cast(v.p_value))); + break; + case STRING: + p_value = new std::string(*(static_cast(v.p_value))); + break; + } + } + return *this; +} + +MapValue::~MapValue() +{ + //std::cout << __PRETTY_FUNCTION__ << std::endl; + clear(); +} + +void MapValue::clear() +{ + //std::cout << __PRETTY_FUNCTION__ << std::endl; + if (!has_value) return; + switch (type) + { + case NUMERIC: + delete static_cast(p_value); + break; + case STRING: + delete static_cast(p_value); + break; + } +} + +MapValue::Type MapValue::getType() const +{ + //std::cout << __PRETTY_FUNCTION__ << std::endl; + return type; +} + +bool MapValue::hasValue() const +{ + //std::cout << __PRETTY_FUNCTION__ << std::endl; + return has_value; +} + +std::ostream& operator<<(std::ostream &os, const MapValue& v) +{ + //std::cout << __PRETTY_FUNCTION__ << std::endl; + if (!v.has_value) return os; + switch (v.type) + { + case MapValue::NUMERIC: + os << *(static_cast(v.p_value)); + break; + case MapValue::STRING: + os << *(static_cast(v.p_value)); + break; + } + return os; +} diff -r 0e4f009eab8b -r 67188bd752db map_value.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/map_value.h Mon Jul 07 08:10:39 2008 -0500 @@ -0,0 +1,43 @@ +#ifndef MAP_VALUE_H +#define MAP_VALUE_H + +#include +#include +#include + +class MapValue +{ + public: + friend std::ostream& operator<<(std::ostream &os, const MapValue& v); + class IllegalOperation : public std::exception + { + virtual const char* what() const throw() + { + return "Illegal operation."; + } + }; + typedef enum + { + NUMERIC = 1 << 0, + STRING = 1 << 1 + } Type; + private: + bool has_value; + void* p_value; + MapValue::Type type; + void clear(); + public: + MapValue(); + MapValue(double); + MapValue(std::string); + MapValue(const char* str); + MapValue(const MapValue& v); + MapValue& operator=(const MapValue& v); + ~MapValue(); + operator std::string() const; + operator double() const; + Type getType() const; + bool hasValue() const; +}; + +#endif diff -r 0e4f009eab8b -r 67188bd752db map_value_map.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/map_value_map.cc Mon Jul 07 08:10:39 2008 -0500 @@ -0,0 +1,32 @@ +#include "map_value_map.h" +#include "mapstorage.h" + +MapValueArcMap::MapValueArcMap(const std::string& _mapName, MapStorage* _pMapStorage) : + mapName(_mapName), + pMapStorage(_pMapStorage) +{ +} + +MapValueArcMap::Value MapValueArcMap::operator[](Key k) const { + return pMapStorage->get(mapName, k); +} + +void MapValueArcMap::set(Key k, Value v) +{ + pMapStorage->set(mapName, k, v); +} + +MapValueNodeMap::MapValueNodeMap(const std::string& _mapName, MapStorage* _pMapStorage) : + mapName(_mapName), + pMapStorage(_pMapStorage) +{ +} + +MapValueNodeMap::Value MapValueNodeMap::operator[](Key k) const { + return pMapStorage->get(mapName, k); +} + +void MapValueNodeMap::set(Key k, Value v) +{ + pMapStorage->set(mapName, k, v); +} diff -r 0e4f009eab8b -r 67188bd752db map_value_map.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/map_value_map.h Mon Jul 07 08:10:39 2008 -0500 @@ -0,0 +1,36 @@ +#ifndef MAP_VALUE_MAP_H +#define MAP_VALUE_MAP_H + +#include "map_value.h" +#include +#include "all_include.h" + +class MapStorage; + +class MapValueArcMap +{ + private: + std::string mapName; + MapStorage* pMapStorage; + public: + typedef MapValue Value; + typedef Digraph::Arc Key; + MapValueArcMap(const std::string&, MapStorage*); + Value operator[](Key k) const; + void set(Key k, Value v); +}; + +class MapValueNodeMap +{ + private: + std::string mapName; + MapStorage* pMapStorage; + public: + typedef MapValue Value; + typedef Digraph::Node Key; + MapValueNodeMap(const std::string&, MapStorage*); + Value operator[](Key k) const; + void set(Key k, Value v); +}; + +#endif diff -r 0e4f009eab8b -r 67188bd752db map_win.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/map_win.cc Mon Jul 07 08:10:39 2008 -0500 @@ -0,0 +1,204 @@ +/* -*- C++ -*- + * + * This file is a part of LEMON, a generic C++ optimization library + * + * Copyright (C) 2003-2006 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#include +#include +#include +#include + +bool MapWin::closeIfEscapeIsPressed(GdkEventKey* e) +{ + if(e->keyval==GDK_Escape) + { + mytab.closeMapWin(); + // hide(); + } + return true; +} + +MapWin::MapWin(const std::string& title, + std::vector n_eml, + std::vector s_eml, + std::vector n_nml, + std::vector s_nml, + NoteBookTab & mw):mytab(mw) +{ + set_title(title); + set_default_size(200, 50); + + set_resizable(false); + + signal_key_press_event().connect(sigc::mem_fun(*this, &MapWin::closeIfEscapeIsPressed)); + + mytab.signal_title_ch().connect(sigc::mem_fun(*this, &MapWin::set_title)); + + e_combo_array=new MapSelector * [EDGE_PROPERTY_NUM]; + + table=new Gtk::Table(EDGE_PROPERTY_NUM, 1, false); + + for(int i=0;isignal_cbt_ch().connect(sigc::bind(sigc::mem_fun(*this, &MapWin::arcMapChanged), i)); + e_combo_array[i]->signal_newmapwin_needed().connect(sigc::mem_fun(*this, &MapWin::newMapWinNeeded)); + } + + vbox.pack_start(*(new Gtk::Label("Arc properties"))); + + vbox.pack_start(*table); + + vbox.pack_start(*(new Gtk::HSeparator)); + + n_combo_array=new MapSelector * [NODE_PROPERTY_NUM]; + + table=new Gtk::Table(NODE_PROPERTY_NUM, 1, false); + + for(int i=0;isignal_cbt_ch().connect(sigc::bind(sigc::mem_fun(*this, &MapWin::nodeMapChanged), i)); + n_combo_array[i]->signal_newmapwin_needed().connect(sigc::mem_fun(*this, &MapWin::newMapWinNeeded)); + } + + add(vbox); + + vbox.pack_start(*(new Gtk::Label("Node properties"))); + + vbox.pack_start(*table); + + update(n_eml, s_eml, n_nml, s_nml); + + show_all_children(); + +} + +void MapWin::nodeMapChanged(std::string mapname, int prop) +{ + mytab.propertyChange(false, prop, mapname); +} + +void MapWin::arcMapChanged(std::string mapname, int prop) +{ + mytab.propertyChange(true, prop, mapname); +} + +void MapWin::newMapWinNeeded(bool itisarc) +{ + mytab.popupNewMapWin(itisarc); +} + +void MapWin::update( + std::vector n_eml, + std::vector s_eml, + std::vector n_nml, + std::vector s_nml) +{ + for(int i=0;iupdate_list(n_eml, s_eml); + } + + for(int i=0;iupdate_list(n_nml, s_nml); + } + + mytab.active_maps_needed(); +} + +void MapWin::registerNewArcMap(std::string newmapname, MapValue::Type type) +{ + for(int i=0;iappend_text((Glib::ustring)newmapname, type); + } +} + +void MapWin::registerNewNodeMap(std::string newmapname, MapValue::Type type) +{ + for(int i=0;iappend_text((Glib::ustring)newmapname, type); + } +} + +bool MapWin::on_delete_event(GdkEventAny * event) +{ + event=event; + mytab.closeMapWin(); + return true; +} + +void MapWin::changeEntry(bool isitarc, int prop, std::string mapname) +{ + if(isitarc) + { + e_combo_array[prop]->set_active_text(mapname); + } + else + { + n_combo_array[prop]->set_active_text(mapname); + } +} + +void MapWin::set_title(std::string tabname) +{ + Gtk::Window::set_title("Map Setup - "+tabname); +} diff -r 0e4f009eab8b -r 67188bd752db map_win.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/map_win.h Mon Jul 07 08:10:39 2008 -0500 @@ -0,0 +1,142 @@ +/* -*- C++ -*- + * + * This file is a part of LEMON, a generic C++ optimization library + * + * Copyright (C) 2003-2006 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#ifndef MAP_WIN_H +#define MAP_WIN_H + +class NoteBookTab; +class MapSelector; + +#include +#include +#include +#include "map_value.h" + +///Digraph visualization setup window. + +///This class is responsible for creating a window, +///on which the visualization attributes can be +///assigned to maps. +class MapWin : public Gtk::Window +{ +protected: + ///\ref NoteBookTab to that the \ref MapWin belongs to. + NoteBookTab & mytab; + + ///Designing element + Gtk::Table * table; + + ///\ref MapSelectors for each property + + ///Each property has an own \ref MapSelector through which + ///the map to visualize by the property van be set. + MapSelector ** e_combo_array; + + ///\ref MapSelectors for each property + + ///Each property has an own \ref MapSelector through which + ///the map to visualize by the property van be set. + MapSelector ** n_combo_array; + + ///Information holder + Gtk::Label * label; + + ///Container in which elements are organized. + Gtk::VBox vbox; + +public: + ///Constructor + + ///It creates the widgets shown in \ref MapWin and + ///binds the needed signal to the correct place. + ///\param title title of window + ///\param mw the owner \ref NoteBookTab (\ref mytab) + MapWin(const std::string& title, + std::vector n_eml, + std::vector s_eml, + std::vector n_nml, + std::vector s_nml, + NoteBookTab & mw); + + ///Deregistrates \ref MapWin in its \ref NoteBookTab (\ref mytab) + virtual bool on_delete_event(GdkEventAny *); + + ///Handles changement in nodemap selection + + ///If \ref MapSelector emits a signal that indicates + ///changement in nodemap selection this function will + ///be called. It calls the appropriate handler function, + ///\ref NoteBookTab::propertyChange with parameters describing the changement. + ///\param mapname the recently selected map + ///\param prop the changed property + void nodeMapChanged(std::string mapname, int prop); + + ///Handles changement in arcmap selection + + ///If \ref MapSelector emits a signal that indicates + ///changement in arcmap selection this function will + ///be called. It calls the appropriate handler function, + ///\ref NoteBookTab::propertyChange with parameters describing the changement. + ///\param mapname the recently selected map + ///\param prop the changed property + void arcMapChanged(std::string mapname, int prop); + + ///Indicates to the owner \ref NoteBookTab that a \ref NewMapWin should be opened. + + ///This function is bound to the + ///signal emitted by the \ref MapSelector in case of + ///the user wants to create a new map. It only pass the + ///information further to the tab owning this \ref MapWin that is needed to open the + ///\ref NewMapWin. (\ref NoteBookTab::popupNewMapWin) + ///\param itisarc should the new map will be an arcmap? (or nodemap) + void newMapWinNeeded(bool itisarc); + + ///This function inserts name of the new arcmap in the name list in \ref MapSelector s + + ///\param new_name + ///name of new map + void registerNewArcMap(std::string new_name, MapValue::Type type); + + ///This function inserts name of the new nodemap in the name list in \ref MapSelector s + + ///\param new_name + ///name of new map + void registerNewNodeMap(std::string new_name, MapValue::Type type); + + ///Close window if Esc key pressed. + virtual bool closeIfEscapeIsPressed(GdkEventKey*); + + ///Updates list of maps in all \ref MapSelector + + ///This function is called by \ref NoteBookTab, when the file + ///showed in it has changed, therefore the contained maps + ///have changed as well. \ref NoteBookTab knows, whether it + ///has to call this function or not from the \ref NoteBookTab::mapwinexists + ///variable. + void update( + std::vector n_eml, + std::vector s_eml, + std::vector n_nml, + std::vector s_nml); + + void changeEntry(bool, int, std::string); + + void set_title(std::string); +}; + +#endif //MAP_WIN_H diff -r 0e4f009eab8b -r 67188bd752db mapselector.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mapselector.cc Mon Jul 07 08:10:39 2008 -0500 @@ -0,0 +1,189 @@ +/* -*- C++ -*- + * + * This file is a part of LEMON, a generic C++ optimization library + * + * Copyright (C) 2003-2006 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#include + +MapSelector::MapSelector(std::vector n_ml, + std::vector s_ml, std::string act, + std::string labeltext, bool arc, bool d, MapType type) : + def(d), + itisarc(arc), + set_new_map(false), + label(labeltext), + map_type(type), + newbut(Gtk::Stock::NEW) +{ + update_list(n_ml, s_ml); + + if(act=="") + { + cbt.set_active(0); + default_state=true; + } + else + { + cbt.set_active_text((Glib::ustring)act); + default_state=false; + } + + //binding signal to the actual entry + cbt.signal_changed().connect + ( + sigc::mem_fun((*this), &MapSelector::comboChanged), + false + ); + + label.set_width_chars(longest_property_string_length); + + if(def) + { + defbut.set_label("Reset"); + defbut.signal_pressed().connect + ( + sigc::mem_fun(*this, &MapSelector::reset) + ); + } + + + newbut.signal_pressed().connect + ( + sigc::mem_fun(*this, &MapSelector::new_but_pressed) + ); + + add(label); + + add(cbt); + + if(def) + { + add(defbut); + } + + add(newbut); +} + +void MapSelector::new_but_pressed() +{ + set_new_map=true; + signal_newmapwin.emit(itisarc); +} + +void MapSelector::update_list(std::vector n_ml, + std::vector s_ml) +{ + int prev_act=cbt.get_active_row_number(); + cbt.clear(); + cbt_content.clear(); + + if (map_type & NUM) + { + std::vector< std::string >::iterator emsi=n_ml.begin(); + for(;emsi!=n_ml.end();emsi++) + { + cbt.append_text(*emsi); + cbt_content.push_back(*emsi); + } + } + if (map_type & STR) + { + std::vector< std::string >::iterator emsi=s_ml.begin(); + for(;emsi!=s_ml.end();emsi++) + { + cbt.append_text(*emsi); + cbt_content.push_back(*emsi); + } + } + if(def) + { + cbt.prepend_text("Default values"); + cbt_content.push_back("Default values"); + } + if(prev_act!=-1) + { + cbt.set_active(prev_act); + } +} + +void MapSelector::comboChanged() +{ + if(cbt.get_active_row_number()!=0 || !def) + { + default_state=false; + Glib::ustring mapname = cbt.get_active_text(); + if(!(mapname.empty())) //We seem to get 2 signals, one when the text is empty. + { + signal_cbt.emit(mapname); + } + } + else if((!default_state)&&(cbt.get_active_row_number()==0)) + { + reset(); + } +} + +void MapSelector::reset() +{ + default_state=true; + + cbt.set_active(0); + + signal_cbt.emit(""); +} + + +Glib::ustring MapSelector::get_active_text() +{ + return cbt.get_active_text(); +} + +void MapSelector::set_active_text(Glib::ustring text) +{ + if(text.compare("")) + { + cbt.set_active_text(text); + } + else + { + cbt.set_active_text("Default values"); + } +} + +void MapSelector::append_text(Glib::ustring text, MapValue::Type type) +{ + if (type & map_type) + { + cbt.append_text(text); + cbt_content.push_back(text); + + if(set_new_map) + { + set_active_text(text); + set_new_map=false; + } + } +} + +sigc::signal MapSelector::signal_cbt_ch() +{ + return signal_cbt; +} + +sigc::signal MapSelector::signal_newmapwin_needed() +{ + return signal_newmapwin; +} diff -r 0e4f009eab8b -r 67188bd752db mapselector.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mapselector.h Mon Jul 07 08:10:39 2008 -0500 @@ -0,0 +1,178 @@ +/* -*- C++ -*- + * + * This file is a part of LEMON, a generic C++ optimization library + * + * Copyright (C) 2003-2006 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#ifndef MAPSELECTOR_H +#define MAPSELECTOR_H + +#include +#include +#include +#include "map_value.h" + +///A widget by which node and arcmaps can be selected, deselected and created. + +///During the usage of \ref glemon we have to select +///maps several times. We also need some aid-function +///like new map creation and deselecting previously +///selected map. Instead of writing a the mapselection +///at all occurences we can use this widget by connecting +///its signals to the correct place. +class MapSelector : public Gtk::HBox +{ + protected: + ///This signal indicates that the selection has been changed by user. + sigc::signal signal_cbt; + + ///Signal that indicates that user wants to create a new map. + sigc::signal signal_newmapwin; + + ///If this is true, beyond the mapnames a 'Default' selection is available as well. + + ///For example \ref MapWin needs 'Default' option as well. In this case no map + ///will be visualized by the appropriate property. + ///But \ref AlgoWin do not need 'Default' option, because if no map is selected, + ///no algorithm can be run. + ///Its value is got and set in contructor. + bool def; + + ///Are the names of arcmaps or nodemaps stored here. + bool itisarc; + + ///Shows whether 'Default' option is selected or not. + bool default_state; + + ///It is true when the new button had been pressed but the new map has not been registrated yet. + + ///Before signal of \ref NewMapWin request is emitted by the \ref MapSelector + ///this variable is set to true. When the new map + ///is done, it will be registrated in all existing \ref MapSelector + ///by \ref append_text function. That function checks + ///whether this variable is true. If it is true that means + ///that this \ref MapSelector has requested \ref NewMapWin. + ///Therefore it set itself to the recently created map. + ///After that \ref set_new_map is set again false, not to + ///set maps active if \ref MapSelector piece is not the requester. + bool set_new_map; + + ///The widget that holds the names of maps. + + ///It can be rolled down + ///Names in it are selectable. + Gtk::ComboBoxText cbt; + + std::vector cbt_content; + + ///New button. + + ///By pressing it + ///\ref NewMapWin wilol pop-up + Gtk::Button newbut; + + ///Reset button. + + ///If pressed \ref cbt will + ///set to 'Default' option. + /// + ///It is visible only if \ref def is true. + Gtk::Button defbut; + + ///Shows purpose of \ref MapSelector piece. + Gtk::Label label; + + /// Which types of maps (integer, string, ...) to display. + MapType map_type; + + public: + + ///Constructor of \ref MapSelector + + ///Creates the layout and binds signal to the correct place. + ///\param mapstorage Pointer to the \ref MapStorage to get the map list from. + ///\param act preselected option + ///\param purpose text of label indicating purpose of \ref MapStorage + ///\param itisarc do \ref MapSelector contains arcmap names or nodemapnames. + ///\param def do we need 'Default' option. See \ref def. + ///\param type Specifies which types of maps to display. + MapSelector(std::vector n_ml, + std::vector s_ml, std::string act, std::string labeltext, + bool arc, bool d = true, MapType type = ALL); + + ///Returns signal emitted if the user has changed the selection. (\ref signal_cbt) + sigc::signal signal_cbt_ch(); + + ///Returns signal emitted if the user has pressed New button (\ref newbut) (\ref signal_newmapwin) + sigc::signal signal_newmapwin_needed(); + + ///Maintain \ref cbt. + + ///Fills in \ref cbt with names, taking + ///into account that the previously selected option + ///has to be set back after the operation. + void update_list(std::vector n_ml, + std::vector s_ml); + + ///Handles changement in \ref cbt. + + ///In default case it emits a signal with the selected option. + ///But if 'Default' option is selected, it resets the \ref MapSelector + virtual void comboChanged(); + + ///Requests a \ref NewMapWin + + ///See \ref set_new_map. + ///First it sets \ref set_new_map true to be identified + ///at registration of new map that + ///it has sent the \ref signal_newmapwin, therefore it + ///has to set \ref cbt to that option. + virtual void new_but_pressed(); + + ///If called, 'Default' option is selected, that means unselection of any maps. + + ///Practically this means that if this is called, + ///properties of digraph will set to default state. + ///The function achieves this by emitting appropriately + ///parametrized signal_cbt. + virtual void reset(); + + ///Returns the currently selected option. + Glib::ustring get_active_text(); + + ///Sets the parameter active in \ref cbt. + + ///\param new_value the + ///new value to be set in \ref cbt. + void set_active_text(Glib::ustring new_value); + + ///Sets the parameter active in \ref cbt. + ///\param index the + ///index of row to be set in \ref cbt. + void set_active(int index){cbt.set_active(index);}; + + ///Clear all options from \ref cbt. + void clear(){cbt.clear();}; + + ///Appends a new option to the existing ones in \ref cbt. + + ///If \ref set_new_map is true, the + ///\ref MapSelector has requested the opened \ref NewMapWin, + ///from that the option to append is coming. In this case + ///this function will set \ref cbt to the new option. + ///\param new_option new option to append + void append_text(Glib::ustring new_option, MapValue::Type); +}; +#endif //MAPSELECTOR_H diff -r 0e4f009eab8b -r 67188bd752db mapstorage.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mapstorage.cc Mon Jul 07 08:10:39 2008 -0500 @@ -0,0 +1,1534 @@ +/* -*- C++ -*- + * + * This file is a part of LEMON, a generic C++ optimization library + * + * Copyright (C) 2003-2006 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all cop ies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#include "i18n.h" +#include +#include +#include +#include +#include +#include +#include +#include "file_import_dialog.h" +#include +#include +#include +#include +#include +#include + +const int i_d=20; +const double a_d=0.05; +const double p_d=40000; + +MapStorage::MapStorage() : + gui_sect_save_dest(LGF_FILE), + node_coords_save_dest(SpecMapSaveOpts::GUI_SECT), + arrow_coords_save_dest(SpecMapSaveOpts::GUI_SECT), + modified(false), + file_name(""), + max_node_label(0), + max_arc_label(0), + node_coords_one_map_name("coord"), + node_coords_two_maps_1_name("coord_x"), + node_coords_two_maps_2_name("coord_y"), + arrow_coords_one_map_name("arrow"), + arrow_coords_two_maps_1_name("arrow_x"), + arrow_coords_two_maps_2_name("arrow_y"), + iterations(i_d), + attraction(a_d), + propulsation(p_d), + node_coords_x(digraph), + node_coords_y(digraph), + arrow_coords_x(digraph), + arrow_coords_y(digraph), + node_label(digraph), + arc_label(digraph), + background_set(false) +{ + node_coords.setXMap(node_coords_x); + node_coords.setYMap(node_coords_y); + arrow_coords.setXMap(arrow_coords_x); + arrow_coords.setYMap(arrow_coords_y); + + active_nodemaps.resize(NODE_PROPERTY_NUM); + for(int i=0;idefault_value = def_val; + + signal_node_map.emit(name, type); +} + +void MapStorage::createArcMap(const std::string& name, MapValue::Type type, + MapValue def_val) +{ + ArcMapStore::const_iterator it = arcmaps.find(name); + if (it != arcmaps.end()) + throw Error("Arc map " + name + " already exists."); + + switch (type) + { + case MapValue::NUMERIC: + arcmaps[name] = new NumericArcMapData(digraph, def_val); + break; + case MapValue::STRING: + arcmaps[name] = new StringArcMapData(digraph, def_val); + break; + } + + arcmaps[name]->default_value = def_val; + + signal_arc_map.emit(name, type); +} + +void MapStorage::changeActiveMap(bool itisarc, int prop, std::string mapname) +{ + if(itisarc) + { + active_arcmaps[prop]=mapname; + } + else + { + active_nodemaps[prop]=mapname; + } + signal_prop.emit(itisarc, prop); +} + +void MapStorage::broadcastActiveMaps() +{ + for(int i=0;i MapStorage::getArcMapList(MapType type) +{ + if (type == ALL) + { + std::vector ret; + for (ArcMapStore::const_iterator it = arcmaps.begin(); + it != arcmaps.end(); ++it) + { + ret.push_back(it->first); + } + return ret; + } + else + { + std::vector ret; + for (ArcMapStore::const_iterator it = arcmaps.begin(); + it != arcmaps.end(); ++it) + { + ArcMapData* data = getArcMapData(it->first); + MapValue::Type t = data->type(); + if ((t == MapValue::NUMERIC && (type & NUM)) || + (t == MapValue::STRING && (type & STR))) + { + ret.push_back(it->first); + } + } + return ret; + } +} + +std::vector MapStorage::getNodeMapList(MapType type) +{ + if (type == ALL) + { + std::vector ret; + for (NodeMapStore::const_iterator it = nodemaps.begin(); + it != nodemaps.end(); ++it) + { + ret.push_back(it->first); + } + return ret; + } + else + { + std::vector ret; + for (NodeMapStore::const_iterator it = nodemaps.begin(); + it != nodemaps.end(); ++it) + { + NodeMapData* data = getNodeMapData(it->first); + MapValue::Type t = data->type(); + if ((t == MapValue::NUMERIC && (type & NUM)) || + (t == MapValue::STRING && (type & STR))) + { + ret.push_back(it->first); + } + } + return ret; + } +} + +sigc::signal MapStorage::signal_prop_ch() +{ + return signal_prop; +} + +int MapStorage::readFromFile(const std::string &filename) +{ + using std::vector; + using std::map; + using std::string; + + //reading content of file + LgfContents content(filename); + try + { + content.run(); + } + catch (Exception& error) + { + Gtk::MessageDialog mdialog(error.what()); + mdialog.run(); + clear(); + return 1; + } + + // check whether the .conf file exists + bool gui_data_in_conf = g_file_test((filename + ".conf").c_str(), + (GFileTest)(G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR)); + + // check whether the .lgf file contains a gui section + bool gui_data_in_lgf = false; + { + for(int i=0;iFound both ") + filename + + _(".conf and a gui section in ") + filename + _("."), true, + Gtk::MESSAGE_QUESTION, Gtk::BUTTONS_NONE); + mdialog.add_button(_("Use the ._conf file"), 1); + mdialog.add_button(_("Use the _gui section"), 2); + switch (mdialog.run()) + { + case 1: + use_gui_data_in_lgf = false; + break; + case 2: + use_gui_data_in_lgf = true; + break; + case Gtk::RESPONSE_NONE: + return 1; + } + } + else + { + use_gui_data_in_lgf = gui_data_in_lgf; + } + + if (gui_data_found) + { + GUISectData gui_data; + if (use_gui_data_in_lgf) + { + // read the gui section from the .lgf file + try + { + sectionReader(filename).sectionStream("gui", GuiReader(this, gui_data)).run(); + gui_sect_save_dest = LGF_FILE; + } + catch (Exception& error) + { + clear(); + return 1; + } + } + else + { + // read the gui section from the .conf file + try + { + sectionReader(filename + ".conf").sectionStream("gui", GuiReader(this, gui_data)).run(); + gui_sect_save_dest = CONF_FILE; + } + catch (Exception& error) + { + clear(); + return 1; + } + } + + // read the digraph and maps form the .lgf file + try + { + std::string node_coord_xmap_name, node_coord_ymap_name; + std::string arrow_coord_xmap_name, arrow_coord_ymap_name; + + if (gui_data.node_coords_save_dest == + MapStorage::SpecMapSaveOpts::NESET_SECT) + { + switch (gui_data.node_coords_save_map_num) + { + case SpecMapSaveOpts::ONE_MAP: + node_coord_xmap_name = gui_data.node_coords_one_map_name + ":x"; + node_coord_ymap_name = gui_data.node_coords_one_map_name + ":y"; + node_coords_one_map_name = gui_data.node_coords_one_map_name; + break; + case SpecMapSaveOpts::TWO_MAPS: + node_coord_xmap_name = gui_data.node_coords_two_maps_1_name; + node_coord_ymap_name = gui_data.node_coords_two_maps_2_name; + node_coords_two_maps_1_name = gui_data.node_coords_two_maps_1_name; + node_coords_two_maps_2_name = gui_data.node_coords_two_maps_2_name; + break; + } + node_coords_save_dest = gui_data.node_coords_save_dest; + node_coords_save_map_num = gui_data.node_coords_save_map_num; + } + + if (gui_data.arrow_coords_save_dest == + MapStorage::SpecMapSaveOpts::NESET_SECT) + { + switch (gui_data.arrow_coords_save_map_num) + { + case SpecMapSaveOpts::ONE_MAP: + arrow_coord_xmap_name = gui_data.arrow_coords_one_map_name + ":x"; + arrow_coord_ymap_name = gui_data.arrow_coords_one_map_name + ":y"; + arrow_coords_one_map_name = gui_data.arrow_coords_one_map_name; + break; + case SpecMapSaveOpts::TWO_MAPS: + arrow_coord_xmap_name = gui_data.arrow_coords_two_maps_1_name; + arrow_coord_ymap_name = gui_data.arrow_coords_two_maps_2_name; + arrow_coords_two_maps_1_name = + gui_data.arrow_coords_two_maps_1_name; + arrow_coords_two_maps_2_name = + gui_data.arrow_coords_two_maps_2_name; + break; + } + arrow_coords_save_dest = gui_data.arrow_coords_save_dest; + arrow_coords_save_map_num = gui_data.arrow_coords_save_map_num; + } + readLGF(filename, true, + gui_data.main_node_map_names, gui_data.main_arc_map_names, + gui_data.node_map_types, gui_data.arc_map_types, + node_coord_xmap_name, node_coord_ymap_name, + arrow_coord_xmap_name, arrow_coord_ymap_name); + } + catch (Exception& error) + { + clear(); + return 1; + } + + // add the maps from the gui section + for (vector::const_iterator + it = gui_data.gui_node_map_names.begin(); + it != gui_data.gui_node_map_names.end(); ++it) + { + string map_name = *it; + switch (gui_data.node_map_types[map_name]) + { + case MapValue::NUMERIC: + { + createNodeMap(map_name, MapValue::NUMERIC, double()); + NumericNodeMap& dmap = getNumericNodeMap(map_name); + map& smap = *gui_data.numeric_node_maps[map_name]; + for (NodeIt n(digraph); n != INVALID; ++n) + { + dmap[n] = smap[node_label[n]]; + } + break; + } + case MapValue::STRING: + { + createNodeMap(map_name, MapValue::STRING, string()); + StringNodeMap& dmap = getStringNodeMap(map_name); + map& smap = *gui_data.string_node_maps[map_name]; + for (NodeIt n(digraph); n != INVALID; ++n) + { + dmap[n] = smap[node_label[n]]; + } + break; + } + } + getNodeMapData(map_name)->save_dest = GUI_SECT; + } + for (vector::const_iterator + it = gui_data.gui_arc_map_names.begin(); + it != gui_data.gui_arc_map_names.end(); ++it) + { + string map_name = *it; + switch (gui_data.arc_map_types[map_name]) + { + case MapValue::NUMERIC: + { + createArcMap(map_name, MapValue::NUMERIC, double()); + NumericArcMap& dmap = getNumericArcMap(map_name); + map& smap = *gui_data.numeric_arc_maps[map_name]; + for (ArcIt e(digraph); e != INVALID; ++e) + { + dmap[e] = smap[arc_label[e]]; + } + break; + } + case MapValue::STRING: + { + createArcMap(map_name, MapValue::STRING, string()); + StringArcMap& dmap = getStringArcMap(map_name); + map& smap = *gui_data.string_arc_maps[map_name]; + for (ArcIt e(digraph); e != INVALID; ++e) + { + dmap[e] = smap[arc_label[e]]; + } + break; + } + } + getArcMapData(map_name)->save_dest = GUI_SECT; + } + + // restore the node coordinate maps + if (gui_data.node_coords_save_dest == + MapStorage::SpecMapSaveOpts::GUI_SECT) + { + for (NodeIt n(digraph); n != INVALID; ++n) + { + node_coords.set(n, gui_data.node_coord_map[node_label[n]]); + } + node_coords_save_dest = gui_data.node_coords_save_dest; + } + // restore the arrow coordinate maps + if (gui_data.arrow_coords_save_dest == + MapStorage::SpecMapSaveOpts::GUI_SECT) + { + for (ArcIt e(digraph); e != INVALID; ++e) + { + arrow_coords.set(e, gui_data.arrow_coord_map[arc_label[e]]); + } + arrow_coords_save_dest = gui_data.arrow_coords_save_dest; + } + } + else + { + // there is no gui section neither in the .lgf file nor in the .conf file + { + if (content.nodeSectionNum() < 1) + { + Gtk::MessageDialog mdialog("No nodeset found in file."); + mdialog.run(); + clear(); + return 1; + } + + if (content.arcSectionNum() < 1) + { + Gtk::MessageDialog mdialog("No arcset found in file."); + mdialog.run(); + clear(); + return 1; + } + + std::vector nodeMapNames = content.nodeMapNames(0); + std::vector arcMapNames = content.arcMapNames(0); + + bool read_arc_label = true; + if (std::find(arcMapNames.begin(), arcMapNames.end(), "label") == + arcMapNames.end()) + { + read_arc_label = false; + } + + nodeMapNames.erase( + std::remove(nodeMapNames.begin(), nodeMapNames.end(), "label"), + nodeMapNames.end()); + + arcMapNames.erase( + std::remove(arcMapNames.begin(), arcMapNames.end(), "label"), + arcMapNames.end()); + + FileImportDialog::ImportData data(nodeMapNames, arcMapNames); + FileImportDialog fidialog(&data); + int response = fidialog.run(); + if (response == Gtk::RESPONSE_OK) + { + try + { + std::string node_coord_xmap_name, node_coord_ymap_name; + std::string arrow_coord_xmap_name, arrow_coord_ymap_name; + bool gen_node_coords = false; + bool gen_arrow_coords = false; + + switch (data.node_coord_load_from) + { + case FileImportDialog::ImportData::ONE_MAP: + node_coord_xmap_name = data.node_coord_one_map_name + ":x"; + node_coord_ymap_name = data.node_coord_one_map_name + ":y"; + node_coords_one_map_name = data.node_coord_one_map_name; + + node_coords_save_dest = SpecMapSaveOpts::NESET_SECT; + node_coords_save_map_num = SpecMapSaveOpts::ONE_MAP; + break; + case FileImportDialog::ImportData::TWO_MAPS: + node_coord_xmap_name = data.node_coord_two_maps_1_name; + node_coord_ymap_name = data.node_coord_two_maps_2_name; + node_coords_two_maps_1_name = data.node_coord_two_maps_1_name; + node_coords_two_maps_2_name = data.node_coord_two_maps_2_name; + + node_coords_save_dest = SpecMapSaveOpts::NESET_SECT; + node_coords_save_map_num = SpecMapSaveOpts::TWO_MAPS; + break; + case FileImportDialog::ImportData::DONT_READ: + node_coord_xmap_name = ""; + node_coord_ymap_name = ""; + + node_coords_save_dest = SpecMapSaveOpts::GUI_SECT; + gen_node_coords = true; + break; + } + + switch (data.arrow_coord_load_from) + { + case FileImportDialog::ImportData::ONE_MAP: + arrow_coord_xmap_name = data.arrow_coord_one_map_name + ":x"; + arrow_coord_ymap_name = data.arrow_coord_one_map_name + ":y"; + arrow_coords_one_map_name = data.arrow_coord_one_map_name; + + arrow_coords_save_dest = SpecMapSaveOpts::NESET_SECT; + arrow_coords_save_map_num = SpecMapSaveOpts::ONE_MAP; + break; + case FileImportDialog::ImportData::TWO_MAPS: + arrow_coord_xmap_name = data.arrow_coord_two_maps_1_name; + arrow_coord_ymap_name = data.arrow_coord_two_maps_2_name; + arrow_coords_two_maps_1_name = data.arrow_coord_two_maps_1_name; + arrow_coords_two_maps_2_name = data.arrow_coord_two_maps_2_name; + + arrow_coords_save_dest = SpecMapSaveOpts::NESET_SECT; + arrow_coords_save_map_num = SpecMapSaveOpts::TWO_MAPS; + break; + case FileImportDialog::ImportData::DONT_READ: + arrow_coord_xmap_name = ""; + arrow_coord_ymap_name = ""; + + arrow_coords_save_dest = SpecMapSaveOpts::GUI_SECT; + gen_arrow_coords = true; + break; + } + + // read arc and node maps + std::vector node_map_names; + std::vector arc_map_names; + std::map node_map_types; + std::map arc_map_types; + for (std::vector::const_iterator it = + data.numeric_node_map_names.begin(); + it != data.numeric_node_map_names.end(); ++it) + { + node_map_names.push_back(*it); + node_map_types[*it] = MapValue::NUMERIC; + } + for (std::vector::const_iterator it = + data.string_node_map_names.begin(); + it != data.string_node_map_names.end(); ++it) + { + node_map_names.push_back(*it); + node_map_types[*it] = MapValue::STRING; + } + for (std::vector::const_iterator it = + data.numeric_arc_map_names.begin(); + it != data.numeric_arc_map_names.end(); ++it) + { + arc_map_names.push_back(*it); + arc_map_types[*it] = MapValue::NUMERIC; + } + for (std::vector::const_iterator it = + data.string_arc_map_names.begin(); + it != data.string_arc_map_names.end(); ++it) + { + arc_map_names.push_back(*it); + arc_map_types[*it] = MapValue::STRING; + } + + readLGF(filename, read_arc_label, + node_map_names, arc_map_names, + node_map_types, arc_map_types, + node_coord_xmap_name, node_coord_ymap_name, + arrow_coord_xmap_name, arrow_coord_ymap_name); + + // generate arc labels + if (!read_arc_label) + { + int l = 0; + for (ArcIt e(digraph); e != INVALID; ++e) + { + arc_label[e] = l++; + } + } + + if (gen_node_coords) + { + // generate node coordinates + int node_num = 0; + for (NodeIt n(digraph); n != INVALID; ++n) { node_num++; } + const double pi = 3.142; + double step = 2 * pi / (double) node_num; + int i = 0; + for (NodeIt n(digraph); n != INVALID; ++n) + { + setNodeCoords(n, + XY(250.0 * std::cos(i * step), + 250.0 * std::sin(i * step))); + i++; + } + } + if (gen_arrow_coords) + { + // generate arrow coordinates + for (ArcIt e(digraph); e != INVALID; ++e) + { + if (digraph.source(e) == digraph.target(e)) + { + setArrowCoords(e, + getNodeCoords(digraph.source(e)) + XY(0.0, 80.0)); + } + else + { + setArrowCoords(e, + (getNodeCoords(digraph.source(e)) + + getNodeCoords(digraph.target(e))) / 2.0); + } + } + } + } + catch (Exception& error) + { + clear(); + return 1; + } + } + else + { + clear(); + return 1; + } + } + } + + // set max_node_label + { + max_node_label = std::numeric_limits::min(); + for (NodeIt n(digraph); n != INVALID; ++n) + { + if (node_label[n] > max_node_label) + { + max_node_label = node_label[n]; + } + } + } + // set max_arc_label + { + max_arc_label = std::numeric_limits::min(); + for (ArcIt e(digraph); e != INVALID; ++e) + { + if (arc_label[e] > max_arc_label) + { + max_arc_label = arc_label[e]; + } + } + } + + return 0; +} + +void MapStorage::writeToFile(const std::string &filename) +{ + // relabel nodes and arcs + int i = 0; + for (NodeIt n(digraph); n != INVALID; ++n) + { + node_label[n] = i++; + } + max_node_label = i-1; + i = 0; + for (ArcIt e(digraph); e != INVALID; ++e) + { + arc_label[e] = i++; + } + max_arc_label = i-1; + + // write .lgf file + { + DigraphWriter gwriter(filename, digraph); + + gwriter.nodeMap("label", node_label); + gwriter.arcMap("label", arc_label); + + // write node maps + for (NodeMapStore::const_iterator it = nodemaps.begin(); + it != nodemaps.end(); ++it) + { + if (it->second->save_dest == NESET_SECT) + { + switch (it->second->type()) + { + case MapValue::NUMERIC: + gwriter.nodeMap(it->first, getNumericNodeMap(it->first)); + break; + case MapValue::STRING: + gwriter.nodeMap(it->first, getStringNodeMap(it->first)); + break; + } + } + } + + // write arc maps + for (ArcMapStore::const_iterator it = arcmaps.begin(); + it != arcmaps.end(); ++it) + { + if (it->second->save_dest == NESET_SECT) + { + switch (it->second->type()) + { + case MapValue::NUMERIC: + gwriter.arcMap(it->first, getNumericArcMap(it->first)); + break; + case MapValue::STRING: + gwriter.arcMap(it->first, getStringArcMap(it->first)); + break; + } + } + } + + // write node coordinates + switch (getNodeCoordsSaveDest()) + { + case MapStorage::SpecMapSaveOpts::GUI_SECT: + break; + case MapStorage::SpecMapSaveOpts::NESET_SECT: + switch (getNodeCoordsSaveMapNum()) + { + case MapStorage::SpecMapSaveOpts::ONE_MAP: + gwriter.nodeMap(node_coords_one_map_name + ":x", + node_coords_x); + gwriter.nodeMap(node_coords_one_map_name + ":y", + node_coords_y); + break; + case MapStorage::SpecMapSaveOpts::TWO_MAPS: + gwriter.nodeMap(node_coords_two_maps_1_name, + node_coords_x); + gwriter.nodeMap(node_coords_two_maps_2_name, + node_coords_y); + break; + } + break; + } + + // write arrow coordinates + switch (getArrowCoordsSaveDest()) + { + case MapStorage::SpecMapSaveOpts::GUI_SECT: + break; + case MapStorage::SpecMapSaveOpts::NESET_SECT: + switch (getArrowCoordsSaveMapNum()) + { + case MapStorage::SpecMapSaveOpts::ONE_MAP: + gwriter.arcMap(arrow_coords_one_map_name + ":x", + arrow_coords_x); + gwriter.arcMap(arrow_coords_one_map_name + ":y", + arrow_coords_y); + break; + case MapStorage::SpecMapSaveOpts::TWO_MAPS: + gwriter.arcMap(arrow_coords_two_maps_1_name, + arrow_coords_x); + gwriter.arcMap(arrow_coords_two_maps_2_name, + arrow_coords_y); + break; + } + break; + } + + if (gui_sect_save_dest == LGF_FILE) + { + GuiWriter gui_writer(this); + gui_writer.write(gwriter.ostream()); + gwriter.run(); + } + else + { + gwriter.run(); + } + } + + // write .conf file + if (gui_sect_save_dest == CONF_FILE) + { + DigraphWriter lwriter(filename + ".conf", digraph); + GuiWriter gui_writer(this); + gui_writer.write(lwriter.ostream()); + lwriter.run(); + } +} + +void MapStorage::clear() +{ + for (NodeMapStore::iterator it = nodemaps.begin(); it != nodemaps.end(); ++it) + { + delete it->second; + nodemaps.erase(it); + } + for (ArcMapStore::iterator it = arcmaps.begin(); it != arcmaps.end(); ++it) + { + delete it->second; + arcmaps.erase(it); + } + digraph.clear(); + file_name = ""; + modified = false; + max_node_label = 0; + max_arc_label = 0; + background_set = false; + + gui_sect_save_dest = LGF_FILE; + node_coords_save_dest = SpecMapSaveOpts::GUI_SECT; + arrow_coords_save_dest = SpecMapSaveOpts::GUI_SECT; + node_coords_one_map_name = "coord"; + node_coords_two_maps_1_name = "coord_x"; + node_coords_two_maps_2_name = "coord_y"; + arrow_coords_one_map_name = "arrow"; + arrow_coords_two_maps_1_name = "arrow_x"; + arrow_coords_two_maps_2_name = "arrow_y"; + + for(int i=0;iget(node); +} + +void MapStorage::set(const std::string& name, Node node, MapValue val) +{ + NodeMapData* data = getNodeMapData(name); + data->set(node, val); +} + +MapValue MapStorage::get(const std::string& name, Arc arc) const +{ + ArcMapData* data = getArcMapData(name); + return data->get(arc); +} + +void MapStorage::set(const std::string& name, Arc arc, MapValue val) +{ + ArcMapData* data = getArcMapData(name); + data->set(arc, val); +} + +const std::string& MapStorage::getFileName() const +{ + return file_name; +} + +void MapStorage::setFileName(const std::string& fn) +{ + file_name = fn; +} + +bool MapStorage::getModified() const +{ + return modified; +} + +void MapStorage::setModified(bool m) +{ + modified = m; +} + +Node MapStorage::addNode(XY coords) +{ + Node node = digraph.addNode(); + + setNodeCoords(node, coords); + + max_node_label++; + + node_label[node] = max_node_label; + + std::vector node_maps = getNodeMapList(); + for (std::vector::const_iterator it = node_maps.begin(); + it != node_maps.end(); ++it) + { + NodeMapData* data = getNodeMapData(*it); + set(*it, node, data->default_value); + } + + return node; +} + +Arc MapStorage::addArc(Node from, Node to) +{ + Arc arc = digraph.addArc(from, to); + + if (from == to) + { + setArrowCoords(arc, getNodeCoords(from) + XY(0.0, 80.0)); + } + else + { + setArrowCoords(arc, (getNodeCoords(from) + getNodeCoords(to)) / 2.0); + } + + max_arc_label++; + + arc_label[arc] = max_arc_label; + + std::vector arc_maps = getArcMapList(); + for (std::vector::const_iterator it = arc_maps.begin(); + it != arc_maps.end(); ++it) + { + ArcMapData* data = getArcMapData(*it); + set(*it, arc, data->default_value); + } + return arc; +} + +MapStorage::NumericNodeMap& MapStorage::getNumericNodeMap(const std::string& name) +{ + NodeMapData* data = getNodeMapData(name); + if (data->type() != MapValue::NUMERIC) + throw Error("Numeric node map " + name + " does not exists."); + return static_cast(data)->map; +} + +MapStorage::StringNodeMap& MapStorage::getStringNodeMap(const std::string& name) +{ + NodeMapData* data = getNodeMapData(name); + if (data->type() != MapValue::STRING) + throw Error("String node map " + name + " does not exists."); + return static_cast(data)->map; +} + +MapStorage::NumericArcMap& MapStorage::getNumericArcMap(const std::string& name) +{ + ArcMapData* data = getArcMapData(name); + if (data->type() != MapValue::NUMERIC) + throw Error("Numeric arc map " + name + " does not exists."); + return static_cast(data)->map; +} + +MapStorage::StringArcMap& MapStorage::getStringArcMap(const std::string& name) +{ + ArcMapData* data = getArcMapData(name); + if (data->type() != MapValue::STRING) + throw Error("String arc map " + name + " does not exists."); + return static_cast(data)->map; +} + +MapValueArcMap MapStorage::getArcMap(const std::string& name) +{ + return MapValueArcMap(name, this); +} + +MapValueNodeMap MapStorage::getNodeMap(const std::string& name) +{ + return MapValueNodeMap(name, this); +} + +int MapStorage::getLabel(Node n) const +{ + return node_label[n]; +} + +int MapStorage::getLabel(Arc e) const +{ + return arc_label[e]; +} + +MapStorage::GuiSectSaveDest MapStorage::getGUIDataSaveLocation() +{ + return gui_sect_save_dest; +} + +void MapStorage::setGUIDataSaveLocation(MapStorage::GuiSectSaveDest dest) +{ + gui_sect_save_dest = dest; +} + +MapStorage::MapSaveDest MapStorage::getNodeMapSaveDest(std::string name) const +{ + NodeMapData *data = getNodeMapData(name); + return data->save_dest; +} + +MapStorage::MapSaveDest MapStorage::getArcMapSaveDest(std::string name) const +{ + ArcMapData *data = getArcMapData(name); + return data->save_dest; +} + +void MapStorage::setNodeMapSaveDest(std::string name, MapStorage::MapSaveDest dest) +{ + NodeMapData *data = getNodeMapData(name); + data->save_dest = dest; +} + +void MapStorage::setArcMapSaveDest(std::string name, MapStorage::MapSaveDest dest) +{ + ArcMapData *data = getArcMapData(name); + data->save_dest = dest; +} + +MapStorage::ArcMapData* MapStorage::getArcMapData(std::string name) const +{ + ArcMapStore::const_iterator it = arcmaps.find(name); + if (it != arcmaps.end()) + return it->second; + else + throw Error("Arc map " + name + " does not exists."); +} + +MapStorage::NodeMapData* MapStorage::getNodeMapData(std::string name) const +{ + NodeMapStore::const_iterator it = nodemaps.find(name); + if (it != nodemaps.end()) + return it->second; + else + throw Error("Node map " + name + " does not exists."); +} + +MapValue::Type MapStorage::getNodeMapElementType(std::string name) const +{ + NodeMapData *data = getNodeMapData(name); + return data->type(); +} + +MapValue::Type MapStorage::getArcMapElementType(std::string name) const +{ + ArcMapData *data = getArcMapData(name); + return data->type(); +} + +const MapStorage::NodeLabelMap& MapStorage::getNodeLabelMap() +{ + return node_label; +} + +const MapStorage::ArcLabelMap& MapStorage::getArcLabelMap() +{ + return arc_label; +} + +const Digraph& MapStorage::getDigraph() +{ + return digraph; +} + +bool MapStorage::nodeMapExists(std::string name) +{ + NodeMapStore::const_iterator it = nodemaps.find(name); + if (it == nodemaps.end()) + return false; + else + return true; +} + +bool MapStorage::arcMapExists(std::string name) +{ + ArcMapStore::const_iterator it = arcmaps.find(name); + if (it == arcmaps.end()) + return false; + else + return true; +} + +std::vector MapStorage::getArcMaps(MapType type) +{ + std::vector maps; + for (ArcMapStore::const_iterator it = arcmaps.begin(); it != arcmaps.end(); ++it) + { + if (it->second->type() & type) + { + maps.push_back(it->first); + } + } + return maps; +} + +std::vector MapStorage::getNodeMaps(MapType type) +{ + std::vector maps; + for (NodeMapStore::const_iterator it = nodemaps.begin(); it != nodemaps.end(); ++it) + { + if (it->second->type() & type) + { + maps.push_back(it->first); + } + } + return maps; +} + +MapStorage::NodeCoordMap& MapStorage::getNodeCoordMap() +{ + return node_coords; +} + +MapStorage::ArrowCoordMap& MapStorage::getArrowCoordMap() +{ + return arrow_coords; +} + +MapStorage::SpecMapSaveOpts::Dest MapStorage::getNodeCoordsSaveDest() +{ + return node_coords_save_dest; +} + +MapStorage::SpecMapSaveOpts::Dest MapStorage::getArrowCoordsSaveDest() +{ + return arrow_coords_save_dest; +} + +void MapStorage::setNodeCoordsSaveDest(MapStorage::SpecMapSaveOpts::Dest dest) +{ + node_coords_save_dest = dest; +} + +void MapStorage::setArrowCoordsSaveDest(MapStorage::SpecMapSaveOpts::Dest dest) +{ + arrow_coords_save_dest = dest; +} + +MapStorage::SpecMapSaveOpts::MapNum MapStorage::getNodeCoordsSaveMapNum() +{ + return node_coords_save_map_num; +} + +MapStorage::SpecMapSaveOpts::MapNum MapStorage::getArrowCoordsSaveMapNum() +{ + return arrow_coords_save_map_num; +} + +void MapStorage::setNodeCoordsSaveMapNum(MapStorage::SpecMapSaveOpts::MapNum num) +{ + node_coords_save_map_num = num; +} + +void MapStorage::setArrowCoordsSaveMapNum(MapStorage::SpecMapSaveOpts::MapNum num) +{ + arrow_coords_save_map_num = num; +} + +const std::string& MapStorage::getNodeCoordsOneMapName() +{ + return node_coords_one_map_name; +} +const std::string& MapStorage::getNodeCoordsTwoMaps1Name() +{ + return node_coords_two_maps_1_name; +} +const std::string& MapStorage::getNodeCoordsTwoMaps2Name() +{ + return node_coords_two_maps_2_name; +} + +void MapStorage::setNodeCoordsOneMapName(const std::string& name) +{ + node_coords_one_map_name = name; +} +void MapStorage::setNodeCoordsTwoMaps1Name(const std::string& name) +{ + node_coords_two_maps_1_name = name; +} +void MapStorage::setNodeCoordsTwoMaps2Name(const std::string& name) +{ + node_coords_two_maps_2_name = name; +} + +const std::string& MapStorage::getArrowCoordsOneMapName() +{ + return arrow_coords_one_map_name; +} +const std::string& MapStorage::getArrowCoordsTwoMaps1Name() +{ + return arrow_coords_two_maps_1_name; +} +const std::string& MapStorage::getArrowCoordsTwoMaps2Name() +{ + return arrow_coords_two_maps_2_name; +} + +void MapStorage::setArrowCoordsOneMapName(const std::string& name) +{ + arrow_coords_one_map_name = name; +} +void MapStorage::setArrowCoordsTwoMaps1Name(const std::string& name) +{ + arrow_coords_two_maps_1_name = name; +} +void MapStorage::setArrowCoordsTwoMaps2Name(const std::string& name) +{ + arrow_coords_two_maps_2_name = name; +} + +void MapStorage::readLGF( + const std::string& filename, + bool read_arc_label, + const std::vector& node_map_names, + const std::vector& arc_map_names, + const std::map& node_map_types, + const std::map& arc_map_types, + const std::string& node_coord_xmap_name, + const std::string& node_coord_ymap_name, + const std::string& arrow_coord_xmap_name, + const std::string& arrow_coord_ymap_name) +{ + using std::vector; + using std::map; + using std::string; + + DigraphReader greader(filename, digraph); + + // read the label maps + greader.nodeMap("label", node_label); + if (read_arc_label) + greader.arcMap("label", arc_label); + + // read the node maps + for (vector::const_iterator + it = node_map_names.begin(); + it != node_map_names.end(); ++it) + { + switch (node_map_types.find(*it)->second) + { + case MapValue::NUMERIC: + { + createNodeMap(*it, MapValue::NUMERIC, double()); + greader.nodeMap(*it, getNumericNodeMap(*it)); + break; + } + case MapValue::STRING: + { + createNodeMap(*it, MapValue::STRING, string()); + greader.nodeMap(*it, getStringNodeMap(*it)); + break; + } + } + getNodeMapData(*it)->save_dest = NESET_SECT; + } + + // read the arc maps + for (vector::const_iterator + it = arc_map_names.begin(); + it != arc_map_names.end(); ++it) + { + switch (arc_map_types.find(*it)->second) + { + case MapValue::NUMERIC: + { + createArcMap(*it, MapValue::NUMERIC, double()); + greader.arcMap(*it, getNumericArcMap(*it)); + break; + } + case MapValue::STRING: + { + createArcMap(*it, MapValue::STRING, string()); + greader.arcMap(*it, getStringArcMap(*it)); + break; + } + } + getArcMapData(*it)->save_dest = NESET_SECT; + } + + // read the node coordinate maps + if (node_coord_xmap_name != "") + greader.nodeMap(node_coord_xmap_name, node_coords_x); + if (node_coord_ymap_name != "") + greader.nodeMap(node_coord_ymap_name, node_coords_y); + + // read the arrow coordinate maps + if (arrow_coord_xmap_name != "") + greader.arcMap(arrow_coord_xmap_name, arrow_coords_x); + if (arrow_coord_ymap_name != "") + greader.arcMap(arrow_coord_ymap_name, arrow_coords_y); + + greader.run(); +} + +void MapStorage::setBackground(const std::string& file_name) +{ + if (file_name == background_file_name) return; + if (file_name == "") + { + background_file_name = ""; + background_set = false; + } + else + { + background_file_name = file_name; + background_set = true; + } + signal_background.emit(); +} + +const std::string& MapStorage::getBackgroundFilename() +{ + return background_file_name; +} + +bool MapStorage::isBackgroundSet() +{ + return background_set; +} + +double MapStorage::getBackgroundScaling() +{ + return background_scaling; +} + +void MapStorage::setBackgroundScaling(double scaling) +{ + background_scaling = scaling; +} + +void MapStorage::exportDigraphToEPS(std::vector options, std::string filename, std::string shapemap) +{ + Digraph::NodeMap _shapes(digraph, 0); + Digraph::NodeMap _nodeColors(digraph, 0); + Digraph::ArcMap _arcColors(digraph, 0); + Digraph::NodeMap _nodeSizes(digraph, 6.0); + Digraph::ArcMap _arcWidths(digraph, 1.0); + bool _drawArrows=options[ARROWS]; + bool _enableParallel=options[PAR]; + + std::string emptyString=""; + Digraph::NodeMap _nodeTextMap(digraph,emptyString); + + //_nodeTextMap=(Digraph::NodeMap *)&emptyStringMap; + + if(options[N_MAPS]) + { + if(active_nodemaps[N_RADIUS]!="") + { + _nodeSizes=getNumericNodeMap(active_nodemaps[N_RADIUS]); + } + if(active_nodemaps[N_COLOR]!="") + { + for(NodeIt ni(digraph);ni!=INVALID;++ni) + { + _nodeColors[ni]=(int)get(active_nodemaps[N_COLOR], ni); + } + } + if(active_nodemaps[N_TEXT]!="") + { + for(NodeIt ni(digraph);ni!=INVALID;++ni) + { + std::ostringstream o; + o << get(active_nodemaps[N_TEXT], ni); + _nodeTextMap[ni]=o.str(); + } + } + } + if(options[E_MAPS]) + { + if(active_arcmaps[E_WIDTH]!="") + { + _arcWidths=getNumericArcMap(active_arcmaps[E_WIDTH]); + } + if(active_arcmaps[E_COLOR]!="") + { + for(ArcIt ei(digraph);ei!=INVALID;++ei) + { + _arcColors[ei]=(int)get(active_arcmaps[E_COLOR], ei); + } + } + } + if(shapemap!="Default values") + { + double min = std::numeric_limits::max(); + double max = std::numeric_limits::min(); + for (NodeIt n(digraph); n != INVALID; ++n) + { + double v = static_cast(get(shapemap, n)); + if (v < min) min = v; + if (v > max) max = v; + } + if((min>=0)&&(max<=4)) + { + NumericNodeMap& map = static_cast(getNodeMapData(shapemap))->map; + for (NodeIt n(digraph); n != INVALID; ++n) + { + _shapes[n] = static_cast(map[n]); + } + } + } + + Palette palette; + Palette paletteW(true); + + graphToEps(digraph,filename). + title("Sample .eps figure (fits to A4)"). + copyright("(C) 2006 LEMON Project"). + absoluteNodeSizes().absoluteArcWidths(). + nodeScale(2).nodeSizes(_nodeSizes). + coords(node_coords). + nodeShapes(_shapes). + nodeColors(composeMap(paletteW,_nodeColors)). + arcColors(composeMap(palette,_arcColors)). + arcWidthScale(0.3).arcWidths(_arcWidths). + nodeTexts(_nodeTextMap).nodeTextSize(7). + enableParallel(_enableParallel).parArcDist(5). + drawArrows(_drawArrows).arrowWidth(7).arrowLength(7). + run(); + +} diff -r 0e4f009eab8b -r 67188bd752db mapstorage.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mapstorage.h Mon Jul 07 08:10:39 2008 -0500 @@ -0,0 +1,530 @@ +/* -*- C++ -*- + * + * This file is a part of LEMON, a generic C++ optimization library + * + * Copyright (C) 2003-2006 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#ifndef MAPSTORAGE_H +#define MAPSTORAGE_H + +class Mapstorage; + +#include +#include +#include +#include "all_include.h" +#include "xymap.h" +#include +#include "map_value.h" +#include "map_value_map.h" + +///class MapStorage handles NodeMaps and ArcMaps. + +///Class MapStorage is responsible for storing +///NodeMaps and ArcMaps that can be shown later +///on GUI. Therefore maps can be added to it, +///and datas over the added maps can be queried. +///The maps will be stored in an std::map, +///referenced with their names. Unfortunately at +///the moment it works only with double type maps +/// +///\todo too many things are public!! +class MapStorage +{ +private: + std::string background_file_name; + bool background_set; + double background_scaling; +public: + class Error : public std::exception + { + private: + std::string message; + public: + Error(const std::string& msg) : message(msg) {} + virtual const char* what() const throw() + { + return message.c_str(); + } + ~Error() throw() {} + }; + + void setBackground(const std::string& file_name); + const std::string& getBackgroundFilename(); + bool isBackgroundSet(); + double getBackgroundScaling(); + void setBackgroundScaling(double scaling); + + enum MapSaveDest { GUI_SECT, NESET_SECT, DONT_SAVE }; + enum GuiSectSaveDest { LGF_FILE, CONF_FILE }; + struct SpecMapSaveOpts + { + enum Dest { GUI_SECT, NESET_SECT }; + enum MapNum { ONE_MAP, TWO_MAPS }; + }; + + typedef Digraph::NodeMap NumericNodeMap; + typedef Digraph::NodeMap StringNodeMap; + typedef Digraph::ArcMap NumericArcMap; + typedef Digraph::ArcMap StringArcMap; + typedef Digraph::NodeMap NodeLabelMap; + typedef Digraph::ArcMap ArcLabelMap; + typedef XYMap > NodeCoordMap; + typedef XYMap > ArrowCoordMap; + + struct ArcMapData + { + /// where to save the map + MapSaveDest save_dest; + /// read-only or read-write + bool writeable; + /// default value + MapValue default_value; + virtual MapValue::Type type() = 0; + virtual MapValue get(Arc e) = 0; + virtual void set(Arc e, MapValue v) = 0; + ArcMapData(MapValue def_val) : + save_dest(GUI_SECT), + writeable(true), + default_value(def_val) + {} + }; + + struct NumericArcMapData : public ArcMapData + { + NumericArcMap map; + MapValue::Type type() { return MapValue::NUMERIC; } + MapValue get(Arc e) { return MapValue(map[e]); } + void set(Arc e, MapValue v) { map.set(e, static_cast(v)); } + NumericArcMapData(Digraph& g, double def_val) : + ArcMapData(MapValue(def_val)), + map(g, def_val) + {} + }; + + struct StringArcMapData : public ArcMapData + { + StringArcMap map; + MapValue::Type type() { return MapValue::STRING; } + MapValue get(Arc e) { return MapValue(map[e]); } + void set(Arc e, MapValue v) { map.set(e, static_cast(v)); } + StringArcMapData(Digraph& g, std::string def_val) : + ArcMapData(MapValue(def_val)), + map(g, def_val) + {} + }; + + struct NodeMapData + { + /// where to save the map + MapSaveDest save_dest; + /// read-only or read-write + bool writeable; + /// default value + MapValue default_value; + virtual MapValue::Type type() = 0; + virtual MapValue get(Node e) = 0; + virtual void set(Node e, MapValue v) = 0; + NodeMapData(MapValue def_val) : + save_dest(GUI_SECT), + writeable(true), + default_value(def_val) + {} + }; + + struct NumericNodeMapData : public NodeMapData + { + NumericNodeMap map; + MapValue::Type type() { return MapValue::NUMERIC; } + MapValue get(Node e) { return MapValue(map[e]); } + void set(Node e, MapValue v) { map.set(e, static_cast(v)); } + NumericNodeMapData(Digraph& g, double def_val) : + NodeMapData(MapValue(def_val)), + map(g, def_val) + {} + }; + + struct StringNodeMapData : public NodeMapData + { + StringNodeMap map; + MapValue::Type type() { return MapValue::STRING; } + MapValue get(Node e) { return MapValue(map[e]); } + void set(Node e, MapValue v) { map.set(e, static_cast(v)); } + StringNodeMapData(Digraph& g, std::string def_val) : + NodeMapData(MapValue(def_val)), + map(g, def_val) + {} + }; + + typedef std::map NodeMapStore; + typedef std::map ArcMapStore; + + struct GUISectData + { + std::vector main_node_map_names; + std::vector main_arc_map_names; + + std::vector gui_node_map_names; + std::vector gui_arc_map_names; + + std::map node_map_types; + std::map arc_map_types; + + std::map* > numeric_node_maps; + std::map* > string_node_maps; + + std::map* > numeric_arc_maps; + std::map* > string_arc_maps; + + std::map node_coord_map; + std::map arrow_coord_map; + + SpecMapSaveOpts::Dest node_coords_save_dest; + SpecMapSaveOpts::MapNum node_coords_save_map_num; + std::string node_coords_one_map_name; + std::string node_coords_two_maps_1_name; + std::string node_coords_two_maps_2_name; + + SpecMapSaveOpts::Dest arrow_coords_save_dest; + SpecMapSaveOpts::MapNum arrow_coords_save_map_num; + std::string arrow_coords_one_map_name; + std::string arrow_coords_two_maps_1_name; + std::string arrow_coords_two_maps_2_name; + + ~GUISectData() + { + using std::map; + using std::vector; + using std::pair; + using std::string; + + for (map* >::iterator it = + numeric_node_maps.begin(); it != numeric_node_maps.end(); ++it) + { + delete it->second; + } + for (map* >::iterator it = + string_node_maps.begin(); it != string_node_maps.end(); ++it) + { + delete it->second; + } + for (map* >::iterator it = + numeric_arc_maps.begin(); it != numeric_arc_maps.end(); ++it) + { + delete it->second; + } + for (map* >::iterator it = + string_arc_maps.begin(); it != string_arc_maps.end(); ++it) + { + delete it->second; + } + } + }; +public: + ///The digraph for which the datas are stored. + Digraph digraph; + const Digraph& getDigraph(); + +private: + GuiSectSaveDest gui_sect_save_dest; + + SpecMapSaveOpts::Dest node_coords_save_dest; + SpecMapSaveOpts::MapNum node_coords_save_map_num; + SpecMapSaveOpts::Dest arrow_coords_save_dest; + SpecMapSaveOpts::MapNum arrow_coords_save_map_num; + + NodeMapStore nodemaps; + ArcMapStore arcmaps; + + NodeLabelMap node_label; + ArcLabelMap arc_label; + + /// the coordinates of the nodes + NodeCoordMap node_coords; + Digraph::NodeMap node_coords_x; + Digraph::NodeMap node_coords_y; + + /// the coordinates of the arrows on the arcs + ArrowCoordMap arrow_coords; + Digraph::ArcMap arrow_coords_x; + Digraph::ArcMap arrow_coords_y; + + ///The content of the object has changed, update is needed. + bool modified; + + ///Name of file loaded in object. + std::string file_name; + + // the largest node label + int max_node_label; + + // the largest arc label + int max_arc_label; + + std::string node_coords_one_map_name; + std::string node_coords_two_maps_1_name; + std::string node_coords_two_maps_2_name; + + std::string arrow_coords_one_map_name; + std::string arrow_coords_two_maps_1_name; + std::string arrow_coords_two_maps_2_name; + +public: + ///Stores the default values for the different visualization node attributes + std::vector > default_nodemaps; + + ///Stores the default values for the different visualization arc attributes + std::vector > default_arcmaps; + + ///Stores the active maps for the different visualization node attributes + std::vector< std::string > active_nodemaps; + + /// Stores the active maps for the different visualization arc attributes + std::vector< std::string > active_arcmaps; + +protected: + + /// Signal emitted on any change made on map values + + /// Signal emitted if the visualization of the maps might have to be updated. + /// bool shows us whether the changed map is arc or nodemap. + /// int tells us the refreshed property + sigc::signal signal_prop; + + /// Signal emitted in the case of nodemap addition + + /// std::string is the + ///name of the new map + sigc::signal signal_node_map; + + /// Signal emitted in the case of arcmap addition + + /// std::string is the + ///name of the new map + sigc::signal signal_arc_map; + + /// Signal emitted, when entry in \ref MapWin should be changed. + sigc::signal signal_map_win; + + /// Signal emitted, when entry in \ref DesignWin should be changed. + sigc::signal signal_design_win; + + ///Signal emitted when background should be set by \ref NoteBookTab + sigc::signal signal_background; + + ///Iteration number during digraph design + int iterations; + + ///Attraction factor during digraph design + double attraction; + + ///Propulsation factor during digraph design + double propulsation; + +public: + ///Constructor of MapStorage. + + ///Its all activity is initializing default values + ///for different visualization attributes. + MapStorage(); + + ///Destructor of MapStorage + + ///Maps stored here are created with new. Destructor + ///deletes them to free up the reserved memory. + ~MapStorage(); + + /// Registrates if the shown map by any attribute has changed to another. + + ///It handles the \ref active_arcmaps and + ///\ref active_nodemaps vectors. It also emits \ref signal_prop signal to let + ///know the interested objects that the visible map of a certain + ///attribute has changed. + ///\param itisarc arcmap or nodemap has changed + ///\param prop the property of which the map is changed + ///\param mapname the visible map + void changeActiveMap(bool itisarc , int prop , std::string mapname); + + ///Emits signals that let change the active maps in \ref MapWin. + void broadcastActiveMaps(); + + /// Returns the active arcmap shown by a visualization property. + + /// \param prop is the property + ///that shows the requested map. + std::string getActiveArcMap(int prop); + + /// Returns the active nodemap shown by a visualization property. + + /// \param prop is the property + ///that shows the requested map. + std::string getActiveNodeMap(int prop); + + /// Returns the names of the arcmaps stored here. + std::vector getArcMapList(MapType type = ALL); + + /// Returns the names of the nodemaps stored here. + std::vector getNodeMapList(MapType type = ALL); + + ///returns \ref signal_prop to be able to connect functions to it + sigc::signal signal_prop_ch(); + + ///returns \ref signal_node_map to be able to connect functions to it + sigc::signal signal_node_map_ch(){return signal_node_map;}; + + ///returns \ref signal_arc_map to be able to connect functions to it + sigc::signal signal_arc_map_ch(){return signal_arc_map;}; + + ///returns \ref signal_map_win to be able to connect functions to it + sigc::signal signal_map_win_ch(){return signal_map_win;}; + + ///returns \ref signal_design_win to be able to connect functions to it + sigc::signal signal_design_win_ch(){return signal_design_win;}; + + void createNodeMap(const std::string& name, MapValue::Type type, + MapValue def_val); + void createArcMap(const std::string& name, MapValue::Type type, + MapValue def_val); + + ///returns \ref signal_background to be able to connect functions to it + sigc::signal signal_background_ch(){return signal_background;}; + + + ///Adds given map to storage. + + ///Emits \ref signal_prop if mapvalues have changed, and MapStorage gets to know it. + + ///If values in a map have changed, this function checks, whether it is displayed. + ///This check means searching the given mapname between active maps + ///(\ref active_nodemaps, \ref active_arcmaps). If it is there at a certain property, + ///it emits a signal with the property, where the gotten mapname was found. One signal + ///is emitted for each property displaying the given map. + ///\param itisarc whether the map an arcmap or nodemap + ///\param mapname name of map to visualize + void mapChanged(bool itisarc, std::string mapname); + + ///Read datas from the given filename. + int readFromFile(const std::string &); + + ///Save datas to the given filename. + void writeToFile(const std::string &); + + ///Deletes all datastructures stored here. + void clear(); + + void get_design_data(double &, double &, int &); + void set_attraction(double); + void set_propulsation(double); + void set_iteration(int); + + void redesign_data_changed(); + + XY getNodeCoords(Node n) const; + void setNodeCoords(Node n, XY c); + XY getArrowCoords(Arc e) const; + void setArrowCoords(Arc e, XY c); + + MapValue get(const std::string& name, Node node) const; + void set(const std::string& name, Node node, MapValue val); + MapValue get(const std::string& name, Arc arc) const; + void set(const std::string& name, Arc arc, MapValue val); + + const std::string& getFileName() const; + void setFileName(const std::string& fn); + + bool getModified() const; + void setModified(bool m = true); + + Node addNode(XY); + Arc addArc(Node, Node); + + NumericNodeMap& getNumericNodeMap(const std::string& name); + StringNodeMap& getStringNodeMap(const std::string& name); + NumericArcMap& getNumericArcMap(const std::string& name); + StringArcMap& getStringArcMap(const std::string& name); + + MapValueArcMap getArcMap(const std::string& name); + MapValueNodeMap getNodeMap(const std::string& name); + + int getLabel(Node) const; + int getLabel(Arc) const; + + GuiSectSaveDest getGUIDataSaveLocation(); + void setGUIDataSaveLocation(GuiSectSaveDest dest); + + MapSaveDest getNodeMapSaveDest(std::string name) const; + MapSaveDest getArcMapSaveDest(std::string name) const; + void setNodeMapSaveDest(std::string name, MapSaveDest dest); + void setArcMapSaveDest(std::string name, MapSaveDest dest); + + SpecMapSaveOpts::Dest getNodeCoordsSaveDest(); + SpecMapSaveOpts::Dest getArrowCoordsSaveDest(); + void setNodeCoordsSaveDest(SpecMapSaveOpts::Dest dest); + void setArrowCoordsSaveDest(SpecMapSaveOpts::Dest dest); + + SpecMapSaveOpts::MapNum getNodeCoordsSaveMapNum(); + SpecMapSaveOpts::MapNum getArrowCoordsSaveMapNum(); + void setNodeCoordsSaveMapNum(SpecMapSaveOpts::MapNum num); + void setArrowCoordsSaveMapNum(SpecMapSaveOpts::MapNum num); + + MapValue::Type getNodeMapElementType(std::string name) const; + MapValue::Type getArcMapElementType(std::string name) const; + + const NodeLabelMap& getNodeLabelMap(); + const ArcLabelMap& getArcLabelMap(); + + bool nodeMapExists(std::string name); + bool arcMapExists(std::string name); + + std::vector getArcMaps(MapType type = ALL); + std::vector getNodeMaps(MapType type = ALL); + + NodeCoordMap& getNodeCoordMap(); + ArrowCoordMap& getArrowCoordMap(); + + const std::string& getNodeCoordsOneMapName(); + const std::string& getNodeCoordsTwoMaps1Name(); + const std::string& getNodeCoordsTwoMaps2Name(); + void setNodeCoordsOneMapName(const std::string& name); + void setNodeCoordsTwoMaps1Name(const std::string& name); + void setNodeCoordsTwoMaps2Name(const std::string& name); + + const std::string& getArrowCoordsOneMapName(); + const std::string& getArrowCoordsTwoMaps1Name(); + const std::string& getArrowCoordsTwoMaps2Name(); + void setArrowCoordsOneMapName(const std::string& name); + void setArrowCoordsTwoMaps1Name(const std::string& name); + void setArrowCoordsTwoMaps2Name(const std::string& name); + +private: + ArcMapData* getArcMapData(std::string name) const; + NodeMapData* getNodeMapData(std::string name) const; + void readLGF( + const std::string& filename, + bool read_arc_label, + const std::vector& node_map_names, + const std::vector& arc_map_names, + const std::map& node_map_types, + const std::map& arc_map_types, + const std::string& node_coord_xmap_name, + const std::string& node_coord_ymap_name, + const std::string& arrow_coord_xmap_name, + const std::string& arrow_coord_ymap_name); + +public: + void exportDigraphToEPS(std::vector, std::string, std::string); +}; + +#endif //MAPSTORAGE_H diff -r 0e4f009eab8b -r 67188bd752db nbtab.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/nbtab.cc Mon Jul 07 08:10:39 2008 -0500 @@ -0,0 +1,372 @@ +/* -*- C++ -*- + * + * This file is a part of LEMON, a generic C++ optimization library + * + * Copyright (C) 2003-2006 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#include +#include +#include +#include +#include +#include + + + +NoteBookTab::NoteBookTab():mapwinexists(false), designwinexists(false), epswinexists(false) +{ + mapstorage=new MapStorage(); + + Gtk::ScrolledWindow *pScrolledWindow = Gtk::manage(new Gtk::ScrolledWindow); + pScrolledWindow->set_shadow_type(Gtk::SHADOW_ETCHED_IN); + gd_canvas=Gtk::manage(new DigraphDisplayerCanvas(*this)); + pScrolledWindow->add(*gd_canvas); + add(*pScrolledWindow); + + //connecting signals - controller character + mapstorage->signal_prop_ch().connect(sigc::mem_fun(*gd_canvas, &DigraphDisplayerCanvas::propertyChange)); + mapstorage->signal_node_map_ch().connect(sigc::mem_fun(*this, &NoteBookTab::registerNewNodeMap)); + mapstorage->signal_arc_map_ch().connect(sigc::mem_fun(*this, &NoteBookTab::registerNewArcMap)); + mapstorage->signal_background_ch().connect(sigc::mem_fun(*gd_canvas, &DigraphDisplayerCanvas::setBackground)); + show_all_children(); + show(); +} + +NoteBookTab::~NoteBookTab() +{ + delete mapstorage; +} + +void NoteBookTab::readFile(const std::string &file) +{ + mapstorage->readFromFile(file); + mapstorage->setFileName(file); + mapstorage->setModified(false); + gd_canvas->drawDigraph(); + if(mapwinexists) + { + mapwin->update( + mapstorage->getArcMapList(NUM), + mapstorage->getArcMapList(STR), + mapstorage->getNodeMapList(NUM), + mapstorage->getNodeMapList(STR)); + } + title_changed(Glib::filename_display_basename(file)); +} + +void NoteBookTab::newFile() +{ + if (mapstorage->getModified()) + { + Gtk::MessageDialog mdialog("Save changes before closing?", true, + Gtk::MESSAGE_WARNING, Gtk::BUTTONS_NONE); + mdialog.add_button("Close file _without Saving", Gtk::RESPONSE_REJECT); + mdialog.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL); + mdialog.add_button(Gtk::Stock::SAVE, Gtk::RESPONSE_ACCEPT); + switch (mdialog.run()) + { + case Gtk::RESPONSE_CANCEL: + return; + case Gtk::RESPONSE_REJECT: + break; + case Gtk::RESPONSE_ACCEPT: + saveFile(); + break; + } + } + gd_canvas->clear(); + mapstorage->clear(); + if(mapwinexists) + { + mapwin->update( + mapstorage->getArcMapList(NUM), + mapstorage->getArcMapList(STR), + mapstorage->getNodeMapList(NUM), + mapstorage->getNodeMapList(STR)); + } + title_changed("unsaved file"); +} + +void NoteBookTab::openFile() +{ + if (mapstorage->getModified()) + { + Gtk::MessageDialog mdialog("Save changes before closing?", true, + Gtk::MESSAGE_WARNING, Gtk::BUTTONS_NONE); + mdialog.add_button("Close file _without Saving", Gtk::RESPONSE_REJECT); + mdialog.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL); + mdialog.add_button(Gtk::Stock::SAVE, Gtk::RESPONSE_ACCEPT); + switch (mdialog.run()) + { + case Gtk::RESPONSE_CANCEL: + return; + case Gtk::RESPONSE_REJECT: + break; + case Gtk::RESPONSE_ACCEPT: + saveFile(); + break; + } + } + Gtk::FileChooserDialog fcdialog("Open File"); + fcdialog.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL); + fcdialog.add_button(Gtk::Stock::OPEN, Gtk::RESPONSE_ACCEPT); + if (fcdialog.run() == Gtk::RESPONSE_ACCEPT) + { + gd_canvas->clear(); + std::cout << mapstorage << std::endl; + mapstorage->clear(); + Glib::ustring filename = fcdialog.get_filename(); + if (!mapstorage->readFromFile(filename)) + { + mapstorage->setFileName(filename); + mapstorage->setModified(false); + gd_canvas->drawDigraph(); + if(mapwinexists) + { + mapwin->update( + mapstorage->getArcMapList(NUM), + mapstorage->getArcMapList(STR), + mapstorage->getNodeMapList(NUM), + mapstorage->getNodeMapList(STR)); + } + title_changed(Glib::filename_display_basename(filename)); + } + } +} + +void NoteBookTab::saveFile() +{ + if (mapstorage->getFileName() == "") { + saveFileAs(); + } + else + { + mapstorage->writeToFile(mapstorage->getFileName()); + mapstorage->setModified(false); + title_changed(Glib::filename_display_basename(mapstorage->getFileName())); + } +} + +void NoteBookTab::saveFileAs() +{ + Gtk::FileChooserDialog fcdialog("Save File", Gtk::FILE_CHOOSER_ACTION_SAVE); + fcdialog.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL); + fcdialog.add_button(Gtk::Stock::SAVE, Gtk::RESPONSE_ACCEPT); + if (fcdialog.run() == Gtk::RESPONSE_ACCEPT) + { + Glib::ustring filename = fcdialog.get_filename(); + mapstorage->setFileName(filename); + mapstorage->writeToFile(filename); + mapstorage->setModified(false); + title_changed(Glib::filename_display_basename(filename)); + } +} + +void NoteBookTab::close() +{ + if (mapstorage->getModified()) + { + Gtk::MessageDialog mdialog("Save changes before closing?", true, + Gtk::MESSAGE_WARNING, Gtk::BUTTONS_NONE); + mdialog.add_button("Close _without Saving", Gtk::RESPONSE_REJECT); + mdialog.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL); + mdialog.add_button(Gtk::Stock::SAVE, Gtk::RESPONSE_ACCEPT); + switch (mdialog.run()) + { + case Gtk::RESPONSE_CANCEL: + return; + case Gtk::RESPONSE_REJECT: + break; + case Gtk::RESPONSE_ACCEPT: + saveFile(); + break; + } + } + gd_canvas->clear(); + mapstorage->clear(); + if(mapwinexists) + { + mapwin->update( + mapstorage->getArcMapList(NUM), + mapstorage->getArcMapList(STR), + mapstorage->getNodeMapList(NUM), + mapstorage->getNodeMapList(STR)); + } + title_changed("unsaved file"); +} + +void NoteBookTab::propertyChange(bool itisarc, int prop, std::string mapname) +{ + mapstorage->changeActiveMap(itisarc, prop, mapname); +} + +sigc::signal NoteBookTab::signal_newmap_needed() +{ + return signal_newmap; +} + +void NoteBookTab::popupNewMapWin(bool itisarc) +{ + signal_newmap.emit(this, itisarc); +} + +std::string NoteBookTab::getActiveArcMap(int prop) +{ + return mapstorage->getActiveArcMap(prop); +} + +std::string NoteBookTab::getActiveNodeMap(int prop) +{ + return mapstorage->getActiveNodeMap(prop); +} + +void NoteBookTab::registerNewArcMap(std::string mapname, MapValue::Type type) +{ + if(mapwinexists) + { + mapwin->registerNewArcMap(mapname, type); + } +} + +void NoteBookTab::registerNewNodeMap(std::string mapname, MapValue::Type type) +{ + if(mapwinexists) + { + mapwin->registerNewNodeMap(mapname, type); + } + if(epswinexists) + { + epswin->registerNewNodeMap(mapname, type); + } +} + +void NoteBookTab::createMapWin(std::string name) +{ + if(!mapwinexists) + { + mapwin=new MapWin("Map Setup - "+name, + mapstorage->getArcMapList(NUM), + mapstorage->getArcMapList(STR), + mapstorage->getNodeMapList(NUM), + mapstorage->getNodeMapList(STR), + *this); + mapst2mapwin=mapstorage->signal_map_win_ch().connect(sigc::mem_fun(*mapwin, &MapWin::changeEntry)); + mapwin->show(); + mapwinexists=true; + } +} + +void NoteBookTab::createExportToEPSWin(std::string name) +{ + if(!epswinexists) + { + epswin=new EpsWin("Export to EPS - "+name, mapstorage->getNodeMapList(NUM), mapstorage->getNodeMapList(STR)); + epswin->show(); + epswinexists=true; + epswin->signal_eps_details_ch().connect(sigc::mem_fun(*this, &NoteBookTab::exportDigraphToEPS)); + epswin->signal_eps_close_ch().connect(sigc::mem_fun(*this, &NoteBookTab::closeEpsWin)); + epswin->signal_new_map_ch().connect(sigc::mem_fun(*this, &NoteBookTab::popupNewMapWin)); + } +} + + +void NoteBookTab::createDesignWin(std::string name) +{ + if(!designwinexists) + { + double attraction, propulsation; + int iterations; + mapstorage->get_design_data(attraction, propulsation, iterations); + designwin=new DesignWin("Design Setup - "+name, attraction, propulsation, iterations); + + designwin->signal_attraction().connect(sigc::mem_fun(*mapstorage, &MapStorage::set_attraction)); + designwin->signal_propulsation().connect(sigc::mem_fun(*mapstorage, &MapStorage::set_propulsation)); + designwin->signal_iteration().connect(sigc::mem_fun(*mapstorage, &MapStorage::set_iteration)); + designwin->close_run().connect(sigc::mem_fun(*gd_canvas, &DigraphDisplayerCanvas::reDesignDigraph)); + + designwin->signal_delete_event().connect(sigc::mem_fun(*this, &NoteBookTab::closeDesignWin)); + + mapst2designwin=mapstorage->signal_design_win_ch().connect(sigc::mem_fun(*designwin, &DesignWin::set_data)); + + designwin->show(); + designwinexists=true; + } +} + +void NoteBookTab::closeMapWin() +{ + mapst2mapwin.disconnect(); + mapwinexists=false; + delete mapwin; +} + +void NoteBookTab::closeEpsWin() +{ + epswinexists=false; + delete epswin; +} + +bool NoteBookTab::closeDesignWin(GdkEventAny * e) +{ + if(e->type==GDK_DELETE) + { + designwinexists=false; + mapst2designwin.disconnect(); + delete designwin; + } +} + +sigc::signal NoteBookTab::signal_title_ch() +{ + return signal_title; +} + +void NoteBookTab::setView(bool autoscale, bool zoomtrack, double width, double radius) +{ + gd_canvas->setView(autoscale, zoomtrack, width, radius); +} + +void NoteBookTab::getView(bool & autoscale, bool & zoomtrack, double& width, double& radius) +{ + gd_canvas->getView(autoscale, zoomtrack, width, radius); +} + +void NoteBookTab::reDesignDigraph() +{ + gd_canvas->reDesignDigraph(); +} + +void NoteBookTab::active_maps_needed() +{ + mapstorage->broadcastActiveMaps(); +} + +void NoteBookTab::exportDigraphToEPS(std::vector options, std::string filename, std::string shapemap) +{ + mapstorage->exportDigraphToEPS(options, filename, shapemap); +} + +void NoteBookTab::title_changed(std::string newtitle) +{ + signal_title.emit(newtitle); + if(epswinexists) + { + epswin->set_title(newtitle); + } + if(designwinexists) + { + designwin->set_title(newtitle); + } +} diff -r 0e4f009eab8b -r 67188bd752db nbtab.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/nbtab.h Mon Jul 07 08:10:39 2008 -0500 @@ -0,0 +1,256 @@ +/* -*- C++ -*- + * + * This file is a part of LEMON, a generic C++ optimization library + * + * Copyright (C) 2003-2006 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#ifndef NBTAB_H +#define NBTAB_H + +class MapStorage; +class EpsWin; +class MapWin; +class DesignWin; +class DigraphDisplayerCanvas; + +#include +#include +#include "map_value.h" + +///One tab in the Notebook that is placed in the main window (\ref MainWin). + +///One digraph and all of its accessories like maps are assigned to one tab in the notebook. +///\ref NoteBookTab is responsible for the user defined display of the digraph: view can be +///set by visualized maps, therefore \ref NoteBookTab must provide an interface to set the +///view of digraph. This is \ref Mapwin window. +/// +///\ref NoteBookTab is also +///responsible for modify the digraph if it is +///requested. Therefore it is responsible for translating user events to modifications to +///do on digraph, like node/arc addition/deletion, map modification, addition and so on. +/// +///To be able to solve these tasks the help of \ref MainWin is also needed, for example to +///know which editor-tool is active at the moment. Therefore \ref MainWin knows \ref NoteBookTab. +/// +///Some information in the other direction is needed as well: for example when new map creation is requested for this tab +///\ref NoteBookTab must ask \ref MainWin to pop-up a \ref NewMapWin. Communication in this direction is realized by signals +///therefore \ref NoteBookTab does not know \ref MainWin at all, but in this way it is not necessary. +class NoteBookTab : public Gtk::VBox +{ +public: + + ///Constructor of \ref NoteBookTab + + ///It initiates the \re DigraphDisplayerCanvas, on which the digraph will be drawn + ///Signals of \ref MapStorage will be bound to the appropriate callback functions here. + NoteBookTab(); + + ~NoteBookTab(); + + ///Maps assigned to the digraph displayed in this \ref NoteBookTab of notebook. + MapStorage * mapstorage; + + ///Title changement indicator. + + ///If digraph is loaded from disk or saved to disk or changed its name somehow + ///this signal will be emit to let + ///\ref MainWin know that it has to modify the title of the main window. + ///It contains the new title. + sigc::signal signal_title; + + ///Returns \ref signal_title to be the caller able to connect it to a callback function. + sigc::signal signal_title_ch(); + + ///Indicates that new map window should be popped up. + + ///\ref NoteBookTab can ask \ref MainWin to pop up a \ref NweMapWin ny emitting this signal. + ///The signal contains whether an arcmap or a nodemap should be popped up. \ref NewMapWin + ///is not popped up by \ref NoteBookTab, because not only \ref NoteBookTab needs \ref NewMapWin, + ///but for example \ref MainWin and \ref AlgoWin s as well. + sigc::signal signal_newmap; + + ///Returns \ref signal_newmap to be the caller able to connect it to a callback function. + sigc::signal signal_newmap_needed(); + + ///Loads the given file. + + ///The given file will be load in the \ref MapStorage and afeter that + ///\ref DigraphDisplayerCanvas will be requested to display the digraph. + ///\ref DigraphDisplayer will get datas from the recently set \ref MapStorage. + void readFile(const std::string &); + + ///The digraph will be drawn on this \ref DigraphDisplayerCanvas + DigraphDisplayerCanvas * gd_canvas; + + ///Indicates whether the \ref MapWin is opened or not. See \ref mapwin. + bool mapwinexists; + + ///Indicates whether the \ref DesignWin is opened or not. See \ref designwin. + bool designwinexists; + + ///Indicates whether the \ref EpsWin is opened or not. See \ref epswin. + bool epswinexists; + + ///Address of the only \ref MapWin that the \ref NoteBookTab can open. + + ///Only one of this window can be opened at the same time (\ref mapwinexists), + ///because there is no need for more, one per tab is enough. + ///There won1t be benefit of more than one, but it would be + ///more complicated to synchronize them. + MapWin * mapwin; + + ///Address of the only \ref DesignWin that the \ref NoteBookTab can open. + + ///Only one of this window can be opened at the same time (\ref designwinexists), + ///because there is no need for more, one per tab is enough. + ///There won't be benefit of more than one, but it would be + ///more complicated to synchronize them. + DesignWin * designwin; + + ///Address of the only \ref EpsWin that the \ref NoteBookTab can open. + + ///Only one of this window can be opened at the same time (\ref epswinexists), + ///because there is no need for more, one per tab is enough. + ///There won't be benefit of more than one. + EpsWin * epswin; + +public: + ///Callback for 'FileNew' action. + virtual void newFile(); + ///Callback for 'FileOpen' action. + virtual void openFile(); + ///Callback for 'FileSave' action. + virtual void saveFile(); + ///Callback for 'FileSaveAs' action. + virtual void saveFileAs(); + ///Callback for 'Close' action. + virtual void close(); + + ///Handles changement of view of digraph. + + ///If the user changes the map to show by a property to a nother in \ref MapWin, + ///\ref MapWin will call this function. This function will registrate in \ref MapStorage + ///the new map to display by the changed property. After that \ref MapStorage will + ///emits a signal that will be forwarded to \ref DigraphDisplayerCanvas to update the + ///appropriate parts of digraph. + ///\param itiesarc whether the changed property is arc property or node property + ///\param prop id of property, see all_include.h + ///\param mapname name of the recently selected map + void propertyChange(bool itisarc, int prop, std::string mapname); + + ///Emits a signal that request \ref MainWin to pop up \ref NewMapWin + + ///This function is called by \ref MapWin. + ///\param itisarc whether the new map should be an arcmap or a nodemap. + void popupNewMapWin(bool itisarc); + + ///Returns the actually selected arcmap to visualize by the given property. + + ///\ref MapWin calls this function, beacuse it does not know \ref MapStorage. + ///\param prop property to inquire. + std::string getActiveArcMap(int prop); + + ///Returns the actually selected nodemap to visualize by the given property. + + ///\ref MapWin calls this function, beacuse it does not know \ref MapStorage. + ///\param prop property to inquire. + std::string getActiveNodeMap(int prop); + + ///Registers recently created arcmap in \ref MapWin. + + ///After creation of new map \ref MapStorage emits a signal. + ///This signal is bound to this callback function, that will call + ///a function with the same name and same parameterin \ref MapWin. + ///This call-forwarder function is needed, because \ref Mapstorage does not know \ref MapWin + ///\param mapname name of new map + void registerNewArcMap(std::string mapname, MapValue::Type type); + + ///Registers recently created nodemap in \ref MapWin. + + ///After creation of new map \ref MapStorage emits a signal. + ///This signal is bound to this callback function, that will call + ///a function with the same name and same parameter in \ref MapWin. + ///This call-forwarder function is needed, because \ref Mapstorage does not know \ref MapWin + ///\param mapname name of new map + void registerNewNodeMap(std::string mapname, MapValue::Type type); + + ///Pops up and registrates the \ref MapWin of \ref NoteBookTab. + + ///See also + ///\ref mapwin. + void createMapWin(std::string); + + ///Pops up and registrates the \ref DesignWin of \ref NoteBookTab. + + ///See also + ///\ref mapwin. + void createDesignWin(std::string); + + ///Pops up a window, that can dump digraph to EPS + + ///Different parameters can be set here. + void createExportToEPSWin(std::string); + + ///Closes and deregistrates the \ref MapWin of \ref NoteBookTab. + + ///See also + ///\ref mapwin. + void closeMapWin(); + + ///Closes and deregistrates the \ref DesignWin of \ref NoteBookTab. + + ///See also + ///\ref designwin. + bool closeDesignWin(GdkEventAny *); + + ///Closes and deregistrates the \ref EpsWin of \ref NoteBookTab. + + ///See also + ///\ref epswin. + void closeEpsWin(); + + ///Sets node representation settings + void setView(bool, bool, double, double); + + ///Gets node representation settings + void getView(bool &, bool &, double&, double&); + + ///Let the digraph redesign, based on gravity and arc elasticity. + void reDesignDigraph(); + + ///Lets Mapstorage export the digraph to EPS + void exportDigraphToEPS(std::vector, std::string, std::string); + + ///\ref MapWin calls this function when it updates the maplist in comboboxes. + void active_maps_needed(); + +private: + ///Called when title of tab has changed + void title_changed(std::string); + + ///Signal connection from \ref MapStorage to \ref MapWin + + ///If \ref MapWin is closed this connection has to be disconnected, + ///therefore we have to store it. + sigc::connection mapst2mapwin; + + ///Signal connection from \ref MapStorage to \ref DesignWin + + ///If \ref DesignWin is closed this connection has to be disconnected, + ///therefore we have to store it. + sigc::connection mapst2designwin; +}; + +#endif //NBTAB_H diff -r 0e4f009eab8b -r 67188bd752db new_map_win.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/new_map_win.cc Mon Jul 07 08:10:39 2008 -0500 @@ -0,0 +1,565 @@ +/* -*- C++ -*- + * + * This file is a part of LEMON, a generic C++ optimization library + * + * Copyright (C) 2003-2006 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#include +#include +#include + +bool NewMapWin::closeIfEscapeIsPressed(GdkEventKey* e) +{ + if(e->keyval==GDK_Escape) + { + hide(); + } + return true; +} + +NewMapWin::NewMapWin(const std::string& title, NoteBookTab & mw, bool itisarc, bool arcnode, MapType type):Gtk::Dialog(title, true, true),mytab(mw),node("Create NodeMap"),arc("Create ArcMap"),map_type(type) +{ + set_default_size(200, 50); + + signal_key_press_event().connect(sigc::mem_fun(*this, &NewMapWin::closeIfEscapeIsPressed)); + + Gtk::VBox * vbox=get_vbox(); + + //entries + table=new Gtk::Table(5, 2, false); + + label=new Gtk::Label; + label->set_text("Name of new map:"); + name.set_text(""); + + (*table).attach(*label,0,1,0,1,Gtk::SHRINK,Gtk::SHRINK,10,3); + (*table).attach(name,1,2,0,1,Gtk::SHRINK,Gtk::SHRINK,10,3); + + lblType.set_label("Element type:"); + if (map_type & NUM) + cbType.append_text("Numeric"); + if (map_type & STR) + cbType.append_text("String"); + cbType.set_active(0); + + (*table).attach(lblType,0,1,1,2,Gtk::SHRINK,Gtk::SHRINK,10,3); + (*table).attach(cbType, 1,2,1,2,Gtk::SHRINK,Gtk::SHRINK,10,3); + + label=new Gtk::Label; + label->set_text("Default value in the map:"); + default_value.set_text("0"); + + (*table).attach(*label,0,1,2,3,Gtk::SHRINK,Gtk::SHRINK,10,3); + (*table).attach(default_value,1,2,2,3,Gtk::SHRINK,Gtk::SHRINK,10,3); + + //node vs. arc map selector + Gtk::RadioButton::Group group = node.get_group(); + arc.set_group(group); + + if(arcnode) + { + (*table).attach(node,0,1,3,4,Gtk::SHRINK,Gtk::SHRINK,10,3); + (*table).attach(arc,1,2,3,4,Gtk::SHRINK,Gtk::SHRINK,10,3); + } + else + { + if(itisarc) + { + arc.set_active(); + } + else + { + node.set_active(); + } + } + + (*table).attach(lblErrorMsg,0,2,4,5,Gtk::SHRINK,Gtk::SHRINK,10,3); + + vbox->pack_start(*table); + + //OK button + add_button(Gtk::Stock::OK, Gtk::RESPONSE_OK); + + show_all_children(); + +} + +void NewMapWin::setErrorMsg(const Glib::ustring& msg) +{ + lblErrorMsg.set_markup("" + msg + ""); +} + +std::vector* NewMapWin::evaluate_expr(const std::string polishform, bool itisarc) +{ + MapStorage& ms = *mytab.mapstorage; + + std::vector* ret = new std::vector; + std::stack polishstack; + + if (itisarc) + { + for(ArcIt k(ms.digraph); k!=INVALID; ++k) + { + for(int i=0;i<(int)polishform.size();i++) + { + double op1=0, op2=0; + bool operation=true; + switch(polishform[i]) + { + case '+': + case '-': + case '/': + case '*': + op1=polishstack.top(); + polishstack.pop(); + op2=polishstack.top(); + polishstack.pop(); + break; + default: + //substitute variable + std::vector maps = ms.getArcMapList(NUM); + bool itisvar=(std::find(maps.begin(), maps.end(), ch2var[ polishform[i] ]) != maps.end()); + if(itisvar) + { + polishstack.push(ms.get(ch2var[ polishform[i] ], k)); + } + else + { + polishstack.push(atof(ch2var[ polishform[i] ].c_str())); + } + operation=false; + break; + } + if(operation) + { + double res; + switch(polishform[i]) + { + case '+': + res=op1+op2; + break; + case '-': + res=op2-op1; + break; + case '/': + res=op2/op1; + break; + case '*': + res=op1*op2; + break; + default: + std::cout << "How could we get here?" << std::endl; + break; + } + polishstack.push(res); + } + }//foreach letter in polishform + ret->push_back(polishstack.top()); + }//foreach arc + } + else + { + for(NodeIt k(ms.digraph); k!=INVALID; ++k) + { + for(int i=0;i<(int)polishform.size();i++) + { + double op1=0, op2=0; + bool operation=true; + switch(polishform[i]) + { + case '+': + case '-': + case '/': + case '*': + op1=polishstack.top(); + polishstack.pop(); + op2=polishstack.top(); + polishstack.pop(); + break; + default: + //substitute variable + std::vector maps = ms.getNodeMapList(NUM); + bool itisvar=(std::find(maps.begin(), maps.end(), ch2var[ polishform[i] ]) != maps.end()); + if(itisvar) + { + polishstack.push(ms.get(ch2var[ polishform[i] ], k)); + } + else + { + polishstack.push(atof(ch2var[ polishform[i] ].c_str())); + } + operation=false; + break; + } + if(operation) + { + double res; + switch(polishform[i]) + { + case '+': + res=op1+op2; + break; + case '-': + res=op2-op1; + break; + case '/': + res=op2/op1; + break; + case '*': + res=op1*op2; + break; + default: + std::cout << "How could we get here?" << std::endl; + break; + } + polishstack.push(res); + } + }//foreach letter in polishform + ret->push_back(polishstack.top()); + }//foreach arc + } + return ret; +} + +void NewMapWin::on_response(int response_id) +{ + MapStorage& ms = *mytab.mapstorage; + + if(response_id==Gtk::RESPONSE_OK) + { + std::string map_name = name.get_text(); + std::string def_val = default_value.get_text(); + + if (map_name.empty()) + { + setErrorMsg("No map name given."); + return; + } + + // check whether the map already exists + if (arc.get_active()) + { + if (ms.arcMapExists(map_name)) + { + setErrorMsg("Map '" + map_name + "' already exists."); + return; + } + } + else + { + if (ms.nodeMapExists(map_name)) + { + setErrorMsg("Map '" + map_name + "' already exists."); + return; + } + } + + Glib::ustring text = cbType.get_active_text(); + if (text == "Numeric") + { + double d; + char *endptr; + d = strtod(def_val.c_str(), &endptr); + if (def_val.c_str() + def_val.length() == endptr) + { + // the full string was a number + if (arc.get_active()) + ms.createArcMap(map_name, MapValue::NUMERIC, + MapValue(d)); + else + ms.createNodeMap(map_name, MapValue::NUMERIC, + MapValue(d)); + } + else + { + // let't try to evaluate the string as an arithmetic expression + std::string polishform = + string2Polishform(def_val, arc.get_active()); + if (polishform.empty()) + return; + std::vector* values = + evaluate_expr(polishform, arc.get_active()); + if (arc.get_active()) + { + ms.createArcMap(map_name, MapValue::NUMERIC, + MapValue(0.0)); + std::vector::const_iterator vit = values->begin(); + for (ArcIt it(ms.digraph); it != INVALID; ++it) + { + ms.set(map_name, it, MapValue(*vit)); + ++vit; + } + } + else + { + ms.createNodeMap(map_name, MapValue::NUMERIC, + MapValue(0.0)); + std::vector::const_iterator vit = values->begin(); + for (NodeIt it(ms.digraph); it != INVALID; ++it) + { + ms.set(map_name, it, MapValue(*vit)); + ++vit; + } + } + delete values; + } + } + else if (text == "String") + { + if (arc.get_active()) + ms.createArcMap(map_name, MapValue::STRING, + MapValue(def_val)); + else + ms.createNodeMap(map_name, MapValue::STRING, + MapValue(def_val)); + } + + name.set_text(""); + default_value.set_text("0"); + arc.show(); + node.show(); + hide(); + } +} + + +std::string NewMapWin::string2Polishform(std::string rawcommand, bool itisarc) +{ + bool valid_entry=true; + + std::map str2i; + + std::string command; + + std::string variable; + + char index='a'; + + for(int i=0;(valid_entry&&(i<(int)rawcommand.size()));i++) + { + switch(rawcommand[i]) + { + case '+': + case '-': + case '*': + case '/': + case ')': + case '(': + if(!variable.empty()) + { + valid_entry=validVariable(variable, itisarc); + ch2var[index]=variable; + command+=index; + index++; + variable.erase(0,variable.size()); + } + command+=rawcommand[i]; + break; + default: + variable+=rawcommand[i]; + break; + } + } + + if(!variable.empty()&&valid_entry) + { + valid_entry=validVariable(variable, itisarc); + ch2var[index]=variable; + command+=index; + index++; + variable.erase(0,variable.size()); + } + + if(valid_entry) + { + unsigned int pr=10000; + bool prevmult=false; + unsigned int prev_change=pr; + unsigned int prev_br=pr; + int counter=0; + std::string comm_nobr=""; + std::vector p; + p.resize(counter+1); + + //limits + //6 brackets embedded + //100 operation in a row from the same priority + + for(int i=0;i<(int)command.size();i++) + { + bool put_in_string=true; + switch(command[i]) + { + case '(': + pr=prev_br+10000; + prev_br=pr; + prevmult=false; + put_in_string=false; + break; + case ')': + pr=prev_br-10000; + prev_br=pr; + prevmult=false; + put_in_string=false; + break; + case '+': + case '-': + if(prevmult) + { + pr=prev_change; + } + p[counter]=pr; + pr-=100; + + prevmult=false; + break; + case '/': + case '*': + if(!prevmult) + { + prev_change=pr; + pr+=200; + pr-=1; + } + p[counter]=pr; + pr-=1; + prevmult=true; + break; + default: + p[counter]=65000; + break; + } + if(put_in_string) + { + counter++; + p.resize(counter+1); + comm_nobr=comm_nobr+command[i]; + } + } + + tree_node * root=weightedString2Tree(comm_nobr, p, 0); + + std::string polishform=postOrder(root); + + deleteTree(root); + + return polishform; + } + return ""; +} + +void NewMapWin::deleteTree(NewMapWin::tree_node * node) +{ + if(node->left_child!=NULL) + { + deleteTree(node->left_child); + } + if(node->right_child!=NULL) + { + deleteTree(node->right_child); + } + delete node; +} + +NewMapWin::tree_node * NewMapWin::weightedString2Tree(std::string to_tree, std::vector & p, int offset) +{ + unsigned int min=p[offset]; + int minplace=0; + for(int i=0;i<(int)to_tree.size();i++) + { + if(min>p[offset+i]) + { + min=p[offset+i]; + minplace=i; + } + } + tree_node * act_node=new tree_node; + act_node->ch=to_tree[minplace]; + if(to_tree.size()>=3) + { + act_node->left_child=weightedString2Tree(to_tree.substr(0,minplace), p, offset); + act_node->right_child=weightedString2Tree(to_tree.substr(minplace+1,to_tree.size()-minplace-1), p, offset+minplace+1); + } + else + { + act_node->left_child=NULL; + act_node->right_child=NULL; + } + return act_node; +} + +std::string NewMapWin::postOrder(tree_node * subtree) +{ + std::string subtree_to_string; + if(subtree->left_child) + { + subtree_to_string=postOrder(subtree->left_child); + } + if(subtree->right_child) + { + subtree_to_string=subtree_to_string+postOrder(subtree->right_child); + } + subtree_to_string=subtree_to_string+subtree->ch; + return subtree_to_string; +} + +bool NewMapWin::validVariable(std::string variable, bool itisarc) +{ + MapStorage& ms = *mytab.mapstorage; + + bool cancel; + //is it mapname? + if(itisarc) + { + std::vector arc_maps = + ms.getArcMapList(NUM); + cancel=(std::find(arc_maps.begin(), arc_maps.end(), variable)==arc_maps.end()); + } + else + { + std::vector node_maps = + ms.getNodeMapList(NUM); + cancel=(std::find(node_maps.begin(), node_maps.end(), variable)==node_maps.end()); + } + //maybe it is number + int point_num=0; + if(cancel) + { + cancel=false; + for(int j=0;(!cancel)&&(j<(int)variable.size());j++) + { + if(((variable[j]<'0')||(variable[j]>'9'))&&(variable[j]!='.')) + { + cancel=true; + } + else + { + if(variable[j]=='.') + { + point_num++; + if(point_num>1) + { + cancel=true; + } + } + } + } + } + if(cancel) + { + return false; + } + return true; +} diff -r 0e4f009eab8b -r 67188bd752db new_map_win.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/new_map_win.h Mon Jul 07 08:10:39 2008 -0500 @@ -0,0 +1,160 @@ +/* -*- C++ -*- + * + * This file is a part of LEMON, a generic C++ optimization library + * + * Copyright (C) 2003-2006 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#ifndef NEWMAPWIN_H +#define NEWMAPWIN_H + +#include +#include +#include +#include + +class NoteBookTab; + +///Digraphical interface for node/arc map creation. + +///This class is responsible for creating a window, +///on which the parameters of a new map can be set. +class NewMapWin : public Gtk::Dialog +{ + ///The \ref NoteBookTab in which the new map has to be placed. + NoteBookTab & mytab; + + MapType map_type; + Gtk::Label lblType; + Gtk::ComboBoxText cbType; + + Gtk::Label lblErrorMsg; + void setErrorMsg(const Glib::ustring& msg); + + std::vector* evaluate_expr(const std::string polishform, bool itisarc); + +public: + + ///Struct to be able to evaluate expressions. + + ///Initial values of map elements can be given + ///by numbers or by expressions. From expressions + ///we build first a tree according to the priorities + ///of operations in the expression. This is the data + ///structure + ///that can store one tree element. + struct tree_node + { + ///Character stored in this tree element + char ch; + ///Left child of tree element. + tree_node * left_child; + ///Right child of tree element. + tree_node * right_child; + }; + + ///Constructor of NewMapWin. + + ///It creates the widgets shown in + ///NewMapWin. + NewMapWin(const std::string& title, NoteBookTab &, bool itisarc=true, bool arcnode=true, MapType type = ALL); + + ///Callback function for OK button. It creates the map. + + ///This function determines whether the input is correct: + ///the name of new map must not be already used, the expression + ///that gives tha initial values of map elements has to be valid. + ///If input is correct it creates and registrates the new map + ///to the correct place. (\ref mytab) + virtual void on_response(int response_id); + + ///Close window if Esc key pressed. + virtual bool closeIfEscapeIsPressed(GdkEventKey*); + + ///Function that creates a tree from an appropriately manipulated string. + + ///Tree is builded according to priorities of operations in expression given by string. + ///Priorities are indicated in a vector that contains weights for each operation. + ///\param to_tree string to build tree from + ///\param weights weights (priorities) + ///\param offset this function call is recursive. This parameter tells us, + ///with which part of the string do we have to deal with. + tree_node * weightedString2Tree(std::string to_tree, std::vector & weights, int offset); + + ///Function that creates a string from a tree by postorder reading. + + ///This is the last step of creating polishform + ///from a given expression string. + ///\param root the root of the tree to read through + std::string postOrder(tree_node * root); + + ///From the given expression it creates expression given in polish form. + + ///First it substitutes variables and numbers in the given expression. + ///The substitutions will be one character long local variables. + ///The substituted-substitution pair is registrated in \ref ch2var. + ///After that it gives weights fo each character in substituted expression. + ///Weights are calculated according to the priority of operations in expression. + ///Then it creates tree (\ref tree_node) from the weighted string. (\ref weightedString2Tree) + ///\param to_polish the string to turn into polish_form + ///\param itisarc do we have to create an arcmap or a nodemap. + ///It is important, because variables are maps and if expression + ///citates a map that does not exists the expression is not valid. + ///But to determine, whether the map exists we have to know where + ///to search for it. And of course for a new arcmap only arcmaps can be serve with values. + std::string string2Polishform(std::string to_polish, bool itisarc); + + ///Returns whether a string can be used as value in an expression. + + ///The given string has to be either a mapname or a number. If it is a mapname + ///we have to know whether it is an arcmap or a nodemap. + ///\param variable the string about the function has to determine whether it is usable in expressions + ///\param itisarc should the mapname be between arcmaps, or nodemaps + bool validVariable(std::string variable, bool itisarc); + + ///Deletes the whole tree created for translating string to polishform. + + ///\param root + ///root of the tree + void deleteTree(tree_node * root); + + ///Dictionary of substitutions in expression. + + ///Variables and numbers are substituted with one character long variables in expressions. + ///This is the dictionary. + std::map ch2var; + + ///Entry which gives us the name of new map. + Gtk::Entry name; + + ///Entry which gives us the initial values of elements of new map. + + ///Initial value can be a number or an expression after that the + ///initial value for each map element can be calculated. + Gtk::Entry default_value; + + ///GTK Designing object. + Gtk::Table * table; + + ///Information holder in window. + Gtk::Label * label; + + ///If selected, nodemap will be created. + Gtk::RadioButton node; + + ///If selected, arcmap will be created. + Gtk::RadioButton arc; +}; + +#endif //NEWMAPWIN_H diff -r 0e4f009eab8b -r 67188bd752db po/LINGUAS --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/po/LINGUAS Mon Jul 07 08:10:39 2008 -0500 @@ -0,0 +1,1 @@ +hu diff -r 0e4f009eab8b -r 67188bd752db po/Makevars --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/po/Makevars Mon Jul 07 08:10:39 2008 -0500 @@ -0,0 +1,41 @@ +# Makefile variables for PO directory in any package using GNU gettext. + +# Usually the message domain is the same as the package name. +DOMAIN = $(PACKAGE) + +# These two variables depend on the location of this directory. +subdir = po +top_builddir = .. + +# These options get passed to xgettext. +XGETTEXT_OPTIONS = --keyword=_ --keyword=N_ + +# This is the copyright holder that gets inserted into the header of the +# $(DOMAIN).pot file. Set this to the copyright holder of the surrounding +# package. (Note that the msgstr strings, extracted from the package's +# sources, belong to the copyright holder of the package.) Translators are +# expected to transfer the copyright for their translations to this person +# or entity, or to disclaim their copyright. The empty string stands for +# the public domain; in this case the translators are expected to disclaim +# their copyright. +COPYRIGHT_HOLDER = Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + +# This is the email address or URL to which the translators shall report +# bugs in the untranslated strings: +# - Strings which are not entire sentences, see the maintainer guidelines +# in the GNU gettext documentation, section 'Preparing Strings'. +# - Strings which use unclear terms or require additional context to be +# understood. +# - Strings which make invalid assumptions about notation of date, time or +# money. +# - Pluralisation problems. +# - Incorrect English spelling. +# - Incorrect formatting. +# It can be your email address, or a mailing list address where translators +# can write to without being subscribed, or the URL of a web page through +# which the translators can contact you. +MSGID_BUGS_ADDRESS = $(PACKAGE_BUGREPORT) + +# This is the list of locale categories, beyond LC_MESSAGES, for which the +# message catalogs shall be used. It is usually empty. +EXTRA_LOCALE_CATEGORIES = diff -r 0e4f009eab8b -r 67188bd752db po/POTFILES.in --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/po/POTFILES.in Mon Jul 07 08:10:39 2008 -0500 @@ -0,0 +1,35 @@ +# List of source files which contain translatable strings. +algobox.cc +algobox.h +algowin.cc +algowin.h +all_include.h +gdc-broken_edge.cc +gettext.h +graph_displayer_canvas.cc +graph_displayer_canvas-edge.cc +graph_displayer_canvas-event.cc +graph_displayer_canvas.h +graph_displayer_canvas-node.cc +graph_displayer_canvas-zoom.cc +graph-displayer.cc +gui_reader.cc +gui_reader.h +gui_writer.cc +gui_writer.h +kruskalbox.cc +kruskalbox.h +main_win.cc +main_win.h +mapselector.cc +mapselector.h +mapstorage.cc +mapstorage.h +map_win.cc +map_win.h +nbtab.cc +nbtab.h +new_map_win.cc +new_map_win.h +xml.h +xymap.h diff -r 0e4f009eab8b -r 67188bd752db po/glemon.pot --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/po/glemon.pot Mon Jul 07 08:10:39 2008 -0500 @@ -0,0 +1,89 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: etik-ol@cs.elte.hu\n" +"POT-Creation-Date: 2006-04-14 20:37+0200\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=CHARSET\n" +"Content-Transfer-Encoding: 8bit\n" + +#: main_win.cc:80 +msgid "_File" +msgstr "" + +#: main_win.cc:85 +msgid "Clear Tab" +msgstr "" + +#: main_win.cc:96 +msgid "_View" +msgstr "" + +#: main_win.cc:106 +msgid "_Show" +msgstr "" + +#: main_win.cc:107 +msgid "_Maps" +msgstr "" + +#: main_win.cc:110 +msgid "_Algorithms" +msgstr "" + +#: main_win.cc:111 +msgid "_General" +msgstr "" + +#: main_win.cc:113 +msgid "_Kruskal" +msgstr "" + +#: main_win.cc:117 +msgid "Move" +msgstr "" + +#: main_win.cc:119 +msgid "Create node" +msgstr "" + +#: main_win.cc:121 +msgid "Create edge" +msgstr "" + +#: main_win.cc:123 +msgid "Delete" +msgstr "" + +#: main_win.cc:126 +msgid "Edit edge map" +msgstr "" + +#: main_win.cc:128 +msgid "Edit node map" +msgstr "" + +#: main_win.cc:259 +msgid "unsaved file" +msgstr "" + +#: main_win.cc:269 +msgid "Save changes before closing?" +msgstr "" + +#: main_win.cc:271 +msgid "Close file _without Saving" +msgstr "" + +#: main_win.cc:458 main_win.cc:487 +msgid "Create New Map - " +msgstr "" diff -r 0e4f009eab8b -r 67188bd752db po/hu.po --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/po/hu.po Mon Jul 07 08:10:39 2008 -0500 @@ -0,0 +1,89 @@ +# Hungarian translations for LEMON package. +# Copyright (C) 2006 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport +# This file is distributed under the same license as the LEMON package. +# Ladanyi Akos , 2006. +# +msgid "" +msgstr "" +"Project-Id-Version: gLEMON svn-head\n" +"Report-Msgid-Bugs-To: etik-ol@cs.elte.hu\n" +"POT-Creation-Date: 2006-04-14 20:37+0200\n" +"PO-Revision-Date: 2006-03-22 15:55+0100\n" +"Last-Translator: Ladanyi Akos \n" +"Language-Team: Hungarian \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" + +#: main_win.cc:80 +msgid "_File" +msgstr "_Fájl" + +#: main_win.cc:85 +msgid "Clear Tab" +msgstr "Lap törlése" + +#: main_win.cc:96 +msgid "_View" +msgstr "_Nézet" + +#: main_win.cc:106 +msgid "_Show" +msgstr "_Mutat" + +#: main_win.cc:107 +msgid "_Maps" +msgstr "_Mapek" + +#: main_win.cc:110 +msgid "_Algorithms" +msgstr "_Algoritmusok" + +#: main_win.cc:111 +msgid "_General" +msgstr "_Általános" + +#: main_win.cc:113 +msgid "_Kruskal" +msgstr "_Kruskal" + +#: main_win.cc:117 +msgid "Move" +msgstr "Mozgat" + +#: main_win.cc:119 +msgid "Create node" +msgstr "Csúcs létrehozása" + +#: main_win.cc:121 +msgid "Create edge" +msgstr "Él létrehozása" + +#: main_win.cc:123 +msgid "Delete" +msgstr "Törlés" + +#: main_win.cc:126 +msgid "Edit edge map" +msgstr "Él map szerkesztése" + +#: main_win.cc:128 +msgid "Edit node map" +msgstr "Csúcs map szerkesztése" + +#: main_win.cc:259 +msgid "unsaved file" +msgstr "nem mentett fájl" + +#: main_win.cc:269 +msgid "Save changes before closing?" +msgstr "Menti a változásokat mielőtt bezárja?" + +#: main_win.cc:271 +msgid "Close file _without Saving" +msgstr "Bezárás mentés _nékül" + +#: main_win.cc:458 main_win.cc:487 +msgid "Create New Map - " +msgstr "Új map létrehozása - " diff -r 0e4f009eab8b -r 67188bd752db save_details_dialog.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/save_details_dialog.cc Mon Jul 07 08:10:39 2008 -0500 @@ -0,0 +1,16 @@ +#include "save_details_dialog.h" +#include + +SaveDetailsDialog::SaveDetailsDialog(MapStorage *ms) : + Gtk::Dialog("Save Details", true), + SaveDetails(ms) +{ + set_size_request(400, -1); + + Gtk::VBox* pVBox = get_vbox(); + pVBox->pack_start(SaveDetails, Gtk::PACK_SHRINK); + + add_button(Gtk::Stock::CLOSE, Gtk::RESPONSE_CLOSE); + + show_all_children(); +} diff -r 0e4f009eab8b -r 67188bd752db save_details_dialog.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/save_details_dialog.h Mon Jul 07 08:10:39 2008 -0500 @@ -0,0 +1,15 @@ +#ifndef SAVE_DETAILS_DIALOG +#define SAVE_DETAILS_DIALOG + +#include +#include "save_details_widget.h" + +class SaveDetailsDialog : public Gtk::Dialog +{ + private: + SaveDetailsWidget SaveDetails; + public: + SaveDetailsDialog(MapStorage*); +}; + +#endif diff -r 0e4f009eab8b -r 67188bd752db save_details_widget.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/save_details_widget.cc Mon Jul 07 08:10:39 2008 -0500 @@ -0,0 +1,616 @@ +#include "save_details_widget.h" +#include "mapstorage.h" + +SaveDetailsWidget::SaveDetailsWidget(MapStorage* ms) : + pMapStorage(ms) +{ + Gtk::Notebook* nb = Gtk::manage(new Gtk::Notebook); + pack_start(*nb, Gtk::PACK_EXPAND_WIDGET); + + nb->set_tab_pos(Gtk::POS_TOP); + + Gtk::VBox* vblueMaps = Gtk::manage(new Gtk::VBox(false, 18)); + vblueMaps->set_border_width(12); + + Gtk::VBox* vbArcMaps = Gtk::manage(new Gtk::VBox(false, 18)); + vbArcMaps->set_border_width(12); + + Gtk::VBox* vbSpecMaps = Gtk::manage(new Gtk::VBox(false, 18)); + vbSpecMaps->set_border_width(12); + + Gtk::VBox* vbGuiSect = Gtk::manage(new Gtk::VBox(false, 18)); + vbGuiSect->set_border_width(12); + + nb->append_page(*vbSpecMaps, "Special Maps"); + nb->append_page(*vblueMaps, "Node Maps"); + nb->append_page(*vbArcMaps, "Arc Maps"); + nb->append_page(*vbGuiSect, "GUI Section"); + + // child widgets of vbSpecMaps + + { + Gtk::VBox* box1 = Gtk::manage(new Gtk::VBox(false, 6)); + vbSpecMaps->pack_start(*box1, Gtk::PACK_SHRINK); + + Gtk::Label* lblNodeCoordMap = + Gtk::manage(new Gtk::Label("Node Coordinates")); + lblNodeCoordMap->set_alignment(Gtk::ALIGN_LEFT, Gtk::ALIGN_CENTER); + lblNodeCoordMap->set_use_markup(); + box1->pack_start(*lblNodeCoordMap, Gtk::PACK_SHRINK); + + Gtk::HBox* box2 = Gtk::manage(new Gtk::HBox); + box1->pack_start(*box2, Gtk::PACK_SHRINK); + + Gtk::Label* fill1 = Gtk::manage(new Gtk::Label(" ")); + box2->pack_start(*fill1, Gtk::PACK_SHRINK); + + Gtk::VBox* box3 = Gtk::manage(new Gtk::VBox); + box2->pack_start(*box3, Gtk::PACK_SHRINK); + + rblueCoordGuiSection.set_label("Save to GUI section"); + rblueCoordNodesetSection.set_label("Save to Nodeset section"); + Gtk::RadioButtonGroup group = rblueCoordGuiSection.get_group(); + rblueCoordNodesetSection.set_group(group); + + box3->pack_start(rblueCoordGuiSection, Gtk::PACK_SHRINK); + box3->pack_start(rblueCoordNodesetSection, Gtk::PACK_SHRINK); + + Gtk::HBox* box4 = Gtk::manage(new Gtk::HBox); + box3->pack_start(*box4, Gtk::PACK_SHRINK); + + Gtk::Label* fill2 = Gtk::manage(new Gtk::Label(" ")); + box4->pack_start(*fill2, Gtk::PACK_SHRINK); + + Gtk::Table* table1 = Gtk::manage(new Gtk::Table(3, 2)); + box4->pack_start(*table1, Gtk::PACK_SHRINK); + + rblueCoordOneMap.set_label("As one map"); + rblueCoordTwoMaps.set_label("As two maps"); + group = rblueCoordOneMap.get_group(); + rblueCoordTwoMaps.set_group(group); + + table1->attach(rblueCoordOneMap, 0, 1, 0, 1); + table1->attach(rblueCoordTwoMaps, 0, 1, 1, 2); + table1->attach(entNodeCoordsOneMap, 1, 2, 0, 1); + table1->attach(entNodeCoordsTwoMaps1, 1, 2, 1, 2); + table1->attach(entNodeCoordsTwoMaps2, 1, 2, 2, 3); + + switch (pMapStorage->getNodeCoordsSaveDest()) + { + case MapStorage::SpecMapSaveOpts::GUI_SECT: + rblueCoordGuiSection.set_active(); + rblueCoordOneMap.set_sensitive(false); + rblueCoordTwoMaps.set_sensitive(false); + entNodeCoordsOneMap.set_sensitive(false); + entNodeCoordsTwoMaps1.set_sensitive(false); + entNodeCoordsTwoMaps2.set_sensitive(false); + break; + case MapStorage::SpecMapSaveOpts::NESET_SECT: + rblueCoordNodesetSection.set_active(); + rblueCoordOneMap.set_sensitive(true); + rblueCoordTwoMaps.set_sensitive(true); + switch (pMapStorage->getNodeCoordsSaveMapNum()) + { + case MapStorage::SpecMapSaveOpts::ONE_MAP: + rblueCoordOneMap.set_active(); + entNodeCoordsOneMap.set_sensitive(true); + entNodeCoordsTwoMaps1.set_sensitive(false); + entNodeCoordsTwoMaps2.set_sensitive(false); + break; + case MapStorage::SpecMapSaveOpts::TWO_MAPS: + rblueCoordTwoMaps.set_active(); + entNodeCoordsOneMap.set_sensitive(false); + entNodeCoordsTwoMaps1.set_sensitive(true); + entNodeCoordsTwoMaps2.set_sensitive(true); + break; + } + break; + } + + entNodeCoordsOneMap.set_text(pMapStorage->getNodeCoordsOneMapName()); + entNodeCoordsTwoMaps1.set_text(pMapStorage->getNodeCoordsTwoMaps1Name()); + entNodeCoordsTwoMaps2.set_text(pMapStorage->getNodeCoordsTwoMaps2Name()); + + entNodeCoordsOneMap.signal_changed().connect( + sigc::mem_fun(*this, &SaveDetailsWidget::onNodeCoordsOneMapName)); + entNodeCoordsTwoMaps1.signal_changed().connect( + sigc::mem_fun(*this, &SaveDetailsWidget::onNodeCoordsTwoMaps1Name)); + entNodeCoordsTwoMaps2.signal_changed().connect( + sigc::mem_fun(*this, &SaveDetailsWidget::onNodeCoordsTwoMaps2Name)); + + rblueCoordGuiSection.signal_toggled().connect( + sigc::mem_fun(*this, &SaveDetailsWidget::onNodeCoordSaveDestChanged)); + rblueCoordNodesetSection.signal_toggled().connect( + sigc::mem_fun(*this, &SaveDetailsWidget::onNodeCoordSaveDestChanged)); + rblueCoordOneMap.signal_toggled().connect( + sigc::mem_fun(*this, &SaveDetailsWidget::onNodeCoordMapNumChanged)); + rblueCoordTwoMaps.signal_toggled().connect( + sigc::mem_fun(*this, &SaveDetailsWidget::onNodeCoordMapNumChanged)); + } + + { + Gtk::VBox* box1 = Gtk::manage(new Gtk::VBox(false, 6)); + vbSpecMaps->pack_start(*box1, Gtk::PACK_SHRINK); + + Gtk::Label* lblArrowCoordMap = + Gtk::manage(new Gtk::Label("Arrow Coordinates")); + lblArrowCoordMap->set_alignment(Gtk::ALIGN_LEFT, Gtk::ALIGN_CENTER); + lblArrowCoordMap->set_use_markup(); + box1->pack_start(*lblArrowCoordMap, Gtk::PACK_SHRINK); + + Gtk::HBox* box2 = Gtk::manage(new Gtk::HBox); + box1->pack_start(*box2, Gtk::PACK_SHRINK); + + Gtk::Label* fill1 = Gtk::manage(new Gtk::Label(" ")); + box2->pack_start(*fill1, Gtk::PACK_SHRINK); + + Gtk::VBox* box3 = Gtk::manage(new Gtk::VBox); + box2->pack_start(*box3, Gtk::PACK_SHRINK); + + rbArrowCoordGuiSection.set_label("Save to GUI section"); + rbArrowCoordArcsetSection.set_label("Save to Arcset section"); + Gtk::RadioButtonGroup group = rbArrowCoordGuiSection.get_group(); + rbArrowCoordArcsetSection.set_group(group); + + box3->pack_start(rbArrowCoordGuiSection, Gtk::PACK_SHRINK); + box3->pack_start(rbArrowCoordArcsetSection, Gtk::PACK_SHRINK); + + Gtk::HBox* box4 = Gtk::manage(new Gtk::HBox); + box3->pack_start(*box4, Gtk::PACK_SHRINK); + + Gtk::Label* fill2 = Gtk::manage(new Gtk::Label(" ")); + box4->pack_start(*fill2, Gtk::PACK_SHRINK); + + Gtk::Table* table1 = Gtk::manage(new Gtk::Table(3, 2)); + box4->pack_start(*table1, Gtk::PACK_SHRINK); + + rbArrowCoordOneMap.set_label("As one map"); + rbArrowCoordTwoMaps.set_label("As two maps"); + group = rbArrowCoordOneMap.get_group(); + rbArrowCoordTwoMaps.set_group(group); + + table1->attach(rbArrowCoordOneMap, 0, 1, 0, 1); + table1->attach(rbArrowCoordTwoMaps, 0, 1, 1, 2); + table1->attach(entArrowCoordsOneMap, 1, 2, 0, 1); + table1->attach(entArrowCoordsTwoMaps1, 1, 2, 1, 2); + table1->attach(entArrowCoordsTwoMaps2, 1, 2, 2, 3); + + switch (pMapStorage->getArrowCoordsSaveDest()) + { + case MapStorage::SpecMapSaveOpts::GUI_SECT: + rbArrowCoordGuiSection.set_active(); + rbArrowCoordOneMap.set_sensitive(false); + rbArrowCoordTwoMaps.set_sensitive(false); + entArrowCoordsOneMap.set_sensitive(false); + entArrowCoordsTwoMaps1.set_sensitive(false); + entArrowCoordsTwoMaps2.set_sensitive(false); + break; + case MapStorage::SpecMapSaveOpts::NESET_SECT: + rbArrowCoordArcsetSection.set_active(); + rbArrowCoordOneMap.set_sensitive(true); + rbArrowCoordTwoMaps.set_sensitive(true); + switch (pMapStorage->getArrowCoordsSaveMapNum()) + { + case MapStorage::SpecMapSaveOpts::ONE_MAP: + rbArrowCoordOneMap.set_active(); + entArrowCoordsOneMap.set_sensitive(true); + entArrowCoordsTwoMaps1.set_sensitive(false); + entArrowCoordsTwoMaps2.set_sensitive(false); + break; + case MapStorage::SpecMapSaveOpts::TWO_MAPS: + rbArrowCoordTwoMaps.set_active(); + entArrowCoordsOneMap.set_sensitive(false); + entArrowCoordsTwoMaps1.set_sensitive(true); + entArrowCoordsTwoMaps2.set_sensitive(true); + break; + } + break; + } + + entArrowCoordsOneMap.set_text(pMapStorage->getArrowCoordsOneMapName()); + entArrowCoordsTwoMaps1.set_text(pMapStorage->getArrowCoordsTwoMaps1Name()); + entArrowCoordsTwoMaps2.set_text(pMapStorage->getArrowCoordsTwoMaps2Name()); + + entArrowCoordsOneMap.signal_changed().connect( + sigc::mem_fun(*this, &SaveDetailsWidget::onArrowCoordsOneMapName)); + entArrowCoordsTwoMaps1.signal_changed().connect( + sigc::mem_fun(*this, &SaveDetailsWidget::onArrowCoordsTwoMaps1Name)); + entArrowCoordsTwoMaps2.signal_changed().connect( + sigc::mem_fun(*this, &SaveDetailsWidget::onArrowCoordsTwoMaps2Name)); + + rbArrowCoordGuiSection.signal_toggled().connect( + sigc::mem_fun(*this, &SaveDetailsWidget::onArrowCoordSaveDestChanged)); + rbArrowCoordArcsetSection.signal_toggled().connect( + sigc::mem_fun(*this, &SaveDetailsWidget::onArrowCoordSaveDestChanged)); + rbArrowCoordOneMap.signal_toggled().connect( + sigc::mem_fun(*this, &SaveDetailsWidget::onArrowCoordMapNumChanged)); + rbArrowCoordTwoMaps.signal_toggled().connect( + sigc::mem_fun(*this, &SaveDetailsWidget::onArrowCoordMapNumChanged)); + } + + // child widgets of vbGuiSect + + { + Gtk::VBox* box1 = Gtk::manage(new Gtk::VBox(false, 6)); + vbGuiSect->pack_start(*box1, Gtk::PACK_SHRINK); + + Gtk::Label* lblGuiSectionSave = + Gtk::manage(new Gtk::Label("Save Destination")); + lblGuiSectionSave->set_alignment(Gtk::ALIGN_LEFT, Gtk::ALIGN_CENTER); + lblGuiSectionSave->set_use_markup(); + box1->pack_start(*lblGuiSectionSave, Gtk::PACK_SHRINK); + + rbLgfFile.set_label("Lgf file"); + rbConfFile.set_label("Conf file"); + + Gtk::RadioButtonGroup group = rbLgfFile.get_group(); + rbConfFile.set_group(group); + + switch (pMapStorage->getGUIDataSaveLocation()) + { + case MapStorage::LGF_FILE: + rbLgfFile.set_active(); + break; + case MapStorage::CONF_FILE: + rbConfFile.set_active(); + break; + } + + Gtk::HBox* box2 = Gtk::manage(new Gtk::HBox); + box1->pack_start(*box2, Gtk::PACK_SHRINK); + + Gtk::Label* fill1 = Gtk::manage(new Gtk::Label(" ")); + box2->pack_start(*fill1, Gtk::PACK_SHRINK); + + Gtk::VBox* box3 = Gtk::manage(new Gtk::VBox); + box2->pack_start(*box3, Gtk::PACK_SHRINK); + + box3->pack_start(rbLgfFile, Gtk::PACK_SHRINK); + box3->pack_start(rbConfFile, Gtk::PACK_SHRINK); + + rbLgfFile.signal_toggled().connect( + sigc::mem_fun(*this, &SaveDetailsWidget::onGuiSectSaveDestChanged)); + rbConfFile.signal_toggled().connect( + sigc::mem_fun(*this, &SaveDetailsWidget::onGuiSectSaveDestChanged)); + } + + // child widgets of vblueMaps + + { + Gtk::VBox* box1 = Gtk::manage(new Gtk::VBox(false, 6)); + vblueMaps->pack_start(*box1, Gtk::PACK_SHRINK); + + Gtk::Label* label1 = + Gtk::manage(new Gtk::Label("Save Destination")); + label1->set_alignment(Gtk::ALIGN_LEFT, Gtk::ALIGN_CENTER); + label1->set_use_markup(); + box1->pack_start(*label1, Gtk::PACK_SHRINK); + + Gtk::HBox* box2 = Gtk::manage(new Gtk::HBox); + box1->pack_start(*box2, Gtk::PACK_SHRINK); + + Gtk::Label* fill1 = Gtk::manage(new Gtk::Label(" ")); + box2->pack_start(*fill1, Gtk::PACK_SHRINK); + + Gtk::Frame* frame = Gtk::manage(new Gtk::Frame); + box2->pack_start(*frame, Gtk::PACK_EXPAND_WIDGET); + + Gtk::ScrolledWindow* swNodeMaps = Gtk::manage(new Gtk::ScrolledWindow); + frame->add(*swNodeMaps); + + swNodeMaps->add(twNodeMaps); + + refNodeMapStore = Gtk::ListStore::create(NodeMapColumns); + + std::vector node_maps = pMapStorage->getNodeMapList(); + for (std::vector::const_iterator it = node_maps.begin(); + it != node_maps.end(); ++it) + { + Gtk::TreeModel::Row row = *(refNodeMapStore->append()); + row[NodeMapColumns.colName] = *it; + switch (pMapStorage->getNodeMapSaveDest(*it)) + { + case MapStorage::GUI_SECT: + row[NodeMapColumns.colSaveToMainSect] = false; + row[NodeMapColumns.colSaveToGuiSect] = true; + break; + case MapStorage::NESET_SECT: + row[NodeMapColumns.colSaveToMainSect] = true; + row[NodeMapColumns.colSaveToGuiSect] = false; + break; + case MapStorage::DONT_SAVE: + row[NodeMapColumns.colSaveToMainSect] = false; + row[NodeMapColumns.colSaveToGuiSect] = false; + break; + } + } + + twNodeMaps.set_model(refNodeMapStore); + twNodeMaps.append_column("Name", NodeMapColumns.colName); + twNodeMaps.append_column_editable("Nodeset section", + NodeMapColumns.colSaveToMainSect); + twNodeMaps.append_column_editable("GUI section", + NodeMapColumns.colSaveToGuiSect); + + swNodeMaps->set_size_request(-1, 200); + swNodeMaps->set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC); + + refNodeMapStore->signal_row_changed().connect( + sigc::mem_fun(*this, &SaveDetailsWidget::onNodeMapRowChanged)); + } + + // child widgets of vbArcMaps + + { + Gtk::VBox* box1 = Gtk::manage(new Gtk::VBox(false, 6)); + vbArcMaps->pack_start(*box1, Gtk::PACK_SHRINK); + + Gtk::Label* label1 = + Gtk::manage(new Gtk::Label("Save Destination")); + label1->set_alignment(Gtk::ALIGN_LEFT, Gtk::ALIGN_CENTER); + label1->set_use_markup(); + box1->pack_start(*label1, Gtk::PACK_SHRINK); + + Gtk::HBox* box2 = Gtk::manage(new Gtk::HBox); + box1->pack_start(*box2, Gtk::PACK_SHRINK); + + Gtk::Label* fill1 = Gtk::manage(new Gtk::Label(" ")); + box2->pack_start(*fill1, Gtk::PACK_SHRINK); + + Gtk::Frame* frame = Gtk::manage(new Gtk::Frame); + box2->pack_start(*frame, Gtk::PACK_EXPAND_WIDGET); + + Gtk::ScrolledWindow* swArcMaps = Gtk::manage(new Gtk::ScrolledWindow); + frame->add(*swArcMaps); + + swArcMaps->add(twArcMaps); + + refArcMapStore = Gtk::ListStore::create(ArcMapColumns); + + std::vector arc_maps = pMapStorage->getArcMapList(); + for (std::vector::const_iterator it = arc_maps.begin(); + it != arc_maps.end(); ++it) + { + Gtk::TreeModel::Row row = *(refArcMapStore->append()); + row[ArcMapColumns.colName] = *it; + switch (pMapStorage->getArcMapSaveDest(*it)) + { + case MapStorage::GUI_SECT: + row[ArcMapColumns.colSaveToMainSect] = false; + row[ArcMapColumns.colSaveToGuiSect] = true; + break; + case MapStorage::NESET_SECT: + row[ArcMapColumns.colSaveToMainSect] = true; + row[ArcMapColumns.colSaveToGuiSect] = false; + break; + case MapStorage::DONT_SAVE: + row[ArcMapColumns.colSaveToMainSect] = false; + row[ArcMapColumns.colSaveToGuiSect] = false; + break; + } + } + + twArcMaps.set_model(refArcMapStore); + twArcMaps.append_column("Name", ArcMapColumns.colName); + twArcMaps.append_column_editable("Arcset section", + ArcMapColumns.colSaveToMainSect); + twArcMaps.append_column_editable("GUI section", + ArcMapColumns.colSaveToGuiSect); + + swArcMaps->set_size_request(-1, 200); + swArcMaps->set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC); + + refArcMapStore->signal_row_changed().connect( + sigc::mem_fun(*this, &SaveDetailsWidget::onArcMapRowChanged)); + } + + show_all_children(); +} + +void SaveDetailsWidget::onGuiSectSaveDestChanged() +{ + if (rbLgfFile.get_active()) + { + pMapStorage->setGUIDataSaveLocation(MapStorage::LGF_FILE); + } + else if (rbConfFile.get_active()) + { + pMapStorage->setGUIDataSaveLocation(MapStorage::CONF_FILE); + } +} + +void SaveDetailsWidget::onArcMapRowChanged(const Gtk::TreeModel::Path& path, + const Gtk::TreeModel::iterator& iter) +{ + Gtk::TreeModel::Row row = *iter; + Glib::ustring map_name = row[ArcMapColumns.colName]; + if (row[ArcMapColumns.colSaveToMainSect] && + row[ArcMapColumns.colSaveToGuiSect]) + { + if (pMapStorage->getArcMapSaveDest(map_name) == MapStorage::NESET_SECT) + { + pMapStorage->setArcMapSaveDest(map_name, MapStorage::GUI_SECT); + row[ArcMapColumns.colSaveToMainSect] = false; + } + else + { + pMapStorage->setArcMapSaveDest(map_name, MapStorage::NESET_SECT); + row[ArcMapColumns.colSaveToGuiSect] = false; + } + } + else if (row[ArcMapColumns.colSaveToMainSect]) + { + pMapStorage->setArcMapSaveDest(map_name, MapStorage::NESET_SECT); + } + else if (row[ArcMapColumns.colSaveToGuiSect]) + { + pMapStorage->setArcMapSaveDest(map_name, MapStorage::GUI_SECT); + } + else + { + pMapStorage->setArcMapSaveDest(map_name, MapStorage::DONT_SAVE); + } +} + +void SaveDetailsWidget::onNodeMapRowChanged(const Gtk::TreeModel::Path& path, + const Gtk::TreeModel::iterator& iter) +{ + Gtk::TreeModel::Row row = *iter; + Glib::ustring map_name = row[NodeMapColumns.colName]; + if (row[NodeMapColumns.colSaveToMainSect] && + row[NodeMapColumns.colSaveToGuiSect]) + { + if (pMapStorage->getNodeMapSaveDest(map_name) == MapStorage::NESET_SECT) + { + pMapStorage->setNodeMapSaveDest(map_name, MapStorage::GUI_SECT); + row[NodeMapColumns.colSaveToMainSect] = false; + } + else + { + pMapStorage->setNodeMapSaveDest(map_name, MapStorage::NESET_SECT); + row[NodeMapColumns.colSaveToGuiSect] = false; + } + } + else if (row[NodeMapColumns.colSaveToMainSect]) + { + pMapStorage->setNodeMapSaveDest(map_name, MapStorage::NESET_SECT); + } + else if (row[NodeMapColumns.colSaveToGuiSect]) + { + pMapStorage->setNodeMapSaveDest(map_name, MapStorage::GUI_SECT); + } + else + { + pMapStorage->setNodeMapSaveDest(map_name, MapStorage::DONT_SAVE); + } +} + +void SaveDetailsWidget::onNodeCoordSaveDestChanged() +{ + if (rblueCoordGuiSection.get_active()) + { + pMapStorage->setNodeCoordsSaveDest(MapStorage::SpecMapSaveOpts::GUI_SECT); + rblueCoordOneMap.set_sensitive(false); + rblueCoordTwoMaps.set_sensitive(false); + entNodeCoordsOneMap.set_sensitive(false); + entNodeCoordsTwoMaps1.set_sensitive(false); + entNodeCoordsTwoMaps2.set_sensitive(false); + } + else if (rblueCoordNodesetSection.get_active()) + { + pMapStorage->setNodeCoordsSaveDest(MapStorage::SpecMapSaveOpts::NESET_SECT); + rblueCoordOneMap.set_sensitive(true); + rblueCoordTwoMaps.set_sensitive(true); + switch (pMapStorage->getNodeCoordsSaveMapNum()) + { + case MapStorage::SpecMapSaveOpts::ONE_MAP: + entNodeCoordsOneMap.set_sensitive(true); + entNodeCoordsTwoMaps1.set_sensitive(false); + entNodeCoordsTwoMaps2.set_sensitive(false); + break; + case MapStorage::SpecMapSaveOpts::TWO_MAPS: + entNodeCoordsOneMap.set_sensitive(false); + entNodeCoordsTwoMaps1.set_sensitive(true); + entNodeCoordsTwoMaps2.set_sensitive(true); + break; + } + } +} + +void SaveDetailsWidget::onNodeCoordMapNumChanged() +{ + if (rblueCoordOneMap.get_active()) + { + pMapStorage->setNodeCoordsSaveMapNum(MapStorage::SpecMapSaveOpts::ONE_MAP); + entNodeCoordsOneMap.set_sensitive(true); + entNodeCoordsTwoMaps1.set_sensitive(false); + entNodeCoordsTwoMaps2.set_sensitive(false); + } + else if (rblueCoordTwoMaps.get_active()) + { + pMapStorage->setNodeCoordsSaveMapNum(MapStorage::SpecMapSaveOpts::TWO_MAPS); + entNodeCoordsOneMap.set_sensitive(false); + entNodeCoordsTwoMaps1.set_sensitive(true); + entNodeCoordsTwoMaps2.set_sensitive(true); + } +} + +void SaveDetailsWidget::onNodeCoordsOneMapName() +{ + pMapStorage->setNodeCoordsOneMapName(entNodeCoordsOneMap.get_text()); +} +void SaveDetailsWidget::onNodeCoordsTwoMaps1Name() +{ + pMapStorage->setNodeCoordsTwoMaps1Name(entNodeCoordsTwoMaps1.get_text()); +} +void SaveDetailsWidget::onNodeCoordsTwoMaps2Name() +{ + pMapStorage->setNodeCoordsTwoMaps2Name(entNodeCoordsTwoMaps2.get_text()); +} + +void SaveDetailsWidget::onArrowCoordSaveDestChanged() +{ + if (rbArrowCoordGuiSection.get_active()) + { + pMapStorage->setArrowCoordsSaveDest(MapStorage::SpecMapSaveOpts::GUI_SECT); + rbArrowCoordOneMap.set_sensitive(false); + rbArrowCoordTwoMaps.set_sensitive(false); + entArrowCoordsOneMap.set_sensitive(false); + entArrowCoordsTwoMaps1.set_sensitive(false); + entArrowCoordsTwoMaps2.set_sensitive(false); + } + else if (rbArrowCoordArcsetSection.get_active()) + { + pMapStorage->setArrowCoordsSaveDest(MapStorage::SpecMapSaveOpts::NESET_SECT); + rbArrowCoordOneMap.set_sensitive(true); + rbArrowCoordTwoMaps.set_sensitive(true); + switch (pMapStorage->getArrowCoordsSaveMapNum()) + { + case MapStorage::SpecMapSaveOpts::ONE_MAP: + entArrowCoordsOneMap.set_sensitive(true); + entArrowCoordsTwoMaps1.set_sensitive(false); + entArrowCoordsTwoMaps2.set_sensitive(false); + break; + case MapStorage::SpecMapSaveOpts::TWO_MAPS: + entArrowCoordsOneMap.set_sensitive(false); + entArrowCoordsTwoMaps1.set_sensitive(true); + entArrowCoordsTwoMaps2.set_sensitive(true); + break; + } + } +} + +void SaveDetailsWidget::onArrowCoordMapNumChanged() +{ + if (rbArrowCoordOneMap.get_active()) + { + pMapStorage->setArrowCoordsSaveMapNum(MapStorage::SpecMapSaveOpts::ONE_MAP); + entArrowCoordsOneMap.set_sensitive(true); + entArrowCoordsTwoMaps1.set_sensitive(false); + entArrowCoordsTwoMaps2.set_sensitive(false); + } + else if (rbArrowCoordTwoMaps.get_active()) + { + pMapStorage->setArrowCoordsSaveMapNum(MapStorage::SpecMapSaveOpts::TWO_MAPS); + entArrowCoordsOneMap.set_sensitive(false); + entArrowCoordsTwoMaps1.set_sensitive(true); + entArrowCoordsTwoMaps2.set_sensitive(true); + } +} + +void SaveDetailsWidget::onArrowCoordsOneMapName() +{ + pMapStorage->setArrowCoordsOneMapName(entArrowCoordsOneMap.get_text()); +} +void SaveDetailsWidget::onArrowCoordsTwoMaps1Name() +{ + pMapStorage->setArrowCoordsTwoMaps1Name(entArrowCoordsTwoMaps1.get_text()); +} +void SaveDetailsWidget::onArrowCoordsTwoMaps2Name() +{ + pMapStorage->setArrowCoordsTwoMaps2Name(entArrowCoordsTwoMaps2.get_text()); +} + +SaveDetailsWidget::~SaveDetailsWidget() +{ +} diff -r 0e4f009eab8b -r 67188bd752db save_details_widget.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/save_details_widget.h Mon Jul 07 08:10:39 2008 -0500 @@ -0,0 +1,87 @@ +#ifndef SAVE_DETAILS_WIDGET +#define SAVE_DETAILS_WIDGET + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +class MapStorage; + +class SaveDetailsWidget : public Gtk::VBox +{ + public: + struct MapModelColumns : public Gtk::TreeModel::ColumnRecord + { + MapModelColumns() + { + add(colName); + add(colSaveToMainSect); + add(colSaveToGuiSect); + } + Gtk::TreeModelColumn colName; + Gtk::TreeModelColumn colSaveToMainSect; + Gtk::TreeModelColumn colSaveToGuiSect; + }; + private: + Gtk::RadioButton rbLgfFile; + Gtk::RadioButton rbConfFile; + + Gtk::TreeView twNodeMaps; + Gtk::TreeView twArcMaps; + + MapModelColumns NodeMapColumns; + MapModelColumns ArcMapColumns; + + Glib::RefPtr refNodeMapStore; + Glib::RefPtr refArcMapStore; + + Gtk::RadioButton rblueCoordGuiSection; + Gtk::RadioButton rblueCoordNodesetSection; + Gtk::RadioButton rblueCoordOneMap; + Gtk::RadioButton rblueCoordTwoMaps; + Gtk::Entry entNodeCoordsOneMap; + Gtk::Entry entNodeCoordsTwoMaps1; + Gtk::Entry entNodeCoordsTwoMaps2; + + Gtk::RadioButton rbArrowCoordGuiSection; + Gtk::RadioButton rbArrowCoordArcsetSection; + Gtk::RadioButton rbArrowCoordOneMap; + Gtk::RadioButton rbArrowCoordTwoMaps; + Gtk::Entry entArrowCoordsOneMap; + Gtk::Entry entArrowCoordsTwoMaps1; + Gtk::Entry entArrowCoordsTwoMaps2; + + MapStorage* pMapStorage; + + void onGuiSectSaveDestChanged(); + + void onNodeCoordSaveDestChanged(); + void onNodeCoordMapNumChanged(); + + void onNodeCoordsOneMapName(); + void onNodeCoordsTwoMaps1Name(); + void onNodeCoordsTwoMaps2Name(); + + void onArrowCoordSaveDestChanged(); + void onArrowCoordMapNumChanged(); + + void onArrowCoordsOneMapName(); + void onArrowCoordsTwoMaps1Name(); + void onArrowCoordsTwoMaps2Name(); + + void onArcMapRowChanged(const Gtk::TreeModel::Path& path, + const Gtk::TreeModel::iterator& iter); + void onNodeMapRowChanged(const Gtk::TreeModel::Path& path, + const Gtk::TreeModel::iterator& iter); + public: + SaveDetailsWidget(MapStorage* ms); + ~SaveDetailsWidget(); +}; + +#endif diff -r 0e4f009eab8b -r 67188bd752db xml.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/xml.h Mon Jul 07 08:10:39 2008 -0500 @@ -0,0 +1,448 @@ +/* -*- C++ -*- + * + * This file is a part of LEMON, a generic C++ optimization library + * + * Copyright (C) 2003-2006 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#ifndef GLEMON_XML_H +#define GLEMON_XML_H + +#include +#include +#include +#include +#include +#include +#include + +namespace lemon { + + class XmlIo + { + bool _writeMode; + public: + ///Check if XmlIo is in write mode. + bool write() { return _writeMode;} + ///Check if XmlIo is in read mode. + bool read() { return !_writeMode;} + + std::ostream& os; + int level; + + protected: + void indent(int level) { + os << std::endl; + for(int i=0;i'; + } + void etag(const std::string &_tag) { + os << "'; + } + void itag(const std::string &_tag) { indent();tag(_tag); } + void ietag(const std::string &_tag) { indent();etag(_tag); } + + void beginTag(const std::string &_tag) { + itag(_tag); + level++; + } + void endTag(const std::string &_tag) { + level--; + ietag(_tag); + } + + public: + ///Indent the line according to its level. + + ///\warning It can only be used in write mode. + /// + void indent() + { + if(write()) + if(level>=0) indent(level); + else level=0; + else throw LogicError(); + } + + ///Read/write a tag + + ///Read/write a tag. + ///In write mode it does not start a new line. + class ContTag + { + XmlIo &ix; + const std::string _tag; + public: + ///\e + + ///\e + /// + ContTag(XmlIo &_ix,const std::string &_t) : + ix(_ix), _tag(_t) + { + if(ix.write()) ix.tag(_tag); + else ix.useTag(_tag); + } + ~ContTag() { + if(ix.write()) ix.etag(_tag); + else if(!std::uncaught_exception()) ix.useTag('/'+_tag); + } + }; + + ///Read/write a tag + + ///Read/write a tag. + ///The whole \ ... \ will be placed in a single line. + class LineTag + { + XmlIo &ix; + const std::string _tag; + public: + ///\e + + ///\e + /// + LineTag(XmlIo &_ix,const std::string &_t) : + ix(_ix), _tag(_t) + { + if(ix.write()) ix.itag(_tag); + else ix.useTag(_tag); + } + ~LineTag() { + if(ix.write()) ix.etag(_tag); + else if(!std::uncaught_exception()) ix.useTag('/'+_tag); + } + }; + + ///Read/write a tag + + ///Read/write a tag. + /// + class Tag + { + XmlIo &ix; + const std::string _tag; + public: + ///\e + + ///\e + /// + Tag(XmlIo &_ix,const std::string &_t) : + ix(_ix), _tag(_t) + { + if(ix.write()) ix.beginTag(_tag); + else ix.useTag(_tag); + } + ~Tag() { + if(ix.write()) ix.endTag(_tag); + else if(!std::uncaught_exception()) ix.useTag('/'+_tag); + } + }; + + private: + std::istream& is; + std::string next_tag; + int line_number; + + void skipWhiteSpaces() + { + if(write()) throw LogicError(); + { + char c; + while (is.get(c) && std::isspace(c,is.getloc())) + if(c=='\n') line_number++; + is.unget(); + } + } + protected: + /// Use the next tag. + + ///\e + /// + void useTag() {next_tag.clear();} + + ///Use the next tag and check if it is equal with \c _tag + + ///\e + /// + void useTag(const std::string &_tag) { + if(nextTag()==_tag) useTag(); + else throw DataFormatError("",line_number,"Unexpected token name"); + } + public: + ///Return the next tag (if a tag follows on the stream). + + ///\warning It can only be used in read mode. + /// + const std::string &nextTag() + { + if(write()) throw LogicError(); + else if(next_tag.empty()) { + char c; + skipWhiteSpaces(); + if(!is.get(c) || c!='<') + throw DataFormatError("",line_number,"Bad format"); + next_tag.clear(); + while (is.get(c) && c!='>') next_tag.push_back(c); + if(c!='>') + throw DataFormatError("",line_number,"Bad format"); + } + return next_tag; + } + + /**********************************************************************/ + + + ///\e + + ///\e + /// + XmlIo(std::ostream& _os) : _writeMode(true), os(_os), + level(-1), + is(std::cin) {} + ///\e + /// + XmlIo(std::istream& _is) : _writeMode(false), + os(std::cout), is(_is), + line_number(1) {} + + ~XmlIo() { if(write()) os<< std::endl; } + + + + XmlIo &operator()(const int &v) + { + if(write()) os << v; + else { + skipWhiteSpaces(); + if(!(is >> const_cast(v))) + throw DataFormatError("",line_number,"Not an 'int'"); + } + return *this; + } + XmlIo &operator()(const double &v) + { + if(write()) os << v; + else { + skipWhiteSpaces(); + if(!(is >> const_cast(v))) + throw DataFormatError("",line_number,"Not an 'double'"); + } + return *this; + } + XmlIo &operator()(const std::string &v) + { + if(write()) + for(std::string::const_iterator i=v.begin();i!=v.end();++i) + switch(*i) { + case '\\': + os << "\\\\"; + break; + case '<': + os << "\\<"; + break; + case '&': + os << "\\&"; + break; + case '\n': + os << "\\n"; + break; + default: + os<<*i; + break; + } + else { + std::string &w = const_cast(v); + w.clear(); + char c; + while (is.get(c) && c!='<') + if(c=='\\') + if(!is.get(c)) + throw DataFormatError("",line_number,"Bad string"); + else switch(c) { + case 'n': + w.push_back('\n'); + break; + default: + w.push_back(c); + break; + } + else { + if(c=='\n') line_number++; + w.push_back(c); + } + if(c!='<') + throw DataFormatError("",line_number,"Unexpected eof"); + is.unget(); + } + return *this; + } + + + XmlIo &operator()(const std::string &_tag,const int &v) + { + LineTag t(*this,_tag); + (*this)(v); + return *this; + } + XmlIo &operator()(const std::string &_tag,const double &v) + { + LineTag t(*this,_tag); + (*this)(v); + return *this; + } + XmlIo &operator()(const std::string &_tag,const std::string &v) + { + LineTag t(*this,_tag); + (*this)(v); + return *this; + } + ///\e + + ///\e + /// + template + XmlIo &operator()(const std::string &_tag,const V &v) + { + Tag t(*this,_tag); + xml(*this,const_cast(v)); + return *this; + } + ///\e + + ///\e + /// + template + XmlIo &operator()(const V &v) + { + xml(*this,const_cast(v)); + return *this; + } + }; + + ////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////// + + ///\e + + ///\relates XmlIo + /// + template + void xml(XmlIo &x,std::auto_ptr &v) + { + if(x.write()) v=new A; + x(*v); + } + + ///\e + + ///\relates XmlIo + /// + template + void xml(XmlIo &x,std::pair &v) + { + x("first",v.first); + x("second",v.second); + } + + ///\e + + ///\relates XmlIo + /// + template + void xml(XmlIo &x,std::list &v) + { + if(x.write()) + for(typename std::list::const_iterator it=v.begin(); + it!=v.end();++it) x("item",*it); + else while(x.nextTag()=="item") + { + v.push_back(T()); + x("item",v.back()); + } + } + ///\e + + ///\relates XmlIo + /// + template + void xml(XmlIo &x,std::vector &v) + { + if(x.write()) + for(typename std::vector::const_iterator it=v.begin(); + it!=v.end();++it) x("item",*it); + else while(x.nextTag()=="item") + { + v.push_back(T()); + x("item",v.back()); + } + } + + ///\e + + ///\relates XmlIo + /// + template + void xml(XmlIo &x,std::map &v) + { + if(x.write()) + for(typename std::map::const_iterator it=v.begin(); + it!=v.end();++it) x("item",*it); + else while(x.nextTag()=="item") + { + typename std::map::value_type it; + x("item",it); + v.insert(it); + } + } + + ///\e + + ///\relates XmlIo + /// + template + void xml(XmlIo &x,lemon::dim2::Point &v) + { + { XmlIo::LineTag t(x,"x"); x(v.x); } + { XmlIo::ContTag t(x,"y"); x(v.y); } + } + + ///\e + + ///\relates XmlIo + /// + template + void xml(XmlIo &x,lemon::dim2::BoundingBox &v) + { + if(x.write()) { + if(!v.empty()) { + x("point",v.bottomLeft()); + if(v.bottomLeft()!=v.topRight()) x("point",v.topRight()); + } + } + else { + v.clear(); + while(x.nextTag()=="point") { + lemon::dim2::Point co; + x("point",co); + v.add(co); + } + } + } + +} + +#endif diff -r 0e4f009eab8b -r 67188bd752db xymap.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/xymap.h Mon Jul 07 08:10:39 2008 -0500 @@ -0,0 +1,50 @@ +/* -*- C++ -*- + * + * This file is a part of LEMON, a generic C++ optimization library + * + * Copyright (C) 2003-2006 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#ifndef XYMAP_H +#define XYMAP_H + +#include +#include + +template +class XYMap +{ + private: + M *xmap, *ymap; + + public: + typedef typename M::Key Key; + typedef lemon::dim2::Point Value; + XYMap() {} + XYMap(M &_xmap, M &_ymap) : xmap(&_xmap), ymap(&_ymap) {} + void setXMap(M &_xmap) { xmap = &_xmap; } + void setYMap(M &_ymap) { ymap = &_ymap; } + Value operator[](Key k) const + { + Value v(xmap->operator[](k), ymap->operator[](k)); + return v; + } + void set(Key k, Value v) + { + xmap->set(k, v.x); + ymap->set(k, v.y); + } +}; + +#endif