def on_action_host_expand_activate(self, action): """Expand the selected host and show the associations""" selected_row = get_treeview_selected_row(self.ui.tvw_connections) if (selected_row and self.is_selected_row_host()): tree_path = self.model_hosts.get_path(selected_row) if not self.ui.tvw_connections.row_expanded(tree_path): self.ui.tvw_connections.expand_row(tree_path, False)
def on_action_edit_activate(self, action): """Edit the selected service""" selected_row = get_treeview_selected_row(self.ui.tvw_services) if selected_row: name = self.model.get_key(selected_row) description = self.model.get_description(selected_row) command = self.model.get_command(selected_row) terminal = self.model.get_terminal(selected_row) icon = self.model.get_icon(selected_row) selected_iter = self.model.get_iter(name) dialog = UIServiceDetail(self.ui.dialog_services, self.model) if dialog.show(default_name=name, default_description=description, default_command=command, default_terminal=terminal, default_icon=icon, title=_('Edit service'), treeiter=selected_iter) == Gtk.ResponseType.OK: # Update values self.model.set_data( selected_iter, ServiceInfo(name=dialog.name, description=dialog.description, command=dialog.command, terminal=dialog.terminal, icon=dialog.icon)) dialog.destroy()
def on_action_host_collapse_activate(self, action): """Collapse the selected host and hide the associations""" selected_row = get_treeview_selected_row(self.ui.tvw_connections) if (selected_row and self.is_selected_row_host()): tree_path = self.model_hosts.get_path(selected_row) if self.ui.tvw_connections.row_expanded(tree_path): self.ui.tvw_connections.collapse_row(tree_path)
def on_action_edit_activate(self, action): """Edit the selected service""" selected_row = get_treeview_selected_row(self.ui.tvw_services) if selected_row: name = self.model.get_key(selected_row) description = self.model.get_description(selected_row) command = self.model.get_command(selected_row) terminal = self.model.get_terminal(selected_row) icon = self.model.get_icon(selected_row) selected_iter = self.model.get_iter(name) dialog = UIServiceDetail(self.ui.dialog_services, self.model) if dialog.show(default_name=name, default_description=description, default_command=command, default_terminal=terminal, default_icon=icon, title=_('Edit service'), treeiter=selected_iter ) == Gtk.ResponseType.OK: # Update values self.model.set_data(selected_iter, ServiceInfo( name=dialog.name, description=dialog.description, command=dialog.command, terminal=dialog.terminal, icon=dialog.icon)) dialog.destroy()
def on_action_group_next_activate(self, action): """Move to the next group""" selected_row = get_treeview_selected_row(self.ui.tvw_groups) new_iter = self.model_groups.model.iter_next(selected_row) if new_iter: # Select the newly selected row in the groups list new_path = self.model_groups.get_path(new_iter) self.ui.tvw_groups.set_cursor(new_path)
def on_tvw_connections_row_activated(self, widget, treepath, column): """Edit the selected row on activation""" selected_row = get_treeview_selected_row(self.ui.tvw_connections) if selected_row and self.is_selected_row_host(): # Start host edit self.ui.action_edit.activate() else: # Connect to the destination self.ui.action_connect.activate()
def on_action_edit_activate(self, action): """Edit the selected service""" selected_row = get_treeview_selected_row(self.ui.tvw_arguments) if selected_row: argument = self.model_arguments[selected_row][0] dialog = UICommandArgument(self.ui.dialog_arguments) if dialog.show(default_value=argument) == Gtk.ResponseType.OK: # Update values self.model_arguments.set_value(selected_row, 0, dialog.argument) dialog.destroy()
def on_tvw_connections_key_press_event(self, widget, event): """Expand and collapse nodes with keyboard arrows""" if event.keyval in (Gdk.KEY_Left, Gdk.KEY_Right): # Collapse or expand the selected row using <Left> and <Right> selected_row = get_treeview_selected_row(self.ui.tvw_connections) if (selected_row and self.is_selected_row_host()): if event.keyval == Gdk.KEY_Left: self.ui.action_host_collapse.activate() elif event.keyval == Gdk.KEY_Right: self.ui.action_host_expand.activate() return True
def on_action_associations_remove_activate(self, action): """Remove the selected destination""" selected_row = get_treeview_selected_row(self.ui.tvw_associations) if selected_row and show_message_dialog( class_=UIMessageDialogNoYes, parent=self.ui.dialog_host, message_type=Gtk.MessageType.QUESTION, title=None, msg1=_("Remove association"), msg2=_("Remove the selected association?"), is_response_id=Gtk.ResponseType.YES): self.model_associations.remove(selected_row)
def on_action_remove_activate(self, action): """Remove the selected service""" selected_row = get_treeview_selected_row(self.ui.tvw_services) if selected_row and show_message_dialog( class_=UIMessageDialogNoYes, parent=self.ui.dialog_services, message_type=Gtk.MessageType.WARNING, title=None, msg1=_("Remove service"), msg2=_("Remove the selected service?"), is_response_id=Gtk.ResponseType.YES): self.model.remove(selected_row)
def on_action_delete_activate(self, action): """Remove the selected host""" selected_row = get_treeview_selected_row(self.ui.tvw_connections) if selected_row and show_message_dialog( class_=UIMessageDialogNoYes, parent=self.ui.win_main, message_type=Gtk.MessageType.QUESTION, title=None, msg1=_("Remove host"), msg2=_("Remove the selected host?"), is_response_id=Gtk.ResponseType.YES): self.remove_host(self.model_hosts.get_key(selected_row))
def on_action_remove_activate(self, action): """Remove the selected service""" selected_row = get_treeview_selected_row(self.ui.tvw_arguments) if selected_row and show_message_dialog( class_=UIMessageDialogNoYes, parent=self.ui.dialog_arguments, message_type=Gtk.MessageType.WARNING, title=None, msg1=_("Remove argument"), msg2=_("Remove the selected argument?"), is_response_id=Gtk.ResponseType.YES): self.model_arguments.remove(selected_row)
def on_action_connect_activate(self, action): """Establish the connection for the destination""" selected_row = get_treeview_selected_row(self.ui.tvw_connections) if selected_row and not self.is_selected_row_host(): host = self.hosts[self.model_hosts.get_key( self.ui.store_hosts.iter_parent(selected_row))] destination_name = self.model_hosts.get_key(selected_row) destination = host.destinations[destination_name] description = self.model_hosts.get_association(selected_row) service_name = self.model_hosts.get_service(selected_row) service_arguments = self.model_hosts.get_arguments(selected_row) arguments = json.loads(service_arguments) association = host.find_association(description=description, destination=destination.name, service=service_name, arguments=arguments) if service_name in model_services.services: service = model_services.services[service_name] command = service.command # Prepares the arguments arguments_map = {} arguments_map['address'] = destination.value for key in association.service_arguments: arguments_map[key] = association.service_arguments[key] # Execute command try: command = command.format(**arguments_map) processes.processes.add_process(host, destination, service, command) except KeyError as error: # An error occurred processing the command error_msg1 = _('Connection open failed') error_msg2 = _('An error occurred processing the ' 'service command.') show_message_dialog(class_=UIMessageDialogClose, parent=self.ui.win_main, message_type=Gtk.MessageType.ERROR, title=None, msg1=error_msg1, msg2=error_msg2, is_response_id=None) debug.add_error(error_msg2) debug.add_error('Host: "%s"' % host.name) debug.add_error('Destination name: "%s"' % destination.name) debug.add_error('Destination value: "%s"' % destination.value) debug.add_error('Service: %s' % service.name), debug.add_error('Command: "%s"' % command) else: debug.add_warning('service %s not found' % service_name)
def on_tvw_processes_row_activated(self, widget, treepath, column): """Expand or collapse the selected row""" selected_row = get_treeview_selected_row(self.ui.tvw_processes) if selected_row: iter_parent = self.ui.store_processes.iter_parent(selected_row) selected_path = self.model.model[selected_row].path # Get the path of the process if iter_parent is None: tree_path = self.model.model[selected_row].path expanded = self.ui.tvw_processes.row_expanded(tree_path) if expanded: self.ui.tvw_processes.collapse_row(tree_path) else: self.ui.tvw_processes.expand_row(tree_path, True)
def on_action_destinations_edit_activate(self, action): """Edit the selected destination""" selected_row = get_treeview_selected_row(self.ui.tvw_destinations) if selected_row: name = self.model_destinations.get_key(selected_row) value = self.model_destinations.get_value(selected_row) selected_iter = self.model_destinations.get_iter(name) dialog = UIDestination(self.ui.dialog_host, self.model_destinations) if dialog.show(default_name=name, default_value=value, title=_('Edit destination'), treeiter=selected_iter) == Gtk.ResponseType.OK: # Update values self.model_destinations.set_data( selected_iter, DestinationInfo(name=dialog.name, value=dialog.value)) dialog.destroy()
def on_action_process_activate(self, action): """Execute an action for the selected process""" selected_row = get_treeview_selected_row(self.ui.tvw_processes) if selected_row: iter_parent = self.model.model.iter_parent(selected_row) selected_path = self.model.model[selected_row].path # Get the path of the process if iter_parent is None: tree_path = self.model.model[selected_row].path else: tree_path = self.model.model[iter_parent].path # selected_key = self.model.get_key(tree_path) if selected_key in self.processes: selected_process = self.processes[selected_key] treeiter = self.model.get_iter(selected_key) if action is self.ui.action_kill: # Resume the process and terminate it selected_process.send_signal(subprocess.signal.SIGCONT) selected_process.terminate() debug.add_info( _('The process with the PID %d was terminated') % ( selected_process.pid)) self.model.add_detail(treeiter, _('Process terminated'), 'media-playback-stop') elif action is self.ui.action_pause: # Pause the process by sending the STOP signal selected_process.send_signal(subprocess.signal.SIGSTOP) debug.add_info( _('The process with the PID %d was paused') % ( selected_process.pid)) self.model.add_detail(treeiter, _('Process paused'), 'media-playback-pause') elif action is self.ui.action_resume: # Pause the process by sending the CONT signal selected_process.send_signal(subprocess.signal.SIGCONT) debug.add_info( _('The process with the PID %d was resumed') % ( selected_process.pid)) self.model.add_detail(treeiter, _('Process resumed'), 'media-playback-start')
def on_action_services_activate(self, action): """Edit services""" selected_row = get_treeview_selected_row(self.ui.tvw_connections) if selected_row: iter_parent = self.ui.store_hosts.iter_parent(selected_row) selected_path = self.model_hosts.model[selected_row].path # Get the path of the host if iter_parent is None: tree_path = self.model_hosts.model[selected_row].path else: tree_path = self.model_hosts.model[iter_parent].path expanded = self.ui.tvw_connections.row_expanded(tree_path) dialog_services = UIServices(parent=self.ui.win_main) # Load services list dialog_services.model.load(model_services.services) dialog_services.show() # Get the new services list, clear and store the list again model_services.services = dialog_services.model.dump() dialog_services.destroy() settings.services.clear() for key in model_services.services.iterkeys(): settings.services.set( section=key, option=OPTION_SERVICE_DESCRIPTION, value=model_services.services[key].description) settings.services.set(section=key, option=OPTION_SERVICE_COMMAND, value=model_services.services[key].command) settings.services.set_boolean( section=key, option=OPTION_SERVICE_TERMINAL, value=model_services.services[key].terminal) settings.services.set(section=key, option=OPTION_SERVICE_ICON, value=model_services.services[key].icon) self.reload_hosts() if selected_row: # Automatically expand the row if it was expanded before if expanded: self.ui.tvw_connections.expand_row(tree_path, True) # Automatically select again the previously selected row self.ui.tvw_connections.set_cursor(path=selected_path, column=None, start_editing=False)
def on_action_destinations_edit_activate(self, action): """Edit the selected destination""" selected_row = get_treeview_selected_row(self.ui.tvw_destinations) if selected_row: name = self.model_destinations.get_key(selected_row) value = self.model_destinations.get_value(selected_row) selected_iter = self.model_destinations.get_iter(name) dialog = UIDestination(self.ui.dialog_host, self.model_destinations) if dialog.show(default_name=name, default_value=value, title=_('Edit destination'), treeiter=selected_iter ) == Gtk.ResponseType.OK: # Update values self.model_destinations.set_data( selected_iter, DestinationInfo(name=dialog.name, value=dialog.value)) dialog.destroy()
def on_tvw_processes_key_press_event(self, widget, event): """Expand and collapse nodes with keyboard arrows""" selected_row = get_treeview_selected_row(self.ui.tvw_processes) if selected_row and event.keyval in (Gdk.KEY_Left, Gdk.KEY_Right): iter_parent = self.ui.store_processes.iter_parent(selected_row) if selected_row and iter_parent is None: tree_path = self.model.get_path(selected_row) expanded = self.ui.tvw_processes.row_expanded(tree_path) if event.keyval == Gdk.KEY_Left and expanded: # Collapse the selected node self.ui.tvw_processes.collapse_row(tree_path) elif event.keyval == Gdk.KEY_Right and not expanded: # Expand the selected node self.ui.tvw_processes.expand_row(tree_path, False) elif event.keyval == Gdk.KEY_Menu: # Show popup menu on Menu key press event = Gdk.EventButton() event.type = Gdk.EventType.BUTTON_RELEASE event.button = Gdk.BUTTON_SECONDARY self.ui.tvw_processes.event(event)
def on_action_associations_edit_activate(self, action): """Edit the selected service association""" selected_row = get_treeview_selected_row(self.ui.tvw_associations) if selected_row: dialog = UIServiceAssociation(self.ui.dialog_host, self.model_destinations) model = self.model_associations selected_key = model.get_key(selected_row) selected_iter = model.get_iter(selected_key) if dialog.show(model.get_description(selected_row), model.get_destination_name(selected_row), model.get_service_name(selected_row), json.loads(model.get_arguments( selected_row))) == Gtk.ResponseType.OK: model.set_data(treeiter=selected_iter, description=dialog.description, destination_name=dialog.destination, service=model_services.services[dialog.service], arguments=dialog.arguments) dialog.destroy()
def on_action_associations_edit_activate(self, action): """Edit the selected service association""" selected_row = get_treeview_selected_row(self.ui.tvw_associations) if selected_row: dialog = UIServiceAssociation(self.ui.dialog_host, self.model_destinations) model = self.model_associations selected_key = model.get_key(selected_row) selected_iter = model.get_iter(selected_key) if dialog.show( model.get_description(selected_row), model.get_destination_name(selected_row), model.get_service_name(selected_row), json.loads(model.get_arguments(selected_row)) ) == Gtk.ResponseType.OK: model.set_data( treeiter=selected_iter, description=dialog.description, destination_name=dialog.destination, service=model_services.services[dialog.service], arguments=dialog.arguments) dialog.destroy()
def on_action_remove_activate(self, action): """Remove the selected group""" selected_row = get_treeview_selected_row(self.ui.tvw_groups) group_name = self.model.get_key(selected_row) if selected_row else '' if selected_row and group_name and show_message_dialog( class_=UIMessageDialogNoYes, parent=self.ui.dialog_groups, message_type=Gtk.MessageType.WARNING, title=None, msg1=_('Remove the group'), msg2=_('Remove the group «%s»?') % group_name, is_response_id=Gtk.ResponseType.YES): group_path = os.path.join(DIR_HOSTS, group_name) # Check for directory not empty if len(os.listdir(group_path)) and not show_message_dialog( class_=UIMessageDialogNoYes, parent=self.ui.dialog_groups, message_type=Gtk.MessageType.WARNING, title=None, msg1=_('The group is not empty'), msg2='%s\n%s\n\n%s' % ( text('If you delete an item, it will ' 'be permanently lost.'), _('All the hosts defined for the group will be lost.'), _('Are you sure you want to delete the ' 'group «%s»?') % group_name, ), is_response_id=Gtk.ResponseType.YES): # Exit immediately without deleting the group return # Delete all the contained files and the directory for the group for filename in os.listdir(group_path): os.remove(os.path.join(group_path, filename)) os.rmdir(group_path) debug.add_info(_('Removed the group "%s"') % group_name) self.model.remove(selected_row)
def on_tvw_connections_cursor_changed(self, widget): """Set actions sensitiveness for host and connection""" if get_treeview_selected_row(self.ui.tvw_connections): self.ui.actions_connection.set_sensitive( not self.is_selected_row_host()) self.ui.actions_host.set_sensitive(self.is_selected_row_host())
def on_tvw_groups_cursor_changed(self, widget): """Set actions sensitiveness for host and connection""" if get_treeview_selected_row(self.ui.tvw_groups): self.reload_hosts() # Automatically select the first host for the group self.ui.tvw_connections.set_cursor(0)
def get_current_group_path(self): """Return the path of the currently selected group""" selected_row = get_treeview_selected_row(self.ui.tvw_groups) group_name = self.model_groups.get_key(selected_row) if selected_row \ else '' return os.path.join(DIR_HOSTS, group_name) if group_name else DIR_HOSTS
def is_selected_row_host(self): """Return if the currently selected row is an host""" return self.ui.store_hosts.iter_parent( get_treeview_selected_row(self.ui.tvw_connections)) is None
def on_action_copy_activate(self, action): """Copy the selected host to another""" selected_row = get_treeview_selected_row(self.ui.tvw_connections) if selected_row: if self.is_selected_row_host(): # First level (host) name = self.model_hosts.get_key(selected_row) description = self.model_hosts.get_description(selected_row) selected_iter = self.model_hosts.get_iter(name) expanded = self.ui.tvw_connections.row_expanded( self.model_hosts.get_path(selected_iter)) dialog = UIHost(parent=self.ui.win_main, hosts=self.model_hosts) # Restore the destinations for the selected host destinations = self.hosts[name].destinations for destination_name in destinations: destination = destinations[destination_name] dialog.model_destinations.add_data(destination) # Restore the associations for the selected host for association in self.hosts[name].associations: service_name = association.service_name if service_name in model_services.services: dialog.model_associations.add_data( index=dialog.model_associations.count(), name=association.destination_name, description=association.description, service=model_services.services[service_name], arguments=association.service_arguments) else: debug.add_warning('service %s not found' % service_name) # Show the edit host dialog response = dialog.show(default_name=_('Copy of %s') % name, default_description='', title=_('Copy host'), treeiter=None) if response == Gtk.ResponseType.OK: destinations = dialog.model_destinations.dump() associations = dialog.model_associations.dump() host = HostInfo(dialog.name, dialog.description) # Set the associations for values in associations: (destination_name, description, service_name, service_arguments) = associations[values] destination = destinations[destination_name] arguments = json.loads(service_arguments) host.add_association(description=description, destination_name=destination_name, service_name=service_name, arguments=arguments) self.add_host(host=host, destinations=destinations, update_settings=True) # Get the path of the host tree_path = self.model_hosts.get_path_by_name(dialog.name) # Automatically select again the previously selected host self.ui.tvw_connections.set_cursor(path=tree_path, column=None, start_editing=False) # Automatically expand the row if it was expanded before if expanded: self.ui.tvw_connections.expand_row(tree_path, False) # Collapse the duplicated row self.ui.tvw_connections.collapse_row( self.model_hosts.get_path(selected_iter))