updated nodes to store actual positions, instead of scaled ones, updated shapes to return actual positions for metadata, added some logic for resetting the canvas and drawn nodes when resizing, convert node update coords into scaled coords for moving nodes

This commit is contained in:
Blake Harnden 2019-12-12 11:06:52 -08:00
parent 0372e43cc5
commit 4e9de862a3
10 changed files with 535 additions and 460 deletions

View file

@ -14,7 +14,7 @@ CUSTOM_EMANE_PATH = HOME_PATH.joinpath("custom_emane")
CUSTOM_SERVICE_PATH = HOME_PATH.joinpath("custom_services")
ICONS_PATH = HOME_PATH.joinpath("icons")
MOBILITY_PATH = HOME_PATH.joinpath("mobility")
XML_PATH = HOME_PATH.joinpath("xml")
XMLS_PATH = HOME_PATH.joinpath("xmls")
CONFIG_PATH = HOME_PATH.joinpath("gui.yaml")
# local paths
@ -22,6 +22,7 @@ DATA_PATH = Path(__file__).parent.joinpath("data")
LOCAL_ICONS_PATH = DATA_PATH.joinpath("icons").absolute()
LOCAL_BACKGROUND_PATH = DATA_PATH.joinpath("backgrounds").absolute()
LOCAL_XMLS_PATH = DATA_PATH.joinpath("xmls").absolute()
LOCAL_MOBILITY_PATH = DATA_PATH.joinpath("mobility").absolute()
# configuration data
TERMINALS = [
@ -43,6 +44,12 @@ class IndentDumper(yaml.Dumper):
return super().increase_indent(flow, False)
def copy_files(current_path, new_path):
for current_file in current_path.glob("*"):
new_file = new_path.joinpath(current_file.name)
shutil.copy(current_file, new_file)
def check_directory():
if HOME_PATH.exists():
logging.info("~/.coretk exists")
@ -54,16 +61,12 @@ def check_directory():
CUSTOM_SERVICE_PATH.mkdir()
ICONS_PATH.mkdir()
MOBILITY_PATH.mkdir()
XML_PATH.mkdir()
for image in LOCAL_ICONS_PATH.glob("*"):
new_image = ICONS_PATH.joinpath(image.name)
shutil.copy(image, new_image)
for background in LOCAL_BACKGROUND_PATH.glob("*"):
new_background = BACKGROUNDS_PATH.joinpath(background.name)
shutil.copy(background, new_background)
for xml_file in LOCAL_XMLS_PATH.glob("*"):
new_xml = XML_PATH.joinpath(xml_file.name)
shutil.copy(xml_file, new_xml)
XMLS_PATH.mkdir()
copy_files(LOCAL_ICONS_PATH, ICONS_PATH)
copy_files(LOCAL_BACKGROUND_PATH, BACKGROUNDS_PATH)
copy_files(LOCAL_XMLS_PATH, XMLS_PATH)
copy_files(LOCAL_MOBILITY_PATH, MOBILITY_PATH)
if "TERM" in os.environ:
terminal = TERMINALS[0]

View file

@ -300,14 +300,16 @@ class CoreClient:
width = self.app.guiconfig["preferences"]["width"]
height = self.app.guiconfig["preferences"]["height"]
width, height = canvas_config.get("dimensions", [width, height])
self.app.canvas.redraw_canvas(width, height)
dimensions = canvas_config.get("dimensions", [width, height])
self.app.canvas.redraw_canvas(dimensions)
wallpaper = canvas_config.get("wallpaper")
if wallpaper:
wallpaper = str(appconfig.BACKGROUNDS_PATH.joinpath(wallpaper))
self.app.canvas.set_wallpaper(wallpaper)
self.app.canvas.update_grid()
self.app.canvas.set_wallpaper(wallpaper)
else:
self.app.canvas.redraw_canvas()
self.app.canvas.set_wallpaper(None)
# load saved shapes
shapes_config = config.get("shapes")
@ -482,7 +484,7 @@ class CoreClient:
"wallpaper-style": self.app.canvas.scale_option.get(),
"gridlines": self.app.canvas.show_grid.get(),
"fit_image": self.app.canvas.adjust_to_dim.get(),
"dimensions": self.app.canvas.width_and_height(),
"dimensions": self.app.canvas.current_dimensions,
}
canvas_config = json.dumps(canvas_config)

View file

@ -0,0 +1,28 @@
#
# nodes: 4, max time: 27.000000, max x: 600.00, max y: 600.00
# nominal range: 300.00 link bw: 54000000.00
# pause: 30.00, min speed 1.50 max speed: 4.50
$node_(6) set X_ 780.0
$node_(6) set Y_ 228.0
$node_(6) set Z_ 0.00
$node_(7) set X_ 816.0
$node_(7) set Y_ 348.0
$node_(7) set Z_ 0.00
$node_(8) set X_ 672.0
$node_(8) set Y_ 420.0
$node_(8) set Z_ 0.00
$node_(9) set X_ 672.0
$node_(9) set Y_ 96.0
$node_(9) set Z_ 0.00
$ns_ at 1.00 "$node_(6) setdest 500.0 178.0 25.0"
$ns_ at 2.00 "$node_(7) setdest 400.0 288.0 15.0"
$ns_ at 1.00 "$node_(8) setdest 590.0 520.0 17.0"
$ns_ at 3.00 "$node_(9) setdest 720.0 300.0 20.0"
$ns_ at 8.00 "$node_(7) setdest 600.0 350.0 10.0"
$ns_ at 9.00 "$node_(8) setdest 730.0 300.0 15.0"
$ns_ at 10.00 "$node_(6) setdest 600.0 108.0 10.0"
$ns_ at 16.00 "$node_(9) setdest 672.0 96.0 20.0"
$ns_ at 17.00 "$node_(7) setdest 816.0 348.0 20.0"
$ns_ at 18.00 "$node_(6) setdest 780.0 228.0 25.0"
$ns_ at 22.00 "$node_(8) setdest 672.0 420.0 20.0"

View file

@ -1,5 +1,5 @@
<?xml version='1.0' encoding='UTF-8'?>
<scenario name="/tmp/tmpsn2dcw73">
<scenario name="/tmp/tmp9vdlfd63">
<networks>
<network id="4" name="n4" icon="" type="SWITCH">
<position x="192" y="252" lat="47.57577240005682" lon="-122.12855068636081" alt="2.0"/>
@ -18,15 +18,6 @@
<service name="IPForward"/>
</services>
</device>
<device id="2" name="n2" icon="" type="router">
<position x="264" y="432" lat="47.57333230650302" lon="-122.1271551492028" alt="2.0"/>
<services>
<service name="zebra"/>
<service name="OSPFv2"/>
<service name="OSPFv3"/>
<service name="IPForward"/>
</services>
</device>
<device id="3" name="n3" icon="" type="router">
<position x="120" y="360" lat="47.57432579524807" lon="-122.13001073884303" alt="2.0"/>
<services>
@ -36,6 +27,23 @@
<service name="IPForward"/>
</services>
</device>
<device id="2" name="n2" icon="" type="router">
<position x="264" y="432" lat="47.57333230650302" lon="-122.1271551492028" alt="2.0"/>
<services>
<service name="zebra"/>
<service name="OSPFv2"/>
<service name="OSPFv3"/>
<service name="IPForward"/>
</services>
</device>
<device id="9" name="n9" icon="" type="mdr">
<position x="672" y="96" z="0" lat="47.57780454700428" lon="-122.11894266318714" alt="2.0"/>
<services>
<service name="zebra"/>
<service name="OSPFv3MDR"/>
<service name="IPForward"/>
</services>
</device>
<device id="6" name="n6" icon="" type="mdr">
<position x="780" y="228" z="0" lat="47.57600659186813" lon="-122.11681868175411" alt="2.0"/>
<services>
@ -44,6 +52,14 @@
<service name="IPForward"/>
</services>
</device>
<device id="7" name="n7" icon="" type="mdr">
<position x="816" y="348" z="0" lat="47.574381616411884" lon="-122.11612798101025" alt="2.0"/>
<services>
<service name="zebra"/>
<service name="OSPFv3MDR"/>
<service name="IPForward"/>
</services>
</device>
<device id="5" name="n5" icon="" type="mdr">
<position x="540" y="348" lat="47.574423900984414" lon="-122.12163213928551" alt="2.0"/>
<services>
@ -61,28 +77,12 @@
<service name="IPForward"/>
</services>
</device>
<device id="7" name="n7" icon="" type="mdr">
<position x="816" y="348" z="0" lat="47.574381616411884" lon="-122.11612798101025" alt="2.0"/>
<services>
<service name="zebra"/>
<service name="OSPFv3MDR"/>
<service name="IPForward"/>
</services>
</device>
<device id="11" name="n11" icon="" type="PC">
<position x="192" y="156" lat="47.57706795991869" lon="-122.1285291884349" alt="2.0"/>
<services>
<service name="DefaultRoute"/>
</services>
</device>
<device id="9" name="n9" icon="" type="mdr">
<position x="672" y="96" z="0" lat="47.57780454700428" lon="-122.11894266318714" alt="2.0"/>
<services>
<service name="zebra"/>
<service name="OSPFv3MDR"/>
<service name="IPForward"/>
</services>
</device>
<device id="12" name="n12" icon="" type="PC">
<position x="264" y="156" lat="47.57705704050324" lon="-122.12709324491955" alt="2.0"/>
<services>
@ -117,62 +117,62 @@
<interface_two id="0" name="eth0" mac="00:00:00:aa:00:11" ip4="10.0.1.21" ip4_mask="24" ip6="a:1::21" ip6_mask="64"/>
<options delay="0" bandwidth="100000000" per="0.0" dup="0" jitter="0" type="1" unidirectional="0"/>
</link>
<link node_one="4" node_two="13">
<interface_two id="0" name="eth0" mac="00:00:00:aa:00:12" ip4="10.0.1.22" ip4_mask="24" ip6="a:1::22" ip6_mask="64"/>
<link node_one="4" node_two="11">
<interface_two id="0" name="eth0" mac="00:00:00:aa:00:10" ip4="10.0.1.20" ip4_mask="24" ip6="a:1::20" ip6_mask="64"/>
<options delay="0" bandwidth="100000000" per="0.0" dup="0" jitter="0" type="1" unidirectional="0"/>
</link>
<link node_one="4" node_two="14">
<interface_two id="0" name="eth0" mac="00:00:00:aa:00:13" ip4="10.0.1.10" ip4_mask="24" ip6="a:1::10" ip6_mask="64"/>
<link node_one="4" node_two="13">
<interface_two id="0" name="eth0" mac="00:00:00:aa:00:12" ip4="10.0.1.22" ip4_mask="24" ip6="a:1::22" ip6_mask="64"/>
<options delay="0" bandwidth="100000000" per="0.0" dup="0" jitter="0" type="1" unidirectional="0"/>
</link>
<link node_one="4" node_two="3">
<interface_two id="0" name="eth0" mac="00:00:00:aa:00:05" ip4="10.0.1.1" ip4_mask="24" ip6="a:1::1" ip6_mask="64"/>
<options delay="0" bandwidth="100000000" per="0.0" dup="0" jitter="0" type="1" unidirectional="0"/>
</link>
<link node_one="4" node_two="11">
<interface_two id="0" name="eth0" mac="00:00:00:aa:00:10" ip4="10.0.1.20" ip4_mask="24" ip6="a:1::20" ip6_mask="64"/>
<link node_one="4" node_two="14">
<interface_two id="0" name="eth0" mac="00:00:00:aa:00:13" ip4="10.0.1.10" ip4_mask="24" ip6="a:1::10" ip6_mask="64"/>
<options delay="0" bandwidth="100000000" per="0.0" dup="0" jitter="0" type="1" unidirectional="0"/>
</link>
<link node_one="10" node_two="6">
<interface_two id="0" name="eth0" mac="00:00:00:aa:00:03" ip4="10.0.0.6" ip4_mask="32" ip6="a::6" ip6_mask="128"/>
<options delay="50000" bandwidth="54000000" per="0.0" dup="0" jitter="0" type="1" unidirectional="0"/>
</link>
<link node_one="10" node_two="8">
<interface_two id="0" name="eth0" mac="00:00:00:aa:00:00" ip4="10.0.0.8" ip4_mask="32" ip6="a::8" ip6_mask="128"/>
<options delay="50000" bandwidth="54000000" per="0.0" dup="0" jitter="0" type="1" unidirectional="0"/>
</link>
<link node_one="10" node_two="5">
<interface_two id="0" name="eth0" mac="00:00:00:aa:00:02" ip4="10.0.0.5" ip4_mask="32" ip6="a::3" ip6_mask="128"/>
<link node_one="10" node_two="6">
<interface_two id="0" name="eth0" mac="00:00:00:aa:00:03" ip4="10.0.0.6" ip4_mask="32" ip6="a::6" ip6_mask="128"/>
<options delay="50000" bandwidth="54000000" per="0.0" dup="0" jitter="0" type="1" unidirectional="0"/>
</link>
<link node_one="10" node_two="7">
<interface_two id="0" name="eth0" mac="00:00:00:aa:00:01" ip4="10.0.0.7" ip4_mask="32" ip6="a::7" ip6_mask="128"/>
<options delay="50000" bandwidth="54000000" per="0.0" dup="0" jitter="0" type="1" unidirectional="0"/>
</link>
<link node_one="10" node_two="5">
<interface_two id="0" name="eth0" mac="00:00:00:aa:00:02" ip4="10.0.0.5" ip4_mask="32" ip6="a::3" ip6_mask="128"/>
<options delay="50000" bandwidth="54000000" per="0.0" dup="0" jitter="0" type="1" unidirectional="0"/>
</link>
<link node_one="10" node_two="9">
<interface_two id="0" name="eth0" mac="00:00:00:aa:00:04" ip4="10.0.0.9" ip4_mask="32" ip6="a::9" ip6_mask="128"/>
<options delay="50000" bandwidth="54000000" per="0.0" dup="0" jitter="0" type="1" unidirectional="0"/>
</link>
<link node_one="3" node_two="2">
<interface_one id="1" name="eth1" mac="00:00:00:aa:00:06" ip4="10.0.2.1" ip4_mask="24" ip6="a:2::1" ip6_mask="64"/>
<interface_two id="0" name="eth0" mac="00:00:00:aa:00:07" ip4="10.0.2.2" ip4_mask="24" ip6="a:2::2" ip6_mask="64"/>
<options delay="25000" bandwidth="100000000" per="0.0" dup="0" jitter="0" type="1" unidirectional="0"/>
</link>
<link node_one="1" node_two="15">
<interface_one id="1" name="eth1" mac="00:00:00:aa:00:0c" ip4="10.0.5.1" ip4_mask="24" ip6="a:5::1" ip6_mask="64"/>
<interface_two id="1" name="eth1" mac="00:00:00:aa:00:0d" ip4="10.0.5.2" ip4_mask="24" ip6="a:5::2" ip6_mask="64"/>
<options delay="0" bandwidth="100000000" per="0.0" dup="0" jitter="0" type="1" unidirectional="0"/>
</link>
<link node_one="2" node_two="1">
<interface_one id="1" name="eth1" mac="00:00:00:aa:00:08" ip4="10.0.3.1" ip4_mask="24" ip6="a:3::1" ip6_mask="64"/>
<interface_two id="0" name="eth0" mac="00:00:00:aa:00:09" ip4="10.0.3.2" ip4_mask="24" ip6="a:3::2" ip6_mask="64"/>
<options delay="0" bandwidth="100000000" per="0.0" dup="0" jitter="0" type="1" unidirectional="0"/>
<link node_one="3" node_two="2">
<interface_one id="1" name="eth1" mac="00:00:00:aa:00:06" ip4="10.0.2.1" ip4_mask="24" ip6="a:2::1" ip6_mask="64"/>
<interface_two id="0" name="eth0" mac="00:00:00:aa:00:07" ip4="10.0.2.2" ip4_mask="24" ip6="a:2::2" ip6_mask="64"/>
<options delay="25000" bandwidth="100000000" per="0.0" dup="0" jitter="0" type="1" unidirectional="0"/>
</link>
<link node_one="15" node_two="5">
<interface_one id="2" name="eth2" mac="00:00:00:aa:00:0e" ip4="10.0.6.1" ip4_mask="24" ip6="a:6::1" ip6_mask="64"/>
<interface_two id="1" name="eth1" mac="00:00:00:aa:00:0f" ip4="10.0.6.2" ip4_mask="24" ip6="a:6::2" ip6_mask="64"/>
<options delay="0" bandwidth="100000000" per="0.0" dup="0" jitter="0" type="1" unidirectional="0"/>
</link>
<link node_one="2" node_two="1">
<interface_one id="1" name="eth1" mac="00:00:00:aa:00:08" ip4="10.0.3.1" ip4_mask="24" ip6="a:3::1" ip6_mask="64"/>
<interface_two id="0" name="eth0" mac="00:00:00:aa:00:09" ip4="10.0.3.2" ip4_mask="24" ip6="a:3::2" ip6_mask="64"/>
<options delay="0" bandwidth="100000000" per="0.0" dup="0" jitter="0" type="1" unidirectional="0"/>
</link>
<link node_one="2" node_two="15">
<interface_one id="2" name="eth2" mac="00:00:00:aa:00:0a" ip4="10.0.4.1" ip4_mask="24" ip6="a:4::1" ip6_mask="64"/>
<interface_two id="0" name="eth0" mac="00:00:00:aa:00:0b" ip4="10.0.4.2" ip4_mask="24" ip6="a:4::2" ip6_mask="64"/>
@ -188,7 +188,7 @@
<configuration name="error" value="0"/>
</mobility_configuration>
<mobility_configuration node="10" model="ns2script">
<configuration name="file" value="/home/developer/.core/configs/sample1.scen"/>
<configuration name="file" value="/home/developer/.coretk/mobility/sample1.scen"/>
<configuration name="refresh_ms" value="50"/>
<configuration name="loop" value="1"/>
<configuration name="autostart" value="5"/>
@ -367,6 +367,177 @@ bootquagga
/sbin/sysctl -w net.ipv4.conf.eth1.forwarding=1
/sbin/sysctl -w net.ipv4.conf.eth1.send_redirects=0
/sbin/sysctl -w net.ipv4.conf.eth1.rp_filter=0
</file>
</files>
</service>
<service name="zebra" node="3">
<directories>
<directory>/usr/local/etc/quagga</directory>
<directory>/var/run/quagga</directory>
</directories>
<startups>
<startup>sh quaggaboot.sh zebra</startup>
</startups>
<validates>
<validate>pidof zebra</validate>
</validates>
<shutdowns>
<shutdown>killall zebra</shutdown>
</shutdowns>
<files>
<file name="/usr/local/etc/quagga/Quagga.conf">interface eth0
ip address 10.0.1.1/24
ipv6 address a:1::1/64
!
interface eth1
ip address 10.0.2.1/24
ipv6 address a:2::1/64
!
router ospf
router-id 10.0.1.1
network 10.0.1.0/24 area 0
network 10.0.2.0/24 area 0
!
router ospf6
router-id 10.0.1.1
interface eth0 area 0.0.0.0
interface eth1 area 0.0.0.0
!
</file>
<file name="quaggaboot.sh">#!/bin/sh
# auto-generated by zebra service (quagga.py)
QUAGGA_CONF=/usr/local/etc/quagga/Quagga.conf
QUAGGA_SBIN_SEARCH="/usr/local/sbin /usr/sbin /usr/lib/quagga"
QUAGGA_BIN_SEARCH="/usr/local/bin /usr/bin /usr/lib/quagga"
QUAGGA_STATE_DIR=/var/run/quagga
searchforprog()
{
prog=$1
searchpath=$@
ret=
for p in $searchpath; do
if [ -x $p/$prog ]; then
ret=$p
break
fi
done
echo $ret
}
confcheck()
{
CONF_DIR=`dirname $QUAGGA_CONF`
# if /etc/quagga exists, point /etc/quagga/Quagga.conf -&gt; CONF_DIR
if [ "$CONF_DIR" != "/etc/quagga" ] &amp;&amp; [ -d /etc/quagga ] &amp;&amp; [ ! -e /etc/quagga/Quagga.conf ]; then
ln -s $CONF_DIR/Quagga.conf /etc/quagga/Quagga.conf
fi
# if /etc/quagga exists, point /etc/quagga/vtysh.conf -&gt; CONF_DIR
if [ "$CONF_DIR" != "/etc/quagga" ] &amp;&amp; [ -d /etc/quagga ] &amp;&amp; [ ! -e /etc/quagga/vtysh.conf ]; then
ln -s $CONF_DIR/vtysh.conf /etc/quagga/vtysh.conf
fi
}
bootdaemon()
{
QUAGGA_SBIN_DIR=$(searchforprog $1 $QUAGGA_SBIN_SEARCH)
if [ "z$QUAGGA_SBIN_DIR" = "z" ]; then
echo "ERROR: Quagga's '$1' daemon not found in search path:"
echo " $QUAGGA_SBIN_SEARCH"
return 1
fi
flags=""
if [ "$1" = "xpimd" ] &amp;&amp; \
grep -E -q '^[[:space:]]*router[[:space:]]+pim6[[:space:]]*$' $QUAGGA_CONF; then
flags="$flags -6"
fi
$QUAGGA_SBIN_DIR/$1 $flags -d
if [ "$?" != "0" ]; then
echo "ERROR: Quagga's '$1' daemon failed to start!:"
return 1
fi
}
bootquagga()
{
QUAGGA_BIN_DIR=$(searchforprog 'vtysh' $QUAGGA_BIN_SEARCH)
if [ "z$QUAGGA_BIN_DIR" = "z" ]; then
echo "ERROR: Quagga's 'vtysh' program not found in search path:"
echo " $QUAGGA_BIN_SEARCH"
return 1
fi
# fix /var/run/quagga permissions
id -u quagga 2&gt;/dev/null &gt;/dev/null
if [ "$?" = "0" ]; then
chown quagga $QUAGGA_STATE_DIR
fi
bootdaemon "zebra"
for r in rip ripng ospf6 ospf bgp babel; do
if grep -q "^router \&lt;${r}\&gt;" $QUAGGA_CONF; then
bootdaemon "${r}d"
fi
done
if grep -E -q '^[[:space:]]*router[[:space:]]+pim6?[[:space:]]*$' $QUAGGA_CONF; then
bootdaemon "xpimd"
fi
$QUAGGA_BIN_DIR/vtysh -b
}
if [ "$1" != "zebra" ]; then
echo "WARNING: '$1': all Quagga daemons are launched by the 'zebra' service!"
exit 1
fi
confcheck
bootquagga
</file>
<file name="/usr/local/etc/quagga/vtysh.conf">service integrated-vtysh-config
</file>
</files>
</service>
<service name="OSPFv2" node="3">
<validates>
<validate>pidof ospfd</validate>
</validates>
<shutdowns>
<shutdown>killall ospfd</shutdown>
</shutdowns>
</service>
<service name="OSPFv3" node="3">
<validates>
<validate>pidof ospf6d</validate>
</validates>
<shutdowns>
<shutdown>killall ospf6d</shutdown>
</shutdowns>
</service>
<service name="IPForward" node="3">
<startups>
<startup>sh ipforward.sh</startup>
</startups>
<files>
<file name="ipforward.sh">#!/bin/sh
# auto-generated by IPForward service (utility.py)
/sbin/sysctl -w net.ipv4.conf.all.forwarding=1
/sbin/sysctl -w net.ipv4.conf.default.forwarding=1
/sbin/sysctl -w net.ipv6.conf.all.forwarding=1
/sbin/sysctl -w net.ipv6.conf.default.forwarding=1
/sbin/sysctl -w net.ipv4.conf.all.send_redirects=0
/sbin/sysctl -w net.ipv4.conf.default.send_redirects=0
/sbin/sysctl -w net.ipv4.conf.all.rp_filter=0
/sbin/sysctl -w net.ipv4.conf.default.rp_filter=0
/sbin/sysctl -w net.ipv4.conf.eth0.forwarding=1
/sbin/sysctl -w net.ipv4.conf.eth0.send_redirects=0
/sbin/sysctl -w net.ipv4.conf.eth0.rp_filter=0
/sbin/sysctl -w net.ipv4.conf.eth1.forwarding=1
/sbin/sysctl -w net.ipv4.conf.eth1.send_redirects=0
/sbin/sysctl -w net.ipv4.conf.eth1.rp_filter=0
</file>
</files>
</service>
@ -550,7 +721,7 @@ bootquagga
</file>
</files>
</service>
<service name="zebra" node="3">
<service name="zebra" node="9">
<directories>
<directory>/usr/local/etc/quagga</directory>
<directory>/var/run/quagga</directory>
@ -566,22 +737,20 @@ bootquagga
</shutdowns>
<files>
<file name="/usr/local/etc/quagga/Quagga.conf">interface eth0
ip address 10.0.1.1/24
ipv6 address a:1::1/64
!
interface eth1
ip address 10.0.2.1/24
ipv6 address a:2::1/64
!
router ospf
router-id 10.0.1.1
network 10.0.1.0/24 area 0
network 10.0.2.0/24 area 0
ip address 10.0.0.9/32
ipv6 address a::9/128
ipv6 ospf6 instance-id 65
ipv6 ospf6 hello-interval 2
ipv6 ospf6 dead-interval 6
ipv6 ospf6 retransmit-interval 5
ipv6 ospf6 network manet-designated-router
ipv6 ospf6 diffhellos
ipv6 ospf6 adjacencyconnectivity uniconnected
ipv6 ospf6 lsafullness mincostlsa
!
router ospf6
router-id 10.0.1.1
router-id 10.0.0.9
interface eth0 area 0.0.0.0
interface eth1 area 0.0.0.0
!
</file>
<file name="quaggaboot.sh">#!/bin/sh
@ -681,15 +850,7 @@ bootquagga
</file>
</files>
</service>
<service name="OSPFv2" node="3">
<validates>
<validate>pidof ospfd</validate>
</validates>
<shutdowns>
<shutdown>killall ospfd</shutdown>
</shutdowns>
</service>
<service name="OSPFv3" node="3">
<service name="OSPFv3MDR" node="9">
<validates>
<validate>pidof ospf6d</validate>
</validates>
@ -697,7 +858,7 @@ bootquagga
<shutdown>killall ospf6d</shutdown>
</shutdowns>
</service>
<service name="IPForward" node="3">
<service name="IPForward" node="9">
<startups>
<startup>sh ipforward.sh</startup>
</startups>
@ -715,9 +876,6 @@ bootquagga
/sbin/sysctl -w net.ipv4.conf.eth0.forwarding=1
/sbin/sysctl -w net.ipv4.conf.eth0.send_redirects=0
/sbin/sysctl -w net.ipv4.conf.eth0.rp_filter=0
/sbin/sysctl -w net.ipv4.conf.eth1.forwarding=1
/sbin/sysctl -w net.ipv4.conf.eth1.send_redirects=0
/sbin/sysctl -w net.ipv4.conf.eth1.rp_filter=0
</file>
</files>
</service>
@ -876,6 +1034,164 @@ bootquagga
/sbin/sysctl -w net.ipv4.conf.eth0.forwarding=1
/sbin/sysctl -w net.ipv4.conf.eth0.send_redirects=0
/sbin/sysctl -w net.ipv4.conf.eth0.rp_filter=0
</file>
</files>
</service>
<service name="zebra" node="7">
<directories>
<directory>/usr/local/etc/quagga</directory>
<directory>/var/run/quagga</directory>
</directories>
<startups>
<startup>sh quaggaboot.sh zebra</startup>
</startups>
<validates>
<validate>pidof zebra</validate>
</validates>
<shutdowns>
<shutdown>killall zebra</shutdown>
</shutdowns>
<files>
<file name="/usr/local/etc/quagga/Quagga.conf">interface eth0
ip address 10.0.0.7/32
ipv6 address a::7/128
ipv6 ospf6 instance-id 65
ipv6 ospf6 hello-interval 2
ipv6 ospf6 dead-interval 6
ipv6 ospf6 retransmit-interval 5
ipv6 ospf6 network manet-designated-router
ipv6 ospf6 diffhellos
ipv6 ospf6 adjacencyconnectivity uniconnected
ipv6 ospf6 lsafullness mincostlsa
!
router ospf6
router-id 10.0.0.7
interface eth0 area 0.0.0.0
!
</file>
<file name="quaggaboot.sh">#!/bin/sh
# auto-generated by zebra service (quagga.py)
QUAGGA_CONF=/usr/local/etc/quagga/Quagga.conf
QUAGGA_SBIN_SEARCH="/usr/local/sbin /usr/sbin /usr/lib/quagga"
QUAGGA_BIN_SEARCH="/usr/local/bin /usr/bin /usr/lib/quagga"
QUAGGA_STATE_DIR=/var/run/quagga
searchforprog()
{
prog=$1
searchpath=$@
ret=
for p in $searchpath; do
if [ -x $p/$prog ]; then
ret=$p
break
fi
done
echo $ret
}
confcheck()
{
CONF_DIR=`dirname $QUAGGA_CONF`
# if /etc/quagga exists, point /etc/quagga/Quagga.conf -&gt; CONF_DIR
if [ "$CONF_DIR" != "/etc/quagga" ] &amp;&amp; [ -d /etc/quagga ] &amp;&amp; [ ! -e /etc/quagga/Quagga.conf ]; then
ln -s $CONF_DIR/Quagga.conf /etc/quagga/Quagga.conf
fi
# if /etc/quagga exists, point /etc/quagga/vtysh.conf -&gt; CONF_DIR
if [ "$CONF_DIR" != "/etc/quagga" ] &amp;&amp; [ -d /etc/quagga ] &amp;&amp; [ ! -e /etc/quagga/vtysh.conf ]; then
ln -s $CONF_DIR/vtysh.conf /etc/quagga/vtysh.conf
fi
}
bootdaemon()
{
QUAGGA_SBIN_DIR=$(searchforprog $1 $QUAGGA_SBIN_SEARCH)
if [ "z$QUAGGA_SBIN_DIR" = "z" ]; then
echo "ERROR: Quagga's '$1' daemon not found in search path:"
echo " $QUAGGA_SBIN_SEARCH"
return 1
fi
flags=""
if [ "$1" = "xpimd" ] &amp;&amp; \
grep -E -q '^[[:space:]]*router[[:space:]]+pim6[[:space:]]*$' $QUAGGA_CONF; then
flags="$flags -6"
fi
$QUAGGA_SBIN_DIR/$1 $flags -d
if [ "$?" != "0" ]; then
echo "ERROR: Quagga's '$1' daemon failed to start!:"
return 1
fi
}
bootquagga()
{
QUAGGA_BIN_DIR=$(searchforprog 'vtysh' $QUAGGA_BIN_SEARCH)
if [ "z$QUAGGA_BIN_DIR" = "z" ]; then
echo "ERROR: Quagga's 'vtysh' program not found in search path:"
echo " $QUAGGA_BIN_SEARCH"
return 1
fi
# fix /var/run/quagga permissions
id -u quagga 2&gt;/dev/null &gt;/dev/null
if [ "$?" = "0" ]; then
chown quagga $QUAGGA_STATE_DIR
fi
bootdaemon "zebra"
for r in rip ripng ospf6 ospf bgp babel; do
if grep -q "^router \&lt;${r}\&gt;" $QUAGGA_CONF; then
bootdaemon "${r}d"
fi
done
if grep -E -q '^[[:space:]]*router[[:space:]]+pim6?[[:space:]]*$' $QUAGGA_CONF; then
bootdaemon "xpimd"
fi
$QUAGGA_BIN_DIR/vtysh -b
}
if [ "$1" != "zebra" ]; then
echo "WARNING: '$1': all Quagga daemons are launched by the 'zebra' service!"
exit 1
fi
confcheck
bootquagga
</file>
<file name="/usr/local/etc/quagga/vtysh.conf">service integrated-vtysh-config
</file>
</files>
</service>
<service name="OSPFv3MDR" node="7">
<validates>
<validate>pidof ospf6d</validate>
</validates>
<shutdowns>
<shutdown>killall ospf6d</shutdown>
</shutdowns>
</service>
<service name="IPForward" node="7">
<startups>
<startup>sh ipforward.sh</startup>
</startups>
<files>
<file name="ipforward.sh">#!/bin/sh
# auto-generated by IPForward service (utility.py)
/sbin/sysctl -w net.ipv4.conf.all.forwarding=1
/sbin/sysctl -w net.ipv4.conf.default.forwarding=1
/sbin/sysctl -w net.ipv6.conf.all.forwarding=1
/sbin/sysctl -w net.ipv6.conf.default.forwarding=1
/sbin/sysctl -w net.ipv4.conf.all.send_redirects=0
/sbin/sysctl -w net.ipv4.conf.default.send_redirects=0
/sbin/sysctl -w net.ipv4.conf.all.rp_filter=0
/sbin/sysctl -w net.ipv4.conf.default.rp_filter=0
/sbin/sysctl -w net.ipv4.conf.eth0.forwarding=1
/sbin/sysctl -w net.ipv4.conf.eth0.send_redirects=0
/sbin/sysctl -w net.ipv4.conf.eth0.rp_filter=0
</file>
</files>
</service>
@ -1221,164 +1537,6 @@ bootquagga
/sbin/sysctl -w net.ipv4.conf.eth0.forwarding=1
/sbin/sysctl -w net.ipv4.conf.eth0.send_redirects=0
/sbin/sysctl -w net.ipv4.conf.eth0.rp_filter=0
</file>
</files>
</service>
<service name="zebra" node="7">
<directories>
<directory>/usr/local/etc/quagga</directory>
<directory>/var/run/quagga</directory>
</directories>
<startups>
<startup>sh quaggaboot.sh zebra</startup>
</startups>
<validates>
<validate>pidof zebra</validate>
</validates>
<shutdowns>
<shutdown>killall zebra</shutdown>
</shutdowns>
<files>
<file name="/usr/local/etc/quagga/Quagga.conf">interface eth0
ip address 10.0.0.7/32
ipv6 address a::7/128
ipv6 ospf6 instance-id 65
ipv6 ospf6 hello-interval 2
ipv6 ospf6 dead-interval 6
ipv6 ospf6 retransmit-interval 5
ipv6 ospf6 network manet-designated-router
ipv6 ospf6 diffhellos
ipv6 ospf6 adjacencyconnectivity uniconnected
ipv6 ospf6 lsafullness mincostlsa
!
router ospf6
router-id 10.0.0.7
interface eth0 area 0.0.0.0
!
</file>
<file name="quaggaboot.sh">#!/bin/sh
# auto-generated by zebra service (quagga.py)
QUAGGA_CONF=/usr/local/etc/quagga/Quagga.conf
QUAGGA_SBIN_SEARCH="/usr/local/sbin /usr/sbin /usr/lib/quagga"
QUAGGA_BIN_SEARCH="/usr/local/bin /usr/bin /usr/lib/quagga"
QUAGGA_STATE_DIR=/var/run/quagga
searchforprog()
{
prog=$1
searchpath=$@
ret=
for p in $searchpath; do
if [ -x $p/$prog ]; then
ret=$p
break
fi
done
echo $ret
}
confcheck()
{
CONF_DIR=`dirname $QUAGGA_CONF`
# if /etc/quagga exists, point /etc/quagga/Quagga.conf -&gt; CONF_DIR
if [ "$CONF_DIR" != "/etc/quagga" ] &amp;&amp; [ -d /etc/quagga ] &amp;&amp; [ ! -e /etc/quagga/Quagga.conf ]; then
ln -s $CONF_DIR/Quagga.conf /etc/quagga/Quagga.conf
fi
# if /etc/quagga exists, point /etc/quagga/vtysh.conf -&gt; CONF_DIR
if [ "$CONF_DIR" != "/etc/quagga" ] &amp;&amp; [ -d /etc/quagga ] &amp;&amp; [ ! -e /etc/quagga/vtysh.conf ]; then
ln -s $CONF_DIR/vtysh.conf /etc/quagga/vtysh.conf
fi
}
bootdaemon()
{
QUAGGA_SBIN_DIR=$(searchforprog $1 $QUAGGA_SBIN_SEARCH)
if [ "z$QUAGGA_SBIN_DIR" = "z" ]; then
echo "ERROR: Quagga's '$1' daemon not found in search path:"
echo " $QUAGGA_SBIN_SEARCH"
return 1
fi
flags=""
if [ "$1" = "xpimd" ] &amp;&amp; \
grep -E -q '^[[:space:]]*router[[:space:]]+pim6[[:space:]]*$' $QUAGGA_CONF; then
flags="$flags -6"
fi
$QUAGGA_SBIN_DIR/$1 $flags -d
if [ "$?" != "0" ]; then
echo "ERROR: Quagga's '$1' daemon failed to start!:"
return 1
fi
}
bootquagga()
{
QUAGGA_BIN_DIR=$(searchforprog 'vtysh' $QUAGGA_BIN_SEARCH)
if [ "z$QUAGGA_BIN_DIR" = "z" ]; then
echo "ERROR: Quagga's 'vtysh' program not found in search path:"
echo " $QUAGGA_BIN_SEARCH"
return 1
fi
# fix /var/run/quagga permissions
id -u quagga 2&gt;/dev/null &gt;/dev/null
if [ "$?" = "0" ]; then
chown quagga $QUAGGA_STATE_DIR
fi
bootdaemon "zebra"
for r in rip ripng ospf6 ospf bgp babel; do
if grep -q "^router \&lt;${r}\&gt;" $QUAGGA_CONF; then
bootdaemon "${r}d"
fi
done
if grep -E -q '^[[:space:]]*router[[:space:]]+pim6?[[:space:]]*$' $QUAGGA_CONF; then
bootdaemon "xpimd"
fi
$QUAGGA_BIN_DIR/vtysh -b
}
if [ "$1" != "zebra" ]; then
echo "WARNING: '$1': all Quagga daemons are launched by the 'zebra' service!"
exit 1
fi
confcheck
bootquagga
</file>
<file name="/usr/local/etc/quagga/vtysh.conf">service integrated-vtysh-config
</file>
</files>
</service>
<service name="OSPFv3MDR" node="7">
<validates>
<validate>pidof ospf6d</validate>
</validates>
<shutdowns>
<shutdown>killall ospf6d</shutdown>
</shutdowns>
</service>
<service name="IPForward" node="7">
<startups>
<startup>sh ipforward.sh</startup>
</startups>
<files>
<file name="ipforward.sh">#!/bin/sh
# auto-generated by IPForward service (utility.py)
/sbin/sysctl -w net.ipv4.conf.all.forwarding=1
/sbin/sysctl -w net.ipv4.conf.default.forwarding=1
/sbin/sysctl -w net.ipv6.conf.all.forwarding=1
/sbin/sysctl -w net.ipv6.conf.default.forwarding=1
/sbin/sysctl -w net.ipv4.conf.all.send_redirects=0
/sbin/sysctl -w net.ipv4.conf.default.send_redirects=0
/sbin/sysctl -w net.ipv4.conf.all.rp_filter=0
/sbin/sysctl -w net.ipv4.conf.default.rp_filter=0
/sbin/sysctl -w net.ipv4.conf.eth0.forwarding=1
/sbin/sysctl -w net.ipv4.conf.eth0.send_redirects=0
/sbin/sysctl -w net.ipv4.conf.eth0.rp_filter=0
</file>
</files>
</service>
@ -1391,164 +1549,6 @@ bootquagga
# auto-generated by DefaultRoute service (utility.py)
ip route add default via 10.0.1.1
ip route add default via a:1::1
</file>
</files>
</service>
<service name="zebra" node="9">
<directories>
<directory>/usr/local/etc/quagga</directory>
<directory>/var/run/quagga</directory>
</directories>
<startups>
<startup>sh quaggaboot.sh zebra</startup>
</startups>
<validates>
<validate>pidof zebra</validate>
</validates>
<shutdowns>
<shutdown>killall zebra</shutdown>
</shutdowns>
<files>
<file name="/usr/local/etc/quagga/Quagga.conf">interface eth0
ip address 10.0.0.9/32
ipv6 address a::9/128
ipv6 ospf6 instance-id 65
ipv6 ospf6 hello-interval 2
ipv6 ospf6 dead-interval 6
ipv6 ospf6 retransmit-interval 5
ipv6 ospf6 network manet-designated-router
ipv6 ospf6 diffhellos
ipv6 ospf6 adjacencyconnectivity uniconnected
ipv6 ospf6 lsafullness mincostlsa
!
router ospf6
router-id 10.0.0.9
interface eth0 area 0.0.0.0
!
</file>
<file name="quaggaboot.sh">#!/bin/sh
# auto-generated by zebra service (quagga.py)
QUAGGA_CONF=/usr/local/etc/quagga/Quagga.conf
QUAGGA_SBIN_SEARCH="/usr/local/sbin /usr/sbin /usr/lib/quagga"
QUAGGA_BIN_SEARCH="/usr/local/bin /usr/bin /usr/lib/quagga"
QUAGGA_STATE_DIR=/var/run/quagga
searchforprog()
{
prog=$1
searchpath=$@
ret=
for p in $searchpath; do
if [ -x $p/$prog ]; then
ret=$p
break
fi
done
echo $ret
}
confcheck()
{
CONF_DIR=`dirname $QUAGGA_CONF`
# if /etc/quagga exists, point /etc/quagga/Quagga.conf -&gt; CONF_DIR
if [ "$CONF_DIR" != "/etc/quagga" ] &amp;&amp; [ -d /etc/quagga ] &amp;&amp; [ ! -e /etc/quagga/Quagga.conf ]; then
ln -s $CONF_DIR/Quagga.conf /etc/quagga/Quagga.conf
fi
# if /etc/quagga exists, point /etc/quagga/vtysh.conf -&gt; CONF_DIR
if [ "$CONF_DIR" != "/etc/quagga" ] &amp;&amp; [ -d /etc/quagga ] &amp;&amp; [ ! -e /etc/quagga/vtysh.conf ]; then
ln -s $CONF_DIR/vtysh.conf /etc/quagga/vtysh.conf
fi
}
bootdaemon()
{
QUAGGA_SBIN_DIR=$(searchforprog $1 $QUAGGA_SBIN_SEARCH)
if [ "z$QUAGGA_SBIN_DIR" = "z" ]; then
echo "ERROR: Quagga's '$1' daemon not found in search path:"
echo " $QUAGGA_SBIN_SEARCH"
return 1
fi
flags=""
if [ "$1" = "xpimd" ] &amp;&amp; \
grep -E -q '^[[:space:]]*router[[:space:]]+pim6[[:space:]]*$' $QUAGGA_CONF; then
flags="$flags -6"
fi
$QUAGGA_SBIN_DIR/$1 $flags -d
if [ "$?" != "0" ]; then
echo "ERROR: Quagga's '$1' daemon failed to start!:"
return 1
fi
}
bootquagga()
{
QUAGGA_BIN_DIR=$(searchforprog 'vtysh' $QUAGGA_BIN_SEARCH)
if [ "z$QUAGGA_BIN_DIR" = "z" ]; then
echo "ERROR: Quagga's 'vtysh' program not found in search path:"
echo " $QUAGGA_BIN_SEARCH"
return 1
fi
# fix /var/run/quagga permissions
id -u quagga 2&gt;/dev/null &gt;/dev/null
if [ "$?" = "0" ]; then
chown quagga $QUAGGA_STATE_DIR
fi
bootdaemon "zebra"
for r in rip ripng ospf6 ospf bgp babel; do
if grep -q "^router \&lt;${r}\&gt;" $QUAGGA_CONF; then
bootdaemon "${r}d"
fi
done
if grep -E -q '^[[:space:]]*router[[:space:]]+pim6?[[:space:]]*$' $QUAGGA_CONF; then
bootdaemon "xpimd"
fi
$QUAGGA_BIN_DIR/vtysh -b
}
if [ "$1" != "zebra" ]; then
echo "WARNING: '$1': all Quagga daemons are launched by the 'zebra' service!"
exit 1
fi
confcheck
bootquagga
</file>
<file name="/usr/local/etc/quagga/vtysh.conf">service integrated-vtysh-config
</file>
</files>
</service>
<service name="OSPFv3MDR" node="9">
<validates>
<validate>pidof ospf6d</validate>
</validates>
<shutdowns>
<shutdown>killall ospf6d</shutdown>
</shutdowns>
</service>
<service name="IPForward" node="9">
<startups>
<startup>sh ipforward.sh</startup>
</startups>
<files>
<file name="ipforward.sh">#!/bin/sh
# auto-generated by IPForward service (utility.py)
/sbin/sysctl -w net.ipv4.conf.all.forwarding=1
/sbin/sysctl -w net.ipv4.conf.default.forwarding=1
/sbin/sysctl -w net.ipv6.conf.all.forwarding=1
/sbin/sysctl -w net.ipv6.conf.default.forwarding=1
/sbin/sysctl -w net.ipv4.conf.all.send_redirects=0
/sbin/sysctl -w net.ipv4.conf.default.send_redirects=0
/sbin/sysctl -w net.ipv4.conf.all.rp_filter=0
/sbin/sysctl -w net.ipv4.conf.default.rp_filter=0
/sbin/sysctl -w net.ipv4.conf.eth0.forwarding=1
/sbin/sysctl -w net.ipv4.conf.eth0.send_redirects=0
/sbin/sysctl -w net.ipv4.conf.eth0.rp_filter=0
</file>
</files>
</service>
@ -1842,8 +1842,8 @@ bootquagga
<configuration name="sdturl" value="tcp://127.0.0.1:50000/"/>
</session_options>
<session_metadata>
<configuration name="canvas" value="{&quot;wallpaper&quot;: &quot;sample1-bg.gif&quot;, &quot;wallpaper-style&quot;: 1}"/>
<configuration name="shapes" value="[{&quot;type&quot;: &quot;rectangle&quot;, &quot;iconcoords&quot;: [125.0, 108.0, 402.0, 293.0], &quot;label&quot;: &quot;&quot;, &quot;fontfamily&quot;: &quot;Arial&quot;, &quot;fontsize&quot;: 12, &quot;labelcolor&quot;: &quot;#000000&quot;, &quot;color&quot;: &quot;#ebebde&quot;, &quot;border&quot;: &quot;#000000&quot;, &quot;width&quot;: 0, &quot;bold&quot;: false, &quot;italic&quot;: false, &quot;underline&quot;: false}, {&quot;type&quot;: &quot;text&quot;, &quot;iconcoords&quot;: [502.0, 405.0], &quot;label&quot;: &quot;gateway&quot;, &quot;fontfamily&quot;: &quot;Arial&quot;, &quot;fontsize&quot;: 12, &quot;labelcolor&quot;: &quot;#000000&quot;, &quot;color&quot;: &quot;&quot;, &quot;border&quot;: &quot;#000000&quot;, &quot;width&quot;: 1, &quot;bold&quot;: true, &quot;italic&quot;: false, &quot;underline&quot;: false}, {&quot;type&quot;: &quot;text&quot;, &quot;iconcoords&quot;: [638.0, 501.0], &quot;label&quot;: &quot;wireless network&quot;, &quot;fontfamily&quot;: &quot;Arial&quot;, &quot;fontsize&quot;: 12, &quot;labelcolor&quot;: &quot;#000000&quot;, &quot;color&quot;: &quot;&quot;, &quot;border&quot;: &quot;#000000&quot;, &quot;width&quot;: 1, &quot;bold&quot;: true, &quot;italic&quot;: false, &quot;underline&quot;: false}]"/>
<configuration name="shapes" value="[{&quot;type&quot;: &quot;text&quot;, &quot;iconcoords&quot;: [543.4965070431643, 411.0598604519878], &quot;label&quot;: &quot;gateway&quot;, &quot;fontfamily&quot;: &quot;Arial&quot;, &quot;fontsize&quot;: 12, &quot;labelcolor&quot;: &quot;#000000&quot;, &quot;color&quot;: &quot;&quot;, &quot;border&quot;: &quot;#000000&quot;, &quot;width&quot;: 1, &quot;bold&quot;: true, &quot;italic&quot;: false, &quot;underline&quot;: false}, {&quot;type&quot;: &quot;text&quot;, &quot;iconcoords&quot;: [706.3568676636945, 564.7259973605969], &quot;label&quot;: &quot;wireless network&quot;, &quot;fontfamily&quot;: &quot;Arial&quot;, &quot;fontsize&quot;: 12, &quot;labelcolor&quot;: &quot;#000000&quot;, &quot;color&quot;: &quot;&quot;, &quot;border&quot;: &quot;#000000&quot;, &quot;width&quot;: 1, &quot;bold&quot;: true, &quot;italic&quot;: false, &quot;underline&quot;: false}, {&quot;type&quot;: &quot;rectangle&quot;, &quot;iconcoords&quot;: [135.99999999999994, 109.0, 389.0, 281.99999999999983], &quot;label&quot;: &quot;&quot;, &quot;fontfamily&quot;: &quot;Arial&quot;, &quot;fontsize&quot;: 12, &quot;labelcolor&quot;: &quot;#000000&quot;, &quot;color&quot;: &quot;#ebebde&quot;, &quot;border&quot;: &quot;#000000&quot;, &quot;width&quot;: 0, &quot;bold&quot;: false, &quot;italic&quot;: false, &quot;underline&quot;: false}]"/>
<configuration name="canvas" value="{&quot;wallpaper&quot;: &quot;sample1-bg.gif&quot;, &quot;wallpaper-style&quot;: 3, &quot;gridlines&quot;: false, &quot;fit_image&quot;: false, &quot;dimensions&quot;: [1000, 800]}"/>
</session_metadata>
<default_services>
<node type="mdr">

View file

@ -21,11 +21,7 @@ class SizeAndScaleDialog(Dialog):
self.canvas = self.app.canvas
self.validation = app.validation
self.section_font = font.Font(weight="bold")
# get current canvas dimensions
plot = self.canvas.find_withtag("rectangle")
x0, y0, x1, y1 = self.canvas.bbox(plot[0])
width = abs(x0 - x1) - 2
height = abs(y0 - y1) - 2
width, height = self.canvas.current_dimensions
self.pixel_width = tk.IntVar(value=width)
self.pixel_height = tk.IntVar(value=height)
location = self.app.core.location
@ -232,7 +228,7 @@ class SizeAndScaleDialog(Dialog):
def click_apply(self):
width, height = self.pixel_width.get(), self.pixel_height.get()
self.canvas.redraw_canvas(width, height)
self.canvas.redraw_canvas((width, height))
if self.canvas.wallpaper:
self.canvas.redraw_wallpaper()
location = self.app.core.location

View file

@ -14,19 +14,13 @@ from coretk.graph.shape import Shape
from coretk.graph.shapeutils import ShapeType, is_draw_shape
from coretk.nodeutils import NodeUtils
SCROLL_BUFFER = 25
ZOOM_IN = 1.1
ZOOM_OUT = 0.9
class CanvasGraph(tk.Canvas):
def __init__(self, master, core, width, height):
super().__init__(
master,
highlightthickness=0,
background="#cccccc",
scrollregion=(0, 0, width + SCROLL_BUFFER, height + SCROLL_BUFFER),
)
super().__init__(master, highlightthickness=0, background="#cccccc")
self.app = master
self.core = core
self.mode = GraphMode.SELECT
@ -44,8 +38,8 @@ class CanvasGraph(tk.Canvas):
self.grid = None
self.throughput_draw = Throughput(self, core)
self.shape_drawing = False
self.default_width = width
self.default_height = height
self.default_dimensions = (width, height)
self.current_dimensions = self.default_dimensions
self.ratio = 1.0
self.offset = (0, 0)
self.cursor = (0, 0)
@ -66,17 +60,22 @@ class CanvasGraph(tk.Canvas):
self.draw_canvas()
self.draw_grid()
def draw_canvas(self):
def draw_canvas(self, dimensions=None):
if self.grid is not None:
self.delete(self.grid)
if not dimensions:
dimensions = self.default_dimensions
self.current_dimensions = dimensions
self.grid = self.create_rectangle(
0,
0,
self.default_width,
self.default_height,
*dimensions,
outline="#000000",
fill="#ffffff",
width=1,
tags="rectangle",
)
self.configure(scrollregion=self.bbox(tk.ALL))
def reset_and_redraw(self, session):
"""
@ -121,6 +120,16 @@ class CanvasGraph(tk.Canvas):
self.bind("<ButtonPress-3>", lambda e: self.scan_mark(e.x, e.y))
self.bind("<B3-Motion>", lambda e: self.scan_dragto(e.x, e.y, gain=1))
def get_actual_coords(self, x, y):
actual_x = (x - self.offset[0]) / self.ratio
actual_y = (y - self.offset[1]) / self.ratio
return actual_x, actual_y
def get_scaled_coords(self, x, y):
scaled_x = (x * self.ratio) + self.offset[0]
scaled_y = (y * self.ratio) + self.offset[1]
return scaled_x, scaled_y
def draw_grid(self):
"""
Create grid.
@ -177,7 +186,9 @@ class CanvasGraph(tk.Canvas):
# draw nodes on the canvas
image = NodeUtils.node_icon(core_node.type, core_node.model)
node = CanvasNode(self.master, core_node, image)
x = core_node.position.x
y = core_node.position.y
node = CanvasNode(self.master, x, y, core_node, image)
self.nodes[node.id] = node
self.core.canvas_nodes[core_node.id] = node
@ -422,8 +433,8 @@ class CanvasGraph(tk.Canvas):
if not factor:
factor = ZOOM_IN if event.delta > 0 else ZOOM_OUT
event.x, event.y = self.canvasx(event.x), self.canvasy(event.y)
self.scale("all", event.x, event.y, factor, factor)
self.configure(scrollregion=self.bbox("all"))
self.scale(tk.ALL, event.x, event.y, factor, factor)
self.configure(scrollregion=self.bbox(tk.ALL))
self.ratio *= float(factor)
self.offset = (
self.offset[0] * factor + event.x * (1 - factor),
@ -444,7 +455,10 @@ class CanvasGraph(tk.Canvas):
x, y = self.canvas_xy(event)
self.cursor = x, y
selected = self.get_selected(event)
logging.debug("click press: %s", selected)
logging.debug("click press(%s): %s", self.cursor, selected)
x_check = self.cursor[0] - self.offset[0]
y_check = self.cursor[1] - self.offset[1]
logging.debug("clock press ofset(%s, %s)", x_check, y_check)
is_node = selected in self.nodes
if self.mode == GraphMode.EDGE and is_node:
x, y = self.coords(selected)
@ -466,6 +480,11 @@ class CanvasGraph(tk.Canvas):
node = self.nodes[selected]
self.select_object(node.id)
self.selected = selected
logging.info(
"selected coords: (%s, %s)",
node.core_node.position.x,
node.core_node.position.y,
)
else:
logging.debug("create selection box")
if self.mode == GraphMode.SELECT:
@ -557,10 +576,14 @@ class CanvasGraph(tk.Canvas):
def add_node(self, x, y):
if self.selected is None or self.selected in self.shapes:
actual_x, actual_y = self.get_actual_coords(x, y)
core_node = self.core.create_node(
int(x), int(y), self.node_draw.node_type, self.node_draw.model
int(actual_x),
int(actual_y),
self.node_draw.node_type,
self.node_draw.model,
)
node = CanvasNode(self.master, core_node, self.node_draw.image)
node = CanvasNode(self.master, x, y, core_node, self.node_draw.image)
self.core.canvas_nodes[core_node.id] = node
self.nodes[node.id] = node
return node
@ -652,18 +675,24 @@ class CanvasGraph(tk.Canvas):
def resize_to_wallpaper(self):
self.delete(self.wallpaper_id)
image = ImageTk.PhotoImage(self.wallpaper)
self.redraw_canvas(image.width(), image.height())
self.redraw_canvas((image.width(), image.height()))
self.draw_wallpaper(image)
def redraw_canvas(self, width, height):
"""
redraw grid with new dimension
def redraw_canvas(self, dimensions=None):
logging.info("redrawing canvas to dimensions: %s", dimensions)
:return: nothing
"""
# resize canvas and scrollregion
self.config(scrollregion=(0, 0, width + SCROLL_BUFFER, height + SCROLL_BUFFER))
self.coords(self.grid, 0, 0, width, height)
# reset scale and move back to original position
logging.info("resetting scaling: %s %s", self.ratio, self.offset)
factor = 1 / self.ratio
self.scale(tk.ALL, self.offset[0], self.offset[1], factor, factor)
self.move(tk.ALL, -self.offset[0], -self.offset[1])
# reset ratio and offset
self.ratio = 1.0
self.offset = (0, 0)
# redraw canvas rectangle
self.draw_canvas(dimensions)
# redraw gridlines to new canvas size
self.delete(tags.GRIDLINE)
@ -672,10 +701,11 @@ class CanvasGraph(tk.Canvas):
def redraw_wallpaper(self):
if self.adjust_to_dim.get():
logging.info("drawing wallpaper to canvas dimensions")
self.resize_to_wallpaper()
else:
option = ScaleOption(self.scale_option.get())
logging.info("canvas scale option: %s", option)
logging.info("drawing canvas using scaling option: %s", option)
if option == ScaleOption.UPPER_LEFT:
self.wallpaper_upper_left()
elif option == ScaleOption.CENTERED:
@ -698,7 +728,7 @@ class CanvasGraph(tk.Canvas):
def set_wallpaper(self, filename):
logging.info("setting wallpaper: %s", filename)
if filename is not None:
if filename:
img = Image.open(filename)
self.wallpaper = img
self.wallpaper_file = filename

View file

@ -20,13 +20,11 @@ NODE_TEXT_OFFSET = 5
class CanvasNode:
def __init__(self, app, core_node, image):
def __init__(self, app, x, y, core_node, image):
self.app = app
self.canvas = app.canvas
self.image = image
self.core_node = core_node
x = self.core_node.position.x
y = self.core_node.position.y
self.id = self.canvas.create_image(
x, y, anchor=tk.CENTER, image=self.image, tags=tags.NODE
)
@ -98,8 +96,10 @@ class CanvasNode:
return image_box[3] + NODE_TEXT_OFFSET
def move(self, x, y):
x_offset = x - self.core_node.position.x
y_offset = y - self.core_node.position.y
x, y = self.canvas.get_scaled_coords(x, y)
current_x, current_y = self.canvas.coords(self.id)
x_offset = x - current_x
y_offset = y - current_y
self.motion(x_offset, y_offset, update=False)
def motion(self, x_offset, y_offset, update=True):
@ -107,8 +107,6 @@ class CanvasNode:
self.canvas.move(self.text_id, x_offset, y_offset)
self.canvas.move_selection(self.id, x_offset, y_offset)
x, y = self.canvas.coords(self.id)
self.core_node.position.x = int(x)
self.core_node.position.y = int(y)
# move antennae
for antenna_id in self.antennae:
@ -131,7 +129,10 @@ class CanvasNode:
else:
self.canvas.coords(edge.id, x1, y1, x, y)
# update core with new location
# set actual coords for node and update core is running
real_x, real_y = self.canvas.get_actual_coords(x, y)
self.core_node.position.x = int(real_x)
self.core_node.position.y = int(real_y)
if self.app.core.is_runtime() and update:
self.app.core.edit_node(self.core_node)

View file

@ -147,6 +147,16 @@ class Shape:
def metadata(self):
coords = self.canvas.coords(self.id)
# update coords to actual positions
if len(coords) == 4:
x1, y1, x2, y2 = coords
x1, y1 = self.canvas.get_actual_coords(x1, y1)
x2, y2 = self.canvas.get_actual_coords(x2, y2)
coords = (x1, y1, x2, y2)
else:
x1, y1 = coords
x1, y1 = self.canvas.get_actual_coords(x1, y1)
coords = (x1, y1)
return {
"type": self.shape_type.value,
"iconcoords": coords,

View file

@ -10,7 +10,7 @@ from tkinter import filedialog, messagebox
import grpc
from coretk.appconfig import XML_PATH
from coretk.appconfig import XMLS_PATH
from coretk.dialogs.about import AboutDialog
from coretk.dialogs.canvassizeandscale import SizeAndScaleDialog
from coretk.dialogs.canvaswallpaper import CanvasBackgroundDialog
@ -82,7 +82,7 @@ class MenuAction:
def file_save_as_xml(self, event=None):
logging.info("menuaction.py file_save_as_xml()")
file_path = filedialog.asksaveasfilename(
initialdir=str(XML_PATH),
initialdir=str(XMLS_PATH),
title="Save As",
filetypes=(("EmulationScript XML files", "*.xml"), ("All files", "*")),
defaultextension=".xml",
@ -93,7 +93,7 @@ class MenuAction:
def file_open_xml(self, event=None):
logging.info("menuaction.py file_open_xml()")
file_path = filedialog.askopenfilename(
initialdir=str(XML_PATH),
initialdir=str(XMLS_PATH),
title="Open",
filetypes=(("XML Files", "*.xml"), ("All Files", "*")),
)

View file

@ -46,7 +46,12 @@ class Menubar(tk.Menu):
:return: nothing
"""
menu = tk.Menu(self)
menu.add_command(label="New Session", accelerator="Ctrl+N", state=tk.DISABLED)
menu.add_command(
label="New Session",
accelerator="Ctrl+N",
command=self.app.core.create_new_session,
)
self.app.bind_all("<Control-n>", lambda e: self.app.core.create_new_session())
menu.add_command(
label="Open...", command=self.menuaction.file_open_xml, accelerator="Ctrl+O"
)
@ -104,10 +109,6 @@ class Menubar(tk.Menu):
:return: nothing
"""
menu = tk.Menu(self)
menu.add_command(label="New", state=tk.DISABLED)
menu.add_command(label="Manage...", state=tk.DISABLED)
menu.add_command(label="Delete", state=tk.DISABLED)
menu.add_separator()
menu.add_command(
label="Size/scale...", command=self.menuaction.canvas_size_and_scale
)
@ -115,6 +116,10 @@ class Menubar(tk.Menu):
label="Wallpaper...", command=self.menuaction.canvas_set_wallpaper
)
menu.add_separator()
menu.add_command(label="New", state=tk.DISABLED)
menu.add_command(label="Manage...", state=tk.DISABLED)
menu.add_command(label="Delete", state=tk.DISABLED)
menu.add_separator()
menu.add_command(label="Previous", accelerator="PgUp", state=tk.DISABLED)
menu.add_command(label="Next", accelerator="PgDown", state=tk.DISABLED)
menu.add_command(label="First", accelerator="Home", state=tk.DISABLED)