예제 #1
0
    def sort_by(self, tree: ttk.Treeview, col, descending):
        # Sort tree contents when a column is clicked on.
        # grab values to sort
        data = [(tree.set(child, col), child)
                for child in tree.get_children('')]
        # reorder data
        if data and all([self.is_float(element[0]) for element in data]):
            data.sort(reverse=descending, key=self.my_func)
        else:
            data.sort(reverse=descending)
        num = 'Even'
        for indx, item in enumerate(data):
            tree.move(item[1], '', indx)

            if bool(self.row_color) is True:
                if num == 'Even':
                    tree.item(item[1], tags=('evenrow', ))
                    num = 'Odd'
                elif num == 'Odd':
                    tree.item(item[1], tags=('oddrow', ))
                    num = 'Even'
            else:
                pass
        if self.row_color is True:
            tree.tag_configure('evenrow', background='#FFF')
            tree.tag_configure('oddrow', background='#EAECEE')
        else:
            pass

        # switch the heading so that it will sort in the opposite direction
        tree.heading(col,
                     command=lambda col=col: self.sort_by(
                         tree, col, int(not descending)))
예제 #2
0
class MainWindow(Frame):

    def __init__(self, parent):
        Frame.__init__(self, parent)
        self.treeview = None
        self.createui()
        self.loadtable()
        self.grid(sticky=(N, S, W, E))
        parent.grid_rowconfigure(0, weight=1)
        parent.grid_columnconfigure(0, weight=1)

    def createui(self):
        image = Image.open('header.png')
        photo = ImageTk.PhotoImage(image)
        lbl = Label(self, image=photo)
        lbl.image = photo
        lbl.grid(row=0, column=0, columnspan=2, sticky='ns')
        self.treeview = Treeview(self)
        self.treeview['columns'] = ['title']
        self.treeview.heading("#0", text='Repeticiones', anchor='center')
        self.treeview.column("#0", anchor="center", width=90)
        self.treeview.heading('title', text='Titulo', anchor='w')
        self.treeview.column('title', anchor='w', width=700)
        self.treeview.grid(sticky=(N, S, W, E))
        self.treeview.bind("<Double-1>", self.openlink)
        ysb = Scrollbar(self, width=18, orient='vertical', command=self.treeview.yview)
        ysb.grid(row=1, column=1, sticky='ns')
        self.treeview.configure(yscroll=ysb.set)
        self.grid_rowconfigure(1, weight=1)
        self.grid_columnconfigure(0, weight=1)

    def openlink(self, event):
        item = self.treeview.identify('item', event.x, event.y)
        web = self.treeview.item(item, 'values')[1]
        webbrowser.open_new(web)

    def loadtable(self):
        self.treeview.delete(*self.treeview.get_children())
        sorted_x = sorted(dic.items(), key=lambda x: x[1][1], reverse=True)
        for key, value in sorted_x:
            self.treeview.insert('', 'end', text=str(value[1]), values=[value[0], key])
예제 #3
0
class Multicolumn_Listbox(object):
    _style_index = 0

    class List_Of_Rows(object):
        def __init__(self, multicolumn_listbox):
            self._multicolumn_listbox = multicolumn_listbox

        def data(self, index):
            return self._multicolumn_listbox.row_data(index)
            
        def get(self, index):
            return Row(self._multicolumn_listbox, index)

        def insert(self, data, index=None):
            self._multicolumn_listbox.insert_row(data, index)

        def delete(self, index):
            self._multicolumn_listbox.delete_row(index)

        def update(self, index, data):
            self._multicolumn_listbox.update_row(index, data)

        def select(self, index):
            self._multicolumn_listbox.select_row(index)

        def deselect(self, index):
            self._multicolumn_listbox.deselect_row(index)

        def set_selection(self, indices):
            self._multicolumn_listbox.set_selection(indices)

        def __getitem__(self, index): 
            return self.get(index)

        def __setitem__(self, index, value): 
            return self._multicolumn_listbox.update_row(index, value)

        def __delitem__(self, index): 
            self._multicolumn_listbox.delete_row(index)

        def __len__(self): 
            return self._multicolumn_listbox.number_of_rows

    class List_Of_Columns(object):
        def __init__(self, multicolumn_listbox):
            self._multicolumn_listbox = multicolumn_listbox
        
        def data(self, index):
            return self._multicolumn_listbox.get_column(index)

        def get(self, index):
            return Column(self._multicolumn_listbox, index)

        def delete(self, index):
            self._multicolumn_listbox.delete_column(index)

        def update(self, index, data):
            self._multicolumn_listbox.update_column(index, data)

        def __getitem__(self, index): 
            return self.get(index)

        def __setitem__(self, index, value): 
            return self._multicolumn_listbox.update_column(index, value)

        def __delitem__(self, index): 
            self._multicolumn_listbox.delete_column(index)

        def __len__(self): 
            return self._multicolumn_listbox.number_of_columns

    def __init__(self, master, columns, data=None, command=None, sort=True, select_mode=None, heading_anchor = CENTER, cell_anchor=W, style=None, height=None, padding=None, adjust_heading_to_content=False, stripped_rows=None, selection_background=None, selection_foreground=None, field_background=None, heading_font= None, heading_background=None, heading_foreground=None, cell_pady=2, cell_background=None, cell_foreground=None, cell_font=None, headers=True):

        self._stripped_rows = stripped_rows

        self._columns = columns
        
        self._number_of_rows = 0
        self._number_of_columns = len(columns)
        
        self.row = self.List_Of_Rows(self)
        self.column = self.List_Of_Columns(self)
        
        s = Style()

        if style is None:
            style_name = "Multicolumn_Listbox%s.Treeview"%self._style_index
            self._style_index += 1
        else:
            style_name = style
        
        style_map = {}
        if selection_background is not None:
            style_map["background"] = [('selected', selection_background)]
            
        if selection_foreground is not None:
            style_map["foeground"] = [('selected', selection_foreground)]

        if style_map:
            s.map(style_name, **style_map)

        style_config = {}
        if cell_background is not None:
            style_config["background"] = cell_background

        if cell_foreground is not None:
            style_config["foreground"] = cell_foreground

        if cell_font is None:
            font_name = s.lookup(style_name, "font")
            cell_font = nametofont(font_name)
        else:
            if not isinstance(cell_font, Font):
                if isinstance(cell_font, basestring):
                    cell_font = nametofont(cell_font)
                else:
                    if len(font) == 1:
                        cell_font = Font(family=cell_font[0])
                    elif len(font) == 2:
                        cell_font = Font(family=cell_font[0], size=cell_font[1])
                        
                    elif len(font) == 3:
                        cell_font = Font(family=cell_font[0], size=cell_font[1], weight=cell_font[2])
                    else:
                        raise ValueError("Not possible more than 3 values for font")
        
            style_config["font"] = cell_font
        
        self._cell_font = cell_font

        self._rowheight = cell_font.metrics("linespace")+cell_pady
        style_config["rowheight"]=self._rowheight

        if field_background is not None:
            style_config["fieldbackground"] = field_background

        s.configure(style_name, **style_config)

        heading_style_config = {}
        if heading_font is not None:
            heading_style_config["font"] = heading_font
        if heading_background is not None:
            heading_style_config["background"] = heading_background
        if heading_foreground is not None:
            heading_style_config["foreground"] = heading_foreground

        heading_style_name = style_name + ".Heading"
        s.configure(heading_style_name, **heading_style_config)

        treeview_kwargs = {"style": style_name}

        if height is not None:
            treeview_kwargs["height"] = height
            
        if padding is not None:
            treeview_kwargs["padding"] = padding
            
        if headers:
            treeview_kwargs["show"] = "headings"
        else:
            treeview_kwargs["show"] = ""
        
        if select_mode is not None:
            treeview_kwargs["selectmode"] = select_mode

        self.interior = Treeview(master, columns=columns, **treeview_kwargs)
        
        if command is not None:
            self._command = command
            self.interior.bind("<<TreeviewSelect>>", self._on_select)

        for i in range(0, self._number_of_columns):

            if sort:
                self.interior.heading(i, text=columns[i], anchor=heading_anchor, command=lambda col=i: self.sort_by(col, descending=False))
            else:
                self.interior.heading(i, text=columns[i], anchor=heading_anchor)
                
            if adjust_heading_to_content:
                self.interior.column(i, width=Font().measure(columns[i]))

            self.interior.column(i, anchor=cell_anchor)
            
        if data is not None:
            for row in data:
                self.insert_row(row)

    @property
    def row_height(self):
        return self._rowheight
        
    @property
    def font(self):
        return self._cell_font

    def configure_column(self, index, width=None, minwidth=None, anchor=None, stretch=None):
        kwargs = {}
        for config_name in ("width", "anchor", "stretch", "minwidth"):
            config_value = locals()[config_name]
            if config_value is not None:
                kwargs[config_name] = config_value
            
        self.interior.column('#%s'%(index+1), **kwargs)

    def row_data(self, index):
        try:
            item_ID = self.interior.get_children()[index]
        except IndexError:
            raise ValueError("Row index out of range: %d"%index)        

        return self.item_ID_to_row_data(item_ID)

    def update_row(self, index, data):
        try:
            item_ID = self.interior.get_children()[index]
        except IndexError:
            raise ValueError("Row index out of range: %d"%index)
            
        if len(data) == len(self._columns):
            self.interior.item(item_ID, values=data)
        else:
            raise ValueError("The multicolumn listbox has only %d columns"%self._number_of_columns)

    def delete_row(self, index):
        list_of_items = self.interior.get_children()

        try:
            item_ID = list_of_items[index]
        except IndexError:
            raise ValueError("Row index out of range: %d"%index)

        self.interior.delete(item_ID)
        self._number_of_rows -= 1
        
        if self._stripped_rows:
            for i in range(index, self._number_of_rows):
                self.interior.tag_configure(list_of_items[i+1], background=self._stripped_rows[i%2])
            
    def insert_row(self, data, index=None):
        if len(data) != self._number_of_columns:
            raise ValueError("The multicolumn listbox has only %d columns"%self._number_of_columns)
        
        if index is None:
            index = self._number_of_rows-1

        item_ID = self.interior.insert('', index, values=data)        
        self.interior.item(item_ID, tags=item_ID)

        self._number_of_rows += 1        

        if self._stripped_rows:            
            list_of_items = self.interior.get_children()

            self.interior.tag_configure(item_ID, background=self._stripped_rows[index%2])

            for i in range(index+1, self._number_of_rows):
                self.interior.tag_configure(list_of_items[i], background=self._stripped_rows[i%2])

    def column_data(self, index):
        return [self.interior.set(child_ID, index) for child_ID in self.interior.get_children('')]

    def update_column(self, index, data):
        for i, item_ID in enumerate(self.interior.get_children()): 
            data_row = self.item_ID_to_row_data(item_ID)
            data_row[index] = data[i]

            self.interior.item(item_ID, values=data_row)

        return data

    def clear(self):
        # Another possibility:
        #  self.interior.delete(*self.interior.get_children())

        for row in self.interior.get_children():
            self.interior.delete(row)
            
        self._number_of_rows = 0
            
    def update(self, data):
        self.clear()

        for row in data:
            self.insert_row(row)
            
    def focus(self, index=None):
        if index is None:
            return self.interior.item(self.interior.focus())
        else:
            item = self.interior.get_children()[index]
            self.interior.focus(item)

    def state(self, state=None):
        if stateSpec is None:
            return self.interior.state()
        else:
            self.interior.state(state)

    @property
    def number_of_rows(self):
        return self._number_of_rows
        
    @property
    def number_of_columns(self):
        return self._number_of_columns
        
    def toogle_selection(self, index):
        list_of_items = self.interior.get_children()
        
        try:
            item_ID = list_of_items[index]
        except IndexError:
            raise ValueError("Row index out of range: %d"%index)

        self.interior.selection_toggle(item_ID)     

    def select_row(self, index):
        list_of_items = self.interior.get_children()
        
        try:
            item_ID = list_of_items[index]
        except IndexError:
            raise ValueError("Row index out of range: %d"%index)

        self.interior.selection_add(item_ID)

    def deselect_row(self, index):
        list_of_items = self.interior.get_children()
        
        try:
            item_ID = list_of_items[index]
        except IndexError:
            raise ValueError("Row index out of range: %d"%index)

        self.interior.selection_remove(item_ID)
        
    def deselect_all(self):
        self.interior.selection_remove(self.interior.selection())

    def set_selection(self, indices):
        list_of_items = self.interior.get_children()

        self.interior.selection_set(" ".join(list_of_items[row_index] for row_index in indices))

    @property
    def selected_rows(self):
        data = []
        for item_ID in self.interior.selection():
            data_row = self.item_ID_to_row_data(item_ID)
            data.append(data_row)
        
        return data

    @property
    def indices_of_selected_rows(self):
        list_of_indices = []
        for index, item_ID in enumerate(self.interior.get_children()):
            if item_ID in self.interior.selection():
                list_of_indices.append(index)

        return list_of_indices
        
    def delete_all_selected_rows(self):
        selected_items = self.interior.selection()
        for item_ID in selected_items:
            self.interior.delete(item_ID)
        
        number_of_deleted_rows = len(selected_items)
        self._number_of_rows -= number_of_deleted_rows

        return number_of_deleted_rows

    def _on_select(self, event):
        for item_ID in event.widget.selection():
            data_row = self.item_ID_to_row_data(item_ID)
            self._command(data_row)

    def item_ID_to_row_data(self, item_ID):
        item = self.interior.item(item_ID)
        return item["values"]
    
    @property
    def table_data(self):
        data = []

        for item_ID in self.interior.get_children():
            data_row = self.item_ID_to_row_data(item_ID)
            data.append(data_row)

        return data
    
    @table_data.setter
    def table_data(self, data):
        self.update(data)
    
    def cell_data(self, row, column):
        """Get the value of a table cell"""
        try:
            item = self.interior.get_children()[row]
        except IndexError:
            raise ValueError("Row index out of range: %d"%row)
            
        return self.interior.set(item, column)
            
    def update_cell(self, row, column, value):
        """Set the value of a table cell"""

        item_ID = self.interior.get_children()[row]
        
        data = self.item_ID_to_row_data(item_ID)
        
        data[column] = value
        self.interior.item(item_ID, values=data)
    
    def __getitem__(self, index):
        if isinstance(index, tuple):
            row, column = index
            return self.cell_data(row, column)
        else:
            raise Exception("Row and column indices are required")
        
    def __setitem__(self, index, value):
        if isinstance(index, tuple):
            row, column = index
            self.update_cell(row, column, value)
        else:
            raise Exception("Row and column indices are required")

    def bind(self, event, handler):
        self.interior.bind(event, handler)

    def sort_by(self, col, descending):
        """
        sort tree contents when a column header is clicked
        """
        # grab values to sort
        data = [(self.interior.set(child_ID, col), child_ID) for child_ID in self.interior.get_children('')]
        
        # if the data to be sorted is numeric change to float
        try:
            data = [(float(number), child_ID) for number, child_ID in data]
        except ValueError:
            pass

        # now sort the data in place
        data.sort(reverse=descending)
        for idx, item in enumerate(data):
            self.interior.move(item[1], '', idx)

        # switch the heading so that it will sort in the opposite direction
        self.interior.heading(col, command=lambda col=col: self.sort_by(col, not descending))
        
        if self._stripped_rows:
            list_of_items = self.interior.get_children('')
            for i in range(len(list_of_items)):
                self.interior.tag_configure(list_of_items[i], background=self._stripped_rows[i%2])

    def destroy(self):
        self.interior.destroy()
        
    def item_ID(self, index):
        return self.interior.get_children()[index]
class Example(Frame):
    def __init__(self):
        Frame.__init__(self)
        self.style = Style()
        self.style.theme_use("default")
        self.master.title("Log viewer")
        self.pack(fill=BOTH, expand=True)

        self.used = []  # List of currently plotted series ([str])
        self.series = {}  # List of all series ({str -> [number]})
        self.names = []  # List of all nodes in tree view ([str])
        self.queues = [] # List of all queues ([str])
        self.logs = {} # List of all text logs ({str -> [str]})

        self.rowconfigure(1, weight=1)
        self.columnconfigure(6, weight=3)
        self.columnconfigure(11, weight=1)

        # Series selection takes row 1-2, col 0-2
        self.series_ui = Treeview(self)
        self.series_ui.grid(row=1, column=0, columnspan=2, rowspan=2, sticky=N+S)
        self.series_ui.configure(show="tree")
        self.series_ui.bind("<Double-Button-1>", self.onselect)
        self.series_ui.tag_configure("graphall", foreground="#070")
        self.series_ui.tag_configure("graphnone", foreground="#000")
        self.series_ui.tag_configure("graphsome", foreground="#007")
        series_ui_scroll = Scrollbar(self, command=self.series_ui.yview, orient=VERTICAL)
        series_ui_scroll.grid(row=1, column=2, rowspan=2, sticky=N+S)
        self.series_ui["yscrollcommand"] = series_ui_scroll.set

        # The plot takes row 1-2, col 3-6
        move_mode = StringVar()
        move_mode.set("pan")
        show_path = IntVar()
        show_path.set(0)
        event_bars = IntVar()
        event_bars.set(1)
        show_debug = IntVar()
        show_debug.set(1)
        show_error = IntVar()
        show_error.set(1)
        show_warning = IntVar()
        show_warning.set(1)
        show_info = IntVar()
        show_info.set(1)
        self.plot = HackPlot(self, move_mode, show_path, event_bars,
                [(show_debug, "[DEBUG]"), (show_error, "[ERROR]"), (show_warning, "[WARNING]"), (show_info, "[INFO]")])
        self.plot.canvas.grid(row=1, column=3, columnspan=4, rowspan=2, sticky=N+S+E+W)
        # Text logs take row 1-2, col 7-12
        self.plot.listbox.grid(row=1, column=7, columnspan=5, sticky=N+S+E+W)
        listbox_yscroll = Scrollbar(self, command=self.plot.listbox.yview, orient=VERTICAL)
        listbox_yscroll.grid(row=1, column=12, sticky=N+S)
        self.plot.listbox["yscrollcommand"] = listbox_yscroll.set
        listbox_xscroll = Scrollbar(self, command=self.plot.listbox.xview, orient=HORIZONTAL)
        listbox_xscroll.grid(row=2, column=7, columnspan=5, sticky=E+W)
        self.plot.listbox["xscrollcommand"] = listbox_xscroll.set


        # Controls take row 0, col 0-12
        Button(self, text="Load Directory", command=self.loaddir).grid(row=0, column=0)
        Button(self, text="Load File", command=self.loadfile).grid(row=0, column=1)
        Button(self, text="Fit X", command=self.plot.fit_x).grid(row=0, column=3, sticky=W)
        Button(self, text="Fit Y", command=self.plot.fit_y).grid(row=0, column=4, sticky=W)
        Button(self, text="Fit Auto", command=self.plot.fit_auto).grid(row=0, column=5, sticky=W)
        Button(self, text="Fit Tele", command=self.plot.fit_tele).grid(row=0, column=6, sticky=W)
        # Plot controls in a subframe to manage padding so it doesn't look awful
        move_mode_control = Frame(self, padx=10)
        Radiobutton(move_mode_control, text="Pan", value="pan", variable=move_mode).grid(row=0, column=0, sticky=W)
        Radiobutton(move_mode_control, text="Zoom In", value="zoomin", variable=move_mode).grid(row=0, column=1, sticky=W)
        Radiobutton(move_mode_control, text="Zoom Out", value="zoomout", variable=move_mode).grid(row=0, column=2, sticky=W)
        move_mode_control.grid(row=0, column=7, sticky=W)
        Checkbutton(self, text="Event Bars", variable=event_bars, command=self.plot.show_textlogs).grid(row=0, column=8, sticky=W)
        Checkbutton(self, text="Debug", variable=show_debug, command=self.plot.show_textlogs).grid(row=0, column=9, sticky=W)
        Checkbutton(self, text="Error", variable=show_error, command=self.plot.show_textlogs).grid(row=0, column=10, sticky=W)
        Checkbutton(self, text="Warning", variable=show_warning, command=self.plot.show_textlogs).grid(row=0, column=11, sticky=W)
        Checkbutton(self, text="Info", variable=show_info, command=self.plot.show_textlogs).grid(row=0, column=12, sticky=W)
        Checkbutton(self, text="Directories", variable=show_path, command=self.plot.show_textlogs).grid(row=0, column=13, sticky=E)

    # Open Directory button clicked
    def loaddir(self):
        dirname = tkFileDialog.askdirectory(initialdir=log_dir)
        if dirname != "" and dirname != (): # Cancel and (x) not pressed
            # Empty the data
            self.used = []
            self.series = {}
            self.names = []
            self.queues = []
            self.logs = {}
            self.plot.reset()
            for node in self.series_ui.get_children():
                self.series_ui.delete(node)
            # For every csv file in the directory, checking recursively and alphabetically
            for subdirname, subsubdirnames, filenames in os.walk(dirname):
                subsubdirnames.sort()
                filenames.sort()
                for filename in filenames:
                    if filename.endswith(".csv") or filename.endswith(".log"):
                        # The name of the directory without the name of the directory selected,
                        # and the name of the file without the extension, separated by "."s
                        # For example if directory selected is /tmp/logs, subdirname is /tmp/logs/beta/666,
                        # and filename is foo.csv, nodeprefix is "beta.666.foo".
                        nodeprefix = ".".join(subdirname[len(dirname)+1:].split("/") + [filename[:-4]])
                        if nodeprefix.startswith("."):
                            nodeprefix = nodeprefix[1:]
                        # Add the file's data
                        self.readfile(subdirname + "/" + filename, nodeprefix)
            for name in self.names:
                # Add name to (name with everything after last dot removed), as the last child,
                # with text (everything after last dot of name) and tags graphnone and (whether name represents data)
                self.series_ui.insert(".".join(name.split(".")[0:-1]), "end", name,
                        text=name.split(".")[-1], tags=["graphnone"])

    # Open File button clicked
    def loadfile(self):
        filename = tkFileDialog.askopenfilename(filetypes=[("CSV Files", "*.csv"), ("Text log file", "*.log")], initialdir=log_dir)
        if filename != "" and filename != (): # Cancel and (x) not pressed
            # Empty the data
            self.used = []
            self.series = {}
            self.names = []
            self.queues = []
            self.logs = {}
            self.plot.reset()
            for node in self.series_ui.get_children():
                self.series_ui.delete(node)
            # Add the file's data
            self.readfile(filename, "")
            for name in self.names:
                # Add name to (name with everything after last dot removed), as the last child,
                # with text (everything after last dot of name) and tags graphnone and (whether name represents data)
                self.series_ui.insert(".".join(name.split(".")[0:-1]), "end", name,
                        text=name.split(".")[-1], tags=["graphnone"])

    # Add a file's data
    # nodeprefix is a string to add before every name in the file, represents file's name in the tree
    def readfile(self, filename, nodeprefix):
        try:
            if filename.endswith(".csv"):
                # For csv files this will always be concatenated with something
                if nodeprefix != "":
                    nodeprefix += "."
                csvfile = open(filename, "rb")
                reader = csv.DictReader(csvfile)
                series = {}
                self.queues.append(nodeprefix[:-1])
                for name in reader.fieldnames:
                    # Add ancestor_names to names, without creating duplicates
                    self.names = list(OrderedDict.fromkeys(self.names + ancestor_names(nodeprefix + name)))
                    # Create a series for this field
                    series[nodeprefix + name] = []
                for row in reader:
                    for name in reader.fieldnames:
                        try:
                            # Add cell to series if it represents a number
                            series[nodeprefix + name].append(float(row[name]))
                        except ValueError:
                            # Not a number, no problem, could be game_specific_string or something
                            pass
                self.series.update(series)
            else:
                self.names.append(nodeprefix)
                self.logs[nodeprefix] = open(filename, "r").readlines()
        except IOError:
            tkMessageBox.showerror(message="Could not open file: " + str(filename))

    # Tree element was double clicked
    def onselect(self, _):
        series = self.series_ui.focus()
        # Set it to graph if no children are graphed, and not to graph if all or some are
        self.setgraphed(series, self.series_ui.tag_has("graphnone", series))
        self.checkgraphed(series)

    # Set a node and its children to be either all or none graphed
    def setgraphed(self, node, shouldgraph):
        if shouldgraph:
            self.series_ui.item(node, tags=["graphall"])
            # If the node represents data and it isn't already graphed, graph it
            if node in self.series and node not in self.used:
                self.used.append(node)
                # Timestamp is queue that contains node + ".timestamp"
                timestamp_name = [queue for queue in self.queues if node.startswith(queue)][0] + ".timestamp"
                self.plot.add_plot(self.series[timestamp_name], self.series[node], node)
            if node in self.logs and node not in self.used:
                self.used.append(node)
                self.plot.add_textlog(self.logs[node], node)
            # If nothing else is plotted, fit the plot to this
            if len(self.used) == 1:
                self.plot.fit_x()
                self.plot.fit_y()
            for child in self.series_ui.get_children(node):
                self.setgraphed(child, True)
        else:
            # Set tags to be (whether node represents data) and graphnone
            self.series_ui.item(node, tags=["graphnone"])
            if node in self.used:
                self.used.remove(node)
                if node in self.logs:
                    self.plot.remove_textlog(node)
                if node in self.series:
                    self.plot.remove_plot(node)
            for child in self.series_ui.get_children(node):
                self.setgraphed(child, False)

    # Update the tags (and color) on a node and its ancestors, should always be called after setgraphed
    def checkgraphed(self, node):
        # Top level nodes are children of ""
        if node == "":
            return
        # True unless a child doesn't share this tag or there are no children
        graphall = True
        graphnone = True
        for child in self.series_ui.get_children(node):
            if not self.series_ui.tag_has("graphall", child):
                graphall = False
            if not self.series_ui.tag_has("graphnone", child):
                graphnone = False
        graphtag = ""
        if graphall and graphnone:
            # There are no children, check the used list instead
            graphtag = "graphall" if node in self.used else "graphnone"
        elif graphall:
            graphtag = "graphall"
        elif graphnone:
            graphtag = "graphnone"
        else:
            graphtag = "graphsome"
        # Set tags to be (whether node represents data) and the computed status
        self.series_ui.item(node, tags=[graphtag])
        # Now that the status of this node is known, check the parent
        self.checkgraphed(self.series_ui.parent(node))
예제 #5
0
파일: main.py 프로젝트: polmp/basesdades
class App(object):
    def __init__(self, root, cursor, db):
        self.frame = Frame(root)
        self.frame.configure(background='white')
        self.list_toplevel = {}
        self.cursor = cursor
        self.db = db
        self.child_toplevel = None
        self.frame.pack()
        image = Image.open("photo.jpg")
        image = image.resize((250, 250), Image.ANTIALIAS)
        photo = ImageTk.PhotoImage(image)
        label = Label(self.frame, image=photo)
        label.grid(row=0, column=0, sticky=W)
        label.image = photo  # keep a reference!
        nou_registre = LabelFrame(self.frame,
                                  text="Nou registre",
                                  fg="Blue",
                                  padx=5,
                                  pady=5)
        nou_registre.configure(background='white')
        nou_registre.grid(row=0, column=1, padx=15, sticky=W)

        text_nom = Label(nou_registre, text="Nom:", fg="Blue")
        text_nom.configure(background='white')
        text_nom.grid(row=0, column=0)
        self.entry_nom = Entry(nou_registre)
        self.entry_nom.grid(row=0, column=1, sticky=W)

        text_telefon = Label(nou_registre, text="Telèfon: ", fg="Blue")
        text_telefon.configure(background='white')
        text_telefon.grid(row=1, column=0)
        self.entry_telefon = Entry(nou_registre)
        self.entry_telefon.grid(row=1, column=1)

        text_email = Label(nou_registre, text="Email: ", fg="Blue")
        text_email.configure(background='white')
        text_email.grid(row=2, column=0)
        self.entry_email = Entry(nou_registre)
        self.entry_email.grid(row=2, column=1)

        button_afegir_contacte = Button(nou_registre,
                                        text="Afegir contacte",
                                        fg="Blue",
                                        command=self.afegeix_contacte)
        button_afegir_contacte.grid(row=3, column=1, sticky=E)

        button_mostra_historic = Button(nou_registre,
                                        text="Mostra historic",
                                        fg="Blue",
                                        command=self.mostra_historic)
        button_mostra_historic.grid(row=4, column=0, sticky=W)

        mostrar_contactes = Button(self.frame,
                                   text="Mostrar contactes",
                                   fg="Blue",
                                   command=self.insert_contacts_treeview)
        mostrar_contactes.grid(sticky=W, row=3)

        self.missatge_error_confirmacio = StringVar()

        self.label_error_confirmacio = Label(
            self.frame, textvariable=self.missatge_error_confirmacio, fg="Red")
        self.label_error_confirmacio.configure(background='white')
        self.label_error_confirmacio.grid(sticky=W, row=3, column=1)

        self.agenda_contactes = Treeview(self.frame,
                                         columns=["nom", "tel"],
                                         show="headings")
        self.agenda_contactes.heading("nom", text="Nom")
        self.agenda_contactes.heading("tel", text="Telefon")
        self.agenda_contactes.column("nom",
                                     minwidth=0,
                                     width=200,
                                     stretch=NO,
                                     anchor="c")
        self.agenda_contactes.column("tel",
                                     minwidth=0,
                                     width=200,
                                     stretch=NO,
                                     anchor="c")
        self.agenda_contactes.grid(row=4, column=0, padx=0, columnspan=2)

        self.insert_contacts_treeview()
        elimina_seleccionat = Button(self.frame,
                                     text="Eliminar seleccionat",
                                     command=self.elimina_contacte,
                                     fg="Blue")
        elimina_seleccionat.grid(row=5, column=0, sticky=W)

        self.modificar_seleccionat = Button(self.frame,
                                            text="Modificar seleccionat",
                                            fg="Blue",
                                            command=self.modifica_contacte)
        self.modificar_seleccionat.grid(row=5, column=1, sticky=W)
        sortir = Button(self.frame,
                        text="Sortir",
                        fg="Blue",
                        command=self.frame.quit)
        sortir.grid(row=5, column=2, sticky=E)

    def mostra_historic(self):
        popup = Toplevel()
        agenda_historic = Treeview(
            popup,
            columns=["nom", "tel", "email", "path", "accio", "data"],
            show="headings")
        agenda_historic.heading("nom", text="Nom")
        agenda_historic.heading("tel", text="Telefon")
        agenda_historic.heading("email", text="Email")
        agenda_historic.heading("path", text="Path")
        agenda_historic.heading("accio", text="Acció")
        agenda_historic.heading("data", text="Data")
        agenda_historic.column("nom",
                               minwidth=0,
                               width=150,
                               stretch=True,
                               anchor="c")
        agenda_historic.column("tel",
                               minwidth=0,
                               width=100,
                               stretch=True,
                               anchor="c")
        agenda_historic.column("email",
                               minwidth=0,
                               width=150,
                               stretch=True,
                               anchor="c")
        agenda_historic.column("path",
                               minwidth=0,
                               width=200,
                               stretch=True,
                               anchor="c")
        agenda_historic.column("accio",
                               minwidth=0,
                               width=100,
                               stretch=True,
                               anchor="c")
        agenda_historic.column("data",
                               minwidth=0,
                               width=150,
                               stretch=True,
                               anchor="c")
        agenda_historic.grid(row=0, column=0, padx=5, pady=5)
        self.cursor.execute("select * from HISTORIC ORDER BY data DESC;")
        dades = self.cursor.fetchall()
        for data_usuari in dades:
            agenda_historic.insert('', 'end', values=data_usuari)

    def insert_contacts_treeview(self):
        self.cursor.execute("select * from CONTACTES order by nom ASC;")
        self.agenda_contactes.delete(*self.agenda_contactes.get_children())
        for i in self.cursor.fetchall():
            self.agenda_contactes.insert('', 'end', values=i[:2])

    def show_image(self, imatge_label, path_imatge=''):
        file_per_default = 'avatar.jpeg'
        if path_imatge == '':

            image = Image.open(file_per_default)
        else:
            if os.path.exists(path_imatge):
                try:
                    image = Image.open(path_imatge)
                except:
                    print "Error al mostrar imatge!"
                    return False
            else:
                image = Image.open(file_per_default)

        image = image.resize((120, 120), Image.ANTIALIAS)
        photo = ImageTk.PhotoImage(image)
        imatge_label.configure(image=photo)
        imatge_label.image = photo
        return True

    def edit_image(self, imatge_label, path_imatge, nom, telefon):
        if os.path.isfile(path_imatge):
            try:
                image = Image.open(path_imatge)
            except:
                self.missatge_error_confirmacio.set("Imatge incorrecte!")

            else:
                try:
                    self.cursor.execute(
                        "UPDATE CONTACTES SET foto=:pathfoto where nom=:nom and telf=:telf",
                        {
                            'pathfoto': path_imatge,
                            'nom': nom,
                            'telf': str(telefon)
                        })
                    self.db.commit()
                except:
                    self.missatge_error_confirmacio.set(
                        "Error actualitzant la imatge!")
                    return False

        self.show_image(imatge_label, path_imatge)

    def demana_imatge(self, imatge_label, nom, telefon):
        t = tkFileDialog.askopenfilename(title="Selecciona foto",
                                         filetypes=(("jpg files", "*.jpg"),
                                                    ("jpeg files", "*.jpeg"),
                                                    ("all files", "*.*")))
        if t:
            self.edit_image(imatge_label, t, nom, telefon)

    def modificar_contacte(self, entries_fixed, entries_variable,
                           treeview_seleccionat):
        #print dades_usuari
        nom_fixed = entries_fixed[0]
        telefon_fixed = entries_fixed[1]
        email_fixed = entries_fixed[2]

        telefon_variable = entries_variable[0]
        email_variable = entries_variable[1]

        valor_text_telefon_antic = entries_fixed[3]
        valor_text_email_antic = entries_fixed[4]

        changed_email = False
        changed_tel = False
        if email_variable.get() != '':
            try:
                self.check_email(email_variable.get())
            except:
                self.missatge_error_confirmacio.set("El mail no és correcte!")
            else:
                self.cursor.execute(
                    "UPDATE CONTACTES SET email=:email where nom=:nom and telf=:telf",
                    {
                        'email': email_variable.get(),
                        'nom': nom_fixed.get(),
                        'telf': str(telefon_fixed.get())
                    })
                valor_text_email_antic.set(email_variable.get())
                changed_email = True

        if telefon_variable.get() != '':
            try:
                assert int(telefon_variable.get()) >= 600000000
            except:
                self.missatge_error_confirmacio.set("Error en el telefon!")
            else:
                try:
                    self.cursor.execute(
                        "UPDATE CONTACTES SET telf=:nou_telf where nom=:nom and telf=:telf",
                        {
                            'nou_telf': telefon_variable.get(),
                            'nom': nom_fixed.get(),
                            'telf': str(telefon_fixed.get())
                        })
                except sqlite3.IntegrityError:
                    self.missatge_error_confirmacio.set(
                        "El telèfon ja està registrat!")
                else:
                    changed_tel = True
                    self.agenda_contactes.item(treeview_seleccionat,
                                               values=(nom_fixed.get(),
                                                       telefon_variable.get()))
                    valor_text_telefon_antic.set(telefon_variable.get())

        self.db.commit()
        if changed_email & changed_tel:
            self.missatge_error_confirmacio.set(
                "Dades modificades correctament!")
        elif changed_email:
            self.missatge_error_confirmacio.set(
                "Email modificat correctament!")
        elif changed_tel:
            self.missatge_error_confirmacio.set(
                "Telefon modificat correctament!")

    def modifica_contacte(self):
        if self.child_toplevel is not None:
            self.child_toplevel.destroy()

        element_a_modificar = self.agenda_contactes.focus()
        valor_usuari = self.agenda_contactes.item(
            element_a_modificar)['values']
        self.cursor.execute("select * from CONTACTES where nom=? and telf=?;",
                            tuple(valor_usuari))
        dades = self.cursor.fetchone()
        t = Toplevel()
        self.child_toplevel = t

        label_imatge = Label(t)
        label_imatge.configure(background='white')
        label_imatge.pack(side="left", fill="both", expand=True)
        self.show_image(label_imatge, dades[3])
        frame_info = Frame(t)
        frame_info.pack(side="right", fill="both", expand=False)
        frame_info.configure(background='white')
        label_nom = Label(frame_info, text="Nom: ")
        label_nom.configure(background='white')
        label_nom.grid(row=0, column=0)
        entry_nom = Entry(frame_info,
                          textvariable=StringVar(frame_info, value=dades[0]),
                          width=20,
                          state='disabled')
        entry_nom.grid(row=0, column=1)
        label_telefon = Label(frame_info, text="Telefon antic: ")
        label_telefon.configure(background='white')
        label_telefon.grid(row=1, column=0)
        text_telefon = StringVar(frame_info, value=dades[1])
        entry_telefon = Entry(frame_info,
                              textvariable=text_telefon,
                              width=20,
                              state='disabled')
        entry_telefon.grid(row=1, column=1)

        label_telefon_nou = Label(frame_info, text="Telefon nou: ")
        label_telefon_nou.configure(background='white')
        label_telefon_nou.grid(row=2, column=0)
        entry_telefon_nou = Entry(frame_info, width=20)
        entry_telefon_nou.grid(row=2, column=1)

        label_email = Label(frame_info, text="Email: ")
        label_email.configure(background='white')
        label_email.grid(row=3, column=0)
        text_email = StringVar(frame_info, value=dades[2])  #-----
        entry_email = Entry(frame_info,
                            width=20,
                            textvariable=text_email,
                            state='disabled')
        entry_email.grid(row=3, column=1)
        label_email_nou = Label(frame_info, text="Email nou:")
        label_email_nou.configure(background='white')
        label_email_nou.grid(row=4, column=0)
        entry_email_nou = Entry(frame_info, width=20)
        entry_email_nou.grid(row=4, column=1)

        selecciona_imatge = Button(
            frame_info,
            text="Edita foto",
            command=lambda: self.demana_imatge(label_imatge, dades[0],
                                               text_telefon.get()))
        selecciona_imatge.grid(row=5)
        button_modifica_contacte = Button(
            frame_info,
            text="Modificar contacte",
            fg="Blue",
            command=lambda: self.modificar_contacte([
                entry_nom, entry_telefon, entry_email, text_telefon, text_email
            ], [entry_telefon_nou, entry_email_nou], element_a_modificar))
        button_modifica_contacte.grid(row=6, column=1, sticky=E)

    def check_email(self, email):
        if re.match("(^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$)",
                    email):
            return True
        else:
            raise "Mail no vàlid!"

    def elimina_contacte(self):
        element_seleccionat = self.agenda_contactes.focus()
        if element_seleccionat != '':
            informacio_contacte = self.agenda_contactes.item(
                element_seleccionat)['values']
            self.cursor.execute("DELETE from CONTACTES where nom=? and telf=?",
                                tuple(informacio_contacte))
            self.db.commit()
            self.agenda_contactes.delete(element_seleccionat)
            self.missatge_error_confirmacio.set("Borrat correctament")
            if self.child_toplevel is not None:
                self.child_toplevel.destroy()
            #print self.agenda_contactes.focus()
            #print self.agenda_contactes.selection()
        else:
            self.missatge_error_confirmacio.set("Selecciona un usuari!")
            print "Selecciona element"

    def afegeix_contacte(self):
        try:
            Nom = self.entry_nom.get()
            assert Nom != ''
            Telef = int(self.entry_telefon.get())
            assert Telef > 600000000
            Email = self.check_email(self.entry_email.get())

        except:
            self.missatge_error_confirmacio.set(
                "Introdueix les dades correctament!")
        else:
            try:
                self.cursor.execute(
                    """INSERT INTO CONTACTES values (?,?,?,'');""",
                    (Nom.title(), Telef, self.entry_email.get()))
                self.db.commit()
            except sqlite3.IntegrityError:
                self.missatge_error_confirmacio.set("Contacte ja existent!")

            else:
                self.insert_contacts_treeview()
                self.missatge_error_confirmacio.set(
                    "Afegit contacte correctament")
예제 #6
0
class GUIMainMenu(Frame):
    """Main menu for test of Genesi i.MX53 systems"""

    def __init__(self,master=None):
        """Initialize the base class"""
        Frame.__init__(self,master)

        """Set window title"""
        self.master.title("Select System Test")

        """System Tests"""
        self.createTestEntries()

        """Constants"""
        self.TEST_COL=0
        self.STATUS_COL=1
        self.TEXT_ROW=0
        self.TREEVIEW_ROW=1
        self.BUTTON_ROW=2

        """Display main window with padding"""
        self.grid()
        self.createWidgets()

    def createTestEntries(self):
        #TODO must be a better way. Pickle?
        self.tests = [TestInfo("Audio", AudioGUI), TestInfo("Clock", Dummy1),
                      TestInfo("Display", Dummy1), TestInfo("Keyboard", Dummy1),
                      TestInfo("Network", Dummy1), TestInfo("SSD", Dummy2),
                      TestInfo("Video", VideoGUI)]
        self.testsLookup = {}
        for te in self.tests:
            self.testsLookup.update({te.name : te})

    def createWidgets(self):
        """Create all the initial widgets for this menu"""
        """Labels"""
        lbl = Label(self, text="Select test below", justify=LEFT)
        lbl.grid(row=self.TEXT_ROW, column=self.TEST_COL)
        
        """Tests"""
        self.trv = Treeview(self, columns=("Status"), displaycolumns='#all')

        for test in self.tests:
            treeviewInsertTest(self.trv, test)

        self.trv.column('#0', width=100)
        self.trv.heading('#0', text="Test")
        self.trv.heading('Status', text='Status')

        self.trv.grid(column=self.TEST_COL, row=self.TREEVIEW_ROW,
                      columnspan=2)

        """Buttons"""
        self.btnOK = Button(self, text="OK", command=self.launchTest)
        self.btnOK.grid(row=self.BUTTON_ROW, column=0)
        self.btnQuit = Button(self, text="Quit", command=self.quit)
        self.btnQuit.grid(row=self.BUTTON_ROW, column=1)

    def launchTest(self):
        # get the item in focus
        testItem = self.trv.item(self.trv.focus())

        if not testItem['text'] == '':
            testInfo = self.testsLookup[testItem['text']]
            testInfo.launchTest(self)

    def processResults(self, testInfo):
        self.trv.item(testInfo.name, values=(testInfo.status),
                      tags=(testInfo.status))
        # update color notifications
        self.trv.tag_configure('Success', foreground='green')
        self.trv.tag_configure('Failure', foreground='red')

        self.deiconify()

    def withdraw(self):
        """Helpful function to hide window"""
        self.master.withdraw()

    def deiconify(self):
        """Helpful function to restore window"""
        self.master.deiconify()
예제 #7
0
class XML_Viwer(Frame):
    def __init__(self,
                 master,
                 xml=None,
                 heading_text=None,
                 heading_anchor=None,
                 padding=None,
                 cursor=None,
                 takefocus=None,
                 style=None):
        Frame.__init__(self, master, class_="XML_Viwer")

        self._vsb = Scrollbar(self, orient=VERTICAL)
        self._hsb = Scrollbar(self, orient=HORIZONTAL)

        kwargs = {}
        kwargs["yscrollcommand"] = lambda f, l: autoscroll(self._vsb, f, l)
        kwargs["xscrollcommand"] = lambda f, l: autoscroll(self._hsb, f, l)

        if style is not None:
            kwargs["style"] = style

        if padding is not None:
            kwargs["padding"] = padding

        if cursor is not None:
            kwargs["cursor"] = cursor

        if takefocus is not None:
            kwargs["takefocus"] = takefocus

        self._treeview = Treeview(self, **kwargs)

        if heading_text is not None:
            if heading_anchor is not None:
                self._treeview.heading("#0",
                                       text=heading_text,
                                       anchor=heading_anchor)
            else:
                self._treeview.heading("#0", text=heading_text)

        self._treeview.bind("<<TreeviewOpen>>", self._on_open)
        self._treeview.bind("<<TreeviewClose>>", self._on_close)

        # Without this line, horizontal scrolling doesn't work properly.
        self._treeview.column("#0", stretch=False)

        self._vsb['command'] = self._treeview.yview
        self._hsb['command'] = self._treeview.xview

        self._treeview.grid(column=0, row=0, sticky=N + S + W + E)
        self._vsb.grid(column=1, row=0, sticky=N + S)
        self._hsb.grid(column=0, row=1, sticky=E + W)

        self.grid_columnconfigure(0, weight=1)
        self.grid_rowconfigure(0, weight=1)

        self._element_tree = None
        self._item_ID_to_element = {}

        if xml is not None:
            self.parse_xml(xml)

    def _on_open(self, event):
        item_ID = self._treeview.focus()
        if item_ID not in self._item_ID_to_element: return

        node = self._item_ID_to_element[item_ID]

        self._treeview.item(item_ID, text=self._repr_of_openning_tag(node))

    def _on_close(self, event):
        item_ID = self._treeview.focus()
        if item_ID not in self._item_ID_to_element: return

        node = self._item_ID_to_element[item_ID]

        text = self._repr_of_openning_tag(node) + self._repr_of_closing_tag(
            node)
        self._treeview.item(item_ID, text=text)

    def parse_xml(self, xml):
        self._element_tree = ET.ElementTree(ET.fromstring(xml))

        self.clear()
        self._walk_xml(self._element_tree.getroot())

    @property
    def element_tree(self):
        return self._element_tree

    @element_tree.setter
    def element_tree(self, element_tree):
        self._element_tree = element_tree

        self.clear()
        self._walk_xml(element_tree.getroot())

    def clear(self):
        self._item_ID_to_element = {}
        self._treeview.delete(*self._treeview.get_children())

    def _repr_of_openning_tag(self, node):
        text = "<" + node.tag

        attrs = node.attrib

        # list function is here necessary to provide support to Python 3
        a_names = list(attrs.keys())
        a_names.sort()

        for a_name in a_names:
            text += ' %s="' % a_name
            text += attrs[a_name]
            text += '"'

        text += ">"
        return text

    def _repr_of_closing_tag(self, node):
        return "</%s>" % node.tag

    def _walk_xml(self, node, depth=0, parent=""):
        text = self._repr_of_openning_tag(node) + self._repr_of_closing_tag(
            node)

        item = self._treeview.insert(parent, END, text=text)
        self._item_ID_to_element[item] = node

        if node.text:
            text = node.text.strip()
            if text != "":
                for line in text.splitlines():
                    self._treeview.insert(item, END, text=line)

        child_nodes = sorted(list(node), key=attrgetter('tag'))
        for child_node in node:
            self._walk_xml(child_node, depth + 1, parent=item)

        if node.tail:
            tail = node.tail.strip()
            if tail != "":
                for line in tail.splitlines():
                    self._treeview.insert(parent, END, text=line)
예제 #8
0
파일: GUI.py 프로젝트: dnav6987/PubApp
class Display:
    def __init__(self, controller):
        self.controller = controller

        self.currIndex = 0

        # initialize the GUI
        self.app = Tk()
        self.app.title('Jack Magee\'s Pub')

        self.tree = Treeview(self.app, height=30)
        
        # name the tree columns, not sure if they have to be named numbers but that's how the example did it
        self.tree["columns"]=("one", "two", "three", "four")
        
        # set the column widths
        self.tree.column("one", width=200)
        self.tree.column("two", width=300)
        self.tree.column("three", width=200)
        self.tree.column("four", width=200)

        # set the column headings
        self.tree.heading("#0", text= "ID")
        self.tree.heading("one", text="Name")
        self.tree.heading("two", text="Order")
        self.tree.heading("three", text="Price")
        self.tree.heading("four", text="Respond (double-click)")

        self.tree.pack()
        
        # register handler for double-clicks
        self.tree.bind("<Double-1>", self.OnDoubleClick)

    def mainloop(self):
        self.app.mainloop()

    # this is like making tree entries buttons
    def OnDoubleClick(self, event):
        # get the pressed item
        item = self.tree.selection()[0]
        # get the item's text
        response =  self.tree.item(item,"text")

        # this is the only response we are sending for now
        if response == 'rdy':
            # get the parent directory whose text is the customer id
            parent = self.tree.parent(item)
            customer_id = self.tree.item(parent,"text")
            # remove it from the tree
            self.tree.delete(parent)
            # send the message to the customer
            self.controller.send_msg(customer_id, response)

    # add a new order to the tree
    def takeOrder(self, customer_id, name, order, price):
        # just a row identifier
        thisRow = str(self.currIndex)

        # insert the i.d. and name at the top level
        self.tree.insert("", self.currIndex, thisRow, text=customer_id, values=(name, "", "", ""))
        # insert the "button" for sending notification to clients
        self.tree.insert(thisRow, 0, text='rdy', values=("", "", "", "Ready For Pick Up"))

        # this is a hacky solution to get multiline orders to appear because treeviews will 
        # crop anything more than 1 line so I just make a new entry for every line
        multiline_order = order.split('\n')
        this_line = 1
        for line in multiline_order[:-1]:   # exclude the last end line
            if this_line == 1:  # the first line has the name of the order and it's price
                self.tree.insert(thisRow, 1, text="order",values=("", order, price, ""))
            else: # just keep printing the extra options, sides, and add ons
                self.tree.insert(thisRow, this_line, text="order",values=("", line, "", ""))
            this_line += 1

        self.currIndex += 1
class LobbyUI(Frame):
    """
    Sudoku multiplayer lobby UI class.
    In case of incorrect inputs error messages are shown.
    """
    action = None

    def __init__(self, parent):
        Frame.__init__(self, parent)
        self.parent = parent
        self.row, self.col = -1, -1
        self.__initUI()

    def __initUI(self):
        """
        Initialize UI with a list and required entry fields and submit buttons."""

        self.parent.title('Multiplayer Game')
        self.pack(fill=BOTH, expand=1)

        self.lobby_list = Treeview(self, columns=('room', 'players'))
        self.lobby_list['show'] = 'headings'
        self.lobby_list.heading('room', text='Room ID')
        self.lobby_list.column('room', width=250, anchor=CENTER)
        self.lobby_list.heading('players', text='Players')
        self.lobby_list.column('players', width=100, anchor=CENTER)
        self.lobby_list.grid(row=1,
                             column=0,
                             columnspan=2,
                             rowspan=2,
                             padx=20,
                             pady=(10, 0))

        self.connect_lobby = Button(self,
                                    text='Joining Sudoku\n Solving Session',
                                    command=self.__connect_lobby)
        self.connect_lobby.grid(row=3, column=1, pady=(0, 10))

        Label(self,
              text='Creating new Sudoku\n solving session:').grid(row=4,
                                                                  column=0)

        self.max_players = Entry(self)
        self.max_players.grid(row=4, column=1)

        self.create_game = Button(self,
                                  text='Join new game',
                                  command=self.__create_game)
        self.create_game.grid(row=5, column=1)

    def __connect_lobby(self):
        """
        Handle lobby connection button."""
        LOG.debug('Lobby connect button has been pressed.')
        current_item = self.lobby_list.focus()
        selected_id = None

        if current_item is not None and current_item.strip() != '':
            # Select game column value from item values dictionary.
            selected_id = self.lobby_list.item(current_item)['values'][0]
            LOG.debug('Player wishes to join game ' + str(selected_id))

            if selected_id is not None:
                self.action = ('select', selected_id)
        else:
            tkMessageBox.showwarning(
                "Connection error",
                "Please select a game from the lobby to join.")

    def __create_game(self):
        """
        Create game with some number of max players."""
        max_ok = False

        try:
            max_count = int(self.max_players.get())
        except (ValueError, TypeError):
            max_count = -1
            tkMessageBox.showwarning("Input error",
                                     "Max player count has to be an integer.")

        if isinstance(max_count, int):
            if max_count >= 2:
                max_ok = True
                LOG.debug('Ok max player count.')
            else:
                tkMessageBox.showwarning(
                    "Input error", "Max player count has to be larger than 2.")
                LOG.error('Bad max count.')

        if max_ok:
            self.action = ('create', max_count)

    def populate_list(self, games):
        """
        Method to re-populate the lobby list every poll.
        Additionally retains the focused line during polling.
        :param games:
        """
        previous_selection = self.lobby_list.selection()
        prev_item = None
        if len(previous_selection) > 0:
            prev_item = self.lobby_list.item(previous_selection[0])

        self.lobby_list.delete(*self.lobby_list.get_children())
        for game in games:
            self.lobby_list.insert('',
                                   'end',
                                   values=(str(game[0]),
                                           str(game[1]) + '/' + str(game[2])))

        if prev_item is not None:
            for item in self.lobby_list.get_children():
                if self.lobby_list.item(item) == prev_item:
                    self.lobby_list.selection_set(item)
                    self.lobby_list.focus(item)
class SleepableThreadManagerGUI:
    ui = None  # Main UI Window

    top = None  # Top UI frame
    bottom = None  # Bottom UI frame

    allow_scroll = True

    manager = None  # Sleepable thread manager

    iidList = []

    ui_update_thread = None  # UI Update thread

    thread_dropdown = None  # Dropdown to select threads
    function_dropdown = None  # Dropdown to select functions

    thread_selected = None  # Variable for the thread selection
    threads_selected = []
    function_selected = None  # Variable for the function selection

    function_menu = None
    selection_context_menu = None
    empty_selection_context_menu = None

    info_tree_view = None  # Tree view for thread info
    output_textbox = None  # Output textbox for the UI thread to write to

    def __init__(self):
        self.manager = SleepableThreadManager()

        self.ui = Tk()
        self.ui.title('Sleepable Thread Manager')
        self.ui.geometry('550x600')

        self.function_selected = StringVar(self.ui)
        self.thread_selected = StringVar(self.ui)

        self.thread_selected.set('Select a Thread...')
        self.function_selected.set('Select a Function...')

        # create all of the main containers
        self.top = Frame(self.ui, width=300, height=50, pady=5)
        self.bottom = Frame(self.ui, bg='orange', width=300, height=20, pady=0)

        # main window
        self.ui.grid_columnconfigure(
            0, weight=1)  # expand main column when main ui resizes
        self.top.grid(row=0, sticky="ew")  # Stick top frame to east/west
        self.bottom.grid(
            row=1,
            sticky="nsew")  # Stick bottom frame to north/south/easy/west
        self.ui.grid_rowconfigure(
            1, weight=1)  # Expand bottom panel when main ui resizes

        # top frame component config
        self.top.grid_rowconfigure(
            0, weight=1)  # Expand first row when top frame resizes
        self.top.grid_rowconfigure(
            1, weight=1)  # Expand second row when top frame resizes
        self.top.grid_columnconfigure(
            1, weight=1)  # Expand second column when top frame resizes

        # bottom frame component config
        self.bottom.grid_rowconfigure(
            0, weight=1)  # Expand row 1 when bottom frame resizes
        self.bottom.grid_rowconfigure(
            1, weight=1)  # Expand row 2 when bottom frame resizes
        self.bottom.grid_columnconfigure(
            0, weight=1)  # Expand column 1 when bottom frame resizes
        self.bottom.grid_columnconfigure(0, weight=1)

        # create widgets for top frame
        function_label = Label(self.top, text='Function name:')
        self.function_dropdown = OptionMenu(
            self.top, self.function_selected,
            *self.manager.function_mappings.keys())

        # layout the widgets in the top frame
        function_label.grid(row=1, column=0)
        self.function_dropdown.grid(row=1, column=1, columnspan=3, sticky="ew")

        # create widgets for bottom frame
        self.selection_context_menu = Menu(self.info_tree_view)
        createMultiple = Menu(self.info_tree_view)
        functionMenu = Menu(self.selection_context_menu)
        functionMenu.add_command(
            label='Square', command=lambda: self.set_thread_function('Square'))
        functionMenu.add_command(
            label='Cube', command=lambda: self.set_thread_function('Cube'))

        self.selection_context_menu.add_cascade(label='Create...',
                                                menu=createMultiple)
        self.selection_context_menu.add_cascade(label='Set function...',
                                                menu=functionMenu)

        self.selection_context_menu.add_command(label='Start',
                                                command=self.start_thread)
        self.selection_context_menu.add_command(label='Sleep',
                                                command=self.sleep_thread)
        self.selection_context_menu.add_command(label='Wake',
                                                command=self.wake_thread)
        self.selection_context_menu.add_command(label='Stop',
                                                command=self.stop_thread)
        self.selection_context_menu.add_command(label='Restart',
                                                command=self.restart_thread)
        self.selection_context_menu.add_command(label='Remove',
                                                command=self.remove_thread)

        self.empty_selection_context_menu = Menu(self.info_tree_view)

        createMultiple.add_command(label='1', command=self.create_thread)
        createMultiple.add_command(
            label='5', command=lambda: self.create_thread(amount=5))
        createMultiple.add_command(
            label='10', command=lambda: self.create_thread(amount=10))
        createMultiple.add_command(
            label='20', command=lambda: self.create_thread(amount=20))

        self.empty_selection_context_menu.add_cascade(label='Create',
                                                      menu=createMultiple)

        self.info_tree_view = Treeview(self.bottom,
                                       columns=('Function', 'Status'))
        self.info_tree_view.heading('#0', text='Thread Name')
        self.info_tree_view.heading('#1', text='Function Name')
        self.info_tree_view.heading('#2', text='Status')
        self.info_tree_view.column('#0', width=100, stretch=NO)
        self.info_tree_view.column('#1', width=75)
        self.info_tree_view.column('#2', width=100, stretch=NO)
        self.info_tree_view.bind('<Button-3>', self.popup)
        self.output_textbox = Text(self.bottom,
                                   background="white",
                                   font=("Helvetica", 8))

        self.output_scrollbar = Scrollbar(self.bottom,
                                          command=self.output_textbox.yview)
        self.info_scrollbar = Scrollbar(self.bottom,
                                        command=self.info_tree_view.yview)

        # layout for the widgets in the bottom frame
        self.info_tree_view.grid(row=0, column=0, sticky='nsew')
        self.info_scrollbar.grid(row=0, column=1, sticky="nse")
        self.info_tree_view.config(yscrollcommand=self.info_scrollbar.set)

        self.output_textbox.grid(row=1, column=0, sticky='nsew')
        self.output_scrollbar.grid(row=1, column=1, sticky="nse")
        self.output_textbox.config(yscrollcommand=self.output_scrollbar.set)

        self.ui_update_thread = SleepableThread(work_wait=0.5)
        self.ui_update_thread.set_thread_work(self.refresh_output)
        self.ui_update_thread.start_thread()

        # Mainloop
        self.ui.mainloop()

    # UI refresh
    def refresh_tree_view(self):
        self.info_tree_view.delete(*self.info_tree_view.get_children())
        for item in self.manager.threads.items():
            self.info_tree_view.insert(
                '',
                'end',
                text=item[0],
                values=(str(item[1].work_function),
                        item[1].thread_state_mappings[item[1].thread_state]))

    def refresh_output(self):
        # function passed to ui thread, change to labels/gridview? need independent message queue on threads
        if self.manager.functions.MessageQueue.__len__() > 0:
            while self.manager.functions.MessageQueue.__len__() != 0:
                item = self.manager.functions.MessageQueue.pop()
                if len(item) >= 400:
                    raise Exception('Output too large')
                else:
                    self.output_textbox.delete('1.0', END)
                    self.output_textbox.insert(END, '{}\n'.format(item))
                    if self.manager.thread_stats(
                    )[1] > 0 and self.allow_scroll:
                        self.output_textbox.see('end')

    def popup(self, event):
        self.allow_scroll = False
        #iid = self.info_tree_view.identify_row(event.y)
        self.iidList = self.info_tree_view.selection()
        if self.iidList:
            if self.iidList > 0:
                for i in self.iidList:
                    self.threads_selected.append(
                        self.info_tree_view.item(i)['text'])
            # self.info_tree_view.selection_set(iid)
            # self.thread_selected.set(self.info_tree_view.item(iid)['text'])
            self.selection_context_menu.post(event.x_root, event.y_root)
        else:
            self.empty_selection_context_menu.post(event.x_root, event.y_root)
            pass
        self.manager.functions.MessageQueue = []
        self.allow_scroll = True

    # Button functions
    def create_thread(self, amount=1):
        i = 0
        while i != amount:
            self.manager.control(command='create')
            i += 1
        self.refresh_tree_view()

    def remove_thread(self):
        while self.threads_selected.__len__() != 0:
            self.manager.control(thread=self.threads_selected.pop(),
                                 command='remove')
        self.refresh_tree_view()

    def start_thread(self):
        while self.threads_selected.__len__() != 0:
            self.manager.control(thread=self.threads_selected.pop(),
                                 command='start')
        self.refresh_tree_view()

    def restart_thread(self):
        while self.threads_selected.__len__() != 0:
            self.manager.control(thread=self.threads_selected.pop(),
                                 command='restart')
        self.refresh_tree_view()

    def sleep_thread(self):
        while self.threads_selected.__len__() != 0:
            self.manager.control(thread=self.threads_selected.pop(),
                                 command='sleep')
        self.refresh_tree_view()

    def wake_thread(self):
        while self.threads_selected.__len__() != 0:
            self.manager.control(thread=self.threads_selected.pop(),
                                 command='wake')
        self.refresh_tree_view()

    def stop_thread(self):
        while self.threads_selected.__len__() != 0:
            self.manager.control(thread=self.threads_selected.pop(),
                                 command='stop')
        self.refresh_tree_view()

    def set_thread_function(self, funct):
        while self.threads_selected.__len__() != 0:
            self.manager.set_function(self.threads_selected.pop(), funct)
        self.refresh_tree_view()
예제 #11
0
파일: gui.py 프로젝트: demetraux/Octopod
class MacroFrame(Frame):
    def __init__(self, parent):
        Frame.__init__(self, parent, background="white")
        self.parent = parent
        self.numStates = 0
        self.initUI()

    def initUI(self):
        self.columnconfigure(0, weight=0)
        self.columnconfigure(1, weight=0)
        self.columnconfigure(2, weight=1)
        self.columnconfigure(3, weight=1)

        self.rowconfigure(0, weight=1)

        self.commandFrame = Frame(self, background="white")
        self.commandFrame.grid(row=0, column=0, columnspan=5, sticky=W + E)
        self.commandFrame.columnconfigure(1, weight=1)

        self.btnCommand = Button(self.commandFrame, text="Run")
        self.btnCommand.grid(row=0, column=0)

        self.strCommand = StringVar()
        self.entCommand = Entry(self.commandFrame, textvariable=self.strCommand)
        self.entCommand.grid(row=0, column=1, sticky=W + E)

        self.lstMacro = Listbox(self)
        self.lstMacro.grid(row=1, column=0, sticky=N + S + W + E)

        self.treeview = Treeview(self, columns=("Angle"), displaycolumns="#all", selectmode="browse")
        self.treeview.grid(row=1, column=1, columnspan=4, sticky=N + S + W + E)
        self.treeScrollbar = Scrollbar(self)
        self.treeScrollbar.grid(row=1, column=5, sticky=N + S)
        self.treeview.config(yscrollcommand=self.treeScrollbar.set)
        self.treeScrollbar.config(command=self.treeview.yview)

        self.btnFrame = Frame(self, background="white")
        self.btnFrame.grid(row=2, column=0, columnspan=5, sticky=W + E)

        self.btnRun = Button(self.btnFrame, text="Run", command=self.runMacro)
        self.btnRun.grid(row=0, column=0)

        self.btnStop = Button(self.btnFrame, text="Stop")
        self.btnStop.grid(row=0, column=1)

        self.btnSaveMacro = Button(self.btnFrame, text="Save Macro", command=self.saveMacro)
        self.btnSaveMacro.grid(row=0, column=2)

        self.btnDeleteMacro = Button(self.btnFrame, text="Delete Macro")
        self.btnDeleteMacro.grid(row=0, column=3)

        self.btnDeleteState = Button(self.btnFrame, text="Delete State")
        self.btnDeleteState.grid(row=0, column=4)

    def addState(self, robot):
        stateName = "state" + str(self.numStates)
        self.treeview.insert("", END, iid=stateName, text=stateName)
        limbNum = 0
        for limb in robot.getLimbs():
            limbName = "limb" + str(limbNum)
            self.treeview.insert(stateName, END, iid=stateName + "_" + limbName, text=limbName)
            partNum = 0
            for part in limb.getComponents():
                partName = "joint" + str(partNum)
                if isinstance(part, Joint):
                    self.treeview.insert(
                        stateName + "_" + limbName,
                        END,
                        iid=stateName + "_" + limbName + "_" + partName,
                        text=partName,
                        values=[part.angle],
                    )
                    partNum += 1
            limbNum += 1
        self.numStates += 1

    def getState(self, stateNum, robot):
        stateName = "state" + str(stateNum)
        limbNum = 0
        for limb in robot.getLimbs():
            limbName = "limb" + str(limbNum)
            partNum = 0
            for part in limb.getComponents():
                partName = "joint" + str(partNum)
                if isinstance(part, Joint):
                    part.setAngle(int(self.treeview.item(stateName + "_" + limbName + "_" + partName, "values")[0]))
                    partNum += 1
            limbNum += 1

    def runMacro(self):
        thread = threading.Thread(target=self.updateState)
        thread.start()

    def updateState(self):
        for i in range(self.numStates):
            self.getState(i, self.parent.robotFrame.robot)
            time.sleep(0.1)

    def saveMacro(self):
        pass
예제 #12
0
class PickerGUI():
    """ This class maintains the TK Inter user interface and contains all the
        data from ontology. Data can be loaded from (and store to) .rdf using
        RDFReader class or from JSON (that is much faster). """
    def __init__(self, master, annotationEffect):
        self.fileName = ""
        self.namespace = None
        self.aEffect = annotationEffect
        self.root = master
        self.root.bind('<Escape>', self.close)
        self.leftFrame = Tkinter.Frame(master)
        self.middleFrame = Tkinter.Frame(master)
        self.rightFrame = Tkinter.Frame(master)
        self.leftFrame.pack(side=Tkinter.LEFT, padx=10, pady=10)
        self.middleFrame.pack(side=Tkinter.LEFT)
        self.rightFrame.pack(side=Tkinter.LEFT)
        self.bottomLeftFrame = Tkinter.Frame(self.leftFrame)
        self.bottomMiddleFrame = Tkinter.Frame(self.middleFrame)
        self.bottomRightFrame = Tkinter.Frame(self.rightFrame)
        self.menuBar = Tkinter.Menu(master)
        self.fileMenu = Tkinter.Menu(self.menuBar, tearoff=0)
        self.fileMenu.add_command(label="Load Ontology",
                                  accelerator="Ctrl+L",
                                  command=self.loadOntology)
        self.fileMenu.add_command(label="Save to Ontology",
                                  accelerator="Ctrl+S",
                                  command=self.saveOntology)
        self.menuBar.add_cascade(label="File", menu=self.fileMenu)
        self.fileMenuUndo = Tkinter.Menu(self.menuBar, tearoff=0)
        self.fileMenuUndo.add_command(label="Undo",
                                      accelerator="Ctrl+Z",
                                      command=self.undoOperation)
        self.root.bind_all("<Control-l>", self.loadOntology)
        self.root.bind_all("<Control-s>", self.saveOntology)
        self.root.bind_all("<Control-z>", self.undoOperation)
        self.menuBar.add_cascade(label="Edit", menu=self.fileMenuUndo)
        # Treeview to choose Ontology Entities to annotate new elements
        self.treeEntityPicker = Treeview(self.leftFrame)
        self.treeEntityPicker.heading("#0", text="Entity/Subject")
        self.treeEntityPicker.column("#0",
                                     width=c.BASIC_WIDTH,
                                     stretch=Tkinter.NO)
        # Treeview to choose Object Properties
        self.treePropertyPicker = Treeview(self.middleFrame)
        self.treePropertyPicker.heading("#0", text="Properties")
        self.treePropertyPicker.column("#0",
                                       width=c.ENLARGERD_WIDTH,
                                       stretch=Tkinter.NO)
        # Treeview to choose range individuals of property
        self.treeRangePicker = Treeview(self.rightFrame)
        self.treeRangePicker.heading("#0", text="Object")
        self.treeRangePicker.column("#0",
                                    width=c.BASIC_WIDTH,
                                    stretch=Tkinter.NO)
        self.buttonAdd = Tkinter.Button(self.bottomLeftFrame)
        self.buttonAdd["text"] = "Add"
        self.buttonAddProperty = Tkinter.Button(self.bottomRightFrame)
        self.buttonAddProperty["text"] = "Add Prop."
        self.buttonEditProperty = Tkinter.Button(self.bottomRightFrame)
        self.buttonEditProperty["text"] = "Edit Prop."
        self.buttonRemoveProperty = Tkinter.Button(self.bottomRightFrame)
        self.buttonRemoveProperty["text"] = "Delete Prop."
        self.buttonSeparateAdd = Tkinter.Button(self.bottomLeftFrame)
        self.buttonSeparateAdd["text"] = "Add Separately"
        self.buttonReplace = Tkinter.Button(self.bottomLeftFrame)
        self.buttonReplace["text"] = "Replace"
        self.buttonRemove = Tkinter.Button(self.bottomLeftFrame)
        self.buttonRemove["text"] = "Remove"
        self.buttonClear = Tkinter.Button(self.bottomMiddleFrame)
        self.buttonClear["text"] = "Clear Views"
        # define options for opening or saving a file
        self.file_opt = options = {}
        options["defaultextension"] = ".rdf"
        options["filetypes"] = [("RDF files", ".rdf")]
        options["parent"] = master
        options["title"] = "Load a RDF Ontology"
        self.resetVariables()

    def prepare(self, master):
        self.treeEntityPicker.pack(pady=15)
        self.treePropertyPicker.pack(pady=15)
        self.treePropertyPicker.bind("<ButtonRelease-1>", self.propertySelect)
        # Handle double click on Property Tree
        self.treePropertyPicker.bind("<Double-1>", self.propertyClick)
        self.treeRangePicker.pack(pady=15)
        self.bottomLeftFrame.pack(fill=Tkinter.X)
        self.bottomMiddleFrame.pack(fill=Tkinter.X)
        self.bottomRightFrame.pack(fill=Tkinter.X, padx=25)
        self.buttonAdd.pack(side=Tkinter.LEFT)
        self.buttonSeparateAdd.pack(side=Tkinter.LEFT)
        self.buttonReplace.pack(side=Tkinter.LEFT)
        self.buttonAddProperty.pack(side=Tkinter.LEFT)
        self.buttonEditProperty.pack(side=Tkinter.LEFT)
        self.buttonRemoveProperty.pack(side=Tkinter.LEFT)
        self.buttonRemove.pack(side=Tkinter.LEFT)
        self.buttonClear.pack(side=Tkinter.BOTTOM)
        self.buttonAdd.bind("<ButtonRelease-1>", self.buttonAddClick)
        self.buttonAdd.bind("<Return>", self.buttonAddClick)
        self.buttonSeparateAdd.bind("<ButtonRelease-1>",
                                    self.buttonSeparateAddClick)
        self.buttonSeparateAdd.bind("<Return>", self.buttonSeparateAddClick)
        self.buttonAddProperty.bind("<ButtonRelease-1>",
                                    self.buttonAddPropertyClick)
        self.buttonAddProperty.bind("<Return>", self.buttonAddPropertyClick)
        self.buttonEditProperty.bind("<ButtonRelease-1>",
                                     self.buttonEditPropertyClick)
        self.buttonEditProperty.bind("<Return>", self.buttonEditPropertyClick)
        self.buttonRemoveProperty.bind("<ButtonRelease-1>",
                                       self.buttonRemovePropertyClick)
        self.buttonRemoveProperty.bind("<Return>",
                                       self.buttonRemovePropertyClick)
        self.buttonReplace.bind("<ButtonRelease-1>", self.buttonReplaceClick)
        self.buttonReplace.bind("<Return>", self.buttonReplaceClick)
        self.buttonRemove.bind("<ButtonRelease-1>", self.buttonRemoveClick)
        self.buttonRemove.bind("<Return>", self.buttonRemoveClick)
        self.buttonClear.bind("<ButtonRelease-1>", self.buttonClearClick)
        self.buttonClear.bind("<Return>", self.buttonClearClick)
        master.config(menu=self.menuBar)
        self.loadSerializedOntology(self.treeEntityPicker)

    def resetVariables(self):
        # Keys: classHierarchy, instances; Values: temporary data
        # (to be serialized and saved)
        self.tempData = {}
        # Key: Class Name; Value: List of IDs of instances of that class
        self.instancesbyClass = {}
        # Key: Property Name; Values: Entities that belong to its range
        self.rangesByProperty = {}
        # Key: Property Name; Values: Entities that belong to its domain
        self.domainsByProperty = {}
        self.ontologyTree = None
        self.lastId = -1
        self.defaultName = ""
        self.defaultTypeValue = ""
        self.defaultTypeValue = ""
        self.undoStack = []
        self.selectedEntities = None
        self.selectedRange = None
        self.selectedProperties = None
        # Keys: properties; Values: occurrences of the property
        # i.e. (s,p,o) triples
        self.objectProperties = {}
        # (s,p,o) triples with object properties to be added to the ontology
        self.objectPropertiesToAdd = []
        self.objectPropertiesToRemove = []
        # Key: TreeView element ID. #Value: (s,p,o) triple.
        self.propertiesByTreeID = {}
        self.dataTypeProperties = {}
        self.dataTypePropertiesToAdd = []
        self.dataTypePropertiesToRemove = []

    def buttonAddClick(self, event):
        """ Button handler for adding entities. """
        self.prepareSelectedEntities()
        close = self.aEffect.addAnnotation(separateAdd=False)
        if close:
            self.closeGUI(isInstanceListChanged=True)

    def buttonSeparateAddClick(self, event):
        """ Button handler for adding entities separately. """
        self.prepareSelectedEntities()
        close = self.aEffect.addAnnotation(separateAdd=True)
        if close:
            self.closeGUI(isInstanceListChanged=True)

    def buttonAddPropertyClick(self, event):
        """ Button handler for adding properties. """
        selectedProperty, tags, rowID = self.prepareSelectedProperty(
            limitObjects=False)
        if self.validateProperty(selectedProperty, tags):
            serialize = self.aEffect.addProperty(selectedProperty, tags)
            if serialize:
                self.serialize()
                self.refreshPropertyTree(self.treePropertyPicker)

    def buttonEditPropertyClick(self, event):
        """ Button handler for editing properties. Removes the previous
            (s,p,o) triple and adds a new one. """
        selectedProperty, tags, rowID = self.prepareSelectedProperty()
        if self.validateProperty(selectedProperty, tags):
            serialize = self.aEffect.editProperty(selectedProperty, tags,
                                                  rowID)
            if serialize:
                self.serialize()
                self.refreshPropertyTree(self.treePropertyPicker)

    def buttonRemovePropertyClick(self, event):
        """ Button handler for removing properties. """
        selectedProperties, tags, rowIDs = \
            self.getSelectedProperty(multiselect=True)

        for p in selectedProperties:
            if not self.validateProperty(p, ""):
                return
        for p, tagList in tags.iteritems():
            if not self.validateProperty("", tagList):
                return
        ser = self.aEffect.removeProperty(selectedProperties, tags, rowIDs)
        if ser:
            self.serialize()
            self.refreshPropertyTree(self.treePropertyPicker)

    def validateProperty(self, property, tags):
        """" Validate that the selected property can be chosen
        :param property: The property name
        :param tags: A list of tags of a selected tree row, containing
        the property name in the case of an instance
        :return: boolean Whether the property is valid
        """
        valid = True
        invalidProperties = [
            c.HAS_SVG_PROPERTY, c.HAS_X_COORD_PR, c.HAS_Y_COORD_PR
        ]
        if property in invalidProperties:
            valid = False
            tkMessageBox.showwarning(c.PROP, c.PROP_INVALID_PROP % property)
        elif tags:
            for tag in tags:
                if tag in invalidProperties:
                    tkMessageBox.showwarning(c.PROP, c.PROP_INVALID_PROP % tag)
                    valid = False
                    break
        return valid

    def prepareSelectedProperty(self, limitObjects=True):
        """ Returns the selected property and ensures that instances of its
            domain (for its range, use validateSelectedRange) have been
            selected.
        :param limitObjects: True if only one object can be selected
        :return: selected property
        """

        selectedProperty, tags, rowID = self.getSelectedProperty()
        if selectedProperty:
            validEntity = self.prepareSelectedEntities(allowOnlyInstances=True)
            if validEntity:
                if len(self.selectedEntities) > 0:
                    if limitObjects and len(self.selectedEntities) > 1:
                        tkMessageBox.showwarning(c.PROP, c.PROP_MORE_SUBJ)
                    else:
                        # TODO: validate that subject and object are instances
                        # and are within the domain and range of the property
                        return selectedProperty, tags, rowID
                else:
                    tkMessageBox.showwarning(c.PROP, c.PROP_NO_SUBJ)
        return None, None, None

    def getSelectedProperty(self, multiselect=False):
        """ Fetches the selected Property from the middle TreeView and handles
            incorrect selections. Returns a triple with the property name
            (as in the Treeview), its tags and the row ID on the TreeView.
        :param multiselect: Is set to 'True' if selection of multiple
            properties is allowed, 'False' otherwise.
        """

        selectedProperty = None
        tags = None
        rowID = None
        selectedProperties = self.treePropertyPicker.selection()
        if len(selectedProperties) == 0:
            tkMessageBox.showwarning(c.PROP, c.PROP_NO_PROP)
        elif multiselect:
            rowIDs = {}
            properties = []
            tags = {}
            for rowID in selectedProperties:
                p = self.treePropertyPicker.item(rowID, "text")
                properties.append(p)
                tags[p] = self.treePropertyPicker.item(rowID, "tags")
                rowIDs[p] = rowID
            return properties, tags, rowIDs
        elif len(selectedProperties) > 1:
            tkMessageBox.showwarning(c.PROP, c.PROP_MORE_PROP)
        else:
            rowID = selectedProperties[0]
            selectedProperty = self.treePropertyPicker.item(rowID, "text")
            tags = self.treePropertyPicker.item(rowID, "tags")
        return selectedProperty, tags, rowID

    def buttonReplaceClick(self, event):
        """ Button handler for replace svg elements in annotation. """
        self.prepareSelectedEntities()
        close = self.aEffect.replaceAnnotation()
        if close:
            self.closeGUI(isInstanceListChanged=True)

    def buttonRemoveClick(self, event):
        """ Button handler for moving svg elements from annotation. """
        self.prepareSelectedEntities()
        close = self.aEffect.removeAnnotation(None, fromUndo=False)
        if close:
            self.closeGUI(isInstanceListChanged=True)

    def undoOperation(self, *args):
        """ Button handler for undo operation. """
        self.prepareSelectedEntities()
        close = self.aEffect.undoAnnotation()
        if close:
            self.closeGUI(isInstanceListChanged=True)

    def buttonClearClick(self, event):
        """ Button handler for clearing tree view and set
            it into default state. """
        self.treeEntityPicker.delete(*self.treeEntityPicker.get_children())
        self.populatePropertyTree(self.treeEntityPicker, [])
        self.treeRangePicker.delete(*self.treeRangePicker.get_children())

    def propertyClick(self, event):
        """ Load the individuals that belong to the range of the selected
            Property on the right-hand TreeView, and to its domain on the
            left-hand TreeView.
        """

        selectedProperty, tags, rowID = self.getSelectedProperty()
        if selectedProperty and c.TREE_TAG_PROPERTIES_HEADER not in tags:
            self.treeRangePicker.delete(*self.treeRangePicker.get_children())
            self.treeEntityPicker.delete(*self.treeEntityPicker.get_children())
            if c.TREE_TAG_INSTANCE in tags:
                # Auto-expand branches of domain and range of selected property
                propertyTriple = self.propertiesByTreeID[rowID]
                self.selectedEntities = [propertyTriple[c.SUBJECT_INDEX]]
                if c.TREE_TAG_OBJECT_PROPERTY in tags:
                    # Auto select range only for object properties
                    self.selectedRange = [propertyTriple[c.OBJECT_INDEX]]
                else:
                    self.selectedRange = []
                # Fetch property name from tags
                for tag in tags:
                    if tag not in c.TREE_TAGS:
                        selectedProperty = tag
                        break

            if selectedProperty in self.rangesByProperty:
                rangeEntities = self.rangesByProperty[selectedProperty]
            else:
                rangeEntities = None
            if selectedProperty in self.domainsByProperty:
                domainEntities = self.domainsByProperty[selectedProperty]
            else:
                domainEntities = None

            self.populatePropertyTree(self.treeEntityPicker,
                                      domainEntities,
                                      selectPrevious="subject")
            if c.TREE_TAG_DATATYPE_PROPERTY in tags:
                self.treeRangePicker.delete(
                    *self.treeRangePicker.get_children())
            else:
                self.populatePropertyTree(self.treeRangePicker,
                                          rangeEntities,
                                          selectPrevious="object")

    def propertySelect(self, event):
        """ Take note of selected properties. """
        selectedPropertyIDs = self.treePropertyPicker.selection()
        self.selectedProperties = [
            self.treePropertyPicker.item(rowID, "text")
            for rowID in selectedPropertyIDs
        ]

    def populatePropertyTree(self,
                             treeViewInstance,
                             entityList,
                             selectPrevious="none"):
        """ Populate an Entity & Individuals TreeView according to the range
            or domain of a property (passed as a list of entities).
            For each entity of the list, its children (entities or individuals)
            are added to the TreeView.
        :param treeViewInstance: View of the tree.
        :param entityList: List of entities.
        :param selectPrevious: This should be "object", "subject" or "none".
        """

        subtrees = []
        if entityList:
            for entity in entityList:
                subtree = self.getSubTreeFromEntity(entity, self.ontologyTree)
                if subtree:
                    subtrees.append(subtree)
        if subtrees:
            for tree in subtrees:
                self.stack = ['']
                self.subTreeFromFileRecursive(tree, treeViewInstance,
                                              selectPrevious)
        else:
            self.stack = ['']
            self.subTreeFromFileRecursive(self.ontologyTree, treeViewInstance,
                                          selectPrevious)

    def getSubTreeFromEntity(self, entity, entityTree):
        """ Returns a subTree with the given entity as the root.
        :param entity: Searched entity for a root of a tree.
        :param entityTree: Tree structure that should be searched.
        :return: subtree with the entity as a root.
        """

        nodeQueue = entityTree[:]
        while nodeQueue:
            element = nodeQueue.pop(0)
            if isinstance(element[0], basestring):
                if element[0] == entity:
                    return element
            iternodes = iter(element)
            next(iternodes)
            for n in iternodes:
                nodeQueue.append(n)
        return []

    def prepareSelectedEntities(self, allowOnlyInstances=False):
        """ Initializes the selectedEntities and selectedRange properties
            (Entities and/or Instances)  according to the user's selection on
            the treeView.
        :param allowOnlyInstances: 'True' if only instances should be added.
        return: 'True' if preparation process finishes correctly,
            'False' otherwise.
        """

        selectedSubjectIDs = self.treeEntityPicker.selection()
        selectedEntities = []
        correct = True
        for s in selectedSubjectIDs:
            text = self.treeEntityPicker.item(s, "text")
            tags = self.treeEntityPicker.item(s, "tags")
            # Select all children of "Instances" group
            if c.TREE_TAG_INSTANCES_HEADER in tags:
                for child in self.treeEntityPicker.get_children(s):
                    text = self.treeEntityPicker.item(child, "text")
                    selectedEntities.append(text)
            else:
                if allowOnlyInstances and c.TREE_TAG_ENTITY in tags:
                    tkMessageBox.showwarning(c.SELECT, c.SELECT_INST)
                    correct = False
                elif text not in selectedEntities:
                    selectedEntities.append(text)
        self.selectedEntities = selectedEntities
        selectedObjectIDs = self.treeRangePicker.selection()
        selectedRange = []
        for o in selectedObjectIDs:
            text = self.treeRangePicker.item(o, "text")
            tags = self.treeRangePicker.item(o, "tags")
            # Select all children of "Instances" group
            if c.TREE_TAG_INSTANCES_HEADER in tags:
                for child in self.treeRangePicker.get_children(o):
                    text = self.treeRangePicker.item(child, "text")
                    selectedRange.append(text)
            else:
                if allowOnlyInstances and c.TREE_TAG_ENTITY in tags:
                    tkMessageBox.showwarning(c.SELECT, c.SELECT_INST)
                    correct = False
                elif text not in selectedRange:
                    selectedRange.append(text)
        self.selectedRange = selectedRange
        return correct

    def saveOntology(self, *args):
        """ This method saves the ontology. It takes data from JSON and
            stores it in the rdf file.
        """

        if not self.instancesbyClass:
            tkMessageBox.showwarning(c.SAVE, c.SAVE_NOT_LOADED)
            return

        if tkMessageBox.askyesno(c.SAVE, c.SAVE_TO_ORIGINAL):
            fileName = self.fileName
        else:
            fileName = tkFileDialog.askopenfilename(**self.file_opt)

        if fileName:
            self.readerOperation(fileName,
                                 self.namespace,
                                 serialize=False,
                                 save=True)

            filePath = os.path.join(os.path.expanduser("~"), c.JSON_FILENAME)
            if os.path.exists(filePath):
                os.remove(filePath)
            self.closeGUI(isInstanceListChanged=False)
        else:
            tkMessageBox.showwarning(c.SAVE, c.SAVE_NOT_CHOSEN)

    def loadOntology(self, *args):
        """ Ask user to choose rdf file. Then load the ontology onto GUI
            and serialize it to a temp file.
        """

        if self.ontologyTree and tkMessageBox.askyesno(c.LOAD, c.LOAD_SAVING):
            self.saveOntology()
            tkMessageBox.showwarning(c.LOAD, c.LOAD_CHOOSING)

        self.resetVariables()
        filePath = os.path.join(os.path.expanduser("~"), c.JSON_FILENAME)
        if os.path.exists(filePath):
            os.remove(filePath)

        namespace = None
        fileName = tkFileDialog.askopenfilename(**self.file_opt)

        if fileName:
            self.fileName = fileName
            candidateSet = self.getCandidateSetOfPrefixes(fileName)
            namespace = self.resolveNamespace(candidateSet)
            if not namespace:
                # User cancels the process or enter empty namespace
                return
            self.namespace = namespace

            self.readerOperation(fileName,
                                 namespace,
                                 serialize=True,
                                 save=False)

            # Detect if the ontology is not loaded properly
            if self.ontologyTree == [c.RDF_ROOT_NAME]:
                tkMessageBox.showwarning(c.LOAD, c.LOAD_NO_TREE)

    def readerOperation(self, fileName, namespace, serialize=True, save=False):
        """ Function created instance of a reader class and loads the data
            into appropriate variables or saves them into rdf file.
        :param fileName: Original fileName of .rdf file.
        :param namespace: Namespace of the original .rdf file.
        :param serialize: If it is 'True' than loaded data are saved into JSON
        :param save: If it is 'True' than data from JSON
            are stored into .rdf file
        """

        try:
            reader = RDFReader(fileName, namespace)
            if save:
                self.addDefaultProperties(reader)
            self.treeEntityPicker.delete(*self.treeEntityPicker.get_children())
            self.treePropertyPicker.delete(
                *self.treePropertyPicker.get_children())
            self.treeRangePicker.delete(*self.treeRangePicker.get_children())
            self.ontologyTree = reader.generateSubTree(c.RDF_ROOT_NAME,
                                                       self.treeEntityPicker)
            self.instancesbyClass = reader.instancesbyClass
            self.initializeTriples(reader, "object")
            self.initializeTriples(reader, "datatype")
            self.domainsByProperty = reader.domainsByProperty
            self.rangesByProperty = reader.rangesByProperty
            self.treeConfiguration(self.treeEntityPicker)
            self.treeConfiguration(self.treeRangePicker)
            self.initializePropertyTree(self.treePropertyPicker)
            self.lastId = reader.getLastId()
            if serialize:
                self.serialize()
            if save:
                self.savingOperations(reader)
        except IOError as e:
            tkMessageBox.showwarning(c.FILE, c.FILE_ERROR % e.strerror)
            self.closeGUI()

    def initializeTriples(self, reader, type):
        """ Initialize instances of properties. Allowed types:
            object, datatype.
        :param reader: Reader instance with data.
        :param type: Type of the data.
        """

        if type == "object":
            properties = reader.objectProperties
        else:
            # type == "datatype":
            properties = reader.dataTypeProperties

        for property in properties:
            triples = reader.getPropertyInstances(property)
            if type == "object":
                self.objectProperties[property] = []
            else:
                self.dataTypeProperties[property] = []
            for s, p, o in triples:
                subject = s.split('#')[1]
                obj = o.split('#')
                # Some objects (e.g. SVG paths) have no NS
                obj = obj[1 if len(obj) > 1 else 0]
                if type == "object":
                    # Cast to lists so they can be serialized
                    self.objectProperties[property].append(
                        [subject, property, obj])
                else:
                    self.dataTypeProperties[property].append(
                        [subject, property, obj])

    def savingOperations(self, reader):
        """
        Save current data into an .rdf file.
        :param reader: Instance of the reader class.
        """

        self.loadSerializedInstances()
        # Check all 'remove' operations performed; maybe elements need
        # to be removed from the ontology

        self.loadSerializedInstances()
        for operation in self.undoStack:
            for atomicAction in operation:
                if atomicAction["type"] == "remove":
                    instance = atomicAction["instanceId"]
                    entity = atomicAction["entityName"]
                    if entity not in self.instancesbyClass or instance not in \
                            self.instancesbyClass[entity]:
                        # Whole annotation removed; check if exists in ontology
                        # and if so, delete it
                        if reader.hasInstance(entity, instance):
                            reader.removeInstance(instance)
                    else:
                        svgElements = atomicAction["SVGElements"]
                        for svgElement in svgElements:
                            if reader.hasSVGElement(instance, svgElement):
                                reader.removeSVGElementProperty(
                                    instance, svgElement)

        for entity, annotations in self.instancesbyClass.iteritems():
            if reader.hasEntity(entity):  # Ensure entity belongs to ontology
                for annotation, svgElements in annotations.iteritems():
                    if not reader.hasInstance(entity, annotation):
                        reader.addInstance(entity, annotation)

                    svg = SVGParser(self.aEffect.document.getroot())
                    cPnt = svg.countCentralPointForListOfElements(svgElements)
                    if cPnt is not None:
                        reader.addCoordinatesXY(annotation, cPnt[0], cPnt[1])

                    h, w = svg.computeDimForListOfElements(svgElements)
                    if h is not None:
                        reader.addLengthAndWidth(annotation, h, w)

                    for svgElement in svgElements:
                        reader.addSVGElementProperty(annotation, svgElement)

        for triple in self.objectPropertiesToRemove:
            reader.removeObjectProperty(triple[c.SUBJECT_INDEX],
                                        triple[c.PROPERTY_INDEX],
                                        triple[c.OBJECT_INDEX])
        for triple in self.objectPropertiesToAdd:
            reader.addObjectProperty(triple[c.SUBJECT_INDEX],
                                     triple[c.PROPERTY_INDEX],
                                     triple[c.OBJECT_INDEX])

        for triple in self.dataTypePropertiesToRemove:
            reader.removeDatatypeProperty(triple[c.SUBJECT_INDEX],
                                          triple[c.PROPERTY_INDEX],
                                          triple[c.OBJECT_INDEX])
        for triple in self.dataTypePropertiesToAdd:
            reader.addDatatypeProperty(triple[c.SUBJECT_INDEX],
                                       triple[c.PROPERTY_INDEX],
                                       triple[c.OBJECT_INDEX])

        reader.saveOntology()

    def getCandidateSetOfPrefixes(self, fileName):
        """ This method tries to find the correct prefix of ontology directly
            from .rdf file.
        :param fileName: Name of the file to be searched.
        :return: Candidate set of prefixes that are used in ontology without
            common ones.
        """

        tree = etree.parse(fileName)
        root = tree.getroot()
        setOfPrefixes = set()

        for name in root.nsmap:
            setOfPrefixes.add(self.removeLastHTag(root.nsmap[name]))

        # namespace generated by the Protege
        inkex.NSS['owl'] = c.OWL_PREFIX
        ontNS = root.xpath(".//owl:Ontology", namespaces=inkex.NSS)
        if ontNS is not None and len(ontNS) > 0 and ontNS[0] is not None:
            if c.RDF_NS_ATTRIBUTE in ontNS[0].attrib:
                cand = self.removeLastHTag(ontNS[0].attrib[c.RDF_NS_ATTRIBUTE])
                setOfPrefixes.add(cand)

        return setOfPrefixes - c.COMMON_PREFIXES

    def resolveNamespace(self, candidateNSSet):
        """ Method allows to resolve the selection of namespaces. It solves
            the cases when nothing is is found, one is found or multiple
            namespaces exists.
        :param candidateNSSet: Candidate set of namespaces.
        :return: Final name of the namespace.
        """

        if len(candidateNSSet) == 0:
            fName = tkSimpleDialog.askstring(c.NSNAME, c.NSNAME_NO_NS)
            if fName is not None and not fName:
                tkMessageBox.showwarning(c.NSNAME, c.NSNAME_NOT_ADDED)
                fName = c.DEFAULT_NS
        elif len(candidateNSSet) == 1:
            el = next(iter(candidateNSSet))
            if tkMessageBox.askokcancel(c.NSNAME, c.NSNAME_DETECTED % el):
                fName = el
            else:
                fName = tkSimpleDialog.askstring(c.NSNAME, c.NSNAME_ENTER)
                if fName is not None and not fName:
                    tkMessageBox.showwarning(c.NSNAME, c.NSNAME_NOT_ADDED)
                    fName = c.DEFAULT_NS
        else:
            description = "\n".join(candidateNSSet)
            el = next(iter(candidateNSSet))

            fName = tkSimpleDialog.askstring(c.NSNAME,
                                             c.NSNAME_MULTIPLE % description,
                                             initialvalue=el)
        return fName

    def removeLastHTag(self, str):
        """ Removes the last hashtag form the string.
        :param str: String to be changed.
        :return: String without the last hashtag.
        """

        if str.endswith("#"):
            return str[:-1]
        return str

    def treeConfiguration(self, treeInstance):
        """ Method configures the tree and set colors for different type of
            entities and instances in the tree.
        :param treeInstance: instance of the tree.
        """

        treeInstance.tag_configure(c.TREE_TAG_ENTITY, background="white")
        treeInstance.tag_configure(c.TREE_TAG_INSTANCE, background="grey")
        treeInstance.tag_configure(c.TREE_TAG_HIGHLIGHT, background="yellow")

    def subTreeFromFileRecursive(self,
                                 treeList,
                                 treeViewInstance,
                                 selectPrevious="none"):
        """ Method creates tree from the treeList.
        :param treeList: List with data from whom the tree is generated.
        :param treeViewInstance:
        :param selectPrevious: This should be "object", "subject" or "none".
        """

        if selectPrevious != "none":
            selected = self.previousSelectedEntities(selectPrevious)
        for i in iter(treeList):
            if isinstance(i, basestring):
                parentID = self.stack[-1]
                # Insert element into GUI ViewTree
                childID = treeViewInstance.insert(parentID,
                                                  'end',
                                                  text=i,
                                                  tags=(c.TREE_TAG_ENTITY, ))
                if selectPrevious != "none" and i in selected:
                    self.expandBranches(treeViewInstance, childID)
                # Insert instances of current Entity
                if i in self.instancesbyClass:
                    self.insertInstancesInTree(self.instancesbyClass[i],
                                               treeViewInstance, childID,
                                               selectPrevious)
                self.stack.append(childID)
            else:
                self.subTreeFromFileRecursive(i, treeViewInstance,
                                              selectPrevious)
        if self.stack:
            self.stack.pop()

    def expandBranches(self, treeViewInstance, rowID):
        """ Expand all branches from the root to the given one.
        :param treeViewInstance: View of the tree.
        :param rowID: Id of the searched row.
        """

        treeViewInstance.item(rowID, open=True)
        tempStack = self.stack[:]  # Slice clone
        while tempStack:
            treeViewInstance.item(tempStack.pop(), open=True)
        self.setFocus(treeViewInstance, rowID)

    def insertInstancesInTree(self,
                              instanceList,
                              treeViewInstance,
                              parentID,
                              selectPrevious="none"):
        """ Insert instances from instanceList into treeView.
        :param instanceList: List of instances.
        :param treeViewInstance: View of the tree.
        :param parentID: Id of the parent in the tree view.
        :param selectPrevious: This should be "object", "subject" or "none".
        """

        localParentID = parentID
        # Only in case that there is a lot of instances
        if len(instanceList) > c.MAX_INSTANCES_IN_DIR:
            localParentID = \
                treeViewInstance.insert(parentID, 'end', text=c.INSTANCES_NAME,
                                        tags=(c.TREE_TAG_INSTANCE,
                                              c.TREE_TAG_INSTANCES_HEADER, ))

        for instance in sorted(instanceList.keys()):
            if set(self.aEffect.selected).intersection(instanceList[instance]):
                tag = c.TREE_TAG_HIGHLIGHT
            else:
                tag = c.TREE_TAG_INSTANCE

            rowID = treeViewInstance.insert(localParentID,
                                            'end',
                                            text=instance,
                                            tags=(tag, ))
            # Expand all branches to instance if it was previously selected
            if selectPrevious != 'none' and instance in \
                    self.previousSelectedEntities(selectPrevious):
                self.expandBranches(treeViewInstance, localParentID)
                # If instances are grouped, expand "Instances" header
                if parentID != localParentID:
                    treeViewInstance.item(parentID, open=True)
                self.setFocus(treeViewInstance, rowID)

    def initializePropertyTree(self, treeViewInstance):
        """ Method initializes tree of properties.
        :param treeViewInstance: View of the tree.
        """
        if self.objectProperties:
            oID = treeViewInstance.insert(
                '',
                'end',
                text='Object Properties',
                tags=(c.TREE_TAG_PROPERTIES_HEADER, ))
        if self.dataTypeProperties:
            dID = treeViewInstance.insert(
                '',
                'end',
                text='Datatype Properties',
                tags=(c.TREE_TAG_PROPERTIES_HEADER, ))
        self.addPropertiesToTreeView(treeViewInstance,
                                     self.objectProperties,
                                     oID,
                                     type=c.TREE_TAG_OBJECT_PROPERTY)
        self.addPropertiesToTreeView(treeViewInstance,
                                     self.dataTypeProperties,
                                     dID,
                                     type=c.TREE_TAG_DATATYPE_PROPERTY)

    def addPropertiesToTreeView(self, treeViewInstance, props, headerID, type):
        """ Insert properties from the instanceList into treeView.
        :param treeViewInstance: View of the tree.
        :param props: Properties to be added.
        :param headerID: Id of the header for adding properties.
        :param type: Type of the property.
        """
        selected = self.previousSelectedProperties()
        for property in props:
            textAdd = property
            parID = treeViewInstance.insert(headerID,
                                            'end',
                                            text=textAdd,
                                            tags=(c.TREE_TAG_PROPERTY, type))
            triples = props[property]
            if selected and textAdd in selected:
                self.expandPropertyBranches(treeViewInstance, [headerID],
                                            parID)
            for triple in triples:
                textAdd = "%s -> %s" % (triple[c.SUBJECT_INDEX],
                                        triple[c.OBJECT_INDEX])
                childID = treeViewInstance.insert(parID,
                                                  'end',
                                                  text=textAdd,
                                                  tags=(c.TREE_TAG_INSTANCE,
                                                        type, property))
                self.propertiesByTreeID[childID] = [
                    triple[c.SUBJECT_INDEX], property, triple[c.OBJECT_INDEX]
                ]
                if selected and textAdd in selected:
                    self.expandPropertyBranches(treeViewInstance,
                                                [headerID, parID], childID)

    def expandPropertyBranches(self, treeViewInstance, ancestorIDs, childID):
        """ Method for expanding branches in the property tree view.
        :param treeViewInstance: View of the tree.
        :param ancestorIDs: ID of the ancestor.
        :param childID: ID of the child.
        """

        for id in ancestorIDs:
            treeViewInstance.item(id, open=True)
        treeViewInstance.item(childID, open=True)
        self.setFocus(treeViewInstance, childID)

    def setFocus(self, treeViewInstance, rowID):
        """ Method for expanding setting focus on specific in the property
            row in the tree view.
        :param treeViewInstance: View of the tree.
        :param rowID: ID of the row that should be focused.
        """

        treeViewInstance.focus(rowID)
        treeViewInstance.selection_set(rowID)
        treeViewInstance.focus_set()

    def refreshPropertyTree(self, treeViewInstance):
        """ Reload all properties and feed the given TreeView with them.
        :param treeViewInstance: View of the tree.
        """

        treeViewInstance.delete(*treeViewInstance.get_children())
        if self.objectProperties or self.dataTypeProperties:
            self.initializePropertyTree(treeViewInstance)
        else:
            tkMessageBox.showwarning(c.PROP, c.PROP_NOTHING_FOUND)

    def loadSerializedOntology(self, treeViewInstance):
        """ Tries to load a serialized ontology and other relevant data
            from a json file.
        :param treeViewInstance: View of the tree.
        """

        filePath = os.path.join(os.path.expanduser("~"), "viso.json")
        if os.path.exists(filePath):
            with open(filePath, 'r') as f:
                try:
                    self.tempData = json.load(f)
                    self.ontologyTree = self.tempData["classHierarchy"]
                    self.stack = ['']
                    self.instancesbyClass = self.tempData["instances"]
                    self.defaultName = self.tempData["defaultName"]
                    self.defaultTypeValue = self.tempData["defaultValue"]
                    self.defaultTypeValue = self.tempData["defaultValue"]
                    self.fileName = self.tempData["fileName"]
                    self.namespace = self.tempData["namespace"]
                    self.lastId = self.tempData["lastId"]
                    self.undoStack = self.tempData["undoStack"]
                    self.subTreeFromFileRecursive(self.ontologyTree,
                                                  treeViewInstance,
                                                  selectPrevious="subject")
                    self.treeConfiguration(self.treeEntityPicker)
                    self.treeConfiguration(self.treeRangePicker)
                    self.objectProperties = self.tempData["objectProperties"]
                    self.dataTypeProperties = \
                        self.tempData["dataTypeProperties"]
                    self.domainsByProperty = self.tempData["domains"]
                    self.rangesByProperty = self.tempData["ranges"]
                    self.objectPropertiesToAdd = \
                        self.tempData["propertyTriples"]
                    self.objectPropertiesToRemove = \
                        self.tempData["propertyTriplesToRemove"]
                    self.dataTypePropertiesToAdd = \
                        self.tempData["dataTypePropertyTriples"]
                    self.dataTypePropertiesToRemove = \
                        self.tempData["dataTypePropertyTriplesToRemove"]
                    self.initializePropertyTree(self.treePropertyPicker)
                except ValueError:
                    self.ontologyTree = None
                finally:
                    self.stack = None
                    f.close()

    def loadSerializedInstances(self):
        """ Load the current instance information (intancesByClass,
            domains, ranges) from the JSON file.
        """

        filePath = os.path.join(os.path.expanduser("~"), "viso.json")
        if os.path.exists(filePath):
            with open(filePath, 'r') as f:
                try:
                    self.tempData = json.load(f)
                    self.instancesbyClass = self.tempData["instances"]
                    self.domainsByProperty = self.tempData["domains"]
                    self.rangesByProperty = self.tempData["ranges"]
                    self.objectProperties = self.tempData["objectProperties"]
                    self.dataTypeProperties = \
                        self.tempData["dataTypeProperties"]
                    self.objectPropertiesToAdd = \
                        self.tempData["propertyTriples"]
                    self.dataTypePropertiesToAdd = \
                        self.tempData["dataTypePropertyTriples"]
                    self.dataTypePropertiesToRemove = \
                        self.tempData["dataTypePropertyTriplesToRemove"]
                    self.objectPropertiesToRemove = \
                        self.tempData["propertyTriplesToRemove"]
                    self.namespace = self.tempData["namespace"]
                except ValueError as e:
                    tkMessageBox.showwarning(c.FILE,
                                             c.FILE_SER_ERROR % e.strerror)
                finally:
                    f.close()

    def previousSelectedEntities(self, type="subject"):
        """ Returns the selected Entities/Instances previously selected
            by the user on the last time the GUI was closed.
        :param type: This should be "object", "subject" or "none".
        """

        if type == "subject":
            if self.selectedEntities:
                selected = self.selectedEntities
            elif "selectedEntities" in self.tempData:
                selected = self.tempData["selectedEntities"]
            else:
                selected = []
        elif type == "object":
            if self.selectedRange:
                selected = self.selectedRange
            elif "selectedRanges" in self.tempData:
                selected = self.tempData["selectedRanges"]
            else:
                selected = []
        else:
            selected = []
        return selected

    def previousSelectedProperties(self):
        """ Returns the last properties selected by the user. """
        if self.selectedProperties:
            selected = self.selectedProperties
        elif "selectedProperties" in self.tempData:
            selected = self.tempData["selectedProperties"]
        else:
            selected = []
        return selected

    def instanceExists(self, instance):
        """ Checks if instance exist.
        :param instance: Instance to be checked.
        :return: 'True' if instance already exist, 'False' otherwise.
        """

        for entity in self.instancesbyClass:
            if instance in self.instancesbyClass[entity]:
                return True
        return False

    def addDefaultProperties(self, reader):
        """ Check if the ontology has the required properties.
            If not, add them and inform the user.
        :param reader: Instance of the RDFReader class that allows to store
            properties into .rdf file.
        """

        default_properties = [
            c.HAS_SVG_PROPERTY, c.COOR_PROPERTY, c.X_COOR_PROPERTY,
            c.Y_COOR_PROPERTY
        ]
        added = []
        for property in default_properties:
            if not reader.hasProperty(property, "datatype"):
                added.append(property)
                reader.addProperty(property, "datatype")
        if added:
            tkMessageBox.showwarning(c.PROP,
                                     c.PROP_DATA_NOT_FOUND % ', '.join(added))
            reader.saveOntology()

    def close(self, event):
        self.closeGUI(isInstanceListChanged=True)

    def closeGUI(self, isInstanceListChanged):
        """ Closes the gui.
        :param isInstanceListChanged: True if something was changed and
            serialization should be done.
        """

        if isInstanceListChanged:
            self.serialize()

        self.root.destroy()

    def serialize(self):
        """ Serialize Ontology into JSON file in the user's home folder. """
        serializedInfo = {}
        if self.ontologyTree:
            serializedInfo["classHierarchy"] = self.ontologyTree
        else:
            tkMessageBox.showwarning(c.FILE, c.FILE_JSON_ERROR)
        serializedInfo["fileName"] = self.fileName
        serializedInfo["namespace"] = self.namespace
        serializedInfo["instances"] = self.instancesbyClass
        serializedInfo["objectProperties"] = self.objectProperties
        serializedInfo["dataTypeProperties"] = self.dataTypeProperties
        serializedInfo["ranges"] = self.rangesByProperty
        serializedInfo["domains"] = self.domainsByProperty
        serializedInfo["lastId"] = self.lastId
        serializedInfo["undoStack"] = self.undoStack
        serializedInfo["selectedEntities"] = [] if not self.selectedEntities \
            else self.selectedEntities
        serializedInfo["selectedRanges"] = [] if not self.selectedRange \
            else self.selectedRange
        serializedInfo["selectedProperties"] = [] if not self.selectedProperties \
            else self.selectedProperties
        serializedInfo["propertyTriples"] = self.objectPropertiesToAdd
        serializedInfo["propertyTriplesToRemove"] = \
            self.objectPropertiesToRemove
        serializedInfo["dataTypePropertyTriples"] = \
            self.dataTypePropertiesToAdd
        serializedInfo["dataTypePropertyTriplesToRemove"] = \
            self.dataTypePropertiesToRemove
        serializedInfo["defaultName"] = self.defaultName
        serializedInfo["defaultValue"] = self.defaultTypeValue
        serializedInfo["defaultValue"] = self.defaultTypeValue
        serialized = json.dumps(serializedInfo)
        filePath = os.path.join(os.path.expanduser("~"), c.JSON_FILENAME)
        try:
            f = open(filePath, 'w+')
            f.write(serialized)
        except IOError as e:
            tkMessageBox.showwarning(c.FILE, c.FILE_JSON_FOLDER)
            raise e
        finally:
            f.close()
예제 #13
0
파일: main.py 프로젝트: tdengg/pylastic
class pylasticGUI(Frame):
  
    def __init__(self):
        
        self.__fileName = 'POSCAR'
        self.__NoP = 11
        self.__strain = 0.05
        self.__executable = '/home/t.dengg/bin/vasp/vasp.5.3/vasp'
        self.__status = None
        self.__finished = None
        self.__paths = None
        self.__structuresinst = None
        self.__p1 = None
        self.__p2 = None
        self.__workdir = os.getcwd()
        Frame.__init__(self, name = 'pylastic')
        self.grid(row=0, column=0, sticky=NSEW)   
        #self.pack(expand=Y, fill=BOTH)
        self._create_panel()
            
        
    def _create_panel(self):
        
        panel = Frame(self, name='elastic')
        #panel.pack(side=TOP, fill=BOTH, expand=Y)
        panel.grid(row=0, column=0, sticky=NSEW) 
        nb = Notebook(panel, name='notebook')
        
        nb.enable_traversal()
        #nb.pack(fill=BOTH, expand=Y, padx=2, pady=3)
        nb.grid(row=0, column=0, sticky=NSEW)
        self._create_setup_tab(nb)
        self._create_analyze_tab(nb)
        
    def _create_setup_tab(self, nb):
        
        frame = Frame(nb, name='setup')
        
        self.e1 = Entry(frame, width=7)
        self.e1.bind()
        self.e1.grid(row=0, column=1)
        self.e1.delete(0, END)
        self.e1.insert(0, '21')
        
        self.label1 = Label(frame, text='Number of points:')
        self.label1.grid(row=0, column=0, sticky=W)
        
        self.e2 = Entry(frame, width=7)
        self.e2.bind()
        self.e2.grid(row=1, column=1)
        self.e2.delete(0, END)
        self.e2.insert(0, '0.05')
        
        self.label2 = Label(frame, text='Max. Lagrangian strain:')
        self.label2.grid(row=1, column=0, sticky=W)
        
        #Choose inputfile (Button)
        b2 = Button(frame, text="Inputfile", width=15, command=self.select_file)
        b2.grid(row=3, column=0, columnspan=2)
        
        b = Button(frame, text="set values", width=15, command=self.read_val)
        b.grid(row=4, column=0, columnspan=2)
        
        #Read structure (Button)
        b1 = Button(frame, text="Read structure", width=15, command=self.read_POS)
        b1.grid(row=5, column=0, columnspan=2)
        
        #Write structures (Button)
        b3 = Button(frame, text="Setup calculation", width=15, command=self.setup_calc)
        b3.grid(row=6, column=0, columnspan=2)
        
        #Strart calculations
        b4 = Button(frame, text="Calculation status", width=15, command=self.check_calc)
        b4.grid(row=7, column=0, columnspan=2)
        
        
        v = IntVar()
        r11 = Radiobutton(frame, text="Energy", variable=v, value=1)
        r12 = Radiobutton(frame, text="Strain", variable=v, value=2, state=DISABLED)
        r11.select()
        r11.grid(row=8, column=0, sticky=W)
        r12.grid(row=9, column=0, sticky=W)
        
        
        w = IntVar()
        r21 = Radiobutton(frame, text="2nd", variable=w, value=1)
        r22 = Radiobutton(frame, text="3rd", variable=w, value=2)
        r21.select()
        r21.grid(row=10, column=0, sticky=W)
        r22.grid(row=11, column=0, sticky=W)
        
        
        nb.add(frame, text='Setup', underline=0, padding=2)
        
        return
    
    
    def _create_analyze_tab(self, nb): 
        frame = Frame(nb, name='analyze')
        
        self._create_treeview(frame, )
        root = self.tree.insert('', END, text = 'calc', values=['text1','text2'])
        
        
        
        #self._populate_tree(root)
        
        #
        b1 = Button(frame, text="Refresh", width=15, command=lambda: self._populate_tree(root))
        b1.grid(row=2, column=0) 
        
        b2 = Button(frame, text="Analyze", width=15, command=lambda: self.analyze(frame))
        b2.grid(row=2, column=1)
        
        b2 = Button(frame, text="Result", width=15, command=lambda: self.create_window())
        b2.grid(row=2, column=2)
        
        
        if self.__status and '--------' in self.__status: self.__finished = False
        else: self.__finished = True
        
        if self.__status and self.__finished:
            ECs.set_analytics()
        
        
        

        
        
        nb.add(frame, text='Analyze', underline=0, padding=2)
        return
    
    def _populate_tree(self, root, lock=None):
        
        if lock: lock.acquire()
        if len(self.tree.get_children(self.tree.get_children())) > 1: 
            for i in self.tree.get_children(self.tree.get_children()): self.tree.delete(i)
        #self.tree.delete(self.tree.get_children())
        status, paths = self.check_calc()
        
        for key in status.keys():
            #print paths[key].lstrip(self.__workdir).split('/')
            self.tree.insert(root, END, text = status[key], values=['text3','text4', paths[key]])
        if lock: lock.release()
        
    
    def _create_treeview(self, parent):
        f = Frame(parent)
        #f.pack(side=TOP, fill=BOTH, expand=Y)
        f.grid(row=0, column=0, sticky=NSEW, columnspan=3)
        
        # create the tree and scrollbars
        self.dataCols = ('fullpath', 'type', 'status')       
        self.tree = Treeview(columns=self.dataCols,
                                 displaycolumns='status')
        
        ysb = Scrollbar(orient=VERTICAL, command= self.tree.yview)
        xsb = Scrollbar(orient=HORIZONTAL, command= self.tree.xview)
        self.tree['yscroll'] = ysb.set
        self.tree['xscroll'] = xsb.set
        
        # setup column headings
        self.tree.heading('#0', text='Directory Structure', anchor=W)
        self.tree.heading('status', text='Status', anchor=W)
        self.tree.column('status', stretch=0, width=100)
        
        # add tree and scrollbars to frame
        self.tree.grid(in_=f, row=0, column=0, sticky=NSEW)
        ysb.grid(in_=f, row=0, column=1, sticky=NS)
        xsb.grid(in_=f, row=1, column=0, sticky=EW)
        
        # set frame resizing priorities
        f.rowconfigure(0, weight=1)
        f.columnconfigure(0, weight=1)
        
        # action to perform when a node is expanded
        self.tree.bind('<<TreeviewOpen>>', self._update_tree)
        
        self.tree.bind("<Double-1>", self.OnDoubleClick)
        
    def OnDoubleClick(self, event):
        item = self.tree.identify('item',event.x,event.y)
        if self.tree.item(item,"text") == 'calc':
            self.create_window()
        
        
    def _update_tree(self, event):
        # user expanded a node - build the related directory
        nodeId = self.tree.focus()      # the id of the expanded node
        
        if self.tree.parent(nodeId):    # not at root
            topChild = self.tree.get_children(nodeId)[0]
            
            # if the node only has a 'dummy' child, remove it and
            # build new directory; skip if the node is already
            # populated
            if self.tree.item(topChild, option='text') == 'dummy':
                self.tree.delete(topChild)
                path = self.tree.set(nodeId, 'fullpath')
                self._populate_tree(nodeId, path, os.listdir(path))
    
    def create_window(self):
        
        t = Toplevel(self)
        t.wm_title("Elastic constants")
        l = Label(t, text="Elastic constants:")
        l.grid(row=0, column=0)
        textf = Text(t)
        try:
            textf.insert(INSERT, self.ec.get_C())
        except:
            textf.insert(INSERT, '')
        textf.grid(row=1, column=0)

    
    def read_val(self):
        self.__NoP = float(self.e1.get())
        self.__strain = float(self.e2.get())
        
    def read_POS(self):
        self.__poscar = POS(self.__fileName).read_pos()
        #print self.__poscar
        
    def read_strain(self):
        self.__strain = self.e2.get()
        
    def select_file(self):
        self.__fileName = askopenfilename()
        print self.__fileName
        self.__workdir = self.__fileName.rstrip('POSCAR')
        print self.__workdir
        
    def setup_calc(self):
        
        ###################### Create Structures instance: ###################
        self.__structuresinst = Structures()
        
        ## Generate distorted structures and add them to structures object: ##
        atom = ElAtoms()
        print self.__poscar
        atom.poscarToAtoms(self.__poscar)
        for etan in np.linspace(-self.__strain, self.__strain, self.__NoP):
            for strains in range(len(atom.strainList)):
                atom = ElAtoms()
                atom.poscarToAtoms(self.__poscar)
                atom.distort(eta=etan, strainType_index = strains)
                self.__structuresinst.append_structure(atom)
        
        ####################### Write vasp input files: #######################
        
        self.__structuresinst.workdir = self.__workdir
        self.__structuresinst.write_structures(self.__structuresinst)
        
        #################### Start local vasp calculation: ####################
        if self.__executable:
            lock = thread.allocate_lock()
            self.__structuresinst.executable = self.__executable
            thread.start_new_thread(self.__structuresinst.calc_vasp, (lock,))
            
    def check_calc(self):
        self.__status = {}
        self.__paths = {}
        if not self.__structuresinst:
            try:
                with open(self.__workdir+'/structures.pkl', 'rb') as input:
                    structures = pickle.load(input)
                atoms = structures.get_structures()
            except:
                raise Exception("Please do setup first!")
            
                
        else:
            atoms = self.__structuresinst.get_structures()
            #print self.__structuresinst
        
        for stype, eta in atoms:
            #print stype, eta, atoms[(stype,eta)].path
            
            try:
                et.parse(atoms[(stype,eta)].path+'/vasprun.xml')
                self.__status[(stype,eta)] = 'finished'
            except:
                self.__status[(stype,eta)] = '--------'
            self.__paths[(stype,eta)] = atoms[(stype,eta)].path
        
        return self.__status, self.__paths
        
    
    def analyze(self, frame):
        if self.__status and '--------' in self.__status: self.__finished = False
        else: self.__finished = True
        
        if self.__status and self.__finished:
        
            self.ec = ECs()
            self.ec.set_structures()
            self.ec.set_gsenergy()
            self.ec.set_analytics()
            
            self.__p1 = self.ec.plot_cvs()
            self.__p2 = self.ec.plot_2nd()
            canvas = FigureCanvasTkAgg(self.__p1, master=frame)
            canvas.show()
            canvas.get_tk_widget().grid(row=3, column=0)
            canvas = FigureCanvasTkAgg(self.__p2, master=frame)
            canvas.show()
            canvas.get_tk_widget().grid(row=3, column=1)

            canvas._tkcanvas.grid(row=3, column=2)
예제 #14
0
파일: gui.py 프로젝트: kelliott121/Octopod
class MacroFrame(Frame):

    def __init__(self, parent):
        Frame.__init__(self, parent, background="white")
        self.parent = parent
        self.numStates = 0
        self.initUI()

    def initUI(self):
        self.columnconfigure(0, weight=0)
        self.columnconfigure(1, weight=0)
        self.columnconfigure(2, weight=1)
        self.columnconfigure(3, weight=1)

        self.rowconfigure(0, weight=1)

        self.commandFrame = Frame(self, background="white")
        self.commandFrame.grid(row=0, column=0, columnspan=5, sticky=W+E)
        self.commandFrame.columnconfigure(1, weight=1)

        self.btnCommand = Button(self.commandFrame, text="Run")
        self.btnCommand.grid(row=0, column=0)

        self.strCommand = StringVar()
        self.entCommand = Entry(self.commandFrame, textvariable=self.strCommand)
        self.entCommand.grid(row=0, column=1, sticky=W+E)
        
        self.lstMacro = Listbox(self)
        self.lstMacro.grid(row=1, column=0, sticky=N+S+W+E)
        
        self.treeview = Treeview(self, columns=("Angle"), displaycolumns="#all", selectmode="browse")
        self.treeview.grid(row=1, column=1, columnspan=4, sticky=N+S+W+E)
        self.treeScrollbar = Scrollbar(self)
        self.treeScrollbar.grid(row=1, column=5, sticky=N+S)
        self.treeview.config(yscrollcommand=self.treeScrollbar.set)
        self.treeScrollbar.config(command=self.treeview.yview)

        self.btnFrame = Frame(self, background="white")
        self.btnFrame.grid(row=2, column=0, columnspan=5, sticky=W+E)

        self.btnRun = Button(self.btnFrame, text="Run", command=self.runMacro)
        self.btnRun.grid(row=0, column=0)
        
        self.btnStop = Button(self.btnFrame, text="Stop")
        self.btnStop.grid(row=0, column=1)

        self.btnSaveMacro = Button(self.btnFrame, text="Save Macro", command=self.saveMacro)
        self.btnSaveMacro.grid(row=0, column=2)

        self.btnDeleteMacro = Button(self.btnFrame, text="Delete Macro")
        self.btnDeleteMacro.grid(row=0, column=3)

        self.btnDeleteState = Button(self.btnFrame, text="Delete State")
        self.btnDeleteState.grid(row=0, column=4)

    def addState(self, robot):
        stateName = "state" + str(self.numStates)
        self.treeview.insert("", END, iid=stateName, text=stateName)
        limbNum = 0
        for limb in robot.getLimbs():
            limbName = "limb" + str(limbNum)
            self.treeview.insert(stateName, END, iid=stateName + "_" + limbName, text=limbName)
            partNum = 0
            for part in limb.getComponents():
                partName = "joint" + str(partNum)
                if isinstance(part, Joint):
                    self.treeview.insert(stateName + "_" + limbName,
                                         END,
                                         iid=stateName + "_" + limbName + "_" + partName,
                                         text=partName,
                                         values=[part.angle])
                    partNum += 1
            limbNum += 1
        self.numStates += 1

    def getState(self, stateNum, robot):
        stateName = "state" + str(stateNum)
        limbNum = 0
        for limb in robot.getLimbs():
            limbName = "limb" + str(limbNum)
            partNum = 0
            for part in limb.getComponents():
                partName = "joint" + str(partNum)
                if isinstance(part, Joint):
                    part.setAngle(int(self.treeview.item(stateName + "_" + limbName + "_" + partName, "values")[0]))
                    partNum += 1
            limbNum += 1

    def runMacro(self):
        thread = threading.Thread(target=self.updateState)
        thread.start()
            
    def updateState(self):
        for i in range(self.numStates):
            self.getState(i, self.parent.robotFrame.robot)
            time.sleep(.1)

    def saveMacro(self):
        pass
예제 #15
0
파일: comm.py 프로젝트: angelalonso/comm
class CommSearch(Frame):
  
    def __init__(self, parent):
        Frame.__init__(self, parent)   
         
        self.parent = parent        
        self.initUI()
        
    def initUI(self):

        self.entries_found = []

        self.parent.title("Search your command cards")
        self.style = Style()
        self.style.theme_use("default")        
        self.pack()
        
        self.input_title = Label(self, text="Enter your command below")
        self.input_title.grid(row=0, columnspan=2)
        self.input_box = Entry(self, width=90)
        self.input_box.grid(row=1, column=0)
        self.input_box.focus()
        self.input_box.bind("<Key>", self.onUpdateSearch)
        self.search_btn = Button(self, text="Search", command=self.onSearch)
        self.search_btn.grid(row=1, column=1)
        self.output_box = Treeview(self, columns=("Example"))
        ysb = Scrollbar(self, orient='vertical', command=self.output_box.yview)
        xsb = Scrollbar(self, orient='horizontal', command=self.output_box.xview)
        self.output_box.configure(yscroll=ysb.set, xscroll=xsb.set)
        self.output_box.heading('Example', text='Example', anchor='w')
        self.output_box.column("#0",minwidth=0,width=0, stretch=NO)
        self.output_box.column("Example",minwidth=0,width=785)
        self.output_box.bind("<Button-1>", self.OnEntryClick)
        self.output_box.grid(row=3, columnspan=2)
        self.selected_box = Text(self, width=110, height=19)
        self.selected_box.grid(row=4, columnspan=2)
        self.gotoadd_btn = Button(self, text="Go to Add", command=self.onGoToAdd)
        self.gotoadd_btn.grid(row=5)

    def OnEntryClick(self, event):
        try:
            item = self.output_box.selection()[0]
        except IndexError:
            pass
        entry_title = self.output_box.item(item,"value")
        for item in self.entries_found:
            if str(entry_title) == str("('" + item.title.strip('\n') + "',)"):
                self.selected_box.delete(0.1, END)
                self.selected_box.insert(END, item.text + '\n')

    def onUpdateSearch(self, key):
    # Somehow calling self.onSearch() does not register last key
    # And we need to correct "special chars"
        global entries, entries_map
        text_entries = ""
        for item in self.output_box.get_children():
            self.output_box.delete(item)		
    # ...like, for instance, deleting last character
        if key.char == '\b':
            search_terms = str(self.input_box.get()[:-1])
        else: 
            search_terms = str(self.input_box.get() + key.char)
        self.entries_found = []
        self.entries_found = data.Search(search_terms,entries,entries_map)
        for item in range(len(self.entries_found)):
            aux = self.output_box.insert('', 'end', '', value=[self.entries_found[item].title.split('\n')[0]])

			
    def onSearch(self):
        global entries, entries_map
        text_entries = ""
        for item in self.output_box.get_children():
            self.output_box.delete(item)
        search_terms = str(self.input_box.get())
        for item in data.Search(search_terms,entries,entries_map):
            self.output_box.insert('', 'end', '', value=[self.entries_found[item].title.split('\n')[0]])
			
    def onGoToAdd(self):
        newroot = Tk()
        newcomm = CommAdd(newroot)
        newroot.geometry("800x600+0+0")
        newroot.mainloop()
예제 #16
0
class Tree(Treeview):
    """ Класс, формирующий таблицу """
    def __init__(self, root, frame, num, logit, all_values, list_styles_names):
        Treeview.__init__(self, root)
        self.root = root
        self.num = num
        self.frame = frame
        self.name = "MOXA-%s" % str(self.num)
        self.tree = Treeview(frame, style=list_styles_names[num])
        self.tree["columns"] = ("one", "two", "three")
        self.tree.heading("#0", text="")
        self.tree.column("#0", minwidth=0, width=5, stretch=NO)
        self.tree.heading("one", text="Port")
        self.tree.column("one", minwidth=0, width=30, stretch=NO)
        self.tree.column("two", minwidth=0, width=name_column, stretch=NO)
        self.tree.heading("three", text="State")
        self.tree.column("three", minwidth=0, width=state_column, stretch=YES)
        self.tree['height'] = 32
        self.tree.tag_configure('green',
                                background='gray7',
                                foreground='green2')
        self.tree.tag_configure('red',
                                background='gray7',
                                foreground='tomato2')
        self.tree.tag_configure('blue',
                                background='gray7',
                                foreground='RoyalBlue')
        self.tree.tag_configure('yellow',
                                background='gray7',
                                foreground='yellow')
        self.tree.tag_configure('ready',
                                background='gray7',
                                foreground='white')
        self.tree.tag_configure(
            'focus',
            background='yellow',
        )
        self.tree.bind("<Motion>", self.mycallback)
        self.last_focus = None
        self.tree.pack(side=LEFT)
        self.logit = logit
        self.moxa = all_values[self.num][0]
        self.wraplength = 180
        for key in self.moxa.keys():
            self.tree.insert("",
                             "end",
                             values=(str(key), self.moxa[key], "<><><>"),
                             tags=("green", ))

    def mycallback(self, event):
        """ Функция, отображающая комментарий при наведении мыши на канал """

        _iid = self.tree.identify_row(event.y)
        if _iid != self.last_focus:
            if self.last_focus:
                try:
                    if self.tw:
                        self.tw.destroy()
                except:
                    pass

            if _iid:
                row = self.tree.item(_iid)
                key = row["values"][0]
                if os.path.isfile('comments/comment_%s_%s.txt' %
                                  (self.num, key)):
                    with open('comments/comment_%s_%s.txt' % (self.num, key),
                              'a+') as comment:
                        file_log = comment.read()
                        param = self.tree.bbox(_iid)
                        x = (param[0] + space_X) * self.num
                        y = param[1] + space_Y
                        self.tw = tk.Toplevel()
                        self.tw.wm_overrideredirect(True)
                        self.tw.wm_geometry("+%d+%d" % (x, y))
                        label = tk.Label(self.tw,
                                         text=file_log,
                                         justify='left',
                                         background="yellow2",
                                         relief='solid',
                                         borderwidth=1,
                                         wraplength=self.wraplength,
                                         font=tkFont.Font(family=main_font,
                                                          size=size_font))
                        label.pack()
                self.last_focus = _iid
예제 #17
0
class XML_Viwer(Frame):

    def __init__(self, master, xml=None, heading_text=None, heading_anchor=None, padding=None, cursor=None, takefocus=None, style=None):
        Frame.__init__(self, master, class_="XML_Viwer")

        self._vsb = Scrollbar(self, orient=VERTICAL)
        self._hsb = Scrollbar(self, orient=HORIZONTAL)

        kwargs = {}
        kwargs["yscrollcommand"] = lambda f, l: autoscroll(self._vsb, f, l)
        kwargs["xscrollcommand"] = lambda f, l: autoscroll(self._hsb, f, l)
       
        if style is not None:
            kwargs["style"] = style
            
        if padding is not None:
            kwargs["padding"] = padding
            
        if cursor is not None:
            kwargs["cursor"] = cursor
            
        if takefocus is not None:
            kwargs["takefocus"] = takefocus

        self._treeview = Treeview(self, **kwargs)
        
        if heading_text is not None:
            if heading_anchor is not None:
                self._treeview.heading("#0", text=heading_text, anchor=heading_anchor)
            else:
                self._treeview.heading("#0", text=heading_text)

        self._treeview.bind("<<TreeviewOpen>>", self._on_open)
        self._treeview.bind("<<TreeviewClose>>", self._on_close)
        
        # Without this line, horizontal scrolling doesn't work properly.
        self._treeview.column("#0", stretch= False)

        self._vsb['command'] = self._treeview.yview
        self._hsb['command'] = self._treeview.xview

        self._treeview.grid(column=0, row=0, sticky=N+S+W+E)
        self._vsb.grid(column=1, row=0, sticky=N+S)
        self._hsb.grid(column=0, row=1, sticky=E+W)
        
        self.grid_columnconfigure(0, weight=1)
        self.grid_rowconfigure(0, weight=1)

        self._element_tree = None
        self._item_ID_to_element = {}

        if xml is not None:
            self.parse_xml(xml)

    def _on_open(self, event):
        item_ID = self._treeview.focus()
        if item_ID not in self._item_ID_to_element: return

        node = self._item_ID_to_element[item_ID]

        self._treeview.item(item_ID, text = self._repr_of_openning_tag(node))
        
    def _on_close(self, event):
        item_ID = self._treeview.focus()
        if item_ID not in self._item_ID_to_element: return

        node = self._item_ID_to_element[item_ID]
        
        text = self._repr_of_openning_tag(node) + self._repr_of_closing_tag(node)
        self._treeview.item(item_ID, text = text)

    def parse_xml(self, xml):
        self._element_tree = ET.ElementTree(ET.fromstring(xml))
        
        self.clear()
        self._walk_xml(self._element_tree.getroot())
        
    @property
    def element_tree(self):
        return self._element_tree
    
    @element_tree.setter
    def element_tree(self, element_tree):
        self._element_tree = element_tree
        
        self.clear()
        self._walk_xml(element_tree.getroot())   
        
    def clear(self):
        self._item_ID_to_element = {}
        self._treeview.delete(*self._treeview.get_children())
        
    def _repr_of_openning_tag(self, node):
        text = "<" + node.tag

        attrs = node.attrib
        
        # list function is here necessary to provide support to Python 3
        a_names = list(attrs.keys())
        a_names.sort()

        for a_name in a_names:
            text += ' %s="' % a_name
            text += attrs[a_name]
            text += '"'

        text += ">"
        return text
        
    def _repr_of_closing_tag(self, node):
        return "</%s>"%node.tag

    def _walk_xml(self, node, depth=0, parent=""):
        text = self._repr_of_openning_tag(node) + self._repr_of_closing_tag(node)

        item = self._treeview.insert(parent, END, text = text)
        self._item_ID_to_element[item] = node
        
        if node.text:
            text = node.text.strip()
            if text != "":
                for line in text.splitlines():
                    self._treeview.insert(item, END, text = line)

        child_nodes = sorted(list(node), key=attrgetter('tag'))
        for child_node in node:
            self._walk_xml(child_node, depth+1, parent=item)

        
        if node.tail:
            tail = node.tail.strip()
            if tail != "":
                for line in tail.splitlines():
                    self._treeview.insert(parent, END, text = line)
예제 #18
0
class App:
    def __init__(self,master):
        self.master = master
        self.master.resizable(0,0)
        self.master.update_idletasks()
        self.master.overrideredirect(1)
        self.master.attributes("-topmost",True)
        self.master.title("New Graph")
        self.master.lift()
        self.menubar = Menu(self.master)
        self.master.config(menu=self.menubar)
        self.default_color = self.master.cget("bg")
        self.active_edit_flag = 0
        self.modify_flag = 0
        self.graph_types = ['Default','Maelstrom','Rankine Half-Body','Rankine Oval', 'Cylinder','Stagnation & Vortex']
       #-----------------------------------------------------------------------
        self.file_menu = Menu(self.menubar)
        
        self.Fig = matplotlib.figure.Figure(figsize=(2.148,1.777),dpi=100,tight_layout=True)
        self.FigSubPlot = self.Fig.add_subplot(111)     
        frame = Frame(master,bg='#%02x%02x%02x' % (231, 231, 231))
        frame.pack(fill=BOTH, expand=1)
        frame2 = Frame(frame,bg='#%02x%02x%02x' % (221, 221, 221))
        frame2.pack(fill=BOTH, expand=1,padx=20,pady=23)
        self.frame3 = Frame(frame2, bg='#%02x%02x%02x' % (221, 221, 221))
        self.frame3.pack(fill=BOTH, padx=17,pady=17,expand=1)
        self.radio_frame = Frame(self.frame3,bg='#%02x%02x%02x' % (221, 221, 221))
      
        #self.listbox = Listbox(self.frame3)
        self.radio_var = StringVar()
        self.radio_var.set('Default')
        for key in self.graph_types:
            b = Radiobutton(self.radio_frame,text=key,variable=self.radio_var,value = key,bg='#%02x%02x%02x' % (221, 221, 221),indicatoron=1)
            b.pack(anchor=W)
#        for key_num in range(0,len(self.graph_types)):
#            self.listbox.insert(END,self.graph_types[key_num])
#        self.listbox.select_set(0)
#        self.listbox.bind('<<ListboxSelect>>',self.changegraph)
        self.radio_var.trace('w',self.changegraph)
#        self.old = self.listbox.get(self.listbox.curselection())
        self.blankc = Canvas(self.frame3,width=225,height=188)
        self.canvas = FigureCanvasTkAgg(self.Fig, master=self.frame3)
        self.canvas.show()
        self.canvas.get_tk_widget().pack(side=RIGHT,padx=0,pady=5)
        self.radio_frame.pack(side=LEFT,anchor=W,padx=8,pady=5,fill=BOTH,expand=1) 
        #self.listbox.pack(side=LEFT,anchor=W,padx=8,pady=5,fill=BOTH,expand=1)   
        self.button_frame = Frame(frame,bg='#%02x%02x%02x' % (231, 231, 231))
        self.button_frame.pack(side=RIGHT)
        self.buffer_frame = Frame(self.button_frame,bg='#%02x%02x%02x' % (231, 231, 231))
        self.buffer_frame.pack(side=BOTTOM,pady=8)
        self.buffer_frame2 = Frame(self.button_frame,bg='#%02x%02x%02x' % (231, 231, 231))
        self.buffer_frame2.pack(side=RIGHT,padx=11)
        self.button_c = Button(self.button_frame,width=9, text='Choose',bg='#%02x%02x%02x' % (231, 231, 231),command=self.Continue)
        self.button_x = Button(self.button_frame,text='Cancel',bg='#%02x%02x%02x' % (231, 231, 231),width=9,command=self.quit)
        self.button_c.focus()
        self.button_c.pack(side=RIGHT)
        self.button_x.pack(side=RIGHT,padx=14)
        self.line_color = StringVar()
        self.line_color.set('#000000')
        self.wt_var = StringVar()
        self.wt_var.set('- WT:')
        self.wt_var.trace('w',self.wt_update)
        self.linet_var = StringVar()
        self.linet_var.set('-')
        self.linet_var.trace('w',self.line_style_update)
        self.line_var = IntVar()
        self.line_var.set(25)
        self.line_val = 25
        self.div_check_var = IntVar()
        self.div_check_var.set(50)
        self.div_val = 50
        self.density_var = IntVar()
        self.density_var.set(35)
        self.density_val = 35
        self.arrow_var = IntVar()
        self.arrow_var.set(25) 
        self.arrow_val = 25
        self.div_var = IntVar()
        self.div_var.set(0)
        self.mark_var = IntVar()
        self.mark_var.set(0)
        self.lock_var = IntVar()
        self.lock_var.set(1)
        self.active_numbers = {'s':0,'v':0,'u':0,'d':0,'n':0}
        self.sel_point = None
        self.selected = None
    def changegraph(self,*args):
        self.xlim = [-5.0,5.0]
        self.ylim = [-5.0,5.0]
        Y, X = mgrid[-5:5:100j, -5:5:100j]
        self.X,self.Y = X,Y
        self.FigSubPlot.clear()
        #if self.listbox.get(self.listbox.curselection()) == 'Default':
        if self.radio_var.get() == 'Default':
            self.U = 0*X
            self.V = 0*X
            self.FigSubPlot.streamplot(X,Y,self.U,self.V)
        #elif self.listbox.get(self.listbox.curselection()) == 'Maelstrom':
        elif self.radio_var.get() == 'Maelstrom':    
            self.U = self.source(X,Y,1)[0]+self.vortex(X,Y,1)[0]
            self.V = self.source(X,Y,1)[1]+self.vortex(X,Y,1)[1]
            self.FigSubPlot.streamplot(X,Y,self.U,self.V, color='k', linewidth=(2.0/71.0)*self.line_var.get()+(13.0/71.0),density=(2.0/71.0)*self.density_var.get()+(13.0/71.0),arrowstyle='-')
        #elif self.listbox.get(self.listbox.curselection()) == 'Rankine Half-Body':
        elif self.radio_var.get() == 'Rankine Half-Body':
            self.U = self.source(X,Y,10)[0]+self.uniform(X,Y,1,1,0)[0]
            self.V = self.source(X,Y,10)[1]+self.uniform(X,Y,1,1,0)[1]
            self.FigSubPlot.streamplot(X, Y,self.U,self.V, color='k', linewidth=(2.0/71.0)*self.line_var.get()+(13.0/71.0),density=(2.0/71.0)*self.density_var.get()+(13.0/71.0),arrowstyle='-')
        #elif self.listbox.get(self.listbox.curselection()) == 'Rankine Oval':
        elif self.radio_var.get() == 'Rankine Oval':
            self.U = self.source(X+2,Y,10)[0]+self.source(X-2,Y,-10)[0]+self.uniform(X,Y,1,1,0)[0]
            self.V = self.source(X+2,Y,10)[1]+self.source(X-2,Y,-10)[1]+self.uniform(X,Y,1,1,0)[1]
            self.FigSubPlot.streamplot(X, Y,self.U,self.V, color='k', linewidth=(2.0/71.0)*self.line_var.get()+(13.0/71.0),density=(2.0/71.0)*self.density_var.get()+(13.0/71.0),arrowstyle='-')
        #elif self.listbox.get(self.listbox.curselection()) == 'Cylinder':
        elif self.radio_var.get() == 'Cylinder':
            self.U = self.doublet(X,Y,25)[0]+self.uniform(X,Y,1,1,0)[0]
            self.V = self.doublet(X,Y,25)[1]+self.uniform(X,Y,1,1,0)[1]
            self.FigSubPlot.streamplot(X, Y,self.U,self.V, color='k', linewidth=(2.0/71.0)*self.line_var.get()+(13.0/71.0),density=(2.0/71.0)*self.density_var.get()+(13.0/71.0),arrowstyle='-')
        #elif self.listbox.get(self.listbox.curselection()) == 'Stagnation & Vortex':
        elif self.radio_var.get() == 'Stagnation & Vortex':
            self.U = self.vortex(X,Y,25)[0]+self.corner(X,Y,'2,1')[0]
            self.V = self.vortex(X,Y,25)[1]+self.corner(X,Y,'2,1')[1]
            self.FigSubPlot.streamplot(X, Y,self.U,self.V, color='k', linewidth=(2.0/71.0)*self.line_var.get()+(13.0/71.0),density=(2.0/71.0)*self.density_var.get()+(13.0/71.0),arrowstyle='-')
        self.FigSubPlot.set_xlim(self.xlim)
        self.FigSubPlot.set_ylim(self.ylim)
        self.canvas.draw()
#        self.old = self.listbox.get(self.listbox.curselection())
    def source(self,X,Y,l):
        l = float(l)
        U = (l/(2*pi))*X/(X*X + Y*Y)
        V = (l/(2*pi))*Y/(X*X + Y*Y)
        return (U,V)
    def vortex(self,X,Y,g):
        g = float(g)
        U = (g/(2*pi))*Y/(X*X + Y*Y)
        V = (g/(2*pi))*-X/(X*X + Y*Y)
        return (U,V)
    def uniform(self,X,Y,v_0,x_0,y_0):
        v_0 = float(v_0)
        x_0 = float(x_0)
        y_0 = float(y_0)
        U = v_0*x_0/(x_0*x_0+y_0*y_0)**0.5
        V = v_0*y_0/(x_0*x_0+y_0*y_0)**0.5
        return (U,V)
    def doublet(self,X,Y,k):
        k = float(k)
        U = (k/(2*pi))*((2*Y*Y/((X*X+Y*Y)*(X*X+Y*Y)))-(1/(X*X+Y*Y)))
        V = -(k/(2*pi))*(2*X*Y/((X*X+Y*Y)*(X*X+Y*Y)))
        return (U,V)
    def corner(self,X,Y,tup):
        comma_flag = 0
        A = ''
        n = ''
        for char in tup:
            if char == ',':
                comma_flag = 1
            elif comma_flag == 0:
                n += char
            elif comma_flag == 1:
                A += char
        A = float(A)
        n = float(n)
        R = (X*X+Y*Y)**0.5
        t = arctan2(-Y,-X)
        U = -A*n*R**(n-1)*(cos(n*t)*cos(t)+sin(n*t)*sin(t))
        V = -A*n*R**(n-1)*(cos(n*t)*sin(t)-sin(n*t)*cos(t))
        return (U,V)
    def stream_source(self,X,Y,l):
        l = float(l)
        stream = (l/(2*pi))*arctan2(-Y,-X)
        return stream
    def stream_vortex(self,X,Y,g):
        g = float(g)
        stream = (g/(2*pi))*log((X*X + Y*Y)**0.5)
        return stream
    def stream_uniform(self,X,Y,v_0,x_0,y_0):
        v_0 = float(v_0)
        x_0 = float(x_0)
        y_0 = float(y_0)
        stream = (v_0*Y*x_0/(x_0*x_0+y_0*y_0)**0.5)-(v_0*X*y_0/(x_0*x_0+y_0*y_0)**0.5)
        return stream
    def stream_doublet(self,X,Y,k):
        k = float(k)
        stream = -(k/(2*pi))*Y/(X*X+Y*Y)
        return stream
    def stream_corner(self,X,Y,tup):
        comma_flag = 0
        A = ''
        n = ''
        for char in tup:
            if char == ',':
                comma_flag = 1
            elif comma_flag == 0:
                n += char
            elif comma_flag == 1:
                A += char
        A = float(A)
        n = float(n)
        stream = A*(X*X+Y*Y)**(n*0.5)*sin(n*arctan2(-Y,-X))
        return stream
    def quit(self):
        self.master.destroy()    
    def Continue(self):
        self.master.withdraw()
        self.main = Toplevel(self.master)
        self.main.geometry("%dx%d+%d+%d" % (1038-206, 
                               694,
                               int((500.0/2560.0)*screen_resolution[0]), 
                               int((60.0/1440.0)*screen_resolution[1])))
        self.main.minsize(376,227)                      
        self.interior = PanedWindow(self.main,sashwidth=5)
        self.interior.pack(fill=BOTH, expand=1)

        self.elements_frame = Frame(self.interior, height=1038, width=212,relief=RIDGE,borderwidth=0)
        self.interior.add(self.elements_frame) 
        self.interior.paneconfig(self.elements_frame,minsize=130)
        self.graph_frame = Frame(self.interior)
        self.interior.add(self.graph_frame)
        self.interior.paneconfig(self.graph_frame,minsize=130)

        self.main.bind("<ButtonRelease-1>",self.pan_update)
        self.main.bind("<ButtonRelease-3>",self.pan_update)
        self.main.bind("<Button-3>",self.right_menu)
        
        self.edit_frame = Frame(self.graph_frame)
        self.edit_frame.pack(side=TOP,fill=X,padx=10)
        self.canvas = FigureCanvasTkAgg(self.Fig, master=self.graph_frame)
        self.canvas.show()
        self.canvas.get_tk_widget().pack(fill=BOTH,expand=1)
        self.nav_frame = Frame(self.edit_frame)
        self.nav_frame.pack(side=LEFT,anchor=W)
        self.toolbar = NavigationToolbar(self.canvas, self.nav_frame)
        
        self.main.protocol('WM_DELETE_WINDOW',self.master.destroy) 
        self.elements = Treeview(self.elements_frame,columns=("values","xlocations","ylocations"),selectmode=BROWSE)
        self.elements.heading("#0",text="Components")
        self.elements.heading("values",text="Str")
        self.elements.heading("xlocations",text="X")
        self.elements.heading("ylocations",text="Y")
        self.elements.column("#0",width=90,anchor=CENTER)
        self.elements.column("values",width=45,anchor=CENTER)
        self.elements.column("xlocations",width=26,anchor=CENTER)
        self.elements.column("ylocations",width=26,anchor=CENTER)
        self.elements.pack(fill=BOTH,expand=1)
        
        self.as_button_frame = Frame(self.elements_frame)
        self.add_button = Button(self.as_button_frame,text = '+',width=2,command=self.add)       
        self.sub_button = Button(self.as_button_frame,text = '-',width=2,command=self.subtract) 
        self.options_button = Button(self.as_button_frame,text='Options',command=self.options)
        self.as_button_frame.pack(side=BOTTOM,anchor=W)
        self.options_button.pack(side=RIGHT)
        self.sub_button.pack(side=RIGHT,anchor=W)
        self.add_button.pack(side=LEFT,anchor=W)
        self.addsub_menu = Menu(self.as_button_frame,tearoff=0)
        self.addsub_menu.add_command(command=self.add_source,label='Source')
        self.addsub_menu.add_command(command=self.add_vortex,label='Vortex')
        self.addsub_menu.add_command(command=self.add_uniform,label='Uniform')
        self.addsub_menu.add_command(command=self.add_doublet,label='Doublet')
        self.addsub_menu.add_command(command=self.add_corner,label='Corner')
        

        #if self.listbox.get(self.listbox.curselection()) == 'Default':
        if self.radio_var.get() == 'Default':
            self.active_components = []
            self.active_calls = {} 
            pass
        #elif self.listbox.get(self.listbox.curselection()) == 'Maelstrom':
        elif self.radio_var.get() == 'Maelstrom':
            self.elements.insert("",0,"M",text="Maelstrom",open=TRUE)
            self.active_components = ['M']
            self.elements.insert("M",0,iid='s%s'%self.active_numbers['s'],text="Source",values=("%s"%1,0,0))
            self.elements.insert("M",0,iid='v%s'%self.active_numbers['v'],text="Vortex",values=("%s"%1,0,0))
            self.active_calls = {'s%s'%self.active_numbers['s']:("s",self.elements.item('s%s'%self.active_numbers['s'],"values")),
                                 'v%s'%self.active_numbers['v']:("v",self.elements.item('v%s'%self.active_numbers['v'],"values"))}
            self.active_numbers['s'] += 1
            self.active_numbers['v'] += 1
        elif self.radio_var.get() == 'Rankine Half-Body':
            self.elements.insert("",0,"RHF",text="Rankine Half-Body",open=TRUE)
            self.active_components = ['RHF']
            self.elements.insert("RHF",0,iid='s%s'%self.active_numbers['s'],text="Source",values=("%s"%10,0,0))
            self.elements.insert("RHF",0,iid='u%s'%self.active_numbers['u'],text="Uniform",values=("%s"%1,1,0))
            self.active_calls = {'s%s'%self.active_numbers['s']:("s",self.elements.item('s%s'%self.active_numbers['s'],"values")),
                                 'u%s'%self.active_numbers['u']:("u",self.elements.item('u%s'%self.active_numbers['u'],"values"))}
            self.active_numbers['s'] += 1
            self.active_numbers['u'] += 1
        elif self.radio_var.get() == 'Rankine Oval':
            self.elements.insert("",0,"RO",text="Rankine Oval",open=TRUE)
            self.active_components = ['RO']
            self.elements.insert("RO",0,iid='s%s'%self.active_numbers['s'],text="Source",values=("%s"%10,-2,0))
            self.elements.insert("RO",0,iid='s%s'%(self.active_numbers['s']+1),text="Source",values=("%s"%-10,2,0))
            self.elements.insert("RO",0,iid='u%s'%self.active_numbers['u'],text="Uniform",values=("%s"%1,1,0))
            self.active_calls = {'s%s'%self.active_numbers['s']:("s",self.elements.item('s%s'%self.active_numbers['s'],"values")),
                                 's%s'%(self.active_numbers['s']+1):("s",self.elements.item('s%s'%(self.active_numbers['s']+1),"values")),
                                 'u%s'%self.active_numbers['u']:("u",self.elements.item('u%s'%self.active_numbers['u'],"values"))}
            self.active_numbers['s'] += 2
            self.active_numbers['u'] += 1       
        elif self.radio_var.get() == 'Cylinder':
            self.elements.insert("",0,'D+U',text="Cylinder",open=TRUE)
            self.active_components = ['D+U']
            self.elements.insert('D+U',0,iid='d%s'%self.active_numbers['d'],text="Doublet",values=("%s"%25,0,0))
            self.elements.insert('D+U',0,iid='u%s'%self.active_numbers['u'],text="Uniform",values=("%s"%1,1,0))
            self.active_calls = {'d%s'%self.active_numbers['d']:("d",self.elements.item('d%s'%self.active_numbers['d'],"values")),
                                 'u%s'%self.active_numbers['u']:("u",self.elements.item('u%s'%self.active_numbers['u'],"values"))}
            self.active_numbers['d'] += 1
            self.active_numbers['u'] += 1
        elif self.radio_var.get() == 'Stagnation & Vortex':
            self.elements.insert("",0,'S+V',text="Stag+Vort",open=TRUE)
            self.active_components = ['S+V']
            self.elements.insert('S+V',0,iid='n%s'%self.active_numbers['n'],text="C (n,A)",values=("%s,%s"%(2,1),0,0))
            self.elements.insert('S+V',0,iid='v%s'%self.active_numbers['v'],text="Vortex",values=("%s"%25,0,0))
            self.active_calls = {'n%s'%self.active_numbers['n']:("n",self.elements.item('n%s'%self.active_numbers['n'],"values")),
                                 'v%s'%self.active_numbers['v']:("v",self.elements.item('v%s'%self.active_numbers['v'],"values"))}
            self.active_numbers['n'] += 1
            self.active_numbers['v'] += 1
        self.elements.bind("<Double-Button-1>",self.edit)
        self.elements.bind('<<TreeviewSelect>>',self.treeview_select)
        self.main.bind("<Return>",self.edit_return)
        self.main.bind("<Escape>",self.edit_return)

        
        self.rightc_menu = Menu(self.graph_frame,tearoff=0)
        self.add_menu = Menu(self.rightc_menu,tearoff=0)
        self.rightc_menu.add_cascade(label="Add",menu=self.add_menu)
        self.add_menu.add_command(command=self.addm_source,label='Source')
        self.add_menu.add_command(command=self.addm_vortex,label='Vortex')
        self.add_menu.add_command(command=self.addm_uniform,label='Uniform')
        self.add_menu.add_command(command=self.addm_doublet,label='Doublet')
        self.add_menu.add_command(command=self.addm_corner,label='Corner')
    def right_menu(self,event):
        print "event", event.x,event.y
        #print "graph", self.main.winfo_x()+self.interior.winfo_x()+self.graph_frame.winfo_x(), self.main.winfo_y()+self.interior.winfo_y()+self.graph_frame.winfo_y()
        self.plot_x,self.plot_y = self.FigSubPlot.transData.inverted().transform((event.x,event.y+20))
        self.plot_y = -self.plot_y
        self.rightc_menu.post(self.main.winfo_x()+self.interior.winfo_x()+self.graph_frame.winfo_x()+event.x+9,self.main.winfo_y()+self.graph_frame.winfo_y()+event.y+66)
        
    def treeview_select(self,event):
        if self.elements.get_children(self.elements.selection()[0]) == ():
            if self.mark_var.get() == 0 or self.selected == self.elements.selection():
                pass
            elif self.mark_var.get() == 1:
                
                #add red markers here
                
                if self.elements.selection() != '':
                    child = self.elements.selection()[0]
                    if child != '':
                        self.sel_point = (self.elements.item(child,"values")[1],self.elements.item(child,"values")[2])
                        self.graph_update()
                        self.selected = self.elements.selection()
                else:
                    pass
        else:
            if self.mark_var.get() == 0 or self.selected == self.elements.selection():
                pass
            elif self.mark_var.get() == 1:
                if self.elements.selection() != '':
                    child = self.elements.selection()[0]
                    if child != '':
                        self.sel_point = None
                        self.graph_update()
                        self.selected = self.elements.selection()
    def mark_check_fun(self):
        if self.mark_var.get() == 0:
            self.sel_point = None
            self.graph_update()
        elif self.elements.selection() != '':
            child = self.elements.selection()[0]
            self.sel_point = [self.elements.item(child,"values")[1],self.elements.item(child,"values")[2]]
            self.graph_update()
            
    def add(self):
        self.addsub_menu.post(self.main.winfo_x()+self.as_button_frame.winfo_x()+self.add_button.winfo_x(),self.main.winfo_y()+self.as_button_frame.winfo_y()+self.add_button.winfo_y()-len(self.active_numbers.keys())*14)
    def subtract(self):
        if self.active_edit_flag == 1:
            self.del_edit(self)
        child = self.elements.selection()[0]
        if child == '':
            return
        if self.elements.parent(child) == '':
            ID = child
            self.active_components.remove(child)
            self.elements.delete(child)
        else:
            ID = self.elements.parent(child)
            self.active_components.remove(ID)
            for comp in self.elements.get_children(ID):
                if comp != child:
                    self.active_components.append(comp)
                    self.elements.move(comp,"",0)
            self.elements.delete(ID)
        self.sel_point = None
        self.graph_update()
    def options(self):
        self.options_window = Toplevel(self.main)
        self.options_window.geometry("%dx%d+%d+%d" % (280, 
                                                      200+20,
                                                      self.main.winfo_x()+self.as_button_frame.winfo_x()+self.options_button.winfo_x()-272+26+72+86,
                                                      self.main.winfo_y()+self.as_button_frame.winfo_y()+self.options_button.winfo_y()-196-20))
        self.main.bind('<FocusIn>',self.close_options)
        self.options_window.title("Options")
        self.options_window.update_idletasks()
        self.options_window.bind("<ButtonRelease-1>",self.pan_update)
        self.options_frame = Frame(self.options_window)
        self.options_frame.pack(fill=BOTH,expand=1)
        self.options_window.attributes("-topmost",True)

        self.line_frame = Frame(self.options_frame,bd=2,relief=RIDGE)
        self.line_frame.grid(row=0,column=1,sticky=N+S+E+W,ipady=7)
        self.color_frame = Frame(self.options_frame,bd=2,relief=RIDGE,padx=2)
        self.color_frame.grid(row=0,column=0,sticky=N+S+E+W)
        
        self.color_button = Label(self.color_frame,bg=self.line_color.get(),text = '     ')
        self.color_button.pack(side=RIGHT)
        Label(self.color_frame,text='C:').pack(side=RIGHT)
        self.color_button.bind('<Button-1>',self.getColor)
        
        self.wt_slider = Scale(self.line_frame,from_=1,to=100,orient=HORIZONTAL,variable=self.line_var)
        if self.wt_var.get() == '-> WT:':
            self.wt_slider.config(variable=self.arrow_var)
        elif self.wt_var.get() == '- WT:':
            self.wt_slider.config(variable=self.line_var)
        elif self.wt_var.get() == 'div WT:':
            self.wt_slider.config(variable=self.div_check_var)
        self.wt_slider.pack(side=RIGHT)
        
        self.wt_menu = OptionMenu(self.line_frame,self.wt_var,'- WT:','-> WT:','div WT:')
        self.wt_menu.pack(side=RIGHT,anchor='center',fill=X,expand=1)
        self.wt_menu.config(width=8)
        self.density_frame = Frame(self.options_frame,bd=2,relief=RIDGE)
        self.density_frame.grid(row=1,column=1,sticky=N+S+E+W)
        self.density_slider = Scale(self.density_frame,from_=1,to=100,orient=HORIZONTAL,variable=self.density_var)
        self.density_slider.pack(side=RIGHT)
        Label(self.density_frame,text='Density').pack(side=LEFT,anchor=CENTER,fill=X,expand=1)
        
        self.linet_frame = Frame(self.options_frame,bd=2,relief=RIDGE)
        self.linet_frame.grid(row=1,column=0,sticky=N+S+E+W)
        Label(self.linet_frame,text='Style').pack(anchor='n')
        self.linet_menu = OptionMenu(self.linet_frame,self.linet_var,'-','->','-|>')
        self.linet_menu.pack(anchor='s',side=BOTTOM)
        self.linet_menu.config(width=5)
        
        self.div_check = Checkbutton(self.options_frame,text = 'Dividing Streamline',variable=self.div_var,onvalue=1,offvalue=0,command = self.graph_update)
        self.div_check.grid(row=2,column=1,sticky=W)
        self.mark_check = Checkbutton(self.options_frame,text = 'Selection Marker',variable=self.mark_var,onvalue=1,offvalue=0,command = self.mark_check_fun)
        self.mark_check.grid(row=3,column=1,sticky=W)
        
        self.limit_frame = Frame(self.options_frame)
        self.limit_frame.grid(row=4,column=1,sticky=W)
        #self.aspect_lock = Checkbutton(self.limit_frame,text='LK',variable = self.lock_var)
        #self.aspect_lock.grid(row=0,column=4,rowspan=2,sticky=E)
        
        Label(self.limit_frame,text='x').grid(row=0,column=0)
        self.xlimlow_var = DoubleVar()
        self.xlimlow_var.set(self.FigSubPlot.get_xlim()[0])
        self.xlimlow_entry = Entry(self.limit_frame,textvariable=self.xlimlow_var,width=5)
        self.xlimlow_entry.grid(row=0,column=1)
        Label(self.limit_frame,text='...').grid(row=0,column=2)
        self.xlimhigh_var = DoubleVar()
        self.xlimhigh_var.set(self.FigSubPlot.get_xlim()[1])
        self.xlimhigh_entry = Entry(self.limit_frame,textvariable=self.xlimhigh_var,width=5)
        self.xlimhigh_entry.grid(row=0,column=3)
        Label(self.limit_frame,text='y').grid(row=1,column=0)
        self.ylimlow_var = DoubleVar()
        self.ylimlow_var.set(self.FigSubPlot.get_ylim()[0])
        self.ylimlow_entry = Entry(self.limit_frame,textvariable=self.ylimlow_var,width=5)
        self.ylimlow_entry.grid(row=1,column=1)
        Label(self.limit_frame,text='...').grid(row=1,column=2)
        self.ylimhigh_var = DoubleVar()
        self.ylimhigh_var.set(self.FigSubPlot.get_ylim()[1])
        self.ylimhigh_entry = Entry(self.limit_frame,textvariable=self.ylimhigh_var,width=5)
        self.ylimhigh_entry.grid(row=1,column=3)
        
        
        #self.limit_frame.bind('<FocusOut>',self.limits_update)
        self.xlimhigh_var.trace('w',self.limits_update)
        self.ylimhigh_var.trace('w',self.limits_update)
        self.xlimlow_var.trace('w',self.limits_update)
        self.ylimlow_var.trace('w',self.limits_update)
        
    def limits_update(self,*args):

        if self.xlimlow_entry.get() == '' or self.ylimlow_entry.get() == '' or self.xlimhigh_entry.get() == '' or self.ylimhigh_entry.get() == '':
            pass
        elif self.xlimlow_entry.get() == '-' or self.ylimlow_entry.get() == '-' or self.xlimhigh_entry.get() == '-' or self.ylimhigh_entry.get() == '-':
            pass
        elif self.xlimlow_entry.get() == '.' or self.ylimlow_entry.get() == '.' or self.xlimhigh_entry.get() == '.' or self.ylimhigh_entry.get() == '.':
            pass
        else:
            self.xlim = [float(self.xlimlow_var.get()),float(self.xlimhigh_var.get())]
            self.ylim = [float(self.ylimlow_var.get()),float(self.ylimhigh_var.get())]

            self.FigSubPlot.set_xlim(self.xlim)
            self.FigSubPlot.set_ylim(self.ylim)
            self.graph_update()
    def getColor(self,event):
        color=askcolor(self.line_color.get())
        if color != "None":
            self.line_color.set(color[1])
            self.graph_update()
    def wt_update(self,*args):
        if self.wt_var.get() == '-> WT:':
            self.wt_slider.config(variable=self.arrow_var)
        elif self.wt_var.get() == '- WT:':
            self.wt_slider.config(variable=self.line_var)
        elif self.wt_var.get() == 'div WT:':
            self.wt_slider.config(variable=self.div_check_var)
    def line_style_update(self,*args):
        self.graph_update()
    def close_options(self,event):
        self.options_window.destroy()
    def add_source(self):
        if self.modify_flag == 0:
            self.plot_x,self.plot_y = 0,0
        self.elements.insert("",0,iid='s%s'%self.active_numbers['s'],text="Source",values=("%s"%1,self.plot_x,self.plot_y))
        self.active_calls['s%s'%self.active_numbers['s']] = ("s",self.elements.item('s%s'%self.active_numbers['s'],"values"))
        self.active_components.append('s%s'%self.active_numbers['s'])
        if self.modify_flag == 1:
            self.elements.selection_set('s%s'%self.active_numbers['s'])
            self.modify_flag = 0
        self.graph_update()
        self.active_numbers['s'] += 1
        
    def add_vortex(self):
        if self.modify_flag == 0:
            self.plot_x,self.plot_y = 0,0
        self.elements.insert("",0,iid='v%s'%self.active_numbers['v'],text="Vortex",values=("%s"%1,self.plot_x,self.plot_y))
        self.active_calls['v%s'%self.active_numbers['v']] = ("v",self.elements.item('v%s'%self.active_numbers['v'],"values"))
        self.active_components.append('v%s'%self.active_numbers['v'])

        if self.modify_flag == 1:
            self.elements.selection_set('v%s'%self.active_numbers['v'])
            self.modify_flag = 0
        self.graph_update()
        self.active_numbers['v'] += 1
    def add_uniform(self):
        if self.modify_flag == 0:
            self.plot_x,self.plot_y = 1,0
        self.elements.insert("",0,iid='u%s'%self.active_numbers['u'],text="Uniform",values=("%s"%1,self.plot_x,self.plot_y))
        self.active_calls['u%s'%self.active_numbers['u']] = ("u",self.elements.item('u%s'%self.active_numbers['u'],"values"))
        self.active_components.append('u%s'%self.active_numbers['u'])
        if self.modify_flag == 1:
            self.elements.selection_set('u%s'%self.active_numbers['u'])
            self.modify_flag = 0
        self.graph_update()
        self.active_numbers['u'] += 1
    def add_doublet(self):
        if self.modify_flag == 0:
            self.plot_x,self.plot_y = 0,0
        self.elements.insert("",0,iid='d%s'%self.active_numbers['d'],text="Doublet",values=("%s"%1,self.plot_x,self.plot_y))
        self.active_calls['d%s'%self.active_numbers['d']] = ("d",self.elements.item('d%s'%self.active_numbers['d'],"values"))
        self.active_components.append('d%s'%self.active_numbers['d'])
        if self.modify_flag == 1:
            self.elements.selection_set('d%s'%self.active_numbers['d'])
            self.modify_flag = 0
        self.graph_update()
        self.active_numbers['d'] += 1
    def add_corner(self):
        if self.modify_flag == 0:
            self.plot_x,self.plot_y = 0,0
        self.elements.insert("",0,iid='n%s'%self.active_numbers['n'],text="Corner (n,A)",values=("%s,%s"%(2,1),self.plot_x,self.plot_y))
        self.active_calls['n%s'%self.active_numbers['n']] = ("n",self.elements.item('n%s'%self.active_numbers['n'],"values"))
        self.active_components.append('n%s'%self.active_numbers['n'])
        if self.modify_flag == 1:
            self.elements.selection_set('n%s'%self.active_numbers['n'])
            self.modify_flag = 0
        self.graph_update()
        self.active_numbers['n'] += 1
    def addm_source(self):
        self.modify_flag = 1 
        self.add_source()
    def addm_vortex(self):
        self.modify_flag = 1
        self.add_vortex()
    def addm_uniform(self):
        self.modify_flag = 1
        self.add_uniform()
    def addm_doublet(self):
        self.modify_flag = 1
        self.add_doublet()
    def addm_corner(self):
        self.modify_flag = 1
        self.add_corner()
    def pan_update(self,event):
        if [self.FigSubPlot.get_xlim()[0],self.FigSubPlot.get_xlim()[1]] != self.xlim or [self.FigSubPlot.get_ylim()[0],self.FigSubPlot.get_ylim()[1]] != self.ylim or self.density_var.get() != self.density_val or self.line_var.get() != self.line_val or self.arrow_var.get() != self.arrow_val or self.arrow_var.get() != self.arrow_val or self.div_check_var.get() != self.div_val:
            self.graph_update()
            self.density_val = self.density_var.get()
            self.line_val = self.line_var.get()
            self.arrow_val = self.arrow_var.get()
            self.div_val = self.div_check_var.get()
        else:
            return
    def graph_update(self):
        self.FigSubPlot.clear()
        Y, X = mgrid[self.FigSubPlot.get_ylim()[0]:self.FigSubPlot.get_ylim()[1]:100j, self.FigSubPlot.get_xlim()[0]:self.FigSubPlot.get_xlim()[1]:100j]     
        self.xlim = [self.FigSubPlot.get_xlim()[0],self.FigSubPlot.get_xlim()[1]]
        self.ylim = [self.FigSubPlot.get_ylim()[0],self.FigSubPlot.get_ylim()[1]]
        self.U = 0*X
        self.V = 0*X      
        self.stream = 0*X
        for ID in self.active_components:
            if self.elements.get_children(ID) == ():
                child = ID
                self.active_calls[child] = (child[0],self.elements.item(child,"values"))
                if self.active_calls[child][0] == "s":
                    self.U += self.source(X-float(self.active_calls[child][1][1]),Y-float(self.active_calls[child][1][2]),self.active_calls[child][1][0])[0]
                    self.V += self.source(X-float(self.active_calls[child][1][1]),Y-float(self.active_calls[child][1][2]),self.active_calls[child][1][0])[1]
                    self.stream += self.stream_source(X-float(self.active_calls[child][1][1]),Y-float(self.active_calls[child][1][2]),self.active_calls[child][1][0])
                elif self.active_calls[child][0] == 'v':
                    self.U += self.vortex(X-float(self.active_calls[child][1][1]),Y-float(self.active_calls[child][1][2]),self.active_calls[child][1][0])[0]
                    self.V += self.vortex(X-float(self.active_calls[child][1][1]),Y-float(self.active_calls[child][1][2]),self.active_calls[child][1][0])[1]
                    self.stream += self.stream_vortex(X-float(self.active_calls[child][1][1]),Y-float(self.active_calls[child][1][2]),self.active_calls[child][1][0])
                elif self.active_calls[child][0] == 'u':
                    if self.active_calls[child][1][1] == '0' and self.active_calls[child][1][2] == '0':
                        pass
                    else:
                        self.U += self.uniform(X,Y,self.active_calls[child][1][0],self.active_calls[child][1][1],self.active_calls[child][1][2])[0]
                        self.V += self.uniform(X,Y,self.active_calls[child][1][0],self.active_calls[child][1][1],self.active_calls[child][1][2])[1]
                        self.stream += self.stream_uniform(X,Y,self.active_calls[child][1][0],self.active_calls[child][1][1],self.active_calls[child][1][2])
                elif self.active_calls[child][0] == 'd':
                    self.U += self.doublet(X-float(self.active_calls[child][1][1]),Y-float(self.active_calls[child][1][2]),self.active_calls[child][1][0])[0]
                    self.V += self.doublet(X-float(self.active_calls[child][1][1]),Y-float(self.active_calls[child][1][2]),self.active_calls[child][1][0])[1]
                    self.stream += self.stream_doublet(X-float(self.active_calls[child][1][1]),Y-float(self.active_calls[child][1][2]),self.active_calls[child][1][0])
                elif self.active_calls[child][0] == 'n':
                    self.U += self.corner(X-float(self.active_calls[child][1][1]),Y-float(self.active_calls[child][1][2]),self.active_calls[child][1][0])[0]
                    self.V += self.corner(X-float(self.active_calls[child][1][1]),Y-float(self.active_calls[child][1][2]),self.active_calls[child][1][0])[1]
                    self.stream += self.stream_corner(X-float(self.active_calls[child][1][1]),Y-float(self.active_calls[child][1][2]),self.active_calls[child][1][0])
            else:
                for child in self.elements.get_children(ID):
                    self.active_calls[child] = (child[0],self.elements.item(child,"values"))
                    if self.active_calls[child][0] == "s":
                        self.U += self.source(X-float(self.active_calls[child][1][1]),Y-float(self.active_calls[child][1][2]),self.active_calls[child][1][0])[0]
                        self.V += self.source(X-float(self.active_calls[child][1][1]),Y-float(self.active_calls[child][1][2]),self.active_calls[child][1][0])[1]
                        self.stream += self.stream_source(X-float(self.active_calls[child][1][1]),Y-float(self.active_calls[child][1][2]),self.active_calls[child][1][0])
                    elif self.active_calls[child][0] == 'v':
                        self.U += self.vortex(X-float(self.active_calls[child][1][1]),Y-float(self.active_calls[child][1][2]),self.active_calls[child][1][0])[0]
                        self.V += self.vortex(X-float(self.active_calls[child][1][1]),Y-float(self.active_calls[child][1][2]),self.active_calls[child][1][0])[1]
                        self.stream += self.stream_vortex(X-float(self.active_calls[child][1][1]),Y-float(self.active_calls[child][1][2]),self.active_calls[child][1][0])
                    elif self.active_calls[child][0] == 'u':
                        if self.active_calls[child][1][1] == '0' and self.active_calls[child][1][2] == '0':
                            pass
                        else:
                            self.U += self.uniform(X,Y,self.active_calls[child][1][0],self.active_calls[child][1][1],self.active_calls[child][1][2])[0]
                            self.V += self.uniform(X,Y,self.active_calls[child][1][0],self.active_calls[child][1][1],self.active_calls[child][1][2])[1]
                            self.stream += self.stream_uniform(X,Y,self.active_calls[child][1][0],self.active_calls[child][1][1],self.active_calls[child][1][2])
                    elif self.active_calls[child][0] == 'd':
                        self.U += self.doublet(X-float(self.active_calls[child][1][1]),Y-float(self.active_calls[child][1][2]),self.active_calls[child][1][0])[0]
                        self.V += self.doublet(X-float(self.active_calls[child][1][1]),Y-float(self.active_calls[child][1][2]),self.active_calls[child][1][0])[1]
                        self.stream += self.stream_doublet(X-float(self.active_calls[child][1][1]),Y-float(self.active_calls[child][1][2]),self.active_calls[child][1][0])
                    elif self.active_calls[child][0] == 'n':
                        self.U += self.corner(X-float(self.active_calls[child][1][1]),Y-float(self.active_calls[child][1][2]),self.active_calls[child][1][0])[0]
                        self.V += self.corner(X-float(self.active_calls[child][1][1]),Y-float(self.active_calls[child][1][2]),self.active_calls[child][1][0])[1]
                        self.stream += self.stream_corner(X-float(self.active_calls[child][1][1]),Y-float(self.active_calls[child][1][2]),self.active_calls[child][1][0])

        self.FigSubPlot.streamplot(X,Y,self.U,self.V,color=self.line_color.get(), linewidth=(2.0/71.0)*self.line_var.get()+(13.0/71.0),density=(2.0/71.0)*self.density_var.get()+(13.0/71.0),arrowstyle=self.linet_var.get(),arrowsize=(4.0/71.0)*self.arrow_var.get()+(13.0/71.0))
        if self.div_var.get() == 1:
            #self.FigSubPlot.contour(X,Y,self.stream,[-0.01,0.01],linewidths=[(4.0/71.0)*self.div_check_var.get()+(13.0/71.0),(4.0/71.0)*self.div_check_var.get()+(13.0/71.0)])
            
            self.FigSubPlot.contour(X,Y,self.stream,[0],linewidths=[(4.0/71.0)*self.div_check_var.get()+(13.0/71.0)])
        if self.mark_var.get() == 1:
            if self.sel_point != None:
                self.plot_point()
        self.FigSubPlot.set_xlim(self.xlim)
        self.FigSubPlot.set_ylim(self.ylim)
        self.canvas.draw()
    def plot_point(self):
        if self.elements.selection()[0][0] == 'u':
            norm = float(float(self.sel_point[0])*float(self.sel_point[0])+float(self.sel_point[1])*float(self.sel_point[1]))**0.5
            if norm == 0:
                norm = 1
            X,Y,U,V = 0,0, float(self.sel_point[0])/norm,float(self.sel_point[1])/norm
            self.FigSubPlot.quiver(X,Y,U,V,angles='xy',scale_units='xy',scale=1,color='g')
        else:
            self.FigSubPlot.plot([self.sel_point[0]],[self.sel_point[1]],'r^',ms=10)
    def edit(self,event):
        if self.active_edit_flag == 1 or self.elements.identify_row(event.y) == '':
            pass
        else:
            self.rowid = self.elements.identify_row(event.y)
            self.column = self.elements.identify_column(event.x)
            self.edit_var = StringVar()
            if int(self.column[-1]) == 0:
                self.edit_var.set('%s'%self.elements.item("%s"%self.elements.identify("item",event.x, event.y))['text'])

            else:
                self.edit_var.set('%s'%self.elements.item("%s"%self.elements.identify("item",event.x, event.y))['values'][int(self.column[-1])-1])

            x,y,width,height = self.elements.bbox(self.rowid, self.column)
            self.edit_entry = Entry(self.elements_frame,textvariable=self.edit_var)
            self.edit_entry.place(x=x,y=y,width=width)
            self.edit_entry.focus_force()
            self.edit_entry.bind("<FocusOut>", self.del_edit)
            self.active_edit_flag = 1
    def edit_return(self,event):
        self.main.focus()
    def del_edit(self,event):
        if self.column[-1] == '0':
            self.elements.item(self.rowid,text='%s'%self.edit_var.get())
        elif self.rowid[0] == 'n' and self.column[-1] == '1' and ',' not in self.edit_var.get():
            pass
        else:
            value = ''
            initial_value = str(self.elements.item(self.rowid)['values'][int(self.column[-1])-1])
            comma_flag = 0
            div_flag = 0
            for index in range(0,len(self.edit_var.get())):
                char = self.edit_var.get()[index]
                if char in '-0123456789.':
                    value += char
                elif self.rowid[0] == 'n' and char == ',':
                    if comma_flag == 1:
                        self.edit_entry.destroy()
                        self.active_edit_flag = 0
                        return
                    value += char
                    comma_flag = 1
                    comma_index = index
                if char == '/':
                    if div_flag == 0:
                        div_flag = 1
                        div_index = index
                    elif div_flag == 1 and comma_flag == 1:
                        div_flag = 2
                        div_index2 = index
                    elif div_flag == 1 and comma_flag == 0 or div_flag == 2:
                        self.edit_entry.destroy()
                        self.active_edit_flag = 0
                        return
                   
            if div_flag == 1:
                if comma_flag == 1:
                    if div_index < comma_index:
                        arg = int(float(value[:div_index])*100/float(value[div_index:comma_index-1]))/100.0
                        value = str(arg)+value[comma_index-1:]
                    elif div_index > comma_index:
                        arg = int(float(value[comma_index+1:div_index])*100/float(value[div_index:]))/100.0
                        value = value[:comma_index+1]+str(arg)
                else:
                    arg = int(float(value[:div_index])*100/float(value[div_index:]))/100.0
                    value = str(arg)
            elif div_flag == 2: 
                arg1 = int(float(value[:div_index])*100/float(value[div_index:comma_index-1]))/100.0
                arg2 = int(float(value[comma_index:div_index2-1])*100/float(value[div_index2-1:]))/100.0
                value = str(arg1)+','+str(arg2)
            if value == '' or value == initial_value:
                self.edit_entry.destroy()
                self.active_edit_flag = 0
                return
            
            self.elements.set(self.rowid,column=(int(self.column[-1])-1),value=value)
            if self.mark_var.get() == 1:
                self.sel_point = [self.elements.item(self.rowid,"values")[1],self.elements.item(self.rowid,"values")[2]]
            self.graph_update()
        self.edit_entry.destroy()
        self.active_edit_flag = 0
예제 #19
0
class WaitingRoom(cll.ClientListener, object): #Note: extending cll.ClientListener if Gui does not extend WaitingRoom
    def __init__(self):
        self.Names = []
        self.tree_headers = ['Player','Status','Address','Game','Color']
        self.quit = False   #quit program after wroom has been closed. it will be passed to Gui.quit

    def startWaitingRoomUI(self, pumpit):
        self.pumpit = True
        if 'pumpit' in locals():
            self.pumpit = pumpit
        cfg.wroom = Tk()
        cfg.wroom.protocol("WM_DELETE_WINDOW", self.quitWaitingRoom)

        """State variables - By using textvariable=var in definition widget is tied to this variable"""
        statusmsg_sv = StringVar() #needed
        entry_sv = StringVar(value = cfg.name)
        #entry_sv.trace("w", lambda name, index, mode, sv=entry_sv: self.changeName(sv))
        chatentry_sv = StringVar(value = "Press enter to chat")

        """Create and grid the outer content frame"""
        content = ttk.Frame(cfg.wroom) #, padding=(5, 5, 12, 0)) 		#Frame in cfg.wroom
        content.grid(column = 0, row = 0, sticky = (N,W,E,S))
        cfg.wroom.grid_columnconfigure(0, weight = 1)
        cfg.wroom.grid_rowconfigure(0, weight = 1)

        """Create the different widgets; note the variables that some widgets are bound to"""
        self.tree = Treeview(content, show="headings", columns=cfg.wroominstance.tree_headers, name = "treeview")
        self.tree.column("#1", minwidth = 100, width = 120, stretch = NO)
        self.tree.column("#2", minwidth = 30, width = 60, stretch = NO)
        self.tree.column("#3", minwidth = 30, width = 50, stretch = YES)
        self.tree.column("#4", minwidth = 30, width = 50, stretch = YES)
        self.tree.column("#5", minwidth = 30, width = 50, stretch = YES)
        namelbl = ttk.Label(content, text="Player name")
        self.nameentry = ttk.Entry(content, bg = 'white', textvariable = entry_sv, name = "nameentry")#, validatecommand=validateIt)
        colorlbl = ttk.Label(content, text="Player color")
        self.colorframe = ttk.Frame(content, name = "colorframe", borderwidth = 1, relief='sunken')
        lbl = ttk.Label(content, text="Send to player:")	#Label on the right
        self.log = Listbox(content, height = 5, bg = 'white', name = "logbox")#, listvariable=cmessagelog		#Listbox with messages
        self.chatAll = ttk.Button(content, text = 'Chat to All', command = self.chatToAll, default = 'active', width = '6',name = "chat")
        self.chatentry = ttk.Entry(content, bg = 'white', foreground = 'gray', textvariable = chatentry_sv, name = "chatentry", selectforeground = 'blue')
        testbtn = ttk.Button(content, text = 'Connections', command = self.test, default = 'active', width = '6', name = "testbtn")
        ready = ttk.Button(content, text = 'Ready', command = self.toggleReadyForGame, default = 'active', width = '6', name = "readybtn")
        solitaire = ttk.Button(content, text = 'Solitaire', command = self.solitaire, default = 'active', width = '6', name = "solitairebtn")
        quit = ttk.Button(content, text = 'Quit', command = self.quitWaitingRoom, default = 'active', width = '6', name = "quitbtn")
        status = ttk.Label(content, textvariable = statusmsg_sv, anchor = W, name = "statuslbl") #Label on the bottom

        def get_tree():
            """Get from the self.tree an item when clicked"""
            idxs = self.tree.item(self.tree.focus())
            vals = idxs['values']
            if len(idxs['values'])==0: return None
            return vals
        """def sortby(tree, col, descending):
            Sort tree contents when a column header is clicked on
            # grab values to sort
            data = [(tree.set(child, col), child) \
                for child in tree.get_children('')]
            # now sort the data in place
            data.sort(reverse=descending)
            for ix, item in enumerate(data):
                tree.move(item[1], '', ix)
            # switch the heading so it will sort in the opposite direction
            tree.heading(col, command=lambda col=col: sortby(tree, col, int(not descending)))
        """
        def showstatus(*args):
            """Called when the selection in the listbox changes;
            Update the status message on the bottom with the new information"""
            list = get_tree()
            if list is None:
                return
            statusmsg_sv.set("Player %s has this status: %s" % (list[0], list[1]))

        # Grid all the widgets
        self.tree.grid(row = 0, column = 0, rowspan = 9, sticky = (N,S,E,W))
        namelbl.grid(row = 0, column = 1, columnspan = 2, sticky = (N,W), padx = 5)
        self.nameentry.grid(row = 1, column = 1, columnspan = 2, sticky = (N,E,W), pady = 5, padx = 5)
        colorlbl.grid(row = 0, column = 3, columnspan = 1, sticky = (N,W), padx = 5)
        self.colorframe.grid(row = 1, column = 3, columnspan = 1, sticky = (N,E,W), pady = 5, padx = 5)
        #testbtn.grid(row = 3, column = 3, columnspan = 1, sticky = E, padx = 5)		#Test Button
        self.log.grid(row = 5, column = 1, columnspan = 3, sticky = (N,S,E,W), padx = 5, pady = 5)   #Listbox with all messages
        self.chatentry.grid(row = 6, column = 1, columnspan = 2, sticky = (N,E), padx = 5, pady = 5)
        self.chatAll.grid(row = 6, column = 3, columnspan = 1, sticky = (N,E), padx = 5, pady = 5)
        ready.grid(row = 7, column = 1, sticky = (W,S), padx = 5, pady = 5)			#
        solitaire.grid(row = 7, column = 2, sticky = (W,S), padx = 5, pady = 5)
        quit.grid(row = 7, column = 3, sticky = (W,S), padx = 5, pady = 5)
        status.grid(row = 9, column = 0, columnspan = 2, sticky = (W,E))

        """Configure content Frame and color Frame"""
        content.grid_columnconfigure(0, weight = 1)
        content.grid_rowconfigure(5, weight = 1)
        h = self.nameentry.winfo_reqheight()
        self.colorframe.configure(height = h, bg = 'red')

        """Set event bindings"""
        self.tree.bind('<<TreeviewSelect>>', showstatus)
        self.nameentry.bind('<Return>', (lambda _: self.askChangeName(self.nameentry)))
        self.nameentry.bind('<FocusOut>', (lambda _: self.askChangeName(self.nameentry)))
        cfg.wroom.bind('<Control-Key-w>', self.quitWaitingRoom)
        cfg.wroom.bind('<Control-Key-q>', self.quitWaitingRoom)
        cfg.wroom.bind('<Control-Key-r>', self.toggleReadyForGame)
        cfg.wroom.bind('<Control-Key-s>', self.solitaire)
        self.chatentry.bind("<Return>",self.chatToAll)
        def chatEntryActive(e = None):
            self.chatentry.config(foreground = 'black')
            self.chatentry.delete(0, 'end')
        def chatEntryInactive(e = None):
            print(self)
            chatentry_sv.set("Press enter to chat")
            self.chatentry.config(foreground = 'gray')
        self.chatentry.bind("<FocusIn>", lambda e: chatEntryActive(e))
        self.chatentry.bind("<FocusOut>", lambda e: chatEntryInactive(e))
        self.colorframe.bind("<ButtonRelease-1>", self.changeColor)

        """Set tooltips on widgets"""
        hover.createToolTip(namelbl, "Type in your name")
        hover.createToolTip(self.nameentry, "Type in your name")
        hover.createToolTip(ready, "Toggle ready state to play tantrix with other players")
        hover.createToolTip(solitaire, "Start a two player game on this computer")
        hover.createToolTip(quit, "Quit Tantrix")
        hover.createToolTip(self.chatentry, "Press enter to send to chat")
        hover.createToolTip(self.chatAll, "Press enter to send to chat")
        hover.createToolTip(self.colorframe, "Click to select your color")
        hover.createToolTip(colorlbl, "Your color")

        """Set the starting state of the interface"""
        statusmsg_sv.set('')
        showstatus()

        """Start main loop for tkinter and Sixpodnet"""
        self.keepLooping = True
        if self.pumpit:
            self.mainLoopWithPump()
        else:
            self.mainLoopWithoutPump()
        return self.quit

    def test(self):
        if self.pumpit:
            self.send_to_server("test")

    def chatToAll(self, e = None):
        """Chat to every player in the wroom"""
        """Get the chat entry and add it to the local log"""
        msgList = [self.chatentry.get()]
        if len(msgList[0]) is 0: return
        """Send message to server"""
        self.sendChatToAll(msgList = msgList)
        """Clear chat entry"""
        self.chatentry.delete(0, 'end')
        self.chatentry.focus_set()


    def buildTree(self, tree_list):
        def sortby(tree, col, descending):
            """Sort tree contents when a column header is clicked on"""
            # grab values to sort
            data = [(tree.set(child, col), child) \
                for child in tree.get_children('')]
            # now sort the data in place
            data.sort(reverse=descending)
            for ix, item in enumerate(data):
                tree.move(item[1], '', ix)
            # switch the heading so it will sort in the opposite direction
            tree.heading(col, command=lambda col=col: sortby(tree, col, int(not descending)))

        for ind, col in enumerate(self.tree_headers):
            self.tree.heading(ind, text=col.title(),command=lambda c=col: sortby(self.tree, c, 0))#
            # adjust the column's width to the header string
            #self.tree.column(col, width=tkFont.Font().measure(col.title()))
        """Convert Status and Game to a better format, then insert in Treeview"""
        convert_status = {0: "Idle", 1: "Ready", -1: "Playing", -2: "Solitaire"}
        for item in tree_list:
            item[1] = convert_status[item[1]]
            if item[3] is None: item[3] = ""
            self.tree.insert('', 'end', values=item)
            # adjust column's width if necessary to fit each value
            #import Tkinter.font as tkFont
            #for ix, val in enumerate(item):
                #col_w = tkFont.Font().measure(val)
            #if self.tree.column(selfcfg.wroominstance.tree_headers[ix],width=None)<col_w:
                #self.tree.column(selfcfg.wroominstance.tree_headers[ix], width=col_w)

    def addToMessageLog(self, listToLog, fg = 'black'):
        """Add a line to the log listbox"""
        for item in listToLog:
            self.log.insert(END, item)
            self.log.itemconfig(END, {'fg': fg})
        self.log.select_set(END)
        self.log.yview(END)

    def searchTreeByHeader(self, val, header = 'Player'):
        """Return item in Treeview by player name"""
        val = str(val)
        items = self.tree.get_children()
        headerIndToSearchInto = cfg.wroominstance.tree_headers.index(header) # ['Player','Status','Address']
        for item in items:
            itemval = str(self.tree.item(item, 'values')[headerIndToSearchInto])
            if itemval.startswith(val):
                return item
        return None

    def editItemInTree(self, item, valList, headerList = ['Player']):
        """Edit an item of TreeView by its header(s)"""
        #Get the current (old) values as a list
        old_vals = self.tree.item(item)['values']
        #Create a list with the new values
        newvalues = list(old_vals)
        for ind, header in enumerate(headerList):
            #Get from headerList which index should be changed
            headerIndex = cfg.wroominstance.tree_headers.index(header)
            newvalues[headerIndex] = valList[ind]
        #Finally change the old values
        self.tree.item(item, values=newvalues)

    def removeFromTree(self, name = ''):
        """remove an item of TreeView by its name filed"""
        item = self.searchTreeByHeader(name, header = 'Player')
        if item is not None:
            self.tree.delete(item)

    def askChangeName(self, sv):
        """User wants to change name. Ask server if ok"""
        name = sv.get()
        self.sendChangedName(name)

    def changeName(self, name):
        """Server sends the name of this player"""
        self.nameentry.delete(0, END)
        self.nameentry.insert(0, name)
        cfg.name = name
        cfg.wroom.title(name + ": waiting room")
        cfg.wroom.update()

    def changeColor(self, e = None):
        current = self.colorframe.cget('bg')
        color_ind = cfg.PLAYERCOLORS.index(current) + 1
        color = cfg.PLAYERCOLORS[color_ind % 4]
        self.colorframe.configure(bg = color)
        cfg.playercolor = color
        self.sendChangedColor(color)

    def toggleReadyForGame(self, e = None):
        if self.pumpit:
            self.sendToggleReady()
            #Change button layout when clicked
            frame = cfg.wroom.winfo_children()[0]
            readybtn = frame.children['readybtn']
            """Configure the button"""
            if readybtn.config('relief')[4]=='raised':
                readybtn.configure(relief='sunken')
                readybtn.configure(bg = 'green')
            elif readybtn.config('relief')[4]=='sunken':
                readybtn.configure(relief='raised')
                readybtn.configure(bg = '#d6d6d6')
            sleep(0.1)
            cfg.wroom.update()

    def quitWaitingRoom(self, e = None):
        print("Quitting the waiting room")
        self.keepLooping = False
        self.quit = True    #used to quit everything after wroom has been closed
        if self.pumpit:
            self.send_to_server("quit")

    def solitaire(self, e = None):
        print("Starting a game on one client (solitaire)")
        cfg.solitaire = True
        self.keepLooping = False
        if self.pumpit:
            self.sendSolitaire()
        #cfg.wroominstance.tree = None

    def mainLoopWithoutPump(self):
        """Start main loop in waiting room. Do not use Sixpodnet to connect with server"""
        while self.keepLooping: #self.keepLooping changed by callbacks below
            """Update the boards"""
            cfg.wroom.update()
            cfg.wroom.update_idletasks()
        cfg.wroom.destroy()

    def mainLoopWithPump(self):
        """Start main loop in waiting room"""
        while self.keepLooping:      #self.keepLooping changed by callbacks below
            """Polling loop for the client. asks the connection singleton for any new messages from the network"""
            connection.Pump()
            """Server"""
            self.Pump()
            """Check if there is a connection. If so start the waiting room, else go to preSolitaire"""
            if cfg.connected:
                """Update the boards"""
                cfg.wroom.update()
                cfg.wroom.update_idletasks()
            else:
                global attempt2connect
                attempt2connect += 1
                if attempt2connect == 20:
                    self.solitaire()
        cfg.wroom.destroy()
class Multicolumn_Listbox(object):
    _style_index = 0

    class List_Of_Rows(object):
        def __init__(self, multicolumn_listbox):
            self._multicolumn_listbox = multicolumn_listbox

        def data(self, index):
            return self._multicolumn_listbox.row_data(index)

        def get(self, index):
            return Row(self._multicolumn_listbox, index)

        def insert(self, data, index=None):
            self._multicolumn_listbox.insert_row(data, index)

        def delete(self, index):
            self._multicolumn_listbox.delete_row(index)

        def update(self, index, data):
            self._multicolumn_listbox.update_row(index, data)

        def select(self, index):
            self._multicolumn_listbox.select_row(index)

        def deselect(self, index):
            self._multicolumn_listbox.deselect_row(index)

        def set_selection(self, indices):
            self._multicolumn_listbox.set_selection(indices)

        def __getitem__(self, index):
            return self.get(index)

        def __setitem__(self, index, value):
            return self._multicolumn_listbox.update_row(index, value)

        def __delitem__(self, index):
            self._multicolumn_listbox.delete_row(index)

        def __len__(self):
            return self._multicolumn_listbox.number_of_rows

    class List_Of_Columns(object):
        def __init__(self, multicolumn_listbox):
            self._multicolumn_listbox = multicolumn_listbox

        def data(self, index):
            return self._multicolumn_listbox.get_column(index)

        def get(self, index):
            return Column(self._multicolumn_listbox, index)

        def delete(self, index):
            self._multicolumn_listbox.delete_column(index)

        def update(self, index, data):
            self._multicolumn_listbox.update_column(index, data)

        def __getitem__(self, index):
            return self.get(index)

        def __setitem__(self, index, value):
            return self._multicolumn_listbox.update_column(index, value)

        def __delitem__(self, index):
            self._multicolumn_listbox.delete_column(index)

        def __len__(self):
            return self._multicolumn_listbox.number_of_columns

    def __init__(self,
                 master,
                 columns,
                 data=None,
                 command=None,
                 sort=True,
                 select_mode=None,
                 heading_anchor=CENTER,
                 cell_anchor=W,
                 style=None,
                 height=None,
                 padding=None,
                 adjust_heading_to_content=False,
                 stripped_rows=None,
                 selection_background=None,
                 selection_foreground=None,
                 field_background=None,
                 heading_font=None,
                 heading_background=None,
                 heading_foreground=None,
                 cell_pady=2,
                 cell_background=None,
                 cell_foreground=None,
                 cell_font=None,
                 headers=True):

        self._stripped_rows = stripped_rows

        self._columns = columns

        self._number_of_rows = 0
        self._number_of_columns = len(columns)

        self.row = self.List_Of_Rows(self)
        self.column = self.List_Of_Columns(self)

        s = Style()

        if style is None:
            style_name = "Multicolumn_Listbox%s.Treeview" % self._style_index
            self._style_index += 1
        else:
            style_name = style

        style_map = {}
        if selection_background is not None:
            style_map["background"] = [('selected', selection_background)]

        if selection_foreground is not None:
            style_map["foeground"] = [('selected', selection_foreground)]

        if style_map:
            s.map(style_name, **style_map)

        style_config = {}
        if cell_background is not None:
            style_config["background"] = cell_background

        if cell_foreground is not None:
            style_config["foreground"] = cell_foreground

        if cell_font is None:
            font_name = s.lookup(style_name, "font")
            cell_font = nametofont(font_name)
        else:
            if not isinstance(cell_font, Font):
                if isinstance(cell_font, basestring):
                    cell_font = nametofont(cell_font)
                else:
                    if len(font) == 1:
                        cell_font = Font(family=cell_font[0])
                    elif len(font) == 2:
                        cell_font = Font(family=cell_font[0],
                                         size=cell_font[1])

                    elif len(font) == 3:
                        cell_font = Font(family=cell_font[0],
                                         size=cell_font[1],
                                         weight=cell_font[2])
                    else:
                        raise ValueError(
                            "Not possible more than 3 values for font")

            style_config["font"] = cell_font

        self._cell_font = cell_font

        self._rowheight = cell_font.metrics("linespace") + cell_pady
        style_config["rowheight"] = self._rowheight

        if field_background is not None:
            style_config["fieldbackground"] = field_background

        s.configure(style_name, **style_config)

        heading_style_config = {}
        if heading_font is not None:
            heading_style_config["font"] = heading_font
        if heading_background is not None:
            heading_style_config["background"] = heading_background
        if heading_foreground is not None:
            heading_style_config["foreground"] = heading_foreground

        heading_style_name = style_name + ".Heading"
        s.configure(heading_style_name, **heading_style_config)

        treeview_kwargs = {"style": style_name}

        if height is not None:
            treeview_kwargs["height"] = height

        if padding is not None:
            treeview_kwargs["padding"] = padding

        if headers:
            treeview_kwargs["show"] = "headings"
        else:
            treeview_kwargs["show"] = ""

        if select_mode is not None:
            treeview_kwargs["selectmode"] = select_mode

        self.interior = Treeview(master, columns=columns, **treeview_kwargs)

        if command is not None:
            self._command = command
            self.interior.bind("<<TreeviewSelect>>", self._on_select)

        for i in range(0, self._number_of_columns):

            if sort:
                self.interior.heading(
                    i,
                    text=columns[i],
                    anchor=heading_anchor,
                    command=lambda col=i: self.sort_by(col, descending=False))
            else:
                self.interior.heading(i,
                                      text=columns[i],
                                      anchor=heading_anchor)

            if adjust_heading_to_content:
                self.interior.column(i, width=Font().measure(columns[i]))

            self.interior.column(i, anchor=cell_anchor)

        if data is not None:
            for row in data:
                self.insert_row(row)

    @property
    def row_height(self):
        return self._rowheight

    @property
    def font(self):
        return self._cell_font

    def configure_column(self,
                         index,
                         width=None,
                         minwidth=None,
                         anchor=None,
                         stretch=None):
        kwargs = {}
        for config_name in ("width", "anchor", "stretch", "minwidth"):
            config_value = locals()[config_name]
            if config_value is not None:
                kwargs[config_name] = config_value

        self.interior.column('#%s' % (index + 1), **kwargs)

    def row_data(self, index):
        try:
            item_ID = self.interior.get_children()[index]
        except IndexError:
            raise ValueError("Row index out of range: %d" % index)

        return self.item_ID_to_row_data(item_ID)

    def update_row(self, index, data):
        try:
            item_ID = self.interior.get_children()[index]
        except IndexError:
            raise ValueError("Row index out of range: %d" % index)

        if len(data) == len(self._columns):
            self.interior.item(item_ID, values=data)
        else:
            raise ValueError("The multicolumn listbox has only %d columns" %
                             self._number_of_columns)

    def delete_row(self, index):
        list_of_items = self.interior.get_children()

        try:
            item_ID = list_of_items[index]
        except IndexError:
            raise ValueError("Row index out of range: %d" % index)

        self.interior.delete(item_ID)
        self._number_of_rows -= 1

        if self._stripped_rows:
            for i in range(index, self._number_of_rows):
                self.interior.tag_configure(list_of_items[i + 1],
                                            background=self._stripped_rows[i %
                                                                           2])

    def insert_row(self, data, index=None):
        if len(data) != self._number_of_columns:
            raise ValueError("The multicolumn listbox has only %d columns" %
                             self._number_of_columns)

        if index is None:
            index = self._number_of_rows - 1

        item_ID = self.interior.insert('', index, values=data)
        self.interior.item(item_ID, tags=item_ID)

        self._number_of_rows += 1

        if self._stripped_rows:
            list_of_items = self.interior.get_children()

            self.interior.tag_configure(item_ID,
                                        background=self._stripped_rows[index %
                                                                       2])

            for i in range(index + 1, self._number_of_rows):
                self.interior.tag_configure(list_of_items[i],
                                            background=self._stripped_rows[i %
                                                                           2])

    def column_data(self, index):
        return [
            self.interior.set(child_ID, index)
            for child_ID in self.interior.get_children('')
        ]

    def update_column(self, index, data):
        for i, item_ID in enumerate(self.interior.get_children()):
            data_row = self.item_ID_to_row_data(item_ID)
            data_row[index] = data[i]

            self.interior.item(item_ID, values=data_row)

        return data

    def clear(self):
        # Another possibility:
        #  self.interior.delete(*self.interior.get_children())

        for row in self.interior.get_children():
            self.interior.delete(row)

        self._number_of_rows = 0

    def update(self, data):
        self.clear()

        for row in data:
            self.insert_row(row)

    def focus(self, index=None):
        if index is None:
            return self.interior.item(self.interior.focus())
        else:
            item = self.interior.get_children()[index]
            self.interior.focus(item)

    def state(self, state=None):
        if stateSpec is None:
            return self.interior.state()
        else:
            self.interior.state(state)

    @property
    def number_of_rows(self):
        return self._number_of_rows

    @property
    def number_of_columns(self):
        return self._number_of_columns

    def toogle_selection(self, index):
        list_of_items = self.interior.get_children()

        try:
            item_ID = list_of_items[index]
        except IndexError:
            raise ValueError("Row index out of range: %d" % index)

        self.interior.selection_toggle(item_ID)

    def select_row(self, index):
        list_of_items = self.interior.get_children()

        try:
            item_ID = list_of_items[index]
        except IndexError:
            raise ValueError("Row index out of range: %d" % index)

        self.interior.selection_add(item_ID)

    def deselect_row(self, index):
        list_of_items = self.interior.get_children()

        try:
            item_ID = list_of_items[index]
        except IndexError:
            raise ValueError("Row index out of range: %d" % index)

        self.interior.selection_remove(item_ID)

    def deselect_all(self):
        self.interior.selection_remove(self.interior.selection())

    def set_selection(self, indices):
        list_of_items = self.interior.get_children()

        self.interior.selection_set(" ".join(list_of_items[row_index]
                                             for row_index in indices))

    @property
    def selected_rows(self):
        data = []
        for item_ID in self.interior.selection():
            data_row = self.item_ID_to_row_data(item_ID)
            data.append(data_row)

        return data

    @property
    def indices_of_selected_rows(self):
        list_of_indices = []
        for index, item_ID in enumerate(self.interior.get_children()):
            if item_ID in self.interior.selection():
                list_of_indices.append(index)

        return list_of_indices

    def delete_all_selected_rows(self):
        selected_items = self.interior.selection()
        for item_ID in selected_items:
            self.interior.delete(item_ID)

        number_of_deleted_rows = len(selected_items)
        self._number_of_rows -= number_of_deleted_rows

        return number_of_deleted_rows

    def _on_select(self, event):
        for item_ID in event.widget.selection():
            data_row = self.item_ID_to_row_data(item_ID)
            self._command(data_row)

    def item_ID_to_row_data(self, item_ID):
        item = self.interior.item(item_ID)
        return item["values"]

    @property
    def table_data(self):
        data = []

        for item_ID in self.interior.get_children():
            data_row = self.item_ID_to_row_data(item_ID)
            data.append(data_row)

        return data

    @table_data.setter
    def table_data(self, data):
        self.update(data)

    def cell_data(self, row, column):
        """Get the value of a table cell"""
        try:
            item = self.interior.get_children()[row]
        except IndexError:
            raise ValueError("Row index out of range: %d" % row)

        return self.interior.set(item, column)

    def update_cell(self, row, column, value):
        """Set the value of a table cell"""

        item_ID = self.interior.get_children()[row]

        data = self.item_ID_to_row_data(item_ID)

        data[column] = value
        self.interior.item(item_ID, values=data)

    def __getitem__(self, index):
        if isinstance(index, tuple):
            row, column = index
            return self.cell_data(row, column)
        else:
            raise Exception("Row and column indices are required")

    def __setitem__(self, index, value):
        if isinstance(index, tuple):
            row, column = index
            self.update_cell(row, column, value)
        else:
            raise Exception("Row and column indices are required")

    def bind(self, event, handler):
        self.interior.bind(event, handler)

    def sort_by(self, col, descending):
        """
        sort tree contents when a column header is clicked
        """
        # grab values to sort
        data = [(self.interior.set(child_ID, col), child_ID)
                for child_ID in self.interior.get_children('')]

        # if the Demo_programs to be sorted is numeric change to float
        try:
            data = [(float(number), child_ID) for number, child_ID in data]
        except ValueError:
            pass

        # now sort the Demo_programs in place
        data.sort(reverse=descending)
        for idx, item in enumerate(data):
            self.interior.move(item[1], '', idx)

        # switch the heading so that it will sort in the opposite direction
        self.interior.heading(
            col, command=lambda col=col: self.sort_by(col, not descending))

        if self._stripped_rows:
            list_of_items = self.interior.get_children('')
            for i in range(len(list_of_items)):
                self.interior.tag_configure(list_of_items[i],
                                            background=self._stripped_rows[i %
                                                                           2])

    def destroy(self):
        self.interior.destroy()

    def item_ID(self, index):
        return self.interior.get_children()[index]
예제 #21
0
class CommSearch(Frame):
    def __init__(self, parent):
        Frame.__init__(self, parent)

        self.parent = parent
        self.initUI()

    def initUI(self):

        self.entries_found = []

        self.parent.title("Search your command cards")
        self.style = Style()
        self.style.theme_use("default")
        self.pack()

        self.input_title = Label(self, text="Enter your command below")
        self.input_title.grid(row=0, columnspan=2)
        self.input_box = Entry(self, width=90)
        self.input_box.grid(row=1, column=0)
        self.input_box.focus()
        self.input_box.bind("<Key>", self.onUpdateSearch)
        self.search_btn = Button(self, text="Search", command=self.onSearch)
        self.search_btn.grid(row=1, column=1)
        self.output_box = Treeview(self, columns=("Example"))
        ysb = Scrollbar(self, orient='vertical', command=self.output_box.yview)
        xsb = Scrollbar(self,
                        orient='horizontal',
                        command=self.output_box.xview)
        self.output_box.configure(yscroll=ysb.set, xscroll=xsb.set)
        self.output_box.heading('Example', text='Example', anchor='w')
        self.output_box.column("#0", minwidth=0, width=0, stretch=NO)
        self.output_box.column("Example", minwidth=0, width=785)
        self.output_box.bind("<Button-1>", self.OnEntryClick)
        self.output_box.grid(row=3, columnspan=2)
        self.selected_box = Text(self, width=110, height=19)
        self.selected_box.grid(row=4, columnspan=2)
        self.gotoadd_btn = Button(self,
                                  text="Go to Add",
                                  command=self.onGoToAdd)
        self.gotoadd_btn.grid(row=5)

    def OnEntryClick(self, event):
        try:
            item = self.output_box.selection()[0]
        except IndexError:
            pass
        entry_title = self.output_box.item(item, "value")
        for item in self.entries_found:
            if str(entry_title) == str("('" + item.title.strip('\n') + "',)"):
                self.selected_box.delete(0.1, END)
                self.selected_box.insert(END, item.text + '\n')

    def onUpdateSearch(self, key):
        # Somehow calling self.onSearch() does not register last key
        # And we need to correct "special chars"
        global entries, entries_map
        text_entries = ""
        for item in self.output_box.get_children():
            self.output_box.delete(item)

    # ...like, for instance, deleting last character
        if key.char == '\b':
            search_terms = str(self.input_box.get()[:-1])
        else:
            search_terms = str(self.input_box.get() + key.char)
        self.entries_found = []
        self.entries_found = data.Search(search_terms, entries, entries_map)
        for item in range(len(self.entries_found)):
            aux = self.output_box.insert(
                '',
                'end',
                '',
                value=[self.entries_found[item].title.split('\n')[0]])

    def onSearch(self):
        global entries, entries_map
        text_entries = ""
        for item in self.output_box.get_children():
            self.output_box.delete(item)
        search_terms = str(self.input_box.get())
        for item in data.Search(search_terms, entries, entries_map):
            self.output_box.insert(
                '',
                'end',
                '',
                value=[self.entries_found[item].title.split('\n')[0]])

    def onGoToAdd(self):
        newroot = Tk()
        newcomm = CommAdd(newroot)
        newroot.geometry("800x600+0+0")
        newroot.mainloop()