Пример #1
0
 def __init__(self, portinghacks=None):
     self.profiles = None
     self.selected_profile = None
     self.dirty = False
     self.portinghacks = portinghacks
     self.imagedir = 'external/commotion_mesh_applet/'
     self.mesh_status = MeshStatus(self.portinghacks,
                                   imagedir=self.imagedir)
     self.commotion = WindowsCommotionCore(
         profiledir="".join([core.get_own_path('/profiles/'), "/"]),
         #TODO: are these even needed?
         olsrdpath=core.olsrd_exe_path,
         olsrdconf=core.olsrd_conf_path)
     if not is_ui_test_mode(): core.refresh_net_list()
     self.profiles = self.read_profiles()
     self.init_ui()
Пример #2
0
 def __init__(self, portinghacks=None):
     self.profiles = None
     self.selected_profile = None
     self.dirty = False
     self.portinghacks = portinghacks
     self.imagedir = 'external/commotion_mesh_applet/'
     self.mesh_status = MeshStatus(self.portinghacks, imagedir=self.imagedir)
     self.commotion = WindowsCommotionCore(
             profiledir="".join([core.get_own_path('/profiles/'), "/"]),
             #TODO: are these even needed?
             olsrdpath=core.olsrd_exe_path,
             olsrdconf=core.olsrd_conf_path
             )
     if not is_ui_test_mode(): core.refresh_net_list()
     self.profiles = self.read_profiles()
     self.init_ui()
Пример #3
0
class WinMeshUI:
    def __init__(self, portinghacks=None):
        self.profiles = None
        self.selected_profile = None
        self.dirty = False
        self.portinghacks = portinghacks
        self.imagedir = 'external/commotion_mesh_applet/'
        self.mesh_status = MeshStatus(self.portinghacks, imagedir=self.imagedir)
        self.commotion = WindowsCommotionCore(
                profiledir="".join([core.get_own_path('/profiles/'), "/"]),
                #TODO: are these even needed?
                olsrdpath=core.olsrd_exe_path,
                olsrdconf=core.olsrd_conf_path
                )
        if not is_ui_test_mode(): core.refresh_net_list()
        self.profiles = self.read_profiles()
        self.init_ui()
        

    def main(self):
        gtk.gdk.threads_init()
        gtk.main()

    def toggle_start(self, button, textview):
        if button.get_active():
            if self.selected_profile is not None:
                button.set_label(strings.TOGGLE_TEXT_STOP)

                self.olsrd_proc = core.connect_or_start_profiled_mesh(
                        self.selected_profile)

                #glib.io_add_watch(self.olsr_proc.stdout, # FILE DESCRIPTOR
                #                  glib.IO_IN,  # CONDITION
                #                  self.write_to_buffer ) # CALLBACK

                self.olsrd_thread = OlsrdThread(self.olsrd_proc)
                self.olsrd_thread.setDaemon(True)
                #self.olsrd_thread.start()
        else:
            button.set_label(strings.TOGGLE_TEXT_START)
            self.shutdown()

    def _profile_selection_made(self, clist, row, col, event, data=None):
        text = clist.get_text(row, 1)  #FIXME: hard coded column for name
        print "profile selection made: %s" % text
        self.selected_profile = self.profiles[text]
        self.display_profile_in_editor(self.profiles[text])
        self.set_dirty_state(False)
        
    def profile_selection_made(self, clist, row, col, event, data=None):
        #if (self.dirty):
        #    print "WARN USER: you will lose changes if you click away"
        #    message = gtk.MessageDialog(type=gtk.MESSAGE_ERROR, buttons=gtk.BUTTONS_OK)
    	#    message.set_markup("You will lose changes if you click away.")
    	#    message.run()
        #    pass # FIXME warn the user they will lose changes
        # TODO how do i reset the selection to the previous if they cancel?
        #       probably we just have to call clist.select_row?
        #else:
            self._profile_selection_made(clist, row, col, event, data)
            
    def save_profile_clicked(self, button):
        # FIXME update profile object and call updateProfile in commotionc
        self.update_profile_from_editor(self.selected_profile)
        self.commotion.updateProfile(self.get_selected_profile_name(), self.selected_profile)
        self.set_dirty_state(False)

    def undo_changes_clicked(self, button):
        self.display_profile_in_editor(self.selected_profile)
        self.set_dirty_state(False)

    def display_profile_in_editor(self, profile):
        self.tbSSID.set_text(profile["ssid"])
        self.tbBSSID.set_text(profile["bssid"])
        self.tbChannel.set_text(profile["channel"])
        self.tbIP.set_text(profile["ip"])
        self.cbIPGenerate.set_active((profile["ipgenerate"] == "true"))
        self.tbNetmask.set_text(profile["netmask"])
        self.tbDNS.set_text(profile["dns"])

    def update_profile_from_editor(self, profile):
        profile["ssid"] = self.tbSSID.get_text()
        profile["bssid"] = self.tbBSSID.get_text()
        profile["channel"] = self.tbChannel.get_text()
        profile["ip"] = self.tbIP.get_text()
        profile["ipgenerate"] = "true" if self.cbIPGenerate.get_active() else "false"
        profile["netmask"] = self.tbNetmask.get_text()
        profile["dns"] = self.tbDNS.get_text()

    def kill_olsrd(self):
        try: 
            self.olsrd_proc.terminate()
        except:
            pass

        try: 
            self.olsrd_thread.stop = True
        except: 
            pass

    def write_to_buffer(self, fd, condition):
        if condition == glib.IO_IN: #IF THERE'S SOMETHING INTERESTING TO READ
            char = fd.read(1) # WE READ ONE BYTE PER TIME, TO AVOID BLOCKING
            print char           
            #buf = self.get_buffer()
            #buf.insert_at_cursor(char) # WHEN RUNNING DON'T TOUCH THE TEXTVIEW!!
            return True # FUNDAMENTAL, OTHERWISE THE CALLBACK ISN'T RECALLED
        else:
            return False # RAISED AN ERROR: EXIT AND I DON'T WANT TO SEE YOU ANYMORE


    def shutdown(self):
        self.kill_olsrd()
        core.apply_rollback_params()
        #core.shutdown_and_cleanup_network_gui()

    def close_application(self, widget):
        self.shutdown()
        gtk.main_quit()

    def show_mesh_status(self, widget):
        self.mesh_status.show()

    def show_jsoninfo(self, widget):
        try: 
            url = "http://*****:*****@" if v["available"] else "", k])
        clist.set_column_width(0, 10)
        clist.set_column_width(1, 190)
        clist.set_shadow_type(gtk.SHADOW_OUT)
        clist.connect("select_row", self.profile_selection_made)
        clist.show()
        hbox.pack_start(clist, expand=False, fill=False, padding=0)
        hbox.show()

        def get_profile_editor_controls():
            def add_item(b, l, t):
                l.set_alignment(0, 0)
                b.pack_start(l, expand=False, fill=False, padding=0)
                b.pack_start(t, expand=False, fill=False, padding=0)

            vbox = gtk.VBox(False, 10)

            label = gtk.Label("Mesh Netword Name (SSID):")
            self.tbSSID = gtk.Entry()
            self.tbSSID.connect("changed", self.changed)
            add_item(vbox, label, self.tbSSID)

            label = gtk.Label("BSSID:")
            self.tbBSSID = gtk.Entry()
            self.tbBSSID.connect("changed", self.changed)
            add_item(vbox, label, self.tbBSSID)

            label = gtk.Label("Channel:")
            self.tbChannel = gtk.Entry()
            self.tbChannel.connect("changed", self.changed)
            add_item(vbox, label, self.tbChannel)

            label = gtk.Label("IP:")
            self.tbIP = gtk.Entry()
            self.tbIP.connect("changed", self.changed)
            add_item(vbox, label, self.tbIP)

            label = gtk.Label("IPGenerate:")
            self.cbIPGenerate = gtk.CheckButton()
            self.cbIPGenerate.connect("toggled", self.changed)
            add_item(vbox, label, self.cbIPGenerate)

            label = gtk.Label("Netmask:")
            self.tbNetmask = gtk.Entry()
            self.tbNetmask.connect("changed", self.changed)
            add_item(vbox, label, self.tbNetmask)

            label = gtk.Label("DNS:")
            self.tbDNS = gtk.Entry()
            self.tbDNS.connect("changed", self.changed)
            add_item(vbox, label, self.tbDNS)
            
            hbox = gtk.HBox(False, 10)
            self.save_button = gtk.Button("Save Profile")
            self.save_button.set_sensitive(False)
            self.save_button.connect("clicked", self.save_profile_clicked)
            hbox.pack_start(self.save_button)

            self.undo_changes_button = gtk.Button("Undo Changes")
            self.undo_changes_button.set_sensitive(False)
            self.undo_changes_button.connect("clicked", self.undo_changes_clicked)
            hbox.pack_start(self.undo_changes_button)

            vbox.pack_end(hbox, expand=False, fill=False, padding=0)

            vbox.show_all()
            
            # load first profile        
            clist.select_row(0, 0)

            return vbox

        vbox_profile_controls = get_profile_editor_controls()
        hbox.pack_start(vbox_profile_controls, expand=True, fill=True, padding=10)
        hbox.show()

        TAB_IMAGE_WIDTH = 40
        TAB_IMAGE_HEIGHT = 40

        pixbuf = gtk.gdk.pixbuf_new_from_file(
                core.get_own_path(os.path.join('images', 'tabProfiles.png')))
        pixbuf = pixbuf.scale_simple(TAB_IMAGE_WIDTH, TAB_IMAGE_HEIGHT, gtk.gdk.INTERP_BILINEAR)
        image = gtk.image_new_from_pixbuf(pixbuf)
        image.show()
        
        add_page(notebook, "Profiles", image, hbox)

        pixbuf = gtk.gdk.pixbuf_new_from_file(
                core.get_own_path(os.path.join('images', 'tabLog.png')))
        pixbuf = pixbuf.scale_simple(TAB_IMAGE_WIDTH, TAB_IMAGE_HEIGHT, gtk.gdk.INTERP_BILINEAR)
        image = gtk.image_new_from_pixbuf(pixbuf)
        image.show()

        """
        vbox = gtk.VBox(False, 10)
        vbox.pack_start(self.textview, True, True, 0)
        button = gtk.Button("show jsoninfo")
        button.connect("clicked", self.show_jsoninfo)
        vbox.pack_start(button, True, True, 0)
        button.show()
        vbox.show()
        add_page(notebook, "Logs", image, vbox)
        """
        add_page(notebook, "Logs", image, self.textview)

        pixbuf = gtk.gdk.pixbuf_new_from_file(
                core.get_own_path(os.path.join('images', 'tabStatus.png')))
        pixbuf = pixbuf.scale_simple(TAB_IMAGE_WIDTH, TAB_IMAGE_HEIGHT, gtk.gdk.INTERP_BILINEAR)
        image = gtk.image_new_from_pixbuf(pixbuf)
        image.show()
        label = gtk.Label("Status goes here...")
        label.show()
        add_page(notebook, "Status", image, label)

        pixbuf = gtk.gdk.pixbuf_new_from_file(
                core.get_own_path(os.path.join('images', 'tabHelp.png')))
        pixbuf = pixbuf.scale_simple(TAB_IMAGE_WIDTH, TAB_IMAGE_HEIGHT, gtk.gdk.INTERP_BILINEAR)
        image = gtk.image_new_from_pixbuf(pixbuf)
        image.show()

        vbox = gtk.VBox(False, 10)

        logo_pixbuf = gtk.gdk.pixbuf_new_from_file(
                core.get_own_path(os.path.join('images', 'commotion_logo.png')))
        logo = gtk.image_new_from_pixbuf(logo_pixbuf)
        logo.show()
        vbox.pack_start(logo)

        blurb = gtk.Label("Commotion is an open-source communication tool that uses mobile phones, computers, and other wireless devices to create decentralized mesh networks.")
        blurb.set_line_wrap(True)
        blurb.show()
        vbox.pack_start(blurb)

        link = gtk.LinkButton("https://commotionwireless.net/", "commotionwireless.net") 
        link.show()
        vbox.pack_start(link)

        vbox.show()
            
        add_page(notebook, "About", image, vbox)

        vbox = gtk.VBox(False, 10)

        box2.pack_start(notebook)

        string = "\n"
        self.textbuffer.set_text(string)

        hbox = gtk.HButtonBox()
        box2.pack_start(hbox, False, False, 0)
        hbox.show()

        vbox = gtk.VBox()
        vbox.show()
        hbox.pack_start(vbox, expand=False, fill=False, padding=0)

        # check button to start up commotion
        check = gtk.ToggleButton(strings.TOGGLE_TEXT_START)
        vbox.pack_start(check, expand=False, fill=False, padding=0)
        check.connect("toggled", self.toggle_start, self.textview)
        check.set_active(False)
        check.show()

        separator = gtk.HSeparator()
        box1.pack_start(separator, False, True, 0)
        separator.show()

        box2 = gtk.HBox(False, 10)
        box2.set_border_width(10)
        box1.pack_start(box2, False, True, 0)
        box2.show()
        
        button = gtk.Button("show mesh status")
        button.connect("clicked", self.show_mesh_status)
        box2.pack_start(button, True, True, 0)
        button.show()
        
        button = gtk.Button("show jsoninfo")
        button.connect("clicked", self.show_jsoninfo)
        box2.pack_start(button, True, True, 0)
        button.show()

        button = gtk.Button("quit winmesh")
        button.connect("clicked", self.close_application)
        box2.pack_start(button, True, True, 0)
        button.set_flags(gtk.CAN_DEFAULT)
        button.grab_default()
        button.show()

        window.show()
Пример #4
0
class WinMeshUI:
    def __init__(self, portinghacks=None):
        self.profiles = None
        self.selected_profile = None
        self.dirty = False
        self.portinghacks = portinghacks
        self.imagedir = 'external/commotion_mesh_applet/'
        self.mesh_status = MeshStatus(self.portinghacks,
                                      imagedir=self.imagedir)
        self.commotion = WindowsCommotionCore(
            profiledir="".join([core.get_own_path('/profiles/'), "/"]),
            #TODO: are these even needed?
            olsrdpath=core.olsrd_exe_path,
            olsrdconf=core.olsrd_conf_path)
        if not is_ui_test_mode(): core.refresh_net_list()
        self.profiles = self.read_profiles()
        self.init_ui()

    def main(self):
        gtk.gdk.threads_init()
        gtk.main()

    def toggle_start(self, button, textview):
        if button.get_active():
            if self.selected_profile is not None:
                button.set_label(strings.TOGGLE_TEXT_STOP)

                self.olsrd_proc = core.connect_or_start_profiled_mesh(
                    self.selected_profile)

                #glib.io_add_watch(self.olsr_proc.stdout, # FILE DESCRIPTOR
                #                  glib.IO_IN,  # CONDITION
                #                  self.write_to_buffer ) # CALLBACK

                self.olsrd_thread = OlsrdThread(self.olsrd_proc)
                self.olsrd_thread.setDaemon(True)
                #self.olsrd_thread.start()
        else:
            button.set_label(strings.TOGGLE_TEXT_START)
            self.shutdown()

    def _profile_selection_made(self, clist, row, col, event, data=None):
        text = clist.get_text(row, 1)  #FIXME: hard coded column for name
        print "profile selection made: %s" % text
        self.selected_profile = self.profiles[text]
        self.display_profile_in_editor(self.profiles[text])
        self.set_dirty_state(False)

    def profile_selection_made(self, clist, row, col, event, data=None):
        #if (self.dirty):
        #    print "WARN USER: you will lose changes if you click away"
        #    message = gtk.MessageDialog(type=gtk.MESSAGE_ERROR, buttons=gtk.BUTTONS_OK)
        #    message.set_markup("You will lose changes if you click away.")
        #    message.run()
        #    pass # FIXME warn the user they will lose changes
        # TODO how do i reset the selection to the previous if they cancel?
        #       probably we just have to call clist.select_row?
        #else:
        self._profile_selection_made(clist, row, col, event, data)

    def save_profile_clicked(self, button):
        # FIXME update profile object and call updateProfile in commotionc
        self.update_profile_from_editor(self.selected_profile)
        self.commotion.updateProfile(self.get_selected_profile_name(),
                                     self.selected_profile)
        self.set_dirty_state(False)

    def undo_changes_clicked(self, button):
        self.display_profile_in_editor(self.selected_profile)
        self.set_dirty_state(False)

    def display_profile_in_editor(self, profile):
        self.tbSSID.set_text(profile["ssid"])
        self.tbBSSID.set_text(profile["bssid"])
        self.tbChannel.set_text(profile["channel"])
        self.tbIP.set_text(profile["ip"])
        self.cbIPGenerate.set_active((profile["ipgenerate"] == "true"))
        self.tbNetmask.set_text(profile["netmask"])
        self.tbDNS.set_text(profile["dns"])

    def update_profile_from_editor(self, profile):
        profile["ssid"] = self.tbSSID.get_text()
        profile["bssid"] = self.tbBSSID.get_text()
        profile["channel"] = self.tbChannel.get_text()
        profile["ip"] = self.tbIP.get_text()
        profile["ipgenerate"] = "true" if self.cbIPGenerate.get_active(
        ) else "false"
        profile["netmask"] = self.tbNetmask.get_text()
        profile["dns"] = self.tbDNS.get_text()

    def kill_olsrd(self):
        try:
            self.olsrd_proc.terminate()
        except:
            pass

        try:
            self.olsrd_thread.stop = True
        except:
            pass

    def write_to_buffer(self, fd, condition):
        if condition == glib.IO_IN:  #IF THERE'S SOMETHING INTERESTING TO READ
            char = fd.read(1)  # WE READ ONE BYTE PER TIME, TO AVOID BLOCKING
            print char
            #buf = self.get_buffer()
            #buf.insert_at_cursor(char) # WHEN RUNNING DON'T TOUCH THE TEXTVIEW!!
            return True  # FUNDAMENTAL, OTHERWISE THE CALLBACK ISN'T RECALLED
        else:
            return False  # RAISED AN ERROR: EXIT AND I DON'T WANT TO SEE YOU ANYMORE

    def shutdown(self):
        self.kill_olsrd()
        core.apply_rollback_params()
        #core.shutdown_and_cleanup_network_gui()

    def close_application(self, widget):
        self.shutdown()
        gtk.main_quit()

    def show_mesh_status(self, widget):
        self.mesh_status.show()

    def show_jsoninfo(self, widget):
        try:
            url = "http://*****:*****@" if v["available"] else "", k])
        clist.set_column_width(0, 10)
        clist.set_column_width(1, 190)
        clist.set_shadow_type(gtk.SHADOW_OUT)
        clist.connect("select_row", self.profile_selection_made)
        clist.show()
        hbox.pack_start(clist, expand=False, fill=False, padding=0)
        hbox.show()

        def get_profile_editor_controls():
            def add_item(b, l, t):
                l.set_alignment(0, 0)
                b.pack_start(l, expand=False, fill=False, padding=0)
                b.pack_start(t, expand=False, fill=False, padding=0)

            vbox = gtk.VBox(False, 10)

            label = gtk.Label("Mesh Netword Name (SSID):")
            self.tbSSID = gtk.Entry()
            self.tbSSID.connect("changed", self.changed)
            add_item(vbox, label, self.tbSSID)

            label = gtk.Label("BSSID:")
            self.tbBSSID = gtk.Entry()
            self.tbBSSID.connect("changed", self.changed)
            add_item(vbox, label, self.tbBSSID)

            label = gtk.Label("Channel:")
            self.tbChannel = gtk.Entry()
            self.tbChannel.connect("changed", self.changed)
            add_item(vbox, label, self.tbChannel)

            label = gtk.Label("IP:")
            self.tbIP = gtk.Entry()
            self.tbIP.connect("changed", self.changed)
            add_item(vbox, label, self.tbIP)

            label = gtk.Label("IPGenerate:")
            self.cbIPGenerate = gtk.CheckButton()
            self.cbIPGenerate.connect("toggled", self.changed)
            add_item(vbox, label, self.cbIPGenerate)

            label = gtk.Label("Netmask:")
            self.tbNetmask = gtk.Entry()
            self.tbNetmask.connect("changed", self.changed)
            add_item(vbox, label, self.tbNetmask)

            label = gtk.Label("DNS:")
            self.tbDNS = gtk.Entry()
            self.tbDNS.connect("changed", self.changed)
            add_item(vbox, label, self.tbDNS)

            hbox = gtk.HBox(False, 10)
            self.save_button = gtk.Button("Save Profile")
            self.save_button.set_sensitive(False)
            self.save_button.connect("clicked", self.save_profile_clicked)
            hbox.pack_start(self.save_button)

            self.undo_changes_button = gtk.Button("Undo Changes")
            self.undo_changes_button.set_sensitive(False)
            self.undo_changes_button.connect("clicked",
                                             self.undo_changes_clicked)
            hbox.pack_start(self.undo_changes_button)

            vbox.pack_end(hbox, expand=False, fill=False, padding=0)

            vbox.show_all()

            # load first profile
            clist.select_row(0, 0)

            return vbox

        vbox_profile_controls = get_profile_editor_controls()
        hbox.pack_start(vbox_profile_controls,
                        expand=True,
                        fill=True,
                        padding=10)
        hbox.show()

        TAB_IMAGE_WIDTH = 40
        TAB_IMAGE_HEIGHT = 40

        pixbuf = gtk.gdk.pixbuf_new_from_file(
            core.get_own_path(os.path.join('images', 'tabProfiles.png')))
        pixbuf = pixbuf.scale_simple(TAB_IMAGE_WIDTH, TAB_IMAGE_HEIGHT,
                                     gtk.gdk.INTERP_BILINEAR)
        image = gtk.image_new_from_pixbuf(pixbuf)
        image.show()

        add_page(notebook, "Profiles", image, hbox)

        pixbuf = gtk.gdk.pixbuf_new_from_file(
            core.get_own_path(os.path.join('images', 'tabLog.png')))
        pixbuf = pixbuf.scale_simple(TAB_IMAGE_WIDTH, TAB_IMAGE_HEIGHT,
                                     gtk.gdk.INTERP_BILINEAR)
        image = gtk.image_new_from_pixbuf(pixbuf)
        image.show()
        """
        vbox = gtk.VBox(False, 10)
        vbox.pack_start(self.textview, True, True, 0)
        button = gtk.Button("show jsoninfo")
        button.connect("clicked", self.show_jsoninfo)
        vbox.pack_start(button, True, True, 0)
        button.show()
        vbox.show()
        add_page(notebook, "Logs", image, vbox)
        """
        add_page(notebook, "Logs", image, self.textview)

        pixbuf = gtk.gdk.pixbuf_new_from_file(
            core.get_own_path(os.path.join('images', 'tabStatus.png')))
        pixbuf = pixbuf.scale_simple(TAB_IMAGE_WIDTH, TAB_IMAGE_HEIGHT,
                                     gtk.gdk.INTERP_BILINEAR)
        image = gtk.image_new_from_pixbuf(pixbuf)
        image.show()
        label = gtk.Label("Status goes here...")
        label.show()
        add_page(notebook, "Status", image, label)

        pixbuf = gtk.gdk.pixbuf_new_from_file(
            core.get_own_path(os.path.join('images', 'tabHelp.png')))
        pixbuf = pixbuf.scale_simple(TAB_IMAGE_WIDTH, TAB_IMAGE_HEIGHT,
                                     gtk.gdk.INTERP_BILINEAR)
        image = gtk.image_new_from_pixbuf(pixbuf)
        image.show()

        vbox = gtk.VBox(False, 10)

        logo_pixbuf = gtk.gdk.pixbuf_new_from_file(
            core.get_own_path(os.path.join('images', 'commotion_logo.png')))
        logo = gtk.image_new_from_pixbuf(logo_pixbuf)
        logo.show()
        vbox.pack_start(logo)

        blurb = gtk.Label(
            "Commotion is an open-source communication tool that uses mobile phones, computers, and other wireless devices to create decentralized mesh networks."
        )
        blurb.set_line_wrap(True)
        blurb.show()
        vbox.pack_start(blurb)

        link = gtk.LinkButton("https://commotionwireless.net/",
                              "commotionwireless.net")
        link.show()
        vbox.pack_start(link)

        vbox.show()

        add_page(notebook, "About", image, vbox)

        vbox = gtk.VBox(False, 10)

        box2.pack_start(notebook)

        string = "\n"
        self.textbuffer.set_text(string)

        hbox = gtk.HButtonBox()
        box2.pack_start(hbox, False, False, 0)
        hbox.show()

        vbox = gtk.VBox()
        vbox.show()
        hbox.pack_start(vbox, expand=False, fill=False, padding=0)

        # check button to start up commotion
        check = gtk.ToggleButton(strings.TOGGLE_TEXT_START)
        vbox.pack_start(check, expand=False, fill=False, padding=0)
        check.connect("toggled", self.toggle_start, self.textview)
        check.set_active(False)
        check.show()

        separator = gtk.HSeparator()
        box1.pack_start(separator, False, True, 0)
        separator.show()

        box2 = gtk.HBox(False, 10)
        box2.set_border_width(10)
        box1.pack_start(box2, False, True, 0)
        box2.show()

        button = gtk.Button("show mesh status")
        button.connect("clicked", self.show_mesh_status)
        box2.pack_start(button, True, True, 0)
        button.show()

        button = gtk.Button("show jsoninfo")
        button.connect("clicked", self.show_jsoninfo)
        box2.pack_start(button, True, True, 0)
        button.show()

        button = gtk.Button("quit winmesh")
        button.connect("clicked", self.close_application)
        box2.pack_start(button, True, True, 0)
        button.set_flags(gtk.CAN_DEFAULT)
        button.grab_default()
        button.show()

        window.show()