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 __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()
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()
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()