class app():
    def __init__(self):
        self.window = Tk()
        self.window.geometry('500x500')
        self.window.title('LIBRUSReader')

        loginLabel = Label(text='Podaj login')
        passwordLabel = Label(text='Podaj hasło')
        loginLabel.place(x=10, y=25)
        passwordLabel.place(x=10, y=50)

        self.login = StringVar()
        self.password = StringVar()
        self.windowMode = BooleanVar()
        self.consoleReadingMessages = BooleanVar()
        self.answer = StringVar()

        loginEntry = Entry(textvariable=self.login, width='30')
        passwordEntry = Entry(textvariable=self.password, show='*', width='30')
        loginEntry.place(x=80, y=25)
        passwordEntry.place(x=80, y=50)

        checkbox = Checkbutton(self.window,
                               text='Tryb okienkowy',
                               variable=self.windowMode)
        checkbox.place(x=15, y=125)

        checkboxOdczyt = Checkbutton(
            self.window,
            text=
            'Wyświetlanie wiadomości w konsoli (użyteczne przy wyłączeniu trybu okienkowego',
            variable=self.consoleReadingMessages)
        checkboxOdczyt.place(x=15, y=150)

        self.answer = Text(self.window, width='54', height='15')
        answerLabel = Label(
            text='Odpowiedź do wiadomości (jeśli puste, nie przesyła)')
        self.answer.place(x=15, y=215)
        answerLabel.place(x=15, y=190)

        runProgram = Button(self.window,
                            text='Uruchom program',
                            width='36',
                            height=' 1',
                            command=self.zapiszDane,
                            bg='grey')
        runProgram.place(x=16, y=100)
        self.window.mainloop()

    def zapiszDane(self):
        data = {
            'login': self.login.get(),
            'password': self.password.get(),
            'windowMode': self.windowMode.get(),
            'consoleReadingMessages': self.consoleReadingMessages.get(),
            'answer': self.answer.get('1.0', 'end-1c')
        }
        with open('config.json', 'w') as f:
            json.dump(data, f)
        self.window.destroy()
예제 #2
0
def generate_color_fading_input():
    interface = InterfaceInfo.get_instance()
    interface.reset_parameters()
    ttk.Label(interface.buttons_frame,
              text="Image width",
              background=constants.TOP_COLOR).grid(row=0, column=0)
    ttk.Label(interface.buttons_frame,
              text="Image height",
              background=constants.TOP_COLOR).grid(row=1, column=0)
    red = BooleanVar()
    green = BooleanVar()
    blue = BooleanVar()
    Checkbutton(interface.buttons_frame,
                text="Red",
                variable=red,
                background=constants.TOP_COLOR).grid(row=2, column=0)
    Checkbutton(interface.buttons_frame,
                text="Green",
                variable=green,
                background=constants.TOP_COLOR).grid(row=2, column=1)
    Checkbutton(interface.buttons_frame,
                text="Blue",
                variable=blue,
                background=constants.TOP_COLOR).grid(row=2, column=2)
    image_width = Entry(interface.buttons_frame)
    image_height = Entry(interface.buttons_frame)
    image_width.grid(row=0, column=1)
    image_height.grid(row=1, column=1)
    generate_gray_fading_button = ttk.Button(
        interface.buttons_frame,
        text="Show",
        command=lambda: color_faded_image(int(image_width.get(
        )), int(image_height.get()), red.get(), green.get(), blue.get()))
    generate_gray_fading_button.grid(row=3, column=0)
예제 #3
0
 def test_invalid_value_domain(self):
     v = BooleanVar(self.root, name="name")
     self.root.globalsetvar("name", "value")
     with self.assertRaises(ValueError):
         v.get()
     self.root.globalsetvar("name", "1.0")
     with self.assertRaises(ValueError):
         v.get()
예제 #4
0
 def service_clicked(self, name: str, var: tk.BooleanVar) -> None:
     if var.get() and name not in self.current_services:
         self.current_services.add(name)
     elif not var.get() and name in self.current_services:
         self.current_services.remove(name)
     self.current.listbox.delete(0, tk.END)
     for name in sorted(self.current_services):
         self.current.listbox.insert(tk.END, name)
예제 #5
0
 def test_invalid_value_domain(self):
     v = BooleanVar(self.root, name="name")
     self.root.globalsetvar("name", "value")
     with self.assertRaises(ValueError):
         v.get()
     self.root.globalsetvar("name", "1.0")
     with self.assertRaises(ValueError):
         v.get()
예제 #6
0
 def test_get(self):
     v = BooleanVar(self.root, True, "name")
     self.assertIs(v.get(), True)
     self.root.globalsetvar("name", "0")
     self.assertIs(v.get(), False)
     self.root.globalsetvar("name", 42 if self.root.wantobjects() else 1)
     self.assertIs(v.get(), True)
     self.root.globalsetvar("name", 0)
     self.assertIs(v.get(), False)
     self.root.globalsetvar("name", "on")
     self.assertIs(v.get(), True)
예제 #7
0
 def test_get(self):
     v = BooleanVar(self.root, True, 'name')
     self.assertIs(v.get(), True)
     self.root.globalsetvar('name', '0')
     self.assertIs(v.get(), False)
     self.root.globalsetvar('name', 42 if self.root.wantobjects() else 1)
     self.assertIs(v.get(), True)
     self.root.globalsetvar('name', 0)
     self.assertIs(v.get(), False)
     self.root.globalsetvar('name', 'on')
     self.assertIs(v.get(), True)
예제 #8
0
 def test_get(self):
     v = BooleanVar(self.root, True, "name")
     self.assertIs(v.get(), True)
     self.root.globalsetvar("name", "0")
     self.assertIs(v.get(), False)
     self.root.globalsetvar("name", 42 if self.root.wantobjects() else 1)
     self.assertIs(v.get(), True)
     self.root.globalsetvar("name", 0)
     self.assertIs(v.get(), False)
     self.root.globalsetvar("name", "on")
     self.assertIs(v.get(), True)
예제 #9
0
 def test_invalid_value_domain(self):
     false = 0 if self.root.wantobjects() else "0"
     v = BooleanVar(self.root, name="name")
     with self.assertRaises(TclError):
         v.set("value")
     self.assertEqual(self.root.globalgetvar("name"), false)
     self.root.globalsetvar("name", "value")
     with self.assertRaises(ValueError):
         v.get()
     self.root.globalsetvar("name", "1.0")
     with self.assertRaises(ValueError):
         v.get()
예제 #10
0
 def test_invalid_value_domain(self):
     false = 0 if self.root.wantobjects() else '0'
     v = BooleanVar(self.root, name='name')
     with self.assertRaises(TclError):
         v.set('value')
     self.assertEqual(self.root.globalgetvar('name'), false)
     self.root.globalsetvar('name', 'value')
     with self.assertRaises(ValueError):
         v.get()
     self.root.globalsetvar('name', '1.0')
     with self.assertRaises(ValueError):
         v.get()
예제 #11
0
class Preferences(Frame):
    def __init__(self, client):
        # Basic setup
        super(Preferences, self).__init__()
        self.client = client

        # Setup the variables used
        self.echo_input = BooleanVar()
        self.echo_input.set(self.client.config['UI'].getboolean('echo_input'))
        self.echo_input.trace("w", self.echo_handler)
        self.logging = BooleanVar()
        self.logging.set(
            self.client.config['logging'].getboolean('log_session'))
        self.logging.trace('w', self.logging_handler)
        self.log_dir = self.client.config['logging']['log_directory']

        # Build the actual window and widgets
        prefs = Toplevel(self)
        prefs.wm_title("Preferences")
        echo_input_label = Label(prefs, text="Echo Input:")
        logging_label = Label(prefs, text='Log to file:')
        echo_checkbox = Checkbutton(prefs, variable=self.echo_input)
        logging_checkbox = Checkbutton(prefs, variable=self.logging)
        logging_button_text = 'Choose file...' if self.log_dir == "" else self.log_dir
        logging_button = Button(prefs,
                                text=logging_button_text,
                                command=self.logging_pick_location)

        # Pack 'em in.
        echo_input_label.grid(row=0, column=0)
        echo_checkbox.grid(row=0, column=1)
        logging_label.grid(row=1, column=0)
        logging_checkbox.grid(row=1, column=1)
        logging_button.grid(row=1, column=2)

    def logging_pick_location(self):
        location = askdirectory(initialdir="%UserProfile%\Documents\\")
        self.client.config['logging']['log_directory'] = location
        self.write_config()

    def echo_handler(self, arg1, arg2, mode):
        pprint(self.echo_input.get())
        self.client.config['UI']['echo_input'] = 'yes' if self.echo_input.get(
        ) else 'no'
        self.write_config()

    def logging_handler(self, arg1, arg2, mode):
        self.client.config['logging'][
            'log_session'] = 'yes' if self.logging.get else 'no'
        self.write_config()

    def write_config(self, file='config.ini'):
        self.client.config.write(open(file, 'w'))
예제 #12
0
 def test_invalid_value_domain(self):
     false = 0 if self.root.wantobjects() else "0"
     v = BooleanVar(self.root, name="name")
     with self.assertRaises(TclError):
         v.set("value")
     self.assertEqual(self.root.globalgetvar("name"), false)
     self.root.globalsetvar("name", "value")
     with self.assertRaises(ValueError):
         v.get()
     self.root.globalsetvar("name", "1.0")
     with self.assertRaises(ValueError):
         v.get()
예제 #13
0
class Preferences(Frame):
    def __init__(self, client):
        # Basic setup
        super(Preferences, self).__init__()
        self.client = client

        # Setup the variables used
        self.echo_input = BooleanVar()
        self.echo_input.set(self.client.config['UI'].getboolean('echo_input'))
        self.echo_input.trace("w", self.echo_handler)
        self.logging = BooleanVar()
        self.logging.set(self.client.config['logging'].getboolean('log_session'))
        self.logging.trace('w', self.logging_handler)
        self.log_dir = self.client.config['logging']['log_directory']

        # Build the actual window and widgets
        prefs = Toplevel(self)
        prefs.wm_title("Preferences")
        echo_input_label = Label(prefs, text="Echo Input:")
        logging_label = Label(prefs, text='Log to file:')
        echo_checkbox = Checkbutton(prefs, variable=self.echo_input)
        logging_checkbox = Checkbutton(prefs, variable=self.logging)
        logging_button_text = 'Choose file...' if self.log_dir == "" else self.log_dir
        logging_button = Button(prefs, text=logging_button_text, command=self.logging_pick_location)

        # Pack 'em in.
        echo_input_label.grid(row=0, column=0)
        echo_checkbox.grid(row=0, column=1)
        logging_label.grid(row=1, column=0)
        logging_checkbox.grid(row=1, column=1)
        logging_button.grid(row=1, column=2)

    def logging_pick_location(self):
        location = askdirectory(initialdir="%UserProfile%\Documents\\")
        self.client.config['logging']['log_directory'] = location
        self.write_config()

    def echo_handler(self, arg1, arg2, mode):
        pprint(self.echo_input.get())
        self.client.config['UI']['echo_input'] = 'yes' if self.echo_input.get() else 'no'
        self.write_config()

    def logging_handler(self, arg1, arg2, mode):
        self.client.config['logging']['log_session'] = 'yes' if self.logging.get else 'no'
        self.write_config()

    def write_config(self, file='config.ini'):
        self.client.config.write(open(file, 'w'))
예제 #14
0
class Application(Frame):
    '''GUI app that allows to choose your favorite genres all-in-ones!'''
    def __init__(self, master):
        '''Frame initiation'''
        super(Application, self).__init__(master)
        self.grid()
        self.create_widgets()

    def create_widgets(self):
        """Elements that will help to choose"""
        # Label with description
        Label(
            self,
            text="Choose everything you like:",
        ).grid(row=1, column=0, sticky=W)
        # comedy flag
        self.likes_comedy = BooleanVar()
        Checkbutton(self,
                    text="Comedy",
                    variable=self.likes_comedy,
                    command=self.update_text).grid(row=2, column=0, sticky=W)
        # drama flag
        self.likes_drama = BooleanVar()
        Checkbutton(self,
                    text="Drama",
                    variable=self.likes_drama,
                    command=self.update_text).grid(row=3, column=0, sticky=W)
        # action flag
        self.likes_action = BooleanVar()
        Checkbutton(self,
                    text="Action",
                    variable=self.likes_action,
                    command=self.update_text).grid(row=4, column=0, sticky=W)
        # text area with results
        self.results_txt = Text(self, width=40, height=5, wrap=WORD)
        self.results_txt.grid(row=5, column=0, columnspan=3)

    def update_text(self):
        '''refreshes text area while user changes his preferences'''
        likes = ""
        if self.likes_comedy.get():
            likes += "You like comedies.\n"
        if self.likes_drama.get():
            likes += "You like drama.\n"
        if self.likes_action.get():
            likes += "You like action.\n"
        self.results_txt.delete(0.0, END)
        self.results_txt.insert(0.0, likes)
예제 #15
0
class KRCCModule:
    __metaclass__ = ABCMeta

    def __init__(self):
        self._terminate = BooleanVar(False)
        self._id = StringVar(False)

    @property
    def terminate(self):
        return self._terminate.get()

    @terminate.setter
    def terminate(self, value):
        self._terminate.set(value)

    @property
    def id(self):
        return self._id.get()

    @id.setter
    def id(self, value):
        self._id.set(value)

    @abstractproperty
    def name(self):
        pass

    @abstractmethod
    def run(self):
        pass
예제 #16
0
class Example(Frame):
  
    def __init__(self):
        super().__init__()   
         
        self.initUI()
        
        
    def initUI(self):
      
        self.master.title("Checkbutton")

        self.pack(fill=BOTH, expand=True)
        self.var = BooleanVar()
        
        cb = Checkbutton(self, text="Show title",
            variable=self.var, command=self.onClick)
        cb.select()
        cb.place(x=50, y=50)
        

    def onClick(self):
       
        if self.var.get() == True:
            self.master.title("Checkbutton")
        else:
            self.master.title("")
예제 #17
0
class Exemple(Frame):
    def __init__(self):
        super().__init__()
        self.initUI()

    def initUI(self):
        self.style = Style()
        self.style.theme_use("default")

        self.master.title("convertisseur")
        self.pack(fill = BOTH, expand = 1)

        frame = Frame(self, relief = RAISED, borderwidth = 1)
        frame.pack(fill = BOTH, expand = True)


        bouton = Button(self, text = "Quit",
                        command = self.quit)
        bouton.pack(side = RIGHT, padx = 5, pady = 5)
        bouton1 = Button(self, text = "stay")
        bouton1.pack(side = RIGHT, padx = 5, pady = 5)

        self.var = BooleanVar()
        cb = Checkbutton(self, text = "Montre le titre",
                         variable = self.var, command = self.onClick)
        self.var.set(True)
        cb.pack(side = LEFT, padx = 5, pady = 5)

    def onClick(self):
        if self.var.get() == True:
            self.master.title("convertisseur")
        else:
            self.master.title("")
예제 #18
0
class KRCCModule:
  __metaclass__ = ABCMeta

  def __init__(self):
    self._terminate = BooleanVar(False)
    self._id = StringVar(False)

  @property
  def terminate(self):
    return self._terminate.get()

  @terminate.setter
  def terminate(self, value):
    self._terminate.set(value)

  @property
  def id(self):
    return self._id.get()

  @id.setter
  def id(self, value):
    self._id.set(value)

  @abstractproperty
  def name(self):
    pass

  @abstractmethod
  def run(self):
    pass
예제 #19
0
class CheckBox:
    def __init__(self, root, text: str, x: int, y: int):
        self.varChecked = BooleanVar()
        self.text = text
        self.checkbox = Checkbutton(root,
                                    text=self.text,
                                    variable=self.varChecked,
                                    onvalue=True,
                                    offvalue=False)
        self.x = x
        self.y = y

        self.checkbox.pack()
        self.checkbox.place(x=self.x, y=self.y)

    @property
    def command(self):
        return self.command

    @command.setter
    def command(self, command):
        self.checkbox['command'] = command

    def isChecked(self):
        return True if self.varChecked.get() else False

    def check(self):
        self.checkbox.select()

    def uncheck(self):
        self.checkbox.deselect()
예제 #20
0
파일: nodeconfig.py 프로젝트: umr-ds/core
def mac_auto(is_auto: tk.BooleanVar, entry: ttk.Entry, mac: tk.StringVar) -> None:
    if is_auto.get():
        mac.set("")
        entry.config(state=tk.DISABLED)
    else:
        mac.set("00:00:00:00:00:00")
        entry.config(state=tk.NORMAL)
예제 #21
0
class SettingsWindow(Toplevel):
    def __init__(self) -> None:
        Toplevel.__init__(self)
        self.title("Settings")
        #self.geometry("300x180")
        self.config = configparser.ConfigParser()
        self.config.read('config.ini')
        self.val_int_cmd = (self.register(vcmdtk.test_int), '%d', '%S')
        self.create_gui()
        self.load_settings()
        self.grid_gui()

    def create_gui(self):
        #Label

        self.y_max_label = Label(self, text='Y max')
        self.y_min_label = Label(self, text='Y min')
        #Entry
        self.y_max_entry = Entry(self,
                                 validate='key',
                                 validatecommand=self.val_int_cmd)
        self.y_min_entry = Entry(self,
                                 validate='key',
                                 validatecommand=self.val_int_cmd)
        #Check buttons
        self.check_var_1 = BooleanVar()
        self.check_var_1.set(
            self.config.getboolean('Y Limits', 'use_auto_values'))
        self.auto_y_cbutton = Checkbutton(self,
                                          text='Use auto Y-value ranges',
                                          variable=self.check_var_1,
                                          command=self.auto_y)
        #buttons
        self.ok_button = Button(self, text='Ok', command=self.ok_command)
        self.cancel_button = Button(self, text='Cancel', command=self.destroy)

    def grid_gui(self):
        self.y_max_label.grid(row=0, column=0, pady=2)
        self.y_min_label.grid(row=1, column=0, pady=2)
        self.y_max_entry.grid(row=0, column=1, pady=2)
        self.y_min_entry.grid(row=1, column=1, pady=2)
        self.auto_y_cbutton.grid(row=0, column=2, columnspan=2, sticky=W)
        self.ok_button.grid(row=2, column=2)
        self.cancel_button.grid(row=2, column=3)

    def auto_y(self):
        '''configures values afor check button'''
        if self.check_var_1.get():  #if checked
            state = 'disabled'
        else:
            state = 'enabled'
        self.y_max_entry['state'] = state
        self.y_min_entry['state'] = state

    def load_settings(
            self):  #Inserts settings values(if not none) to tk.entry widghets
        if (x := self.config['Y Limits']['y_max']) != 'None':
            self.y_max_entry.insert(0, x)
        if (x := self.config['Y Limits']['y_min']) != 'None':
            self.y_min_entry.insert(0, x)
예제 #22
0
def generate_circle_input():
    interface = InterfaceInfo.get_instance()
    interface.clean_images()
    interface.delete_widgets(interface.buttons_frame)
    interface.delete_widgets(interface.image_frame)
    ttk.Label(interface.buttons_frame, text="Radius", background=constants.TOP_COLOR).grid(row=0, column=2)
    ttk.Label(interface.buttons_frame, text="Image width", background=constants.TOP_COLOR).grid(row=0, column=0)
    ttk.Label(interface.buttons_frame, text="Image height", background=constants.TOP_COLOR).grid(row=1, column=0)
    radius = Entry(interface.buttons_frame)
    image_width = Entry(interface.buttons_frame)
    image_height = Entry(interface.buttons_frame)
    radio_var = BooleanVar()
    radio_var.set(True)
    Radiobutton(interface.buttons_frame, text="Filled", value=True,
                variable=radio_var, background=constants.TOP_COLOR).grid(row=0, column=4)
    Radiobutton(interface.buttons_frame, text="Empty", value=False,
                variable=radio_var, background=constants.TOP_COLOR).grid(row=1, column=4)
    radius.grid(row=0, column=3)
    image_width.grid(row=0, column=1)
    image_height.grid(row=1, column=1)
    draw_pixel_button = ttk.Button(interface.buttons_frame, text="Draw",
                                   command=lambda:generate_circle("circle.png", int(image_width.get()),
                                                                  int(image_height.get()), int(radius.get()),
                                                                  radio_var.get()))
    # Todo validate params
    draw_pixel_button.grid(row=3, column=0)
예제 #23
0
class OBCheckbutton(Tk):
    """ Messagebox with only one button and a checkbox below the button
        for instance to add a 'Do not show this again' option """
    def __init__(self,
                 title="",
                 message="",
                 button="Ok",
                 image=None,
                 checkmessage="",
                 **options):
        """
            Create a messagebox with one button and a checkbox below the button:
                parent: parent of the toplevel window
                title: message box title
                message: message box text
                button: message displayed on the button
                image: image displayed at the left of the message
                checkmessage: message displayed next to the checkbox
                **options: other options to pass to the Toplevel.__init__ method
        """
        Tk.__init__(self, **options)
        self.title(title)
        self.resizable(False, False)
        self.columnconfigure(1, weight=1)
        self.rowconfigure(0, weight=1)

        style = Style(self)
        style.theme_use(STYLE)
        self.img = None
        if isinstance(image, str):
            try:
                self.img = PhotoImage(file=image)
            except TclError:
                self.img = PhotoImage(data=image)
        elif image:
            self.img = image
        if self.img:
            Label(self, image=self.img).grid(row=0,
                                             column=0,
                                             padx=10,
                                             pady=(10, 0))
        Label(self, text=message, wraplength=335,
              font="TkDefaultFont 10 bold").grid(row=0,
                                                 column=1,
                                                 padx=10,
                                                 pady=(10, 0))
        b = Button(self, text=button, command=self.destroy)
        b.grid(row=2, padx=10, pady=10, columnspan=2)
        self.var = BooleanVar(self)
        c = Checkbutton(self, text=checkmessage, variable=self.var)
        c.grid(row=1, padx=10, pady=4, sticky="e", columnspan=2)
        self.grab_set()
        b.focus_set()

    def get_check(self):
        return self.var.get()
예제 #24
0
 def toggle_column(self, variable: tk.BooleanVar, index: int, column: str):
     columns = list(self.parent.widget_treeview["displaycolumns"])
     if variable.get():
         columns.insert(index, column)
         # print("Added '{}' to the shown columns.".format(column))
     else:
         columns.pop(columns.index(column))
         # print("Removed '{}' from the shown columns.".format(column))
     self.parent.widget_treeview["displaycolumns"] = columns = tuple(
         columns)
예제 #25
0
def mac_auto(is_auto: tk.BooleanVar, entry: ttk.Entry):
    logging.info("mac auto clicked")
    if is_auto.get():
        logging.info("disabling mac")
        entry.delete(0, tk.END)
        entry.insert(tk.END, "")
        entry.config(state=tk.DISABLED)
    else:
        entry.delete(0, tk.END)
        entry.insert(tk.END, "00:00:00:00:00:00")
        entry.config(state=tk.NORMAL)
예제 #26
0
class RootFrame(Frame):
    def __init__(self, master):
        Frame.__init__(self, master)

        self._value = os.getcwd()
        self._var = StringVar(self)
        self._var.set(self._value)
        self._var.trace('w', self._validate)

        label = Label(self, text="Root:")
        label.pack(side=LEFT)
        self._entry = Entry(self, textvariable=self._var)
        self._entry.pack(side=LEFT, fill=X, expand=True)

        self._recursive_var = BooleanVar()
        recursive_cb = Checkbutton(self, text='Recursive', variable=self._recursive_var)
        recursive_cb.pack(side=LEFT)
        self._recursive_var.trace('w', self._validate)
        
        open_button = Button(self, text="Open", command=self._select_root)
        open_button.pack(side=LEFT)
        
        refresh_button = Button(self, text="Refresh", command=self._refresh)
        refresh_button.pack(side=LEFT)

        repad(self, 'padx', 0, 5)

    def _refresh(self):
        self.event_generate('<<Refresh>>', when='tail')

    def _validate(self, *_):
        res = self._var.get().strip()
        if os.path.isdir(res):
            self._entry.config(fg='black')
            self._value = res
        else:
            self._entry.config(fg='red')
            self._value = None
        self.event_generate('<<RootUpdate>>', when='tail')

    def _select_root(self):
        value = askdirectory()
        if value:
            self._var.set(value)
            self._validate()

    @property
    def root(self):
        return self._value

    
    @property
    def recursive(self):
        return self._recursive_var.get()
예제 #27
0
class Boolean(Editor):
    def __init__(self, master, style_def=None):
        super().__init__(master, style_def)
        self.config(**self.style.dark, **self.style.dark_highlight_active)
        self._var = BooleanVar()
        self._var.trace('w', self.check_change)
        self._check = Checkbutton(self, text='')
        self._check['variable'] = self._var
        self._check.pack(fill="x")

    def check_change(self, *_):
        self._check.config(text=str(self._var.get()))
        if self._on_change is not None:
            self._on_change(self._var.get())

    def set(self, value):
        self._var.set(bool(value))
        self._check.config(text=str(self._var.get()))

    def get(self):
        return bool(self._var.get())
예제 #28
0
파일: main.py 프로젝트: Nircek/dots
class Dots(Tk):
    def __init__(self):
        super().__init__()
        self.w = Canvas(self, bg='#aaa')
        self.d = []
        self.t = Thread(target=self.physics, daemon=True)
        self.g = .04
        self.closing = False
        self.start = BooleanVar(self)
        self.w.pack()
        self.w.bind('<Button-1>', lambda ev: self.new(ev.x, ev.y))
        self.bind('<space>', lambda ev: self.start.set(not self.start.get()))
        self.protocol('WM_DELETE_WINDOW', self.on_close)
        self.t.start()

    def on_close(self):
        self.closing = True
        self.destroy()

    def new(self, x, y):
        self.d += [Dot(x, y)]

    def physics(self):
        try:
            while not self.closing:
                if self.d:
                    x = sum([e.x for e in self.d]) / len(self.d)
                    y = sum([e.y for e in self.d]) / len(self.d)
                    self.w.delete(ALL)
                    for e in self.d:
                        if self.start.get():
                            e.vx += self.g * (x - e.x)
                            e.vy += self.g * (y - e.y)
                            e.update()
                        e.render(self.w)
                sleep(1 / 20)
        except:
            if not self.closing:
                raise
예제 #29
0
class Application(Frame):
    "application frame"

    def __init__(self, master):
        """
         @ brief
             initialize the frame with master
         @ params
             self    -- new instance
             master  -- root container
             """
        super(Application, self).__init__(master)

        self.grid()
        self.__createWidgets()

    def __createWidgets(self):
        """
            @ brief
                create the widgets
                """
        Label(self, text="input dictionary tree: ") \
            .grid(row=0, column=0, sticky=W)

        self.dict_with_label = BooleanVar()
        Checkbutton(self, text="label edge", variable=self.dict_with_label) \
            .grid(row=0, column=0, sticky=E)

        self.source_text = Text(self, width=40, wrap=WORD)
        self.source_text.grid(row=1, column=0, sticky=W)

        Button(self, text="visual tree",
               command=self.__submitSource) \
            .grid(row=2, column=0, sticky=W)

        Button(self, text="clear",
               command=self.__clearText)    \
            .grid(row=2, column=0, sticky=E)

    def __submitSource(self):
        "listener for visual button"
        source = self.source_text.get("1.0", END)
        if "" != source:
            current_view = Draw(self)
            current_view.initDot()
            current_view.setSource(source, self.dict_with_label.get())
            current_view.show()

    def __clearText(self):
        "clear button callback"
        self.source_text.delete(0.0, END)
예제 #30
0
def popup_settings() -> None:
    """Открывает окно 'Настройки'."""
    popup = Toplevel()
    log_var = BooleanVar()
    launchicon = PhotoImage(file = 'data/imgs/20ok.png')
    center_x_pos = int(popup.winfo_screenwidth() / 2) - POPUP_WIDTH
    center_y_pos = int(popup.winfo_screenheight() / 2) - POPUP_HEIGHT

    popup.geometry(f'{POPUP_WIDTH}x{POPUP_HEIGHT}+'
                   f'{center_x_pos}+{center_y_pos}')
    popup.title(_('Settings'))
    popup.resizable(False, False)
    frame_settings = LabelFrame(popup, text = _('Settings'))
    frame_settings.grid(sticky = 'NWSE', column = 0, row = 0,
                        ipadx = 5, padx = 5, pady = 5)

    lang_label = Label(frame_settings, text = _('Localisation'))
    lang_label.grid(column = 0, row = 0, ipadx = 5)

    logs_label = Label(frame_settings, text = _('Logging'))
    logs_label.grid(column = 0, row = 1, ipadx = 5)

    lang_vars = Combobox(frame_settings, state = 'readonly',
                         values = check_langs(), width = 4)
    lang_vars.current(current_lang())
    lang_vars.grid(column = 1, row = 0)
    log_settings = Checkbutton(frame_settings,
                               variable = log_var, onvalue = True,
                               offvalue = False)

    log_settings.grid(column = 1, row = 1)

    if getconfig()['settings']['logging'] == 'True':
        log_var.set(True)
    elif getconfig()['settings']['logging'] == 'False':
        log_var.set(False)

    apply_button = Button(popup, text = _('Apply'), width = 20,
                          compound = 'left', image = launchicon,
                          command = lambda: apply(
                                                  lang_vars.get(),
                                                  popup, log_var.get()
                                                  )
                          )
    apply_button.grid(column = 0, row = 1)

    popup.grab_set()
    popup.focus_set()
    popup.wait_window()
예제 #31
0
class CustomRun(Query):
    """Get settings for custom run of module.

    1. Command line arguments to extend sys.argv.
    2. Whether to restart Shell or not.
    """
    # Used in runscript.run_custom_event

    def __init__(self, parent, title, *, cli_args=[],
                 _htest=False, _utest=False):
        """cli_args is a list of strings.

        The list is assigned to the default Entry StringVar.
        The strings are displayed joined by ' ' for display.
        """
        message = 'Command Line Arguments for sys.argv:'
        super().__init__(
                parent, title, message, text0=cli_args,
                _htest=_htest, _utest=_utest)

    def create_extra(self):
        "Add run mode on rows 10-12."
        frame = self.frame
        self.restartvar = BooleanVar(self, value=True)
        restart = Checkbutton(frame, variable=self.restartvar, onvalue=True,
                              offvalue=False, text='Restart shell')
        self.args_error = Label(frame, text=' ', foreground='red',
                                font=self.error_font)

        restart.grid(column=0, row=10, columnspan=3, padx=5, sticky='w')
        self.args_error.grid(column=0, row=12, columnspan=3, padx=5,
                             sticky='we')

    def cli_args_ok(self):
        "Validity check and parsing for command line arguments."
        cli_string = self.entry.get().strip()
        try:
            cli_args = shlex.split(cli_string, posix=True)
        except ValueError as err:
            self.showerror(str(err))
            return None
        return cli_args

    def entry_ok(self):
        "Return apparently valid (cli_args, restart) or None."
        cli_args = self.cli_args_ok()
        restart = self.restartvar.get()
        return None if cli_args is None else (cli_args, restart)
예제 #32
0
class LoginController:
    def __init__(self, view, user):
        self.view = view
        self.user = user
        self.mail = StringVar()
        self.password = StringVar()
        self.checkbox = BooleanVar()
        self.configControl()

    def configControl(self):
        self.view.mail.config(textvariable=self.mail)
        self.view.password.config(textvariable=self.password)
        self.view.admin.config(variable=self.checkbox)

    def valideEmail(self):
        return self.mail.get() != ""

    def validePassword(self):
        return self.password.get() != ""

    def onButtonValidationClicked(self):
        if self.valideEmail() and self.validePassword():
            self.user.mail = self.mail.get()
            self.user.password = self.password.get()
            if self.user.exist():
                if self.checkbox.get():
                    if self.user.isAdmin():
                        self.user.connect(True)
                        admin = Admin(self.user)
                        self.view.master.connectAdmin(admin)
                    else:
                        messagebox.showerror(
                            title="Bad Entry",
                            message="This admin account does not exist")

                else:
                    self.user.connect(False)
                    customer = Customer(self.user)
                    self.view.master.connectCustomer(customer)

            else:
                messagebox.showerror(title="Bad Entry",
                                     message="Error wrong email or password ")

        else:
            messagebox.showerror(title="Bad Entry",
                                 message="Error wrong email or password ")
예제 #33
0
class CheckSpin(Frame):
    def __init__(self,
                 parent,
                 width=200,
                 height=50,
                 val=(0, 100),
                 inc=1,
                 font=('Times', 12),
                 ratio=0.5):
        Frame.__init__(self, parent, width=width, height=height)
        self.pack_propagate(0)

        self.f1 = Frame(self, width=int(width * ratio), height=height)
        self.f1.pack_propagate(0)
        self.f1.pack(side='left')

        self.f2 = Frame(self, width=int(width * (1 - ratio)), height=height)
        self.f2.pack_propagate(0)
        self.f2.pack(side='left')

        self.isfloat = BooleanVar(self.f1)
        self.limit = val
        self.rd_f = Checkbutton(self.f1,
                                text="float",
                                font=font,
                                variable=self.isfloat,
                                onvalue=True,
                                offvalue=False)
        self.rd_f.pack(side='left', fill="y")

        self.sp = Spinbox(self.f2,
                          font=font,
                          from_=val[0],
                          to=val[1],
                          increment=inc)
        self.sp.pack(fill='both', expand=True)

    def get(self):
        valstr = self.sp.get()
        try:
            val = float(valstr)
            val = self.limit[1] if val > self.limit[1] else val
            val = self.limit[0] if val < self.limit[0] else val
        except ValueError:
            val = 0
        return self.isfloat.get(), val
예제 #34
0
class Location:
    def __init__(self, master: Frame = None):
        self.raw_path = StringVar(master)
        self.path = StringVar(master)
        self.nas = BooleanVar(master)

    def set_dir(self):
        path = askdirectory()
        self.raw_path.set(path)
        self.set_nas_dir()

    def set_nas_dir(self):
        path = self.raw_path.get()
        if self.nas.get():
            path = remove_prefix(path, "/Volumes")
            path = (Rsync.base_nas + path).replace("//", "/")
        self.path.set(path)
예제 #35
0
파일: query.py 프로젝트: dothq/mozillabuild
class CustomRun(Query):
    """Get settings for custom run of module.

    1. Command line arguments to extend sys.argv.
    2. Whether to restart Shell or not.
    """
    # Used in runscript.run_custom_event

    def __init__(self, parent, title, *, cli_args='',
                 _htest=False, _utest=False):
        # TODO Use cli_args to pre-populate entry.
        message = 'Command Line Arguments for sys.argv:'
        super().__init__(
                parent, title, message, text0=cli_args,
                _htest=_htest, _utest=_utest)

    def create_widgets(self):
        super().create_widgets(ok_text='Run')
        frame = self.frame
        self.restartvar = BooleanVar(self, value=True)
        restart = Checkbutton(frame, variable=self.restartvar, onvalue=True,
                              offvalue=False, text='Restart shell')
        self.args_error = Label(frame, text=' ', foreground='red',
                                font=self.error_font)

        restart.grid(column=0, row=4, columnspan=3, padx=5, sticky='w')
        self.args_error.grid(column=0, row=12, columnspan=3, padx=5,
                             sticky='we')

    def cli_args_ok(self):
        "Validity check and parsing for command line arguments."
        cli_string = self.entry.get().strip()
        try:
            cli_args = shlex.split(cli_string, posix=True)
        except ValueError as err:
            self.showerror(str(err))
            return None
        return cli_args

    def entry_ok(self):
        "Return apparently valid (cli_args, restart) or None"
        self.entry_error['text'] = ''
        cli_args = self.cli_args_ok()
        restart = self.restartvar.get()
        return None if cli_args is None else (cli_args, restart)
예제 #36
0
class Application(Frame):
    "application frame"

    def __init__(self, master):
        """
         @ brief
             initialize the frame with master
         @ params
             self    -- new instance
             master  -- root container
             """
        super(Application, self).__init__(master)

        self.grid()
        self.__createWidgets()

    def __createWidgets(self):
        """
            @ brief
                create the widgets
                """
        Label(self, text="input dictionary tree: ").grid(row=0, column=0, sticky=W)

        self.dict_with_label = BooleanVar()
        Checkbutton(self, text="label edge", variable=self.dict_with_label).grid(row=0, column=0, sticky=E)

        self.source_text = Text(self, width=40, wrap=WORD)
        self.source_text.grid(row=1, column=0, sticky=W)

        Button(self, text="visual tree", command=self.__submitSource).grid(row=2, column=0, sticky=W)

        Button(self, text="clear", command=self.__clearText).grid(row=2, column=0, sticky=E)

    def __submitSource(self):
        "listener for visual button"
        source = self.source_text.get("1.0", END)
        if "" != source:
            current_view = Draw(self)
            current_view.initDot()
            current_view.setSource(source, self.dict_with_label.get())
            current_view.show()

    def __clearText(self):
        "clear button callback"
        self.source_text.delete(0.0, END)
예제 #37
0
class OBCheckbutton(Tk):
    """ Messagebox with only one button and a checkbox below the button
        for instance to add a 'Do not show this again' option """

    def __init__(self, title="", message="", button="Ok", image=None,
                 checkmessage="", style="clam", **options):
        """
            Create a messagebox with one button and a checkbox below the button:
                parent: parent of the toplevel window
                title: message box title
                message: message box text
                button: message displayed on the button
                image: image displayed at the left of the message
                checkmessage: message displayed next to the checkbox
                **options: other options to pass to the Toplevel.__init__ method
        """
        Tk.__init__(self, **options)
        self.resizable(False, False)
        self.title(title)
        s = Style(self)
        s.theme_use(style)
        if image:
            Label(self, text=message, wraplength=335,
                  font="Sans 11", compound="left",
                  image=image).grid(row=0, padx=10, pady=(10, 0))
        else:
            Label(self, text=message, wraplength=335,
                  font="Sans 11").grid(row=0, padx=10, pady=(10, 0))
        b = Button(self, text=button, command=self.destroy)
        b.grid(row=2, padx=10, pady=10)
        self.var = BooleanVar(self)
        c = Checkbutton(self, text=checkmessage, variable=self.var)
        c.grid(row=1, padx=10, pady=0, sticky="e")
        self.grab_set()
        b.focus_set()
        self.wait_window(self)

    def get_check(self):
        return self.var.get()
예제 #38
0
 def test_default(self):
     v = BooleanVar(self.root)
     self.assertEqual(False, v.get())
예제 #39
0
class dpph_measurement:
    '''
    '''

    def __init__(self, pype, toplevel=False, **runargs):
        '''
        '''
        self.pype = pype
        self.runargs = runargs
        self.toplevel = toplevel
        self.sweep_result = {}

        self.powerVar = DoubleVar(value=20) #dBm
        self.set_power_BoolVar = BooleanVar(value=True)
        self.start_freq_Var = DoubleVar(value=26350) #MHz
        self.stop_freq_Var = DoubleVar(value=26600) #MHz
        self.start_search_freq_Var = DoubleVar(value=26450) #MHz
        self.stop_search_freq_Var = DoubleVar(value=26510) #MHz
        self.sweep_time_Var = DoubleVar(value=15) #s
        self.num_points_Var = IntVar(value=400) #ms
        self.spanVar = DoubleVar(value=100)
        self.stepVar = DoubleVar(value=4)
        #self.fit_channel_Var = StringVar(value='xdata')
        self.result_str_Var = StringVar(value='')

        self._BuildGui()

    def _BuildGui(self):
        '''
            Dpph popup window
        '''
        row = 0
        ##################################################################
        # Lockin Scan
        Label(self.toplevel, text='Input Power'
              ).grid(row=row, column=0, sticky='ew')
        Entry(self.toplevel, textvariable=self.powerVar
              ).grid(row=row, column=1, sticky='ew')
        Label(self.toplevel, text='[dBm]', justify='left'
              ).grid(row=row, column=2, sticky='w')
        Checkbutton(self.toplevel, text="Don't Change",
                    variable=self.set_power_BoolVar).grid(row=row, column=3)
        row += 1

        Label(self.toplevel, text='Scan Frequency Range'
              ).grid(row=row, column=0, sticky='ew')
        Entry(self.toplevel, textvariable=self.start_freq_Var
              ).grid(row=row, column=1, sticky='ew')
        Entry(self.toplevel, textvariable=self.stop_freq_Var
              ).grid(row=row, column=2, columnspan=2, sticky='ew')
        Label(self.toplevel, text='[MHz]').grid(row=row, column=4, sticky='w')
        row += 1

        Label(self.toplevel, text='Sweep Time'
              ).grid(row=row, column=0, sticky='ew')
        Entry(self.toplevel, textvariable=self.sweep_time_Var
              ).grid(row=row, column=1, sticky='ew')
        Label(self.toplevel, text='[s]').grid(row=row, column=2, sticky='w')
        row += 1

        Label(self.toplevel, text='Number of Points'
              ).grid(row=row, column=0, sticky='ew')
        Entry(self.toplevel, textvariable=self.num_points_Var
              ).grid(row=row, column=1, sticky='ew')
        row += 1

        Button(self.toplevel, text='take data', command=self._CollectSweep
               ).grid(row=row, column=0)
        row += 1

        Label(self.toplevel, text='-'*50).grid(row=row, column=0, columnspan=4, sticky='ew')
        row += 1


        ##################################################################
        # Resonance Search
        Label(self.toplevel, text='Search Frequency Range'
              ).grid(row=row, column=0, sticky='ew')
        Entry(self.toplevel, textvariable=self.start_search_freq_Var
              ).grid(row=row, column=1, sticky='ew')
        Entry(self.toplevel, textvariable=self.stop_search_freq_Var
              ).grid(row=row, column=2, columnspan=2, sticky='ew')
        Label(self.toplevel, text='[MHz]').grid(row=row, column=4, sticky='w')
        row += 1

        #ch_options = ['xdata', 'ydata']
        #OptionMenu(self.toplevel, self.fit_channel_Var, *ch_options
        #           ).grid(row=row, column=0, rowspan=2, sticky='ew')
        Button(self.toplevel, text='find resonance', command=self._FindResonance
               ).grid(row=row, column=1, rowspan=2, sticky='ew')
        Label(self.toplevel, textvariable=self.result_str_Var
              ).grid(row=row, column=2, rowspan=2, columnspan=3, sticky='ew')
        row += 2

        Button(self.toplevel, text='Dump To json', command=self._SaveJson
               ).grid(row=row, column=0)
        Button(self.toplevel, text='Save Image', command=self._SaveFigure
               ).grid(row=row, column=1)
        Button(self.toplevel, text='Log DPPH', command=self._LogDPPH
               ).grid(row=row, column=2)

        self._SetupPlot(row=0, column=5)

    def _SetupPlot(self, row, column):
        '''
            Initialize the plot in the gui
        '''
        self.figure = Figure()
        self.figure.subplots_adjust(left=0.15, bottom=0.2)
        self.subfigure = self.figure.add_subplot(1, 1, 1)
        self.subfigure.plot([0], [0])
        self.subfigure.plot([0], [0])
        self.subfigure.set_xlabel('Freq [MHz]')
        self.canvas = FigureCanvasTkAgg(self.figure, master=self.toplevel)
        self.canvas.show()
        self.canvas.get_tk_widget().grid(row=row, column=column, rowspan=10)

    def _CollectSweep(self):
        '''
        '''
        tmp_power = self.powerVar.get()
        if self.set_power_BoolVar.get():
            tmp_power = False
        while True:
            sweep = _GetSweptVoltages(pype=self.pype,
                                  start_freq=self.start_freq_Var.get(),
                                  stop_freq=self.stop_freq_Var.get(),
                                  sweep_time=self.sweep_time_Var.get(),
                                  power=tmp_power,
                                  num_points=self.num_points_Var.get())
            self.sweep_result = sweep.copy()
            freqdata = array(sweep['frequency_curve'])
            magdata = sweep['amplitude_curve']
            if type(magdata[0]) is unicode:
                print('Warning: _GetSweptVoltages failed;')
                print('magdata:')
                print(magdata)
                print('Acquiring data again...')
            elif type(magdata[0]) is int:
                break
        if not sweep['frequencies_confirmed']:
            showwarning('Warning', 'Communication with lockin amp failed. Frequencies data may be wrong')
        magdata = magdata - mean(magdata)
        #ydata = sweep['y_curve']
        print('freq range is ', min(freqdata), ' to ', max(freqdata))
        #xdata = sweep['x_curve']
        y_del = max((max(magdata) - min(magdata)) * .05, 1)
        self.subfigure.set_xlim(left=freqdata[0], right=freqdata[-1])
        self.subfigure.set_ylim(bottom=(min(magdata) - y_del), top=(max(magdata) + y_del))
        line = self.subfigure.get_lines()[0]
        line.set_xdata(array(freqdata))
        line.set_ydata(array(magdata))
        line.set_label('lockin output')
        #line = self.subfigure.get_lines()[1]
        #line.set_xdata(array(freqdata))
        #line.set_ydata(array(ydata))
        #line.set_label('y output')
        self.figure.legends = []
        self.figure.legend(*self.subfigure.get_legend_handles_labels())
        self.figure.legends[0].draggable(True)
        self.canvas.draw()
        self.canvas.show()
        print('Searching for resonance...')
        self._FindResonance()

    def _FindResonance(self):
        '''
        '''
        #if self.fit_channel_Var.get() == 'xdata':
        #    line = self.subfigure.get_lines()[0]
        #elif self.fit_channel_Var.get() == 'ydata':
        #    line = self.subfigure.get_lines()[1]
        line = self.subfigure.get_lines()[0]
        #else:
        #    raise ValueError('not a valid dataset selection')
        xdata = line.get_xdata()
        ydata = line.get_ydata()
        fit = _FindFieldFFT(min_freq=self.start_search_freq_Var.get(),
                            max_freq=self.stop_search_freq_Var.get(),
                            freq_data=xdata,
                            volts_data=ydata)
        outline = self.subfigure.get_lines()[1]
        factor = max(ydata) / max(fit['result'])
        scaled_data = [val * factor for val in fit['result']]
        scaled_data = scaled_data - mean(scaled_data)
        outline.set_xdata(fit['freqs'])
        outline.set_ydata(scaled_data)
        outline.set_label('filter result')
        self.figure.legends = []
        self.figure.legend(*self.subfigure.get_legend_handles_labels())
        self.figure.legends[0].draggable(True)
        self.canvas.draw()
        self.canvas.show()
        res_freq = max(zip(fit['result'], fit['freqs']))[1]
        res_unct = fit['freqs'][1] - fit['freqs'][0]
        print('resonance found at:', res_freq, 'MHz')
        print('err is:', res_unct)
        geff = 2.0036
        chargemass = 1.758e11
        freq_to_field = 4 * pi * 10 ** 7 / (geff * chargemass)
        res_field = freq_to_field * res_freq
        res_field_unct = freq_to_field * res_unct
        print('for a field of', res_field)
        print('field unct of', res_field_unct)
        self.result_str_Var.set('{:.4E} +/- {:.1E} MHz \n({:.4E} +/- {:.1E} kG)'.format(
            res_freq, res_unct, res_field, res_field_unct))
        self.sweep_result.update({'res_freq': res_freq,
                                  'res_freq_unct': res_unct,
                                  'res_field': res_field,
                                  'res_field_unct': res_field_unct})

    def _SaveJson(self):
        '''
        '''
        if not self.sweep_result:
            print('no result stored')
            return
        outfile = asksaveasfile(defaultextension='.json')
        dump(self.sweep_result, outfile, indent=4)
        outfile.close()

    def _SaveFigure(self):
        '''
        '''
        file_extensions = [('vectorized', '.eps'), ('adobe', '.pdf'), ('image', '.png'), ('all', '.*')]
        outfile = asksaveasfilename(defaultextension='.pdf',
                                    filetypes=file_extensions)
        self.figure.savefig(outfile)

    def _LogDPPH(self):
        if not self.sweep_result:
            print('no dpph_result stored')
            return
        result = {
                  'uncal': self.sweep_result['res_freq'],
                  'uncal_err': self.sweep_result['res_freq_unct'],
                  'uncal_units': 'MHz',
                  'cal': self.sweep_result['res_field'],
                  'cal_err': self.sweep_result['res_field_unct'],
                  'cal_units': 'kG',
                 }
        dpph_result = {'uncal_val': ' '.join([str(result['uncal']), '+/-', str(result['uncal_err']), result['uncal_units']]),
                       'cal_val': ' '.join([str(result['cal']), '+/-', str(result['cal_err']), result['cal_units']]),
                       'timestamp': datetime.utcnow()}
        self.pype.LogValue(sensor='dpph_field', **dpph_result)
        print('dpph_result stored')
예제 #40
0
class SearchEngine:
    """Handles searching a text widget for Find, Replace, and Grep."""

    def __init__(self, root):
        '''Initialize Variables that save search state.

        The dialogs bind these to the UI elements present in the dialogs.
        '''
        self.root = root  # need for report_error()
        self.patvar = StringVar(root, '')   # search pattern
        self.revar = BooleanVar(root, False)   # regular expression?
        self.casevar = BooleanVar(root, False)   # match case?
        self.wordvar = BooleanVar(root, False)   # match whole word?
        self.wrapvar = BooleanVar(root, True)   # wrap around buffer?
        self.backvar = BooleanVar(root, False)   # search backwards?

    # Access methods

    def getpat(self):
        return self.patvar.get()

    def setpat(self, pat):
        self.patvar.set(pat)

    def isre(self):
        return self.revar.get()

    def iscase(self):
        return self.casevar.get()

    def isword(self):
        return self.wordvar.get()

    def iswrap(self):
        return self.wrapvar.get()

    def isback(self):
        return self.backvar.get()

    # Higher level access methods

    def setcookedpat(self, pat):
        "Set pattern after escaping if re."
        # called only in SearchDialog.py: 66
        if self.isre():
            pat = re.escape(pat)
        self.setpat(pat)

    def getcookedpat(self):
        pat = self.getpat()
        if not self.isre():  # if True, see setcookedpat
            pat = re.escape(pat)
        if self.isword():
            pat = r"\b%s\b" % pat
        return pat

    def getprog(self):
        "Return compiled cooked search pattern."
        pat = self.getpat()
        if not pat:
            self.report_error(pat, "Empty regular expression")
            return None
        pat = self.getcookedpat()
        flags = 0
        if not self.iscase():
            flags = flags | re.IGNORECASE
        try:
            prog = re.compile(pat, flags)
        except re.error as what:
            args = what.args
            msg = args[0]
            col = args[1] if len(args) >= 2 else -1
            self.report_error(pat, msg, col)
            return None
        return prog

    def report_error(self, pat, msg, col=-1):
        # Derived class could override this with something fancier
        msg = "Error: " + str(msg)
        if pat:
            msg = msg + "\nPattern: " + str(pat)
        if col >= 0:
            msg = msg + "\nOffset: " + str(col)
        tkMessageBox.showerror("Regular expression error",
                               msg, master=self.root)

    def search_text(self, text, prog=None, ok=0):
        '''Return (lineno, matchobj) or None for forward/backward search.

        This function calls the right function with the right arguments.
        It directly return the result of that call.

        Text is a text widget. Prog is a precompiled pattern.
        The ok parameter is a bit complicated as it has two effects.

        If there is a selection, the search begin at either end,
        depending on the direction setting and ok, with ok meaning that
        the search starts with the selection. Otherwise, search begins
        at the insert mark.

        To aid progress, the search functions do not return an empty
        match at the starting position unless ok is True.
        '''

        if not prog:
            prog = self.getprog()
            if not prog:
                return None # Compilation failed -- stop
        wrap = self.wrapvar.get()
        first, last = get_selection(text)
        if self.isback():
            if ok:
                start = last
            else:
                start = first
            line, col = get_line_col(start)
            res = self.search_backward(text, prog, line, col, wrap, ok)
        else:
            if ok:
                start = first
            else:
                start = last
            line, col = get_line_col(start)
            res = self.search_forward(text, prog, line, col, wrap, ok)
        return res

    def search_forward(self, text, prog, line, col, wrap, ok=0):
        wrapped = 0
        startline = line
        chars = text.get("%d.0" % line, "%d.0" % (line+1))
        while chars:
            m = prog.search(chars[:-1], col)
            if m:
                if ok or m.end() > col:
                    return line, m
            line = line + 1
            if wrapped and line > startline:
                break
            col = 0
            ok = 1
            chars = text.get("%d.0" % line, "%d.0" % (line+1))
            if not chars and wrap:
                wrapped = 1
                wrap = 0
                line = 1
                chars = text.get("1.0", "2.0")
        return None

    def search_backward(self, text, prog, line, col, wrap, ok=0):
        wrapped = 0
        startline = line
        chars = text.get("%d.0" % line, "%d.0" % (line+1))
        while 1:
            m = search_reverse(prog, chars[:-1], col)
            if m:
                if ok or m.start() < col:
                    return line, m
            line = line - 1
            if wrapped and line < startline:
                break
            ok = 1
            if line <= 0:
                if not wrap:
                    break
                wrapped = 1
                wrap = 0
                pos = text.index("end-1c")
                line, col = map(int, pos.split("."))
            chars = text.get("%d.0" % line, "%d.0" % (line+1))
            col = len(chars) - 1
        return None
예제 #41
0
class FrameMapping(FrameCustomItem):
    """Holds and visualizes a Map between two columns of different datasets"""
    row_index = None

    is_key = None
    src_reference = None
    src_datatype = None
    src_cast_to = None
    dest_table = None
    curr_data = None
    curr_raw_data = None
    mapping = None

    preview = None
    dest_reference = None

    def __init__(self, _master, _mapping = None,
                 _on_get_source_references = None,
                 _on_get_destination_references = None,
                 _on_select = None):
        super(FrameMapping, self).__init__(_master)


        # Add monitored variables.
        self.is_key = BooleanVar()
        self.src_reference = StringVar()
        self.src_datatype = StringVar()
        self.curr_data = StringVar()

        self.result_cast_to = StringVar()
        self.preview = StringVar()

        self.dest_reference = StringVar()

        self.on_get_source_references = _on_get_source_references
        self.on_get_destination_references = _on_get_destination_references

        self.on_select = _on_select
        self.init_widgets()

        self.mapping = _mapping



        if _mapping is not None:
            self.mapping_to_gui()


    def mapping_to_gui(self):

        self.src_reference.set(str(empty_when_none(self.mapping.src_reference)))
        self.dest_reference.set(str(empty_when_none(self.mapping.dest_reference)))
        self.src_datatype.set(self.mapping.src_datatype)
        self.is_key.set(bool_to_binary_int(self.mapping.is_key))

    def gui_to_mapping(self):

        self.mapping.src_reference = self.src_reference.get()
        self.mapping.dest_reference = self.dest_reference.get()

        self.mapping.is_key = binary_int_to_bool(self.is_key.get())

    def reload_references(self):
        self.cb_source_ref['values'] = self.get_source_references()
        self.cb_dest_ref['values'] = self.get_destination_references()


    def get_source_references(self, _force = None):
        if self.on_get_source_references:
            return self.on_get_source_references(_force)

    def get_destination_references(self, _force = None):
        if self.on_get_destination_references:
            return self.on_get_destination_references( _force)


    def on_change_source_ref(self, *args):
        # reload dataset.
        pass


    def init_widgets(self):

        """Init all widgets"""

        # Source reference
        self.cb_source_ref = ttk.Combobox(self, textvariable=self.src_reference, state='normal')
        self.cb_source_ref['values'] = self.get_source_references()
        self.cb_source_ref.pack(side=LEFT, fill=X, expand=1)


        # Data type label
        self.l_data_type = ttk.Label(self, textvariable=self.src_datatype, width=8)
        self.src_datatype.set("Not set")

        self.l_data_type.pack(side=LEFT)

        # Dest reference
        self.cb_dest_ref = ttk.Combobox(self, textvariable=self.dest_reference, state='normal')
        self.cb_dest_ref['values'] = self.get_destination_references()
        self.cb_dest_ref.pack(side=RIGHT, fill=X, expand=1)

        # Is key field
        self.cb_is_key = ttk.Checkbutton(self, variable=self.is_key)
        self.cb_is_key.pack(side=RIGHT)

        # Current data
        self.l_data = ttk.Label(self, textvariable=self.curr_data)
        self.curr_data.set("No data")
        self.l_data.pack(side=RIGHT, fill=X, padx=5)
예제 #42
0
class take_data:
    '''
    '''

    def __init__(self, pype, toplevel=False, filename=False, num_sequences=10,
                 run_tag=''):
        '''
        '''
        self.pype = pype
        self.toplevel = toplevel

        self.keep_runningVar = BooleanVar(value=True)
        self.extend_runVar = BooleanVar(value=False)
        self.run_typeVar = StringVar(value="/tmp/")
        self.run_tagVar = StringVar(value=run_tag)
        self.num_sequencesVar = IntVar(value=num_sequences)
        self.sequence_spacingVar = DoubleVar(value=0)
        self.len_sequenceVar = DoubleVar()
        self.stateVar = StringVar(value='done')
        self.conf_filename = StringVar(value='')
        self.params = {}
        self.runthread = multiprocessing.Process()

        self._GetParamFuncs()
        if toplevel:
            self._BuildGui()

    def _BuildGui(self):
        '''
            Setup all of the buttons and user entries
        '''
        # Data Location
        row = 0
        Label(self.toplevel, text='-'*20+'Data Location'+'-'*20).grid(row=row,
                                                        columnspan=3, column=0)
        row += 1
        Label(self.toplevel, text='/data').grid(row=row, column=0, sticky='E')
        run_type_options = ["/tmp/", "/commissioning/", "/runs/"]
        OptionMenu(self.toplevel, self.run_typeVar, *run_type_options).grid(
                                             row=row, column=1, sticky='EW')
        Entry(self.toplevel, textvariable=self.run_tagVar).grid(row=row,
                                                                column=2)
        Checkbutton(self.toplevel, text="Extend if Exists",
                    variable=self.extend_runVar).grid(row=row, column=3)
        row += 1
        Label(self.toplevel, text="(raid location)").grid(row=row, column=0, sticky='E')
        Label(self.toplevel, text="(run type)").grid(row=row, column=1)
        Label(self.toplevel, text="(run tag)").grid(row=row, column=2)
        row += 1

        # Acquisition Cycle Details
        Label(self.toplevel, text='-'*20+'Acquisition Cycles'+'-'*20).grid(row=row,
                                                        columnspan=3, column=0)
        row += 1
        Label(self.toplevel, text='Number of Sequences').grid(row=row,
                                                              column=0)
        Entry(self.toplevel, textvariable=self.num_sequencesVar).grid(row=row,
                                                                      column=1)
        row += 1
        Label(self.toplevel, text='Delay Between').grid(row=row, column=0)
        Entry(self.toplevel, textvariable=self.sequence_spacingVar).grid(row=row, column=1)
        Label(self.toplevel, text='[s]').grid(row=row, column=2, sticky='W')
        row += 1
        builtins_list = ['default_run', 'noise_analysis_run']
        self.conf_filename.set(builtins_list[0])
        Button(self.toplevel, text='Load Builtin Run Def',
               command=self._GetParamFuncs).grid(row=row, column=0)
        OptionMenu(self.toplevel, self.conf_filename, *builtins_list).grid(
            row=row, column=1)
        self.conf_filename.set(builtins_list[0])
        row += 1
        Label(self.toplevel, text='Load Custom Run Def').grid(row=row,
                                                              column=0)
        Button(self.toplevel, text="find file", command=self._ParamFuncFile
               ).grid(row=row, column=1)
        row += 1

        # Mantis Settings
        Label(self.toplevel, text='-'*20+'Mantis Settings'+'-'*20).grid(row=row,
                                                        columnspan=3, column=0)
        row += 1
        Label(self.toplevel, text='(Empty fields use default values)').grid(row=row,
                                                        columnspan=3, column=0)
        row += 1
        Label(self.toplevel, text='Digitization Time').grid(row=row, column=0)
        Entry(self.toplevel, textvariable=self.len_sequenceVar).grid(row=row,
                                                                     column=1)
        Label(self.toplevel, text='[ms]').grid(row=row, column=2, sticky='W')
        row += 1

        Button(self.toplevel, text="Start Run", command=self.DoRun
               ).grid(row=row, column=0)
        Button(self.toplevel, text="ABORT", command=self._Abort, bg='red'
               ).grid(row=row, column=1)
        Label(self.toplevel, textvariable=self.stateVar).grid(row=row, column=2)

    def _ParamFuncFile(self):
        '''
        '''
        self.conf_filename.set(askopenfilename())
        if self.conf_filename.get():
            self._GetParamFuncs()

    def _Abort(self):
        '''
        '''
        self.keep_runningVar.set(False)
        if self.runthread.is_alive():
            print('terminating child process')
            self.runthread.terminate()
        else:
            print('no current thread')
        self.stateVar.set('aborted')

    def _IsRunning(self):
        '''
        '''
        print(self.runthread.is_alive())

    def _GetParamFuncs(self):
        '''
        '''
        fname = self.conf_filename.get()
        if not fname or fname == 'default_run':
            if not 'run_params' in sys.modules:
                from . import default_run as run_params
            else:
                reload(run_params)
        elif fname == 'noise_analysis_run':
            from . import noise_analysis_run as run_params
        else:
            imp.load_source('run_params', fname)
            import run_params
        self.DefaultParams = run_params.DefaultParams
        self.SequenceParams = run_params.SequenceParams
        self.FilenamePrefix = run_params.FilenamePrefix
        self.Mantis_kwargs = run_params.Mantis_kwargs()
        if 'duration' in self.Mantis_kwargs:
            self.len_sequenceVar.set(self.Mantis_kwargs['duration'])

    def DoRun(self):
        '''
            Execute the run
        '''
        self.keep_runningVar.set(True)
        self.stateVar.set('normal')
        if self.runthread.is_alive():
            print('there is already live process, abort first or let it finish')
        else:
            self.runthread = multiprocessing.Process(target=self.__DoRun)
            self.runthread.start()

    def __DoRun(self):
        '''
            the run called by DoRun in a subprocess
        '''
        self.params['run_tag'] = self.run_tagVar.get()
        self.params['num_sequences'] = self.num_sequencesVar.get()
        print('setting defaults')
        self._SetParams(self.DefaultParams())
        for sequence_num in range(self.params['num_sequences']):
            print('--> starting sequence {0}/{1}'.format(sequence_num, self.params['num_sequences'] - 1))
            if not self.keep_runningVar.get():
                print('Aborting!')
                break
            self._DoSequence(sequence_num)
            print('--> sequence {0}/{1} complete.'.format(sequence_num, self.params['num_sequences'] - 1))
            sleep(self.sequence_spacingVar.get())
        print('-> run (tag: {0}) complete.'.format(self.params['run_tag']))
        self.stateVar.set('run complete')

    def _SetParams(self, params_list):
        '''
        '''
        for channel_name, value in params_list:
            setattempt = self.pype.Set(channel_name, value)
            setattempt.Wait()
            if setattempt.Waiting():
                raise NoResponseError('setting ' + str(channel_name))
            print(channel_name, '->', value)

    def _DoSequence(self, sequence_number):
        '''
            Do one sequence within the run
        '''
        mantis_kwargs = self.Mantis_kwargs.copy()
        run_doc = self.pype.NewDump(uuid4().hex, self.params['run_tag'],
                                    new_run=((not sequence_number) and
                                    not self.extend_runVar.get()))
        self._SetParams(self.SequenceParams(sequence_number))
        for channel in self.pype.ListWithProperty('dump'):
            run_doc[channel] = self.pype.Get(channel)
            run_doc[channel].Update()
            run_doc[channel].Wait()
        run_doc._UpdateTo()
        outfilename = '/data/{:s}_{:05d}_{:05d}.egg'.format(
            self.FilenamePrefix(sequence_number),
            run_doc['run_number'],
            run_doc['sequence_number'])
        print('outputting '+outfilename)
        run_descrip = ast.literal_eval(mantis_kwargs['description'])
        for (chan, val) in self.SequenceParams(sequence_number):
            run_descrip[chan] = val
        run_descrip['run_tag'] = self.params['run_tag']
        run_doc['sequence_tag'] = dumps(run_descrip)
        mantis_kwargs.update({'output': outfilename,
                              'description': dumps(run_descrip),
                              'duration': self.len_sequenceVar.get()})
        run = self.pype.RunMantis(**mantis_kwargs)
        print('mantis run starting')
        run.Wait()
        run_doc['mantis'] = run
        run_doc._UpdateTo()
예제 #43
0
 def test_default(self):
     v = BooleanVar(self.root)
     self.assertIs(v.get(), False)
예제 #44
0
class GrepDialog(SearchDialogBase):

    title = "Find in Files Dialog"
    icon = "Grep"
    needwrapbutton = 0

    def __init__(self, root, engine, flist):
        SearchDialogBase.__init__(self, root, engine)
        self.flist = flist
        self.globvar = StringVar(root)
        self.recvar = BooleanVar(root)

    def open(self, text, searchphrase, io=None):
        SearchDialogBase.open(self, text, searchphrase)
        if io:
            path = io.filename or ""
        else:
            path = ""
        dir, base = os.path.split(path)
        head, tail = os.path.splitext(base)
        if not tail:
            tail = ".py"
        self.globvar.set(os.path.join(dir, "*" + tail))

    def create_entries(self):
        SearchDialogBase.create_entries(self)
        self.globent = self.make_entry("In files:", self.globvar)[0]

    def create_other_buttons(self):
        f = self.make_frame()[0]

        btn = Checkbutton(f, anchor="w",
                variable=self.recvar,
                text="Recurse down subdirectories")
        btn.pack(side="top", fill="both")
        btn.select()

    def create_command_buttons(self):
        SearchDialogBase.create_command_buttons(self)
        self.make_button("Search Files", self.default_command, 1)

    def default_command(self, event=None):
        prog = self.engine.getprog()
        if not prog:
            return
        path = self.globvar.get()
        if not path:
            self.top.bell()
            return
        from OutputWindow import OutputWindow  # leave here!
        save = sys.stdout
        try:
            sys.stdout = OutputWindow(self.flist)
            self.grep_it(prog, path)
        finally:
            sys.stdout = save

    def grep_it(self, prog, path):
        dir, base = os.path.split(path)
        list = self.findfiles(dir, base, self.recvar.get())
        list.sort()
        self.close()
        pat = self.engine.getpat()
        print("Searching %r in %s ..." % (pat, path))
        hits = 0
        try:
            for fn in list:
                try:
                    with open(fn, errors='replace') as f:
                        for lineno, line in enumerate(f, 1):
                            if line[-1:] == '\n':
                                line = line[:-1]
                            if prog.search(line):
                                sys.stdout.write("%s: %s: %s\n" %
                                                 (fn, lineno, line))
                                hits += 1
                except OSError as msg:
                    print(msg)
            print(("Hits found: %s\n"
                  "(Hint: right-click to open locations.)"
                  % hits) if hits else "No hits.")
        except AttributeError:
            # Tk window has been closed, OutputWindow.text = None,
            # so in OW.write, OW.text.insert fails.
            pass

    def findfiles(self, dir, base, rec):
        try:
            names = os.listdir(dir or os.curdir)
        except OSError as msg:
            print(msg)
            return []
        list = []
        subdirs = []
        for name in names:
            fn = os.path.join(dir, name)
            if os.path.isdir(fn):
                subdirs.append(fn)
            else:
                if fnmatch.fnmatch(name, base):
                    list.append(fn)
        if rec:
            for subdir in subdirs:
                list.extend(self.findfiles(subdir, base, rec))
        return list

    def close(self, event=None):
        if self.top:
            self.top.grab_release()
            self.top.withdraw()
예제 #45
0
class OmxGui(Frame):
   
   def __init__(self, parent, argv):
      
      Frame.__init__(self, parent, padding=(3,6,3,12), style="TFrame")
      
      self.parent = parent
      
      self.initData()
      
      self.initUI()
      
      if len(argv) > 1:
         try:
            self.updateAndPlayVideo(argv[1])
         except FileNotFoundError:
            self.logDebug('File Not Found')
      
   def initData(self):
      self.browseInitialDir = def_initialDir
      
      self.recentFile = def_recentFile
      
      self.menuOutputAudio = StringVar()
      self.menuOutputAudio.set(def_menuOutputAudio)
      
      self.menuVideoRefresh = BooleanVar()
      self.menuVideoRefresh.set(def_menuVideoRefresh)
      
      self.menuBgBlack = BooleanVar()
      self.menuBgBlack.set(def_menuBgBlack)
      
      self.maxRecentVideos = def_maxRecentVideos
      
      self.moreOptions = def_moreOptions
      
      self.playProcess = None

   def initUI(self):
      
      self.parent.title('OMX GUI')
      
      self.parent.bind("<Key>", self.keyEvt)
      
      # ---- STYLE ----
      
      Style().theme_use('default')

      Style().configure("TFrame", background="white")
      Style().configure("TButton", font="12", padding=(5,1,5,1), background="#4285F4", foreground="white")
      Style().configure("TEntry", font="12", padding=(5,3,5,2))
      Style().configure("TLabel", background="white")
      Style().map('TButton',
                 foreground=[('pressed', 'white'), ('active', 'white')],
                 background=[('pressed', '!disabled', '#3367d6'), ('active', '#3b78e7')],
                 highlightcolor=[('focus','#4285F4')],
                 relief=[('pressed', '!disabled', 'flat')])
      Style().configure('Treeview', foreground='#333', background="white", highlightthickness='0')
      Style().map('Treeview',
                 foreground=[('focus', '#000')],
                 background=[('focus', '#F5F5F5')])

      # ---- MENU ----
      self.menubar = menubar = MenuBar(self, self.parent)
      
      # ---- TREE ----
      self.filesTree = filesTree = FilesTree(self)
      self.filesTree.loadRecentFile()
      
      # ---- BUTTONS ----
      bBrowse = Button(self, text=_("browse"), width="6", command=self.openVideo)
      bPlay = Button(self, text=_("play"), width="6", command=self.playVideo)
      
      # ---- GRID ----
      self.grid(column=0, row=0, sticky=(N, E, W, S))
      filesTree.grid(column=0, row=0, columnspan=2, rowspan=2, sticky=(N,W,E))
      bBrowse.grid(column=0, row=2, sticky=(N,W))
      bPlay.grid(column=0, row=2, sticky=(N,W), padx=70)
      
      self.parent.columnconfigure(0, weight=1)
      self.parent.rowconfigure(0, weight=1)
      self.columnconfigure(0, weight=1)
      self.columnconfigure(1, weight=1)
      self.rowconfigure(0, weight=1)
      self.rowconfigure(1, weight=1)
      
      self.centerWindow()
      
   def centerWindow(self):
      self.parent.update_idletasks()
      
      w = self.parent.winfo_reqwidth() + 20
      h = self.parent.winfo_reqheight() + 20
      sw = self.parent.winfo_screenwidth()
      sh = self.parent.winfo_screenheight()

      x = (sw - w)/4
      y = (sh - h)/4
      self.parent.geometry("%dx%d+%d+%d" % (w, h, x, y))
      self.parent.resizable(False,False)
      self.parent.focus_force()
      self.parent.lift()
   
   def quitProgram(self):
      self.parent.quit()

   def clearRecentVideos(self):
      self.filesTree.clearRecentVideos()

   def updateRecentVideos(self, fullpath):
      return self.filesTree.updateRecentVideos(fullpath)

   def updateAndPlayVideo(self, fullpath):
      if self.updateRecentVideos(fullpath):
         self.playVideo()

   def openVideo(self):
      fullpath = fileDialog.askopenfilename(
         title=_('open.file')
         ,initialdir=self.browseInitialDir)
      self.updateAndPlayVideo(fullpath)
      
   def playVideo(self):
      lastFile = self.filesTree.getLastFile()
      if lastFile is not None and lastFile['fullpath'] is not '':
         outputAudio = '-o ' + self.menuOutputAudio.get() + ' '
         adjustVideo = '-r ' if self.menuVideoRefresh.get() else ''
         bgBlack = '-b ' if self.menuBgBlack.get() else ''
         moreOptions = self.moreOptions
         fPath = lastFile['fullpath'].replace(' ', '\ ')
         cmdStr = 'omxplayer ' + outputAudio + adjustVideo + bgBlack + moreOptions + fPath
         
         self.logDebug(cmdStr)
         self.playProcess = Popen(['bash', '-c', cmdStr], stdin=PIPE, bufsize = 1)
         self.parent.focus_force()
   
   def keyEvt(self, event):
      self.logDebug('char: ' + event.char + ' --- key simbol: ' + event.keysym + ' ---  key code: ' + str(event.keycode))
      if self.playProcess is not None:
         # right
         if event.keysym == 'Right':
            self.playProcess.stdin.write(bytes('^[[C', 'UTF-8'))
         # left
         elif event.keysym == 'Left':
            self.playProcess.stdin.write(bytes('^[[D', 'UTF-8'))
         # up
         elif event.keysym == 'Up':
            self.playProcess.stdin.write(bytes('^[[A', 'UTF-8'))
         # down
         elif event.keysym == 'Down':
            self.playProcess.stdin.write(bytes('^[[B', 'UTF-8'))
         elif event.char == 'x':
            self.playProcess.kill()
            self.playProcess = None
         else:
            self.playProcess.stdin.write(bytes(event.char, 'UTF-8'))
         try:
            self.playProcess.stdin.flush()
         except IOError:
            try:
               self.playProcess.stdin.close()
               self.playProcess = None
            except IOError:
               self.playProcess = None
         self.parent.focus_force()
   
   def logDebug(self, msg):
      if isDebug and msg is not None:
         print(str(msg))
예제 #46
0
파일: grep.py 프로젝트: 1st1/cpython
class GrepDialog(SearchDialogBase):
    "Dialog for searching multiple files."

    title = "Find in Files Dialog"
    icon = "Grep"
    needwrapbutton = 0

    def __init__(self, root, engine, flist):
        """Create search dialog for searching for a phrase in the file system.

        Uses SearchDialogBase as the basis for the GUI and a
        searchengine instance to prepare the search.

        Attributes:
            globvar: Value of Text Entry widget for path to search.
            recvar: Boolean value of Checkbutton widget
                    for traversing through subdirectories.
        """
        SearchDialogBase.__init__(self, root, engine)
        self.flist = flist
        self.globvar = StringVar(root)
        self.recvar = BooleanVar(root)

    def open(self, text, searchphrase, io=None):
        "Make dialog visible on top of others and ready to use."
        SearchDialogBase.open(self, text, searchphrase)
        if io:
            path = io.filename or ""
        else:
            path = ""
        dir, base = os.path.split(path)
        head, tail = os.path.splitext(base)
        if not tail:
            tail = ".py"
        self.globvar.set(os.path.join(dir, "*" + tail))

    def create_entries(self):
        "Create base entry widgets and add widget for search path."
        SearchDialogBase.create_entries(self)
        self.globent = self.make_entry("In files:", self.globvar)[0]

    def create_other_buttons(self):
        "Add check button to recurse down subdirectories."
        btn = Checkbutton(
                self.make_frame()[0], variable=self.recvar,
                text="Recurse down subdirectories")
        btn.pack(side="top", fill="both")

    def create_command_buttons(self):
        "Create base command buttons and add button for search."
        SearchDialogBase.create_command_buttons(self)
        self.make_button("Search Files", self.default_command, 1)

    def default_command(self, event=None):
        """Grep for search pattern in file path. The default command is bound
        to <Return>.

        If entry values are populated, set OutputWindow as stdout
        and perform search.  The search dialog is closed automatically
        when the search begins.
        """
        prog = self.engine.getprog()
        if not prog:
            return
        path = self.globvar.get()
        if not path:
            self.top.bell()
            return
        from idlelib.outwin import OutputWindow  # leave here!
        save = sys.stdout
        try:
            sys.stdout = OutputWindow(self.flist)
            self.grep_it(prog, path)
        finally:
            sys.stdout = save

    def grep_it(self, prog, path):
        """Search for prog within the lines of the files in path.

        For the each file in the path directory, open the file and
        search each line for the matching pattern.  If the pattern is
        found,  write the file and line information to stdout (which
        is an OutputWindow).
        """
        dir, base = os.path.split(path)
        list = self.findfiles(dir, base, self.recvar.get())
        list.sort()
        self.close()
        pat = self.engine.getpat()
        print(f"Searching {pat!r} in {path} ...")
        hits = 0
        try:
            for fn in list:
                try:
                    with open(fn, errors='replace') as f:
                        for lineno, line in enumerate(f, 1):
                            if line[-1:] == '\n':
                                line = line[:-1]
                            if prog.search(line):
                                sys.stdout.write(f"{fn}: {lineno}: {line}\n")
                                hits += 1
                except OSError as msg:
                    print(msg)
            print(f"Hits found: {hits}\n(Hint: right-click to open locations.)"
                  if hits else "No hits.")
        except AttributeError:
            # Tk window has been closed, OutputWindow.text = None,
            # so in OW.write, OW.text.insert fails.
            pass

    def findfiles(self, dir, base, rec):
        """Return list of files in the dir that match the base pattern.

        If rec is True, recursively iterate through subdirectories.
        """
        try:
            names = os.listdir(dir or os.curdir)
        except OSError as msg:
            print(msg)
            return []
        list = []
        subdirs = []
        for name in names:
            fn = os.path.join(dir, name)
            if os.path.isdir(fn):
                subdirs.append(fn)
            else:
                if fnmatch.fnmatch(name, base):
                    list.append(fn)
        if rec:
            for subdir in subdirs:
                list.extend(self.findfiles(subdir, base, rec))
        return list
예제 #47
0
class FrameFlatfileDataset(FrameCustomFileDataset):
    """
        Holds an instance of, and visually represents, a flatfile dataset.
        See qal.dataset.flatfile.FlatfileDataset
    """

    def __init__(self, _master, _dataset = None, _relief = None, _is_destination=None):
        super(FrameFlatfileDataset, self ).__init__(_master, _dataset, _relief, _is_destination=_is_destination)

        if _dataset is None:
            self.dataset = FlatfileDataset()

    def on_select(self):
        """Brings up a selector dialog, prompting the user to select a file,
        the relative path if the file is then saved to the filename property.
        Also, the base path is set.
        """
        self.select_file(_default_extension = ".csv", _file_types=[('.csv files', '.csv'), ('all files', '.*')])

    def init_widgets(self):
        # file selector
        self.btn_file_select=Button(self, text="Select file",command=self.on_select)
        self.btn_file_select.grid(column=0, row=0, columnspan=2)
        # filename
        self.filename, self.e_filename, self.l_filename = make_entry(self,"File name: ", 1)

        # delimiter
        self.delimiter, self.e_delimiter, self.l_delimiter = make_entry(self,"Delimiter: ", 2)

        # has_header
        self.l_has_header = ttk.Label(self, text="Has header: ")
        self.l_has_header.grid(column=0, row=3, sticky=W)
        self.has_header = BooleanVar()
        self.e_has_header = ttk.Checkbutton(self, variable=self.has_header)
        self.e_has_header.grid(column=1, row=3, sticky=W)

        # csv_dialect
        self.csv_dialect, self.e_csv_dialect, self.l_csv_dialect = make_entry(self,"CSV dialect: ", 4)

        # quoting
        self.quoting, self.e_quoting, self.l_quoting = make_entry(self, "Quoting: ", 5)

        # escapechar
        self.escapechar, self.e_escapechar, self.l_escapechar = make_entry(self, "Escape character: ", 6)

        # lineterminator
        self.lineterminator, self.e_lineterminator, self.l_lineterminator = make_entry(self, "Line terminator: ", 7)

        # quotechar
        self.quotechar, self.e_quotechar, self.l_quotechar = make_entry(self, "Quote character: ", 8)

        # skipinitialspace
        self.skipinitialspace, self.e_skipinitialspace, self.l_skipinitialspace = make_entry(self, "Skip initial space: ", 9)

    def read_from_dataset(self):
        super(FrameFlatfileDataset, self ).read_from_dataset()

        self.filename.set(empty_when_none(self.dataset.filename))
        self.delimiter.set(empty_when_none(self.dataset.delimiter))
        self.has_header.set(bool_to_binary_int(self.dataset.has_header))
        self.csv_dialect.set(empty_when_none(self.dataset.csv_dialect))
        self.quoting.set(empty_when_none(self.dataset.quoting))
        self.escapechar.set(empty_when_none(self.dataset.escapechar))
        self.lineterminator.set(empty_when_none(self.dataset.lineterminator))
        self.quotechar.set(empty_when_none(self.dataset.quotechar))
        self.skipinitialspace.set(empty_when_none(self.dataset.skipinitialspace))

    def write_to_dataset(self):
        super(FrameFlatfileDataset, self ).write_to_dataset()

        if self.dataset is None:
            self.dataset = FlatfileDataset()

        self.dataset.filename = self.filename.get()
        self.dataset.delimiter = self.delimiter.get()
        self.dataset.has_header = self.has_header.get()
        self.dataset.csv_dialect = self.csv_dialect.get()
        self.dataset.quoting = self.quoting.get()
        self.dataset.escapechar = self.escapechar.get()
        self.dataset.lineterminator = self.lineterminator.get()
        self.dataset.quotechar = self.quotechar.get()
        self.dataset.skipinitialspace = self.skipinitialspace.get()


    def reload(self):
        self.notify_task("Load file "+ self.dataset.filename, 10)
        self.dataset.load()
        self.notify_task("Loaded filed "+ self.dataset.filename + ".", 100)

    def get_possible_references(self, _force = None):

        if not self.dataset.field_names or _force == True:
            self.reload()

        self.references = self.dataset.field_names
        return self.dataset.field_names

    def check_reload(self):
        _filename = self.filename.get()
        if not os.path.isabs(_filename) and self.base_path is None:
            return "First save the merge. You use a relative path to the flatfile dataset."
        else:
            return False
예제 #48
0
파일: main.py 프로젝트: pielambr/ydlui
class YdlGUI(Frame):
    def __init__(self, parent):
        Frame.__init__(self, parent)
        self.parent = parent
        self.pack(fill=BOTH, expand=True)
        self.parent.title("youtube-dl GUI")
        # Initialise variables
        self._extract_audio = BooleanVar()
        self._video_url = StringVar()
        self._output_path = StringVar()
        # Initialise
        self._logger = LogWindow(self)
        self._init_ui()

    def _init_ui(self):
        # Label to specify video link
        lbl_video_url = Label(self, text="Video URL:")
        lbl_video_url.place(x=20, y=20)
        # Entry to enter video url
        entr_video_url = Entry(self, width=50, textvariable=self._video_url)
        entr_video_url.place(x=100, y=20)
        # Checkbutton to extract audio
        cb_extract_audio = Checkbutton(self, var=self._extract_audio, text="Only keep audio")
        cb_extract_audio.pack()
        cb_extract_audio.place(x=20, y=60)
        # Button to browse for location
        b_folder_choose = Button(self, text="Choose output directory", command=self.ask_directory)
        b_folder_choose.place(x=150, y=90)
        # Button to start downloading
        b_start_download = Button(self, text="Start download", command=self.download)
        b_start_download.place(x=20, y=90)
        # Log window to log progress
        self._logger.place(x=20, y=130)

    def ask_directory(self):
        self._output_path.set(file_dialog.askdirectory())

    def start_youtube_dl(self):
        # Start downloading the specified url
        if self._output_path.get():
            output_path = self._output_path.get()
        else:
            try:
                output_path = os.path.dirname(os.path.abspath(__file__))
            except NameError:
                import sys
                output_path = os.path.dirname(os.path.abspath(sys.argv[0]))
        output_tmpl = output_path + '/%(title)s-%(id)s.%(ext)s'
        options = {
            'format': 'bestvideo[ext=mp4]+bestaudio[ext=m4a]/bestvideo+bestaudio/best',
            'merge_output_format': 'mp4',
            'socket_timeout': '15',
            'progress_hooks': [self._logger.log],
            'ignoreerrors': True,
            'outtmpl': output_tmpl,
        }
        if self._extract_audio.get():
            options['format'] = 'bestaudio/best',
            options['postprocessors'] = [{
                'key': 'FFmpegExtractAudio',
                'preferredcodec': 'mp3',
                'preferredquality': '3',
            }]
        dl = YoutubeDL(options)
        status = dl.download([self._video_url.get()])
        if status != 0:
            mbox.showerror("youtube-dl error", "An error happened whilst processing your video(s)")
        else:
            mbox.showinfo("youtube-dl finished", "Your video(s) have been successfully processed")

    def download(self):
        thr = Thread(target=self.start_youtube_dl)
        thr.start()
예제 #49
0
 def test_get(self):
     v = BooleanVar(self.root, True, "name")
     self.assertAlmostEqual(True, v.get())
     self.root.globalsetvar("name", "0")
     self.assertAlmostEqual(False, v.get())
예제 #50
0
class MarkovDemo(Frame):

    "MarkovDemo(master=None, **kw) -> MarkovDemo instance"

    TEXT = dict(height=2, width=46, wrap=WORD)  # Text Options
    GRID = dict(padx=5, pady=5)                 # Grid Options

    # Initialize a MarkovDemo instance with a GUI for interaction.

    def __init__(self, master=None, **kw):
        "Initialize the MarkovDemo instance's widgets and settings."
        super().__init__(master, **kw)
        self.build_widgets()
        self.place_widgets()
        self.setup_widgets()
        self.grid_rowconfigure(2, weight=1)
        self.grid_rowconfigure(3, weight=1)
        self.grid_columnconfigure(0, weight=1)
        self.key = self.primer = None

    def build_widgets(self):
        "Build the various widgets that will be used in the program."
        # Create processing frame widgets.
        self.processing_frame = LabelFrame(self, text='Processing Mode:')
        self.mode_var = StringVar(self, 'encode')
        self.decode_button = Radiobutton(self.processing_frame,
                                         text='Decode Cipher-Text',
                                         command=self.handle_radiobuttons,
                                         value='decode',
                                         variable=self.mode_var)
        self.encode_button = Radiobutton(self.processing_frame,
                                         text='Encode Plain-Text',
                                         command=self.handle_radiobuttons,
                                         value='encode',
                                         variable=self.mode_var)
        self.freeze_var = BooleanVar(self, False)
        self.freeze_button = Checkbutton(self.processing_frame,
                                         text='Freeze Key & Primer',
                                         command=self.handle_checkbutton,
                                         offvalue=False,
                                         onvalue=True,
                                         variable=self.freeze_var)
        # Create encoding frame widgets.
        self.encoding_frame = LabelFrame(self, text='Encoding Options:')
        self.chain_size_label = Label(self.encoding_frame, text='Chain Size:')
        self.chain_size_entry = Entry(self.encoding_frame)
        self.plain_text_label = Label(self.encoding_frame, text='Plain-Text:')
        self.plain_text_entry = Entry(self.encoding_frame)
        # Create input frame widgets.
        self.input_frame = LabelFrame(self, text='Input Area:')
        self.input_text = ScrolledText(self.input_frame, **self.TEXT)
        # Create output frame widgets.
        self.output_frame = LabelFrame(self, text='Output Area:')
        self.output_text = ScrolledText(self.output_frame, **self.TEXT)

    def place_widgets(self):
        "Place the widgets where they belong in the MarkovDemo frame."
        # Locate processing frame widgets.
        self.processing_frame.grid(sticky=EW, **self.GRID)
        self.decode_button.grid(row=0, column=0, **self.GRID)
        self.encode_button.grid(row=0, column=1, **self.GRID)
        self.freeze_button.grid(row=0, column=2, **self.GRID)
        # Locate encoding frame widgets.
        self.encoding_frame.grid(sticky=EW, **self.GRID)
        self.chain_size_label.grid(row=0, column=0, sticky=W, **self.GRID)
        self.chain_size_entry.grid(row=0, column=1, sticky=EW, **self.GRID)
        self.plain_text_label.grid(row=1, column=0, sticky=W, **self.GRID)
        self.plain_text_entry.grid(row=1, column=1, sticky=EW, **self.GRID)
        self.encoding_frame.grid_columnconfigure(1, weight=1)
        # Locate input frame widgets.
        self.input_frame.grid(sticky=NSEW, **self.GRID)
        self.input_text.grid(sticky=NSEW, **self.GRID)
        self.input_frame.grid_rowconfigure(0, weight=1)
        self.input_frame.grid_columnconfigure(0, weight=1)
        # Locate output frame widgets.
        self.output_frame.grid(sticky=NSEW, **self.GRID)
        self.output_text.grid(sticky=NSEW, **self.GRID)
        self.output_frame.grid_rowconfigure(0, weight=1)
        self.output_frame.grid_columnconfigure(0, weight=1)

    def setup_widgets(self):
        "Setup each widget's configuration for the events they handle."
        self.input_text.bind('<Key>', self.handle_key_events)
        self.input_text.bind('<Control-Key-a>', self.handle_control_a)
        self.input_text.bind('<Control-Key-/>', lambda event: 'break')
        self.output_text['state'] = DISABLED
        self.output_text.bind('<Control-Key-a>', self.handle_control_a)
        self.output_text.bind('<Control-Key-/>', lambda event: 'break')

    ########################################################################

    # Take care of any special event needing dedicated processing.

    def handle_radiobuttons(self):
        "Change the interface based on the encoding / decoding setting."
        if self.encrypting:
            self.freeze_button.grid()
            if not self.freeze_var.get():
                self.encoding_frame.grid()
        else:
            self.freeze_button.grid_remove()
            if not self.freeze_var.get():
                self.encoding_frame.grid_remove()
        self.handle_key_events(None)

    def handle_checkbutton(self):
        "Change the interface based on the key / primer freeze setting."
        if self.freeze_var.get():
            self.encoding_frame.grid_remove()
        else:
            self.encoding_frame.grid()

    def handle_key_events(self, event):
        "Schedule refreshing the output area after an input area event."
        if event is None or event.char and event.state | 0o11 == 0o11:
            self.after_idle(self.refresh)

    @staticmethod
    def handle_control_a(event):
        "Select all text in the widget associated with the given event."
        event.widget.tag_add(SEL, 1.0, END + '-1c')
        return 'break'

    ########################################################################

    # Handle interface's updates when either encoding or decoding.

    def refresh(self):
        "Refresh the output based on the value of the input."
        text = self.input_text.get(1.0, END + '-1c')
        if not text:
            self.output = text
        elif self.encrypting:
            self.encode(text)
        else:
            self.decode(text)

    def output(self, value):
        "Set the text in the output area to the string value."
        self.output_text['state'] = NORMAL
        self.output_text.delete(1.0, END)
        self.output_text.insert(END, value)
        if self.encrypting and self.freeze_var.get():
            self.output_text.see(END)
        self.output_text['state'] = DISABLED

    output = property(fset=output, doc='Output area property.')

    @property
    def chain_size(self):
        "Chain size for the Markov chains used when encrypting."
        try:
            value = ast.literal_eval(self.chain_size_entry.get())
            assert isinstance(value, int) and 2 <= value <= 256
            return value
        except:
            self.chain_size_entry.delete(0, END)
            self.chain_size_entry.insert(0, '2')
            return 2

    @property
    def plain_text(self):
        "Plain text or ignored characters in encryption process."
        try:
            value = self.repr_to_obj(self.plain_text_entry.get(), '')
            assert isinstance(value, str)
            return value
        except:
            self.plain_text_entry.delete(0, END)
            return ''

    ########################################################################

    # Encrypt a string for display in the interface's output area.

    def encode(self, string):
        "Encode the string and show the cipher-text in the output."
        try:
            cipher = self.build_cipher(string)
        except ValueError:
            self.output = ''
        except:
            self.output = traceback.format_exc()
        else:
            self.output = self.build_header() + '\n\n' + cipher

    def build_cipher(self, string):
        "Build cipher-text based on plain-text and return answer."
        if self.key and self.freeze_var.get():
            cipher, primer = me.encrypt_str(string, self.key, self.primer)
        else:
            args = string, self.chain_size, self.plain_text
            cipher, self.key, self.primer = me.auto_encrypt_str(*args)
        return cipher

    def build_header(self):
        "Build header from key and primer values in current use."
        header = '\n'.join(map(self.bytes_to_repr, self.key.data))
        header += '\n' + self.bytes_to_repr(self.primer.data)
        return header

    ########################################################################

    # Decrypt a string for display in the interface's output area.

    def decode(self, string):
        "Decode encrypted message and display plain-text in output."
        try:
            cipher = self.extract_keys(string)
            text = self.extract_text(cipher)
        except ValueError:
            self.output = ''
        except:
            self.output = traceback.format_exc()
        else:
            self.output = text

    def extract_keys(self, string):
        "Extract keys to decryption and return the cipher-text area."
        header, cipher = string.split('\n\n', 1)
        *key, primer = map(self.repr_to_obj, header.split('\n'))
        self.key, self.primer = me.Key(tuple(key)), me.Primer(primer)
        return cipher

    def extract_text(self, string):
        "Extract text message from string using built key and primer."
        text, primer = me.decrypt_str(string, self.key, self.primer)
        return text

    ########################################################################

    # Provide some special methods to simplify the program's code.

    @property
    def encrypting(self):
        "Encrypting boolean stating current operations mode."
        return {'encode': True, 'decode': False}[self.mode_var.get()]

    @staticmethod
    def bytes_to_repr(obj):
        "Convert bytes object into suitable representation."
        if not isinstance(obj, bytes):
            raise TypeError('Object must be a bytes instance!')
        return repr(obj)[2:-1]

    @staticmethod
    def repr_to_obj(string, prefix='b'):
        "Convert representation into an equivalent object."
        for template in '{}"{}"', "{}'{}'":
            try:
                return ast.literal_eval(template.format(prefix, string))
            except:
                pass
        raise ValueError('Cannot convert {!r} to object!'.format(string))

    @classmethod
    def main(cls):
        "Create context for demo and run a test instance."
        NoDefaultRoot()
        root = Tk()
        root.minsize(420, 330)
        root.title('Markov Demo 2')
        test = cls(root)
        test.grid(sticky=NSEW)
        root.grid_rowconfigure(0, weight=1)
        root.grid_columnconfigure(0, weight=1)
        root.mainloop()
예제 #51
0
class Xls2kml(object):
    '''
    Interface builted in Tkinter()
    '''

    def __init__(self):
        '''
        None -> None

        Builds the Tkinter window and all his elements.
        '''
        # variables ----------------------------------------------------
        # log file
        open("erros.log", "w").close()  # to open and clean the logfile
        logging.basicConfig(level=logging.DEBUG, filename='erros.log')
        sys.stderr = LogFile('stderr')  # Redirect stderr
        self.original_working_dir = os.getcwd()  # original working dir
        self.master = Tk()  # Tk() object
        self.master.title('EXCEL to KMZ Transformer - ver. 1.6')  # window name
        icons = os.getcwd() + os.sep + "icons" + os.sep  # path to icons
        foto_folder = os.getcwd() + os.sep + "fotos"  # path to fotos
        icon = icons + "compass.ico"
        self.master.iconbitmap(icon)  # window icon
        self.master.resizable(width=FALSE, height=FALSE)
        self.master.geometry("548x314")
        self.file_name = ""  # the name of the EXEL file
        self.last_dir = "C:/"
        # image to decorate the window
        self.img = ImageTk.PhotoImage(Image.open(icons + "excel-kmz.jpg"))
        # to use in frame, message, labels and buttons -----------------
        self.message = StringVar()
        self.message.set("\nSelecciona um ficheiro EXCEL")
        bg = "gray25"
        bg1 = "dark orange"
        fc = "white smoke"
        font = ("Helvetica", "8", "bold")
        text0 = " ----- "  # " ------------------------------------------ "
        text1 = " Boris & Vladimir Software "
        text = text0 + text1 + text0

        # Menu ---------------------------------------------------------
        self.menu = Menu(self.master)
        self.master.config(menu=self.menu)
        filemenu = Menu(self.menu)
        self.menu.add_cascade(label="Ficheiro", menu=filemenu)
        filemenu.add_command(label="Sair", command=self.__callback_3)
        filemenu.add_command(label='Pasta Fotos', command=lambda: (self.__open_folder(foto_folder)))
        # --------------------- NOVO -----------------------------------
        self.openGE = BooleanVar()  # não esquecer de importar BooleanVar
        self.openGE.set(False)
        optionsmenu = Menu(self.menu)
        self.menu.add_cascade(label="Opções", menu=optionsmenu)
        optionsmenu.add_checkbutton(label="Não abrir o Google Earth",
                                    onvalue=True, offvalue=False,
                                    variable=self.openGE)
        docsmenu = Menu(self.menu)
        docs = ["docs\manual.pdf", "docs\icons.pdf", "docs\colors.pdf",
                "docs\GPS.xlsx", "docs\GPS.kmz", "docs\Celulas.xlsx",
                "docs\Celulas.kmz", "docs\Foto.xlsx", "docs\Foto.kmz",
                "docs\Quadrado.xls", "docs\Quadrado.kmz"]
        self.menu.add_cascade(label="Documentação", menu=docsmenu)
        docsmenu.add_command(label="Manual",
                             command=lambda: (self.__open_file(docs[0])))
        docsmenu.add_command(label="Ícones",
                             command=lambda: (self.__open_file(docs[1])))
        docsmenu.add_command(label="Cores",
                             command=lambda: (self.__open_file(docs[2])))

        exemplemenu = Menu(docsmenu)
        docsmenu.add_cascade(label="Exemplos", menu=exemplemenu)

        gpsmenu = Menu(exemplemenu)
        exemplemenu.add_cascade(label="Trajetos", menu=gpsmenu)
        gpsmenu.add_command(label="Excel",
                            command=lambda: (self.__open_file(docs[3])))
        gpsmenu.add_command(label="Google Earth",
                            command=lambda: (self.__open_file(docs[4])))

        cellmenu = Menu(exemplemenu)
        exemplemenu.add_cascade(label="Células Telefónicas", menu=cellmenu)
        cellmenu.add_command(label="Excel",
                             command=lambda: (self.__open_file(docs[5])))
        cellmenu.add_command(label="Google Earth",
                             command=lambda: (self.__open_file(docs[6])))

        fotomenu = Menu(exemplemenu)
        exemplemenu.add_cascade(label="Fotos", menu=fotomenu)
        fotomenu.add_command(label="Excel",
                             command=lambda: (self.__open_file(docs[7])))
        fotomenu.add_command(label="Google Earth",
                             command=lambda: (self.__open_file(docs[8])))

        squaremenu = Menu(exemplemenu)
        exemplemenu.add_cascade(label="Quadrado", menu=squaremenu)
        squaremenu.add_command(label="Excel",
                             command=lambda: (self.__open_file(docs[9])))
        squaremenu.add_command(label="Google Earth",
                             command=lambda: (self.__open_file(docs[10])))

        helpmenu = Menu(self.menu)
        self.menu.add_cascade(label='Ajuda', menu=helpmenu)
        helpmenu.add_command(label="Sobre", command=self.__about)
        helpmenu.add_command(label="Ver erros",
                             command=lambda: (self.__open_file("erros.log")))

        # Frame to suport butons, labels and separators ----------------
        self.f = Frame(self.master, bg=bg)
        self.f.pack_propagate(0)  # don't shrink
        self.f.pack(side=BOTTOM, padx=0, pady=0)

        # Message and Labels -------------------------------------------
        self.l1 = Message(
            self.f, bg=bg1, bd=5, fg=bg, textvariable=self.message,
            font=("Helvetica", "13", "bold italic"), width=500).grid(
            row=0, columnspan=6, sticky=EW, padx=5, pady=5)
        self.l2 = Label(
            self.f, image=self.img, fg=bg
            ).grid(row=1, columnspan=6, padx=5, pady=2)
        self.l6 = Label(
            self.f, text=text, font=("Helvetica", "11", "bold"), bg=bg, fg=bg1
            ).grid(row=3, column=2, columnspan=3, sticky=EW, pady=5)

        # Buttons ------------------------------------------------------
        self.b0 = Button(
            self.f, text="Abrir EXCEL...", command=self.__callback, width=10,
            bg="forest green", fg=fc, font=font
            ).grid(row=3, column=0, padx=5, sticky=W)
        self.b1 = Button(
            self.f, text="Gravar KMZ", command=self.__callback_2, width=10,
            bg="DodgerBlue4", fg=fc, font=font
            ).grid(row=3, column=1, sticky=W)
        self.b2 = Button(
            self.f, text="Sair", command=self.__callback_3, width=10,
            bg="orange red", fg=fc, font=font
            ).grid(row=3, column=5, sticky=E, padx=5)

        # Separator ----------------------------------------------------
        # self.s = ttk.Separator(self.f, orient=HORIZONTAL).grid(
        #    row=4, columnspan=5, sticky=EW, padx=5, pady=5)

        # Progressbar --------------------------------------------------
        # self.pb = Canvas(self.f, width=260, height=10)
        self.s = ttk.Style()
        # themes: winnative, clam, alt, default, classic, vista, xpnative
        self.s.theme_use('winnative')
        self.s.configure("red.Horizontal.TProgressbar", foreground='green',
                         background='forest green')
        self.pb = ttk.Progressbar(self.f, orient='horizontal',
                                  mode='determinate',
                                  style="red.Horizontal.TProgressbar")
        self.pb.grid(row=2, column=0, columnspan=6, padx=5, pady=5, sticky=EW)

        # Mainloop -----------------------------------------------------
        self.master.mainloop()

    def __callback(self):  # "Abrir EXEL..." button handler ------------
        '''
        None -> None

        Opens a new window (filedialog.askopenfilename) to choose the
        EXCEL file that is necessary to make the KMZ file.
        '''
        title = 'Selecciona um ficheiro Excel'
        message = 'Ficheiro EXCEL carregado em memória.\nTransforma-o em KMZ!'
        self.file_name = filedialog.askopenfilename(title=title,
                                                    initialdir=self.last_dir)
        self.last_dir = self.file_name[:self.file_name.rfind('/')]

        if self.file_name[self.file_name.rfind('.')+1:] != 'xls' and \
                self.file_name[self.file_name.rfind('.')+1:] != 'xlsx':
            message = self.file_name + ' não é um ficheiro Excel válido!'
        self.message.set(message)

    def __callback_2(self):  # "Gravar KMZ" button handler ---------------
        '''
        None -> None

        Calls the function self.__threat()
        '''
        sleep(1)
        message = 'Ficheiro EXCEL carregado em memória.\nTransforma-o em KMZ!'
        if self.message.get() != message:
            self.message.set("\nEscolhe um ficheiro EXCEL primeiro")
            self.master.update_idletasks()
        else:
            self.message.set("\nA processar...")
            self.master.update_idletasks()
            sleep(1)
            self.__threads()

    def __callback_3(self):  # "Sair" button handler ---------------------
        '''
        None -> None

        Kills the window
        '''
        self.master.destroy()

    def __threads(self):
        '''
        None -> MyTread() objects

        Creates two threads to run at the same time the functions:
        self.__create_kmz()
        self.__progressbar()
        '''
        funcs = [self.__create_kmz, self.__progressbar]
        threads = []
        nthreads = list(range(len(funcs)))

        for i in nthreads:
            t = MyThread(funcs[i], (), funcs[i].__name__)
            threads.append(t)

        for i in nthreads:
            threads[i].start()

    def __create_kmz(self):
        '''
        None -> None

        Calls the exel_to_kml() atribute of the MotherControl() class
        And when it returns, calls self.__open_Google_Earth()
        '''
        kmz = MotherControl(self.file_name, self.original_working_dir).exel_to_kml()
        if type(kmz) == str:
            self.message.set(kmz)
            self.pb.stop()
            self.master.update_idletasks
        else:
            sleep(2)
            self.pb.stop()
            self.master.update_idletasks()
            self.__open_Google_Earth()

    def __open_Google_Earth(self):
        '''
        None -> None

        Opens the maded KMZ file in Google Earth
        '''
        sleep(1)
        self.master.update_idletasks()
        if not self.openGE.get():
            self.message.set("KMZ gravado com sucesso.\nA abrir o Google Earth...")
        else:
            self.message.set("\nKMZ gravado com sucesso.\n")
        sleep(2)
        self.master.update_idletasks()
        path = self.file_name[:self.file_name.rindex('/')]
        path_1 = self.file_name[self.file_name.rindex('/')+1:self.file_name.rfind('.')]
        kmzs = [x for x in os.listdir(path) if x[-4:] == '.kmz' and x[:-12] ==
                path_1]
        kmzs.sort()
        try:
            if not self.openGE.get():
                os.startfile(path + os.sep + kmzs[-1])
                sleep(2)
            self.message.set("\nSelecciona um ficheiro EXCEL")
        except:
            self.message.set("Instale o Google Earth\nhttp://www.google.com/earth/")
            self.master.update_idletasks()

    def __progressbar(self, ratio=0):
        '''
        None -> None

        Starts the progressbar in the window
        '''
        self.pb.start(50)

    def __about(self):
        '''
        None -> None

        Associated with the Help Menu.
        Creates a new window with the "About" information
        '''
        appversion = "1.6"
        appname = "EXCEL to KML Transformer"
        copyright = 14 * ' ' + '(c) 2013' + 12 * ' ' + \
            'SDATO - DP - UAF - GNR\n' + 34 * ' '\
            + "All Rights Reserved"
        licence = 18 * ' ' + 'http://opensource.org/licenses/GPL-3.0\n'
        contactname = "Nuno Venâncio"
        contactphone = "(00351) 969 564 906"
        contactemail = "*****@*****.**"

        message = "Version: " + appversion + 5 * "\n"
        message0 = "Copyright: " + copyright + "\n" + "Licença: " + licence
        message1 = contactname + '\n' + contactphone + '\n' + contactemail

        icons = os.getcwd() + os.sep + "icons" + os.sep  # path to icons
        icon = icons + "compass.ico"

        tl = Toplevel(self.master)
        tl.configure(borderwidth=5)
        tl.title("Sobre...")
        tl.iconbitmap(icon)
        tl.resizable(width=FALSE, height=FALSE)
        f1 = Frame(tl, borderwidth=2, relief=SUNKEN, bg="gray25")
        f1.pack(side=TOP, expand=TRUE, fill=BOTH)

        l0 = Label(f1, text=appname, fg="white", bg="gray25",
                   font=('courier', 16, 'bold'))
        l0.grid(row=0, column=0, sticky=W, padx=10, pady=5)
        l1 = Label(f1, text=message, justify=CENTER,
                   fg="white", bg="gray25")
        l1.grid(row=2, column=0, sticky=E, columnspan=3, padx=10, pady=0)
        l2 = Label(f1, text=message0,
                   justify=LEFT, fg="white", bg="gray25")
        l2.grid(row=6, column=0, columnspan=2, sticky=W, padx=10, pady=0)
        l3 = Label(f1, text=message1,
                   justify=CENTER, fg="white", bg="gray25")
        l3.grid(row=7, column=0, columnspan=2, padx=10, pady=0)

        button = Button(tl, text="Ok", command=tl.destroy, width=10)
        button.pack(pady=5)

    def __open_file(self, doc):
        try:
            os.startfile(doc)
        except:
            pass
            # os.system(doc)
            # não gosto disto mas os.startfile(doc)
            # faz com que a janela não se desenhe bem

    def __open_folder(self, folder):
        os.system('start explorer "' + folder + '"')
예제 #52
0
class GraphicalUserInterface(Frame):
    def __init__(self, parent):
        Frame.__init__(self, parent)
        self.parent = parent
        self.__initUI()

    def __initUI(self):
        self.parent.title("Fuel Manager")

        # parameters that the user can modify
        self.__exchvar = BooleanVar()
        self.__exchrate = True
        self.__datevar = BooleanVar()
        self.__datetime = True
        self.__empty_tank_var = BooleanVar()
        self.__empty_tank = False
        self.__airport_file = "input files/airport.csv"
        self.__aircraft_file = "input files/aircraft.csv"
        self.__currency_file = "input files/countrycurrency.csv"
        self.__exchange_rate_file = "input files/currencyrates.csv"
        self.__itinerary_file = "input files/testroutes.csv"
        self.__output_file = "bestroutes/bestroutes.csv"
        self.__home_airport = ["DUB"]
        self.__other_airports = ["LHR", "CDG", "JFK", "AAL", "AMS", "ORK"]
        self.__hubs = ["MHP"]
        self.__stopover_cost = 0
        self.__constraints = "JFK AAL / JFK CDG"
        self.__aircraft_code = "747"

        # main frame
        frame = Frame(self, relief=RAISED, borderwidth=1)
        frame.pack(fill=BOTH, expand=True)
        self.pack(fill=BOTH, expand=True)

        # manage single itinerary frame
        self.manual_frame = LabelFrame(self, text="Manage a single itinerary", font=("Helvetica", 14), width=300)
        self.manual_frame.place(x=50, y=50)

        # Empty row to put some space between the other rows and to control the width of this frame because
        # I don't know what I'm doing
        self.empty_label = Label(self.manual_frame, text=" ", width=60, height=1, font=("Helvetica", 1))
        self.empty_label.grid(row=0, sticky="W")

        # Text field where user can enter home airport
        self.home_airport_label = Label(self.manual_frame, width=22, text="Home airport:", anchor='w')
        self.home_airport_label.grid(row=1, sticky="W")
        self.home_airport_entry = Entry(self.manual_frame, width=50)
        self.home_airport_entry.grid(row=2, sticky="E")
        self.home_airport_entry.insert(0, self.__home_airport)

        self.empty_label = Label(self.manual_frame, text=" ", width=60, height=1, font=("Helvetica", 1))
        self.empty_label.grid(row=3, sticky="W")

        # Text field where user can enter other airports
        self.other_airports_label = Label(self.manual_frame, width=22, text="Other airports:", anchor='w')
        self.other_airports_label.grid(row=4, sticky="W")
        self.other_airports_entry = Entry(self.manual_frame, width=50)
        self.other_airports_entry.grid(row=5, sticky="E")
        self.other_airports_entry.insert(0, self.__other_airports)

        self.empty_label = Label(self.manual_frame, text=" ", width=60, height=1, font=("Helvetica", 1))
        self.empty_label.grid(row=6, sticky="W")

        # Text field where user can enter aircraft code
        self.aircraft_label = Label(self.manual_frame, width=22, text="Aircraft code:", anchor='w')
        self.aircraft_label.grid(row=7, sticky="W")
        self.aircraft_entry = Entry(self.manual_frame, width=50)
        self.aircraft_entry.grid(row=8, sticky="E")
        self.aircraft_entry.insert(0, self.__aircraft_code)

        self.empty_label = Label(self.manual_frame, text=" ", width=60, height=1, font=("Helvetica", 1))
        self.empty_label.grid(row=9, sticky="W")

        # Text field where user can enter constraints
        self.constraints_label = Label(self.manual_frame, width=22, text="Constraints:", anchor='w')
        self.constraints_label.grid(row=13, sticky="W")
        self.constraints_entry = Entry(self.manual_frame, width=50)
        self.constraints_entry.grid(row=14, sticky="E")
        self.constraints_entry.insert(0, self.__constraints)
        self.constraints_explanation_label = \
            Label(self.manual_frame, width=50,
                  text="Each constraint should consist of three-letter airport codes"
                       "\nseparated by spaces. To enter more than one constraint,"
                       "\nuse ' / ' to separate them", anchor='w', justify='left')
        self.constraints_explanation_label.grid(row=15, sticky="W")

        self.empty_label = Label(self.manual_frame, text=" ", width=60, height=1, font=("Helvetica", 1))
        self.empty_label.grid(row=16, sticky="W")

        # run button
        self.run_button = Button(self.manual_frame, text='Manage itinerary', command=self.__manage_single_itinerary,
                                 bg="#CCE1E8")
        self.run_button.grid(row=16, sticky="E")

        # manage list of itineraries frame
        self.itinerary_list_frame = LabelFrame(self, text="Manage a list of itineraries",
                                               font=("Helvetica", 14), width=300)
        self.itinerary_list_frame.place(x=50, y=375)

        # Empty row to put some space between the other rows and to control the width of this frame
        self.empty_label = Label(self.itinerary_list_frame, text=" ", width=60, height=1, font=("Helvetica", 1))
        self.empty_label.grid(row=12, sticky="W")

        # Text field where user can enter itinerary filepath
        self.itinerary_label = Label(self.itinerary_list_frame, width=22, text="Itinerary list: ", anchor='w')
        self.itinerary_label.grid(row=13, sticky="W")
        self.itinerary_entry = Entry(self.itinerary_list_frame, width=50)
        self.itinerary_entry.grid(row=13, sticky="E")
        self.itinerary_entry.insert(0, self.__itinerary_file)
        self.itinerary_button = Button(self.itinerary_list_frame, text='Browse...',
                                       command=self.__get_itinerary_filename)
        self.itinerary_button.grid(row=14, sticky="E")

        self.empty_label = Label(self.itinerary_list_frame, text=" ", width=60, height=2, font=("Helvetica", 1))
        self.empty_label.grid(row=15, sticky="W")

        # run button
        self.run_button = Button(self.itinerary_list_frame, text='Manage list of itineraries',
                                 command=self.__manage_list, bg="#CCE1E8")
        self.run_button.grid(row=16, sticky="E")

        # Fuel management settings frame
        self.general_frame = LabelFrame(self, text="Fuel management settings", font=("Helvetica", 14), width=300)
        self.general_frame.place(x=500, y=50)

        # Empty row to put some space between the other rows and to control the width of this frame
        self.empty_label = Label(self.general_frame, text=" ", width=60, height=1, font=("Helvetica", 1))
        self.empty_label.grid(row=0, sticky="W")

        # Text field where user can enter hubs
        self.hubs_label = Label(self.general_frame, width=22, text="Hubs:", anchor='w')
        self.hubs_label.grid(row=1, sticky="W")
        self.hubs_entry = Entry(self.general_frame, width=50)
        self.hubs_entry.grid(row=2, sticky="E")
        self.hubs_entry.insert(0, self.__hubs)

        self.empty_label = Label(self.general_frame, text=" ", width=60, height=1, font=("Helvetica", 1))
        self.empty_label.grid(row=3, sticky="W")

        # Text field where user can enter cost of extra stopovers
        self.stopover_cost_label = Label(self.general_frame, width=40, text="Cost of each extra stopover (euros):",
                                         anchor='w')
        self.stopover_cost_label.grid(row=4, sticky="W")
        self.stopover_cost_entry = Entry(self.general_frame, width=50)
        self.stopover_cost_entry.grid(row=5, sticky="E")
        self.stopover_cost_entry.insert(0, self.__stopover_cost)

        self.empty_label = Label(self.general_frame, text=" ", width=60, height=1, font=("Helvetica", 1))
        self.empty_label.grid(row=6, sticky="W")

        # bring home extra fuel checkbox
        self.empty_tank_cb = Checkbutton(self.general_frame,
                                         text="Always return to home airport with an empty tank",
                                         variable=self.__empty_tank_var, command=self.__empty_tank_toggle)
        self.empty_tank_cb.grid(row=7, sticky="W")

        self.empty_label = Label(self.general_frame, text=" ", width=60, height=1, font=("Helvetica", 1))
        self.empty_label.grid(row=8, sticky="W")

        # manage inputs frame
        self.input_frame = LabelFrame(self, text="Inputs", font=("Helvetica", 14), width=300)
        self.input_frame.place(x=500, y=250)

        self.empty_label = Label(self.input_frame, text=" ", width=60, height=1, font=("Helvetica", 1))
        self.empty_label.grid(row=0, sticky="W")

        # Text field where user can enter airport filepath
        self.airport_label = Label(self.input_frame, width=22, text="Airport list: ", anchor='w')
        self.airport_label.grid(row=1, sticky="W")
        self.airport_entry = Entry(self.input_frame, width=50)
        self.airport_entry.grid(row=1, sticky="E")
        self.airport_entry.insert(0, self.__airport_file)
        self.airport_button = Button(self.input_frame, text='Browse...', command=self.__get_airport_filename)
        self.airport_button.grid(row=2, sticky="E")

        self.empty_label = Label(self.input_frame, text=" ", width=60, height=1, font=("Helvetica", 1))
        self.empty_label.grid(row=3, sticky="W")

        # Text field where user can enter aircraft filepath
        self.aircraft_file_label = Label(self.input_frame, width=22, text="Aircraft list: ", anchor='w')
        self.aircraft_file_label.grid(row=4, sticky="W")
        self.aircraft_file_entry = Entry(self.input_frame, width=50)
        self.aircraft_file_entry.grid(row=4, sticky="E")
        self.aircraft_file_entry.insert(0, self.__aircraft_file)
        self.aircraft_file_button = Button(self.input_frame, text='Browse...', command=self.__get_aircraft_filename)
        self.aircraft_file_button.grid(row=5, sticky="E")

        self.empty_label = Label(self.input_frame, text=" ", width=425, height=1, font=("Helvetica", 1))
        self.empty_label.grid(row=6, sticky="W")

        # Text field where user can enter country-currency filepath
        self.currency_label = Label(self.input_frame, width=22, text="Currency list: ", anchor='w')
        self.currency_label.grid(row=7, sticky="W")
        self.currency_entry = Entry(self.input_frame, width=50)
        self.currency_entry.grid(row=7, sticky="E")
        self.currency_entry.insert(0, self.__currency_file)
        self.currency_button = Button(self.input_frame, text='Browse...', command=self.__get_currency_filename)
        self.currency_button.grid(row=8, sticky="E")

        self.empty_label = Label(self.input_frame, text=" ", width=60, height=1, font=("Helvetica", 1))
        self.empty_label.grid(row=9, sticky="W")

        # Text field where user can enter exchange rate filepath
        self.exchange_rate_label = Label(self.input_frame, width=22, text="Exchange rate list: ", anchor='w')
        self.exchange_rate_label.grid(row=10, sticky="W")
        self.exchange_rate_entry = Entry(self.input_frame, width=50)
        self.exchange_rate_entry.grid(row=10, sticky="E")
        self.exchange_rate_entry.insert(0, self.__exchange_rate_file)
        self.exchange_rate_button = Button(self.input_frame, text='Browse...', command=self.__get_exchange_rate_filename)
        self.exchange_rate_button.grid(row=11, sticky="E")

        # real-time exchange rates checkbox
        self.forex = Checkbutton(self.input_frame, text="Use real-time exchange rates", variable=self.__exchvar,
                                 command=self.__forex_toggle)
        self.forex.select()
        self.forex.grid(row=12, sticky="W")

        # manage output frame
        self.output_frame = LabelFrame(self, text="Output", font=("Helvetica", 14), width=300)
        self.output_frame.place(x=500, y=550)

        self.empty_label = Label(self.output_frame, text=" ", width=60, height=1, font=("Helvetica", 1))
        self.empty_label.grid(row=0, sticky="W")

        # Text field where user can enter output filepath
        self.output_label = Label(self.output_frame, width=22, text="Output file: ", anchor='w')
        self.output_label.grid(row=1, sticky="W")
        self.output_entry = Entry(self.output_frame, width=50)
        self.output_entry.grid(row=1, sticky="E")
        self.output_entry.insert(0, self.__output_file)
        self.output_button = Button(self.output_frame, text='Browse...', command=self.__get_output_filename)
        self.output_button.grid(row=2, sticky="E")

        # append date to output filename checkbox
        self.datetime_cb = Checkbutton(self.output_frame,
                                       text="Append date and time to filename (e.g., bestroutes 20151218 160000.csv)",
                                       variable=self.__datevar, command=self.__datetime_toggle)
        self.datetime_cb.grid(row=3, sticky="W")
        self.datetime_cb.select()

    # GUI methods

    def __forex_toggle(self):
        if self.__exchvar.get() == True:
            self.__exchrate = True
        else:
            self.__exchrate = False

    def __datetime_toggle(self):
        if self.__datevar.get() == True:
            self.__datetime = True
        else:
            self.__datetime = False

    def __empty_tank_toggle(self):
        if self.__empty_tank_var.get() == True:
            self.__empty_tank = True
        else:
            self.__empty_tank = False

    def __get_airport_filename(self):
        self.__airport_file = filedialog.askopenfilename(
            filetypes=(("Comma-separated values files", "*.csv"), ("All files", "*.*")))
        self.airport_entry.delete(0, END)
        self.airport_entry.insert(0, self.__airport_file)

    def __get_aircraft_filename(self):
        self.__aircraft_file = filedialog.askopenfilename(
            filetypes=(("Comma-separated values files", "*.csv"), ("All files", "*.*")))
        self.aircraft_file_entry.delete(0, END)
        self.aircraft_file_entry.insert(0, self.__aircraft_file)

    def __get_currency_filename(self):
        self.__currency_file = filedialog.askopenfilename(
            filetypes=(("Comma-separated values files", "*.csv"), ("All files", "*.*")))
        self.currency_entry.delete(0, END)
        self.currency_entry.insert(0, self.__currency_file)

    def __get_exchange_rate_filename(self):
        self.__exchange_rate_file = filedialog.askopenfilename(
            filetypes=(("Comma-separated values files", "*.csv"), ("All files", "*.*")))
        self.exchange_rate_entry.delete(0, END)
        self.exchange_rate_entry.insert(0, self.__exchange_rate_file)

    def __get_itinerary_filename(self):
        self.__itinerary_file = filedialog.askopenfilename(
            filetypes=(("Comma-separated values files", "*.csv"), ("All files", "*.*")))
        self.itinerary_entry.delete(0, END)
        self.itinerary_entry.insert(0, self.__itinerary_file)

    def __get_output_filename(self):
        self.__output_file = filedialog.asksaveasfilename(defaultextension=".csv", filetypes=(
            ("Comma-separated values file", "*.csv"), ("All Files", "*.*")))
        self.output_entry.delete(0, END)
        self.output_entry.insert(0, self.__output_file)

    def __manage_list(self):
        # validate user inputs
        hubs, stopover_cost = validate_inputs_for_list_of_itineraries(self.hubs_entry.get().upper().split(),
                                                                      self.stopover_cost_entry.get())
        print("Managing list of itineraries...")
        manage_list_of_routes(self.__exchrate,
                      self.__datetime,
                      self.__empty_tank,
                      hubs,
                      stopover_cost,
                      self.itinerary_entry.get(),
                      self.airport_entry.get(),
                      self.aircraft_file_entry.get(),
                      self.currency_entry.get(),
                      self.exchange_rate_entry.get(),
                      self.output_entry.get())

    def __manage_single_itinerary(self):
        # validate user inputs
        try:
            hubs, stopover_cost, constraints_list, home_airport, other_airports, aircraft_code = \
                validate_inputs_for_single_itinerary(self.hubs_entry.get().upper().split(),
                                self.stopover_cost_entry.get(),
                                self.constraints_entry.get().upper().split(),
                                self.home_airport_entry.get().upper(),
                                self.other_airports_entry.get().upper().split(),
                                self.aircraft_entry.get().upper())
        except TypeError:
            return

        print("Managing single itinerary...")
        manage_single_route(home_airport,
                            other_airports,
                            aircraft_code,
                            self.__exchrate,
                            self.__datetime,
                            self.__empty_tank,
                            hubs,
                            stopover_cost,
                            constraints_list,
                            self.airport_entry.get(),
                            self.aircraft_file_entry.get(),
                            self.currency_entry.get(),
                            self.exchange_rate_entry.get(),
                            self.output_entry.get())
예제 #53
0
class MainWindow(ttk.Frame):
    def __init__(self, master):

        # Variables
        self.url = StringVar()
        self.url_analyzer = None
        self.list_of_urls = []
        self.url_dict = dict()

        # Main Window
        self.master = master
        self.master.iconbitmap(default=ico_path)
        self.master.title(string="URL Finder")
        self.master.minsize(width=300, height=375)
        self.master.maxsize(width=800, height=375)

        # Top Menu
        self.show_all = BooleanVar()
        self.file = Menu(self.master, tearoff=False)
        self.file.add_command(label="About", command=self.display_about)
        self.file.add_command(label="Exit", command=self.master.quit)
        self.edit = Menu(self.master, tearoff=False)
        self.edit.add_checkbutton(label="Show All", variable=self.show_all, command=self.update_list)

        self.menubar = Menu(self.master)
        self.menubar.add_cascade(label="File", menu=self.file)
        self.menubar.add_cascade(label="Edit", menu=self.edit)
        self.master.config(menu=self.menubar)

        # Right-click menu for entry widget
        self.right_click_entry = Menu(self.master, tearoff=False)
        self.right_click_entry.add_command(label="Copy", command=self.copy_from_entry)
        self.right_click_entry.add_command(label="Paste", command=self.paste_to_entry)

        # Right-click menu for treeview
        self.right_click = Menu(self.master, tearoff=False)
        self.right_click.add_command(label="Copy", command=self.get_selected_url)

        # Frame containing text box and enter button
        self.top_frame = ttk.Frame(self.master)
        self.top_frame.columnconfigure(0, minsize=200, weight=10)
        self.top_frame.columnconfigure(1, minsize=100, weight=1)

        # Frame containing urls and scrollbar
        self.bottom_frame = ttk.Frame(self.master)
        self.bottom_frame.columnconfigure(0, minsize=260, weight=1000)
        self.bottom_frame.columnconfigure(1, minsize=25, weight=1)

        # Url entry box and enter button
        self.entry = ttk.Entry(self.top_frame, textvariable=self.url)
        self.entry.bind('<Return>', self.on_enter)
        self.entry.bind('<Button-3>', self.entry_popup)
        self.enter = ttk.Button(self.top_frame, text="Find Urls", command=self.on_click)

        self.entry.grid(row=0, column=0, sticky=W+E, padx=5, pady=5)
        self.enter.grid(row=0, column=1, sticky=W+E, padx=5, pady=5)

        # Url list treeview
        self.list = ttk.Treeview(self.bottom_frame, height=15, columns=['percentage', 'domain'])
        self.list['show'] = 'headings'
        self.list.column('#0', width=0)
        self.list.column('percentage', width=30, minwidth=30, stretch=False)
        self.list.column('domain', width=250, minwidth=200, stretch=False)

        self.list.heading('percentage', text="%")
        self.list.heading('domain', text='Domain')

        self.list.bind('<Control-c>', self.ctrl_c)
        self.list.bind('<Button-3>', self.treeview_popup)

        self.list.grid(row=1, column=0, sticky=W+E+N+S, padx=5, pady=5)

        # Scrollbar widget
        self.scrollbar = ttk.Scrollbar(self.bottom_frame)
        self.scrollbar.grid(column=1, row=1, sticky=N+S+E+W)
        self.list.config(yscrollcommand=self.scrollbar.set)
        self.scrollbar.config(command=self.list.yview)

        self.top_frame.pack(fill=BOTH)
        self.bottom_frame.pack(fill=BOTH)

    def populate_list(self, url_percentage):
        del self.list_of_urls[:]
        for url, percentage in sorted(url_percentage.items(), key=lambda x: x[1]):
            if self.show_all.get() is True:
                row = (str(round(percentage)), url)
                self.list_of_urls.append(row)
            else:
                if percentage >= 1:
                    row = (str(round(percentage)), url)
                    self.list_of_urls.append(row)

        for row in self.list_of_urls:
            self.list.insert('', 0, values=row)


    def on_click(self):
        self.list.delete(*self.list.get_children())
        self.enter.config(text="Running")
        url = self.url.get()
        t = threading.Thread(target=self.run_scan, args=(url,))
        t.start()


    def run_scan(self, url):
        pm = ProcessManager(url)
        pm.start()
        count = 0
        while pm.continue_scanning:
            time.sleep(1)
            count += 1
            # This is to keep the system from reaching a timeout
            if count > 20:
                logging.info("Reached max timeout")
                pm.analyze_potential_urls()
                break

        self.url_dict = pm.url_percentage
        self.populate_list(pm.url_percentage)
        self.enter.config(text="Find Urls")


    def ctrl_c(self, event):
        self.get_selected_url()


    def add_to_clipboard(self, copy):
        self.master.clipboard_clear()
        self.master.clipboard_append(copy)


    def get_from_clipboad(self):
        return self.master.clipboard_get()


    def get_selected_url(self):
        curr_item = self.list.focus()
        item_dict = self.list.item(curr_item)
        self.add_to_clipboard(item_dict['values'][1])


    def paste_to_entry(self):
        self.url.set(self.get_from_clipboad())


    def copy_from_entry(self):
        self.add_to_clipboard(self.url.get())


    def treeview_popup(self, event):
        item = self.list.identify_row(event.y) # Get Row
        self.list.selection_set(item) # Highlight Row
        self.list.focus(item) # Focus Row
        self.right_click.post(event.x_root, event.y_root) # Popup menu


    def entry_popup(self, event):
        self.right_click_entry.post(event.x_root, event.y_root)

    def on_enter(self, event):
        self.on_click()


    def update_list(self):
        self.list.delete(*self.list.get_children())
        self.populate_list(self.url_dict)


    def display_about(self):
        about = "Supporting Url Finder Version: %s" % VERSION
        messagebox.showinfo("About", about)
예제 #54
0
class ConfigureGUI:

    def __init__(self):
        #
        # Main application window
        #
        self._root = Tk()
        self._root.title("Othello")
        self._root.focus()
        self._root.minsize(400, 250)
        self._root.columnconfigure(0, weight=1)
        self._root.rowconfigure(1, weight=1)
        
        #
        # Welcome label
        #
        welcome_frame = ttk.Frame(self._root, borderwidth=5)
        welcome_label = ttk.Label(welcome_frame, text="Welcome to GUI Othello!")
        
        welcome_frame.grid(row=0, column=0, sticky="ew")
        welcome_label.grid(row=0, column=0, padx=5, pady=5)
        
        welcome_frame.columnconfigure(0, weight=1)
        
        #
        # Main content (Configuration)
        #
        self._content = ttk.Frame(self._root)
        
        self._row = IntVar()
        row_label = ttk.Label(self._content, text="Number of Rows: ")
        row_picker = ttk.Combobox(self._content, state="readonly", textvariable=self._row, values=[4, 6, 8, 10, 12, 14, 16])
        row_picker.set(8)
        
        self._col = IntVar()
        col_label = ttk.Label(self._content, text="Number of Columns: ")
        col_picker = ttk.Combobox(self._content, state="readonly", textvariable=self._col, values=[4, 6, 8, 10, 12, 14, 16])
        col_picker.set(8)
        
        self._white_starts = BooleanVar()
        white_starts_label = ttk.Label(self._content, text="White starts: ")
        white_starts_picker = ttk.Combobox(self._content, state="readonly", textvariable=self._white_starts, values=[True, False])
        white_starts_picker.current(1)
        
        self._classic_board_str = StringVar()
        classic_board_str_label = ttk.Label(self._content, text="Opening Board Style: ")
        classic_board_str_picker = ttk.Combobox(self._content, state="readonly", textvariable=self._classic_board_str)
        classic_board_str_picker["values"] = ["Classic (white starts in the top left)", "Inverted (black starts in the top left)"]
        classic_board_str_picker.set("Classic (white starts in the top left)")
        
        self._most_wins = BooleanVar()
        most_wins_label = ttk.Label(self._content, text="Most Pieces Wins: ")
        most_wins_picker = ttk.Combobox(self._content, state="readonly", textvariable=self._most_wins, values=[True, False])
        most_wins_picker.current(0)

        self._content.grid(row=1, column=0, sticky="nsew")
        
        row_label.grid(row=0, column=0, sticky=(const.N, const.E), padx=5, pady=2)
        row_picker.grid(row=0, column=1, columnspan=2, sticky=(const.N, const.W, const.E), padx=2, pady=2)
        col_label.grid(row=1, column=0, sticky=(const.N, const.E), padx=5, pady=2)
        col_picker.grid(row=1, column=1, columnspan=2, sticky=(const.N, const.W, const.E), padx=2, pady=2)
        white_starts_label.grid(row=2, column=0, sticky=(const.N, const.E), padx=5, pady=2)
        white_starts_picker.grid(row=2, column=1, columnspan=2, sticky=(const.N, const.W, const.E), padx=2, pady=2)
        classic_board_str_label.grid(row=3, column=0, sticky=(const.N, const.E), padx=5, pady=2)
        classic_board_str_picker.grid(row=3, column=1, columnspan=2, sticky=(const.N, const.W, const.E), padx=2, pady=2)
        most_wins_label.grid(row=4, column=0, sticky=(const.N, const.E), padx=5, pady=2)
        most_wins_picker.grid(row=4, column=1, columnspan=2, sticky=(const.N, const.W, const.E), padx=2, pady=2)
        
        self._content.columnconfigure(0, minsize=70)
        self._content.columnconfigure(1, weight=1, minsize=50)
        self._content.columnconfigure(2, weight=1, minsize=50)
        self._content.rowconfigure(0, weight=1, minsize=30)
        self._content.rowconfigure(1, weight=1, minsize=30)
        self._content.rowconfigure(2, weight=1, minsize=30)
        self._content.rowconfigure(3, weight=1, minsize=30)
        self._content.rowconfigure(4, weight=1, minsize=30)
        
        #
        # Play/Quit buttons frame
        #
        play_frame = ttk.Frame(self._root, borderwidth=5)
        play = ttk.Button(play_frame, text="Play", command=self._press_play)
        cancel = ttk.Button(play_frame, text="Quit", command=exit)
        
        play_frame.grid(row=2, column=0, sticky="nsew")
        play.grid(row=0, column=0, sticky=(const.N, const.S, const.E), padx=5, pady=2)
        cancel.grid(row=0, column=1, sticky=(const.N, const.S, const.W), padx=5, pady=2)
        
        play_frame.columnconfigure(0, weight=1)
        play_frame.columnconfigure(1, weight=1)

    def _press_play(self):
        self._root.destroy()
        self.play = True

    def start(self) -> None:
        self._root.mainloop()
        if not self.play:
            exit()

    def getOthello(self) -> Othello:
        return Othello(self._row.get(), self._col.get(), self._white_starts.get(), True if (self._classic_board_str.get() == "Classic (white starts in the top left)") else False, self._most_wins.get())       
예제 #55
0
class FrameSpreadsheetDataset(FrameCustomFileDataset):
    """
        Holds an instance of, and visually represents, a spreadsheet dataset.
        See qal.dataset.spreadsheet.SpreadsheetDataset
    """

    def __init__(self, _master, _dataset=None, _relief=None, _is_destination=None):
        super(FrameSpreadsheetDataset, self).__init__(_master, _dataset, _relief, _is_destination=_is_destination)

        if _dataset is None:
            self.dataset = SpreadsheetDataset()

    def on_select(self):
        """Brings up a selector dialog, prompting the user to select a file,
        the relative path if the file is then saved to the filename property.
        Also, the base path is set.
        """
        self.select_file(_default_extension=".xlsx", _file_types=[('.xlsx files', '.xlsx'), ('all files', '.*')])

    def init_widgets(self):
        # file selector
        self.btn_file_select = Button(self, text="Select file", command=self.on_select)
        self.btn_file_select.grid(column=0, row=0, columnspan=2)

        # filename
        self.filename, self.e_filename, self.l_filename = make_entry(self, "File name: ", 1)


        # delimiter
        self.delimiter, self.e_delimiter, self.l_delimiter = make_entry(self, "Delimiter: ", 2)

        # has_header
        self.l_has_header = ttk.Label(self, text="Has header: ")
        self.l_has_header.grid(column=0, row=3, sticky=W)
        self.has_header = BooleanVar()
        self.e_has_header = ttk.Checkbutton(self, variable=self.has_header)
        self.e_has_header.grid(column=1, row=3, sticky=W)

        # sheet_name
        self.sheet_name, self.e_sheet_name, self.l_sheet_name = make_entry(self, "Sheet name: ", 4)

        # x_offset
        self.x_offset, self.e_x_offset, self.l_x_offset = make_entry(self, "X offset: ", 5)


        # y_offset
        self.y_offset, self.e_y_offset, self.l_y_offset = make_entry(self, "Y offset: ", 6)


    def read_from_dataset(self):
        super(FrameSpreadsheetDataset, self).read_from_dataset()

        self.filename.set(empty_when_none(self.dataset.filename))
        self.has_header.set(bool_to_binary_int(self.dataset.has_header))
        self.sheet_name.set(empty_when_none(self.dataset.sheet_name))
        self.x_offset.set(empty_when_none(self.dataset.x_offset))
        self.y_offset.set(empty_when_none(self.dataset.y_offset))


    def write_to_dataset(self):
        super(FrameSpreadsheetDataset, self).write_to_dataset()

        if self.dataset is None:
            self.dataset = SpreadsheetDataset()

        self.dataset.filename = self.filename.get()
        self.dataset.delimiter = self.delimiter.get()
        self.dataset.has_header = binary_int_to_bool(self.has_header.get())

        self.dataset.sheet_name = self.sheet_name.get()
        if self.x_offset.get() == "":
            self.dataset.x_offset = None
        else:
            self.dataset.x_offset = int(self.x_offset.get())

        if self.y_offset.get() == "":
            self.dataset.y_offset = None
        else:
            self.dataset.y_offset = int(self.y_offset.get())

    def reload(self):
        self.notify_task("Load spreadsheet " + self.dataset.filename, 10)
        self.dataset.load()
        self.notify_task("Loaded spreadsheet " + self.dataset.filename + ".", 100)

    def get_possible_references(self, _force=None):

        if not self.dataset.field_names or _force == True:
            self.reload()

        self.references = self.dataset.field_names

        return self.dataset.field_names
예제 #56
0
class ViewRenderedGrid(ViewWinGrid.ViewGrid):
    def __init__(self, modelXbrl, tabWin, lang):
        super(ViewRenderedGrid, self).__init__(modelXbrl, tabWin, "Rendering", True, lang)
        self.newFactItemOptions = ModelInstanceObject.NewFactItemOptions(xbrlInstance=modelXbrl)
        self.factPrototypes = []
        self.zOrdinateChoices = None
        # context menu Boolean vars
        self.options = self.modelXbrl.modelManager.cntlr.config.setdefault("viewRenderedGridOptions", {})
        self.ignoreDimValidity = BooleanVar(value=self.options.setdefault("ignoreDimValidity",True))
        self.xAxisChildrenFirst = BooleanVar(value=self.options.setdefault("xAxisChildrenFirst",True))
        self.yAxisChildrenFirst = BooleanVar(value=self.options.setdefault("yAxisChildrenFirst",False))
            
    def close(self):
        super(ViewRenderedGrid, self).close()
        if self.modelXbrl:
            for fp in self.factPrototypes:
                fp.clear()
            self.factPrototypes = None
        
    def loadTablesMenu(self):
        tblMenuEntries = {}             
        tblRelSet = self.modelXbrl.relationshipSet("Table-rendering")
        for tblLinkroleUri in tblRelSet.linkRoleUris:
            for tableAxisArcrole in (XbrlConst.euTableAxis, XbrlConst.tableBreakdown, XbrlConst.tableBreakdown201301, XbrlConst.tableAxis2011):
                tblAxisRelSet = self.modelXbrl.relationshipSet(tableAxisArcrole, tblLinkroleUri)
                if tblAxisRelSet and len(tblAxisRelSet.modelRelationships) > 0:
                    # table name
                    modelRoleTypes = self.modelXbrl.roleTypes.get(tblLinkroleUri)
                    if modelRoleTypes is not None and len(modelRoleTypes) > 0:
                        roledefinition = modelRoleTypes[0].definition
                        if roledefinition is None or roledefinition == "":
                            roledefinition = os.path.basename(tblLinkroleUri)       
                        for table in tblAxisRelSet.rootConcepts:
                            # add table to menu if there's any entry
                            tblMenuEntries[roledefinition] = tblLinkroleUri
                            break
        self.tablesMenu.delete(0, self.tablesMenuLength)
        self.tablesMenuLength = 0
        self.tblELR = None
        for tblMenuEntry in sorted(tblMenuEntries.items()):
            tbl,elr = tblMenuEntry
            self.tablesMenu.add_command(label=tbl, command=lambda e=elr: self.view(viewTblELR=e))
            self.tablesMenuLength += 1
            if self.tblELR is None: 
                self.tblELR = elr # start viewing first ELR
        
    def viewReloadDueToMenuAction(self, *args):
        if not self.blockMenuEvents:
            # update config (config saved when exiting)
            self.options["ignoreDimValidity"] = self.ignoreDimValidity.get()
            self.options["xAxisChildrenFirst"] = self.xAxisChildrenFirst.get()
            self.options["yAxisChildrenFirst"] = self.yAxisChildrenFirst.get()
            self.view()
        
    def view(self, viewTblELR=None, newInstance=None):
        startedAt = time.time()
        self.blockMenuEvents += 1
        if newInstance is not None:
            self.modelXbrl = newInstance # a save operation has created a new instance to use subsequently
            clearZchoices = False
        if viewTblELR:  # specific table selection
            self.tblELR = viewTblELR
            clearZchoices = True
        else:   # first or subsequenct reloading (language, dimensions, other change)
            clearZchoices = self.zOrdinateChoices is None
            if clearZchoices: # also need first time initialization
                self.loadTablesMenu()  # load menus (and initialize if first time
            viewTblELR = self.tblELR
            
        if not self.tblELR:
            return  # no table to display

        if clearZchoices:
            self.zOrdinateChoices = {}

        # remove old widgets
        self.viewFrame.clearGrid()

        tblAxisRelSet, xTopStructuralNode, yTopStructuralNode, zTopStructuralNode = resolveAxesStructure(self, viewTblELR) 
        
        if tblAxisRelSet:
            #print("tbl hdr width rowHdrCols {0}".format(self.rowHdrColWidth))
            self.gridTblHdr.tblHdrWraplength = 200 # to  adjust dynamically during configure callbacks
            self.gridTblHdr.tblHdrLabel = \
                gridHdr(self.gridTblHdr, 0, 0, 
                        (self.modelTable.genLabel(lang=self.lang, strip=True) or  # use table label, if any 
                         self.roledefinition),
                        anchor="nw",
                        #columnspan=(self.dataFirstCol - 1),
                        #rowspan=(self.dataFirstRow),
                        wraplength=200) # in screen units
                        #wraplength=sum(self.rowHdrColWidth)) # in screen units
            zAspects = defaultdict(set)
            self.zAxis(1, zTopStructuralNode, zAspects, clearZchoices)
            xStructuralNodes = []
            self.xAxis(self.dataFirstCol, self.colHdrTopRow, self.colHdrTopRow + self.colHdrRows - 1, 
                       xTopStructuralNode, xStructuralNodes, self.xAxisChildrenFirst.get(), True, True)
            self.yAxis(1, self.dataFirstRow,
                       yTopStructuralNode, self.yAxisChildrenFirst.get(), True, True)
            for fp in self.factPrototypes: # dereference prior facts
                if fp is not None:
                    fp.clear()
            self.factPrototypes = []
            self.bodyCells(self.dataFirstRow, yTopStructuralNode, xStructuralNodes, zAspects, self.yAxisChildrenFirst.get())
                
            # data cells
            #print("body cells done")
                
        self.modelXbrl.profileStat("viewTable_" + os.path.basename(viewTblELR), time.time() - startedAt)

        #self.gridView.config(scrollregion=self.gridView.bbox(constants.ALL))
        self.blockMenuEvents -= 1

            
    def zAxis(self, row, zStructuralNode, zAspects, clearZchoices):
        if zStructuralNode is not None:
            gridBorder(self.gridColHdr, self.dataFirstCol, row, TOPBORDER, columnspan=2)
            gridBorder(self.gridColHdr, self.dataFirstCol, row, LEFTBORDER)
            gridBorder(self.gridColHdr, self.dataFirstCol, row, RIGHTBORDER, columnspan=2)
            label = zStructuralNode.header(lang=self.lang)
            hdr = gridHdr(self.gridColHdr, self.dataFirstCol, row,
                          label, 
                          anchor="w", columnspan=2,
                          wraplength=200, # in screen units
                          objectId=zStructuralNode.objectId(),
                          onClick=self.onClick)
    
            if zStructuralNode.choiceStructuralNodes: # combo box
                valueHeaders = [''.ljust(zChoiceStructuralNode.indent * 4) + # indent if nested choices 
                                (zChoiceStructuralNode.header(lang=self.lang) or '')
                                for zChoiceStructuralNode in zStructuralNode.choiceStructuralNodes]
                combobox = gridCombobox(
                             self.gridColHdr, self.dataFirstCol + 2, row,
                             values=valueHeaders,
                             selectindex=zStructuralNode.choiceNodeIndex,
                             columnspan=2,
                             comboboxselected=self.onComboBoxSelected)
                combobox.zStructuralNode = zStructuralNode
                combobox.zChoiceOrdIndex = row - 1
                combobox.objectId = hdr.objectId = zStructuralNode.objectId()
                gridBorder(self.gridColHdr, self.dataFirstCol + 3, row, RIGHTBORDER)
    
            if zStructuralNode.childStructuralNodes:
                for zStructuralNode in zStructuralNode.childStructuralNodes:
                    self.zAxis(row + 1, zStructuralNode, zAspects, clearZchoices)
            else: # nested-nost element, aspects process inheritance
                for aspect in aspectModels[self.aspectModel]:
                    for ruleAspect in aspectRuleAspects.get(aspect, (aspect,)):
                        if zStructuralNode.hasAspect(ruleAspect): #implies inheriting from other z axes
                            if ruleAspect == Aspect.DIMENSIONS:
                                for dim in (zStructuralNode.aspectValue(Aspect.DIMENSIONS) or emptyList):
                                    zAspects[dim].add(zStructuralNode)
                            else:
                                zAspects[ruleAspect].add(zStructuralNode)
            
    def onComboBoxSelected(self, *args):
        combobox = args[0].widget
        self.zOrdinateChoices[combobox.zStructuralNode._definitionNode] = \
            combobox.zStructuralNode.choiceNodeIndex = combobox.valueIndex
        self.view() # redraw grid
            
    def xAxis(self, leftCol, topRow, rowBelow, xParentStructuralNode, xStructuralNodes, childrenFirst, renderNow, atTop):
        if xParentStructuralNode is not None:
            parentRow = rowBelow
            noDescendants = True
            rightCol = leftCol
            widthToSpanParent = 0
            sideBorder = not xStructuralNodes
            if atTop and sideBorder and childrenFirst:
                gridBorder(self.gridColHdr, self.dataFirstCol, 1, LEFTBORDER, rowspan=self.dataFirstRow)
            for xStructuralNode in xParentStructuralNode.childStructuralNodes:
                if not xStructuralNode.isRollUp:
                    noDescendants = False
                    rightCol, row, width, leafNode = self.xAxis(leftCol, topRow + 1, rowBelow, xStructuralNode, xStructuralNodes, # nested items before totals
                                                                childrenFirst, childrenFirst, False)
                    if row - 1 < parentRow:
                        parentRow = row - 1
                    #if not leafNode: 
                    #    rightCol -= 1
                    nonAbstract = not xStructuralNode.isAbstract
                    if nonAbstract:
                        width += 100 # width for this label, in screen units
                    widthToSpanParent += width
                    label = xStructuralNode.header(lang=self.lang,
                                                   returnGenLabel=isinstance(xStructuralNode.definitionNode, (ModelClosedDefinitionNode, ModelEuAxisCoord)))
                    if childrenFirst:
                        thisCol = rightCol
                        sideBorder = RIGHTBORDER
                    else:
                        thisCol = leftCol
                        sideBorder = LEFTBORDER
                    if renderNow:
                        columnspan = (rightCol - leftCol + (1 if nonAbstract else 0))
                        gridBorder(self.gridColHdr, leftCol, topRow, TOPBORDER, columnspan=columnspan)
                        gridBorder(self.gridColHdr, leftCol, topRow, 
                                   sideBorder, columnspan=columnspan,
                                   rowspan=(rowBelow - topRow + 1) )
                        gridHdr(self.gridColHdr, leftCol, topRow, 
                                label if label else "         ", 
                                anchor="center",
                                columnspan=(rightCol - leftCol + (1 if nonAbstract else 0)),
                                rowspan=(row - topRow + 1) if leafNode else 1,
                                wraplength=width, # screen units
                                objectId=xStructuralNode.objectId(),
                                onClick=self.onClick)
                        if nonAbstract:
                            for i, role in enumerate(self.colHdrNonStdRoles):
                                gridBorder(self.gridColHdr, thisCol, self.dataFirstRow - len(self.colHdrNonStdRoles) + i, TOPBORDER)
                                gridBorder(self.gridColHdr, thisCol, self.dataFirstRow - len(self.colHdrNonStdRoles) + i, sideBorder)
                                gridHdr(self.gridColHdr, thisCol, self.dataFirstRow - len(self.colHdrNonStdRoles) + i, 
                                        xStructuralNode.header(role=role, lang=self.lang), 
                                        anchor="center",
                                        wraplength=100, # screen units
                                        objectId=xStructuralNode.objectId(),
                                        onClick=self.onClick)
                            ''' was
                            if self.colHdrDocRow:
                                gridBorder(self.gridColHdr, thisCol, self.dataFirstRow - 1 - self.rowHdrCodeCol, TOPBORDER)
                                gridBorder(self.gridColHdr, thisCol, self.dataFirstRow - 1 - self.rowHdrCodeCol, sideBorder)
                                gridHdr(self.gridColHdr, thisCol, self.dataFirstRow - 1 - self.rowHdrCodeCol, 
                                        xStructuralNode.header(role="http://www.xbrl.org/2008/role/documentation",
                                                               lang=self.lang), 
                                        anchor="center",
                                        wraplength=100, # screen units
                                        objectId=xStructuralNode.objectId(),
                                        onClick=self.onClick)
                            if self.colHdrCodeRow:
                                gridBorder(self.gridColHdr, thisCol, self.dataFirstRow - 1, TOPBORDER)
                                gridBorder(self.gridColHdr, thisCol, self.dataFirstRow - 1, sideBorder)
                                gridHdr(self.gridColHdr, thisCol, self.dataFirstRow - 1, 
                                        xStructuralNode.header(role="http://www.eurofiling.info/role/2010/coordinate-code"),
                                        anchor="center",
                                        wraplength=100, # screen units
                                        objectId=xStructuralNode.objectId(),
                                        onClick=self.onClick)
                            '''
                            gridBorder(self.gridColHdr, thisCol, self.dataFirstRow - 1, BOTTOMBORDER)
                            xStructuralNodes.append(xStructuralNode)
                    if nonAbstract:
                        rightCol += 1
                    if renderNow and not childrenFirst:
                        self.xAxis(leftCol + (1 if nonAbstract else 0), topRow + 1, rowBelow, xStructuralNode, xStructuralNodes, childrenFirst, True, False) # render on this pass
                    leftCol = rightCol
            if atTop and sideBorder and not childrenFirst:
                gridBorder(self.gridColHdr, rightCol - 1, 1, RIGHTBORDER, rowspan=self.dataFirstRow)
            return (rightCol, parentRow, widthToSpanParent, noDescendants)
            
    def yAxis(self, leftCol, row, yParentStructuralNode, childrenFirst, renderNow, atLeft):
        if yParentStructuralNode is not None:
            nestedBottomRow = row
            if atLeft:
                gridBorder(self.gridRowHdr, self.rowHdrCols + len(self.rowHdrNonStdRoles), # was: self.rowHdrDocCol + self.rowHdrCodeCol, 
                           self.dataFirstRow, 
                           RIGHTBORDER, 
                           rowspan=self.dataRows)
                gridBorder(self.gridRowHdr, 1, self.dataFirstRow + self.dataRows - 1, 
                           BOTTOMBORDER, 
                           columnspan=(self.rowHdrCols + len(self.rowHdrNonStdRoles))) # was: self.rowHdrDocCol + self.rowHdrCodeCol))
            for yStructuralNode in yParentStructuralNode.childStructuralNodes:
                if not yStructuralNode.isRollUp:
                    nestRow, nextRow = self.yAxis(leftCol + 1, row, yStructuralNode,  # nested items before totals
                                            childrenFirst, childrenFirst, False)
                    
                    isAbstract = (yStructuralNode.isAbstract or 
                                  (yStructuralNode.childStructuralNodes and
                                   not isinstance(yStructuralNode.definitionNode, (ModelClosedDefinitionNode, ModelEuAxisCoord))))
                    isNonAbstract = not isAbstract
                    label = yStructuralNode.header(lang=self.lang,
                                                   returnGenLabel=isinstance(yStructuralNode.definitionNode, (ModelClosedDefinitionNode, ModelEuAxisCoord)))
                    topRow = row
                    if childrenFirst and isNonAbstract:
                        row = nextRow
                    if renderNow:
                        columnspan = self.rowHdrCols - leftCol + 1 if isNonAbstract or nextRow == row else None
                        gridBorder(self.gridRowHdr, leftCol, topRow, LEFTBORDER, 
                                   rowspan=(nestRow - topRow + 1) )
                        gridBorder(self.gridRowHdr, leftCol, topRow, TOPBORDER, 
                                   columnspan=(1 if childrenFirst and nextRow > row else columnspan))
                        if childrenFirst and row > topRow:
                            gridBorder(self.gridRowHdr, leftCol + 1, row, TOPBORDER, 
                                       columnspan=(self.rowHdrCols - leftCol))
                        depth = yStructuralNode.depth
                        gridHdr(self.gridRowHdr, leftCol, row, 
                                label if label is not None else "         ", 
                                anchor=("w" if isNonAbstract or nestRow == row else "center"),
                                columnspan=columnspan,
                                rowspan=(nestRow - row if isAbstract else None),
                                # wraplength is in screen units
                                wraplength=(self.rowHdrColWidth[depth] if isAbstract else
                                            self.rowHdrWrapLength - sum(self.rowHdrColWidth[0:depth])),
                                #minwidth=self.rowHdrColWidth[leftCol],
                                minwidth=(16 if isNonAbstract and nextRow > topRow else None),
                                objectId=yStructuralNode.objectId(),
                                onClick=self.onClick)
                        if isNonAbstract:
                            for i, role in enumerate(self.rowHdrNonStdRoles):
                                isCode = "code" in role
                                docCol = self.dataFirstCol - len(self.rowHdrNonStdRoles) + i
                                gridBorder(self.gridRowHdr, docCol, row, TOPBORDER)
                                gridBorder(self.gridRowHdr, docCol, row, LEFTBORDER)
                                gridHdr(self.gridRowHdr, docCol, row, 
                                        yStructuralNode.header(role=role, lang=self.lang), 
                                        anchor="c" if isCode else "w",
                                        wraplength=40 if isCode else 100, # screen units
                                        objectId=yStructuralNode.objectId(),
                                        onClick=self.onClick)
                            ''' was:
                            if self.rowHdrDocCol:
                                docCol = self.dataFirstCol - 1 - self.rowHdrCodeCol
                                gridBorder(self.gridRowHdr, docCol, row, TOPBORDER)
                                gridBorder(self.gridRowHdr, docCol, row, LEFTBORDER)
                                gridHdr(self.gridRowHdr, docCol, row, 
                                        yStructuralNode.header(role="http://www.xbrl.org/2008/role/documentation",
                                                             lang=self.lang), 
                                        anchor="w",
                                        wraplength=100, # screen units
                                        objectId=yStructuralNode.objectId(),
                                        onClick=self.onClick)
                            if self.rowHdrCodeCol:
                                codeCol = self.dataFirstCol - 1
                                gridBorder(self.gridRowHdr, codeCol, row, TOPBORDER)
                                gridBorder(self.gridRowHdr, codeCol, row, LEFTBORDER)
                                gridHdr(self.gridRowHdr, codeCol, row, 
                                        yStructuralNode.header(role="http://www.eurofiling.info/role/2010/coordinate-code"),
                                        anchor="center",
                                        wraplength=40, # screen units
                                        objectId=yStructuralNode.objectId(),
                                        onClick=self.onClick)
                            # gridBorder(self.gridRowHdr, leftCol, self.dataFirstRow - 1, BOTTOMBORDER)
                            '''
                    if isNonAbstract:
                        row += 1
                    elif childrenFirst:
                        row = nextRow
                    if nestRow > nestedBottomRow:
                        nestedBottomRow = nestRow + (isNonAbstract and not childrenFirst)
                    if row > nestedBottomRow:
                        nestedBottomRow = row
                    #if renderNow and not childrenFirst:
                    #    dummy, row = self.yAxis(leftCol + 1, row, yStructuralNode, childrenFirst, True, False) # render on this pass
                    if not childrenFirst:
                        dummy, row = self.yAxis(leftCol + 1, row, yStructuralNode, childrenFirst, renderNow, False) # render on this pass
            return (nestedBottomRow, row)
    
    def bodyCells(self, row, yParentStructuralNode, xStructuralNodes, zAspects, yChildrenFirst):
        if yParentStructuralNode is not None:
            rendrCntx = getattr(self.modelXbrl, "rendrCntx", None) # none for EU 2010 tables
            dimDefaults = self.modelXbrl.qnameDimensionDefaults
            for yStructuralNode in yParentStructuralNode.childStructuralNodes:
                if yChildrenFirst:
                    row = self.bodyCells(row, yStructuralNode, xStructuralNodes, zAspects, yChildrenFirst)
                if not yStructuralNode.isAbstract:
                    yAspects = defaultdict(set)
                    for aspect in aspectModels[self.aspectModel]:
                        for ruleAspect in aspectRuleAspects.get(aspect, (aspect,)):
                            if yStructuralNode.hasAspect(ruleAspect):
                                if ruleAspect == Aspect.DIMENSIONS:
                                    for dim in (yStructuralNode.aspectValue(Aspect.DIMENSIONS) or emptyList):
                                        yAspects[dim].add(yStructuralNode)
                                else:
                                    yAspects[ruleAspect].add(yStructuralNode)
                        
                    gridSpacer(self.gridBody, self.dataFirstCol, row, LEFTBORDER)
                    # data for columns of row
                    ignoreDimValidity = self.ignoreDimValidity.get()
                    for i, xStructuralNode in enumerate(xStructuralNodes):
                        xAspects = defaultdict(set)
                        for aspect in aspectModels[self.aspectModel]:
                            for ruleAspect in aspectRuleAspects.get(aspect, (aspect,)):
                                if xStructuralNode.hasAspect(ruleAspect):
                                    if ruleAspect == Aspect.DIMENSIONS:
                                        for dim in (xStructuralNode.aspectValue(Aspect.DIMENSIONS) or emptyList):
                                            xAspects[dim].add(xStructuralNode)
                                    else:
                                        xAspects[ruleAspect].add(xStructuralNode)
                        cellAspectValues = {}
                        matchableAspects = set()
                        for aspect in _DICT_SET(xAspects.keys()) | _DICT_SET(yAspects.keys()) | _DICT_SET(zAspects.keys()):
                            aspectValue = inheritedAspectValue(self, aspect, xAspects, yAspects, zAspects, xStructuralNode, yStructuralNode)
                            if dimDefaults.get(aspect) != aspectValue: # don't include defaulted dimensions
                                cellAspectValues[aspect] = aspectValue
                            matchableAspects.add(aspectModelAspect.get(aspect,aspect)) #filterable aspect from rule aspect
                        cellDefaultedDims = _DICT_SET(dimDefaults) - _DICT_SET(cellAspectValues.keys())
                        priItemQname = cellAspectValues.get(Aspect.CONCEPT)
                            
                        concept = self.modelXbrl.qnameConcepts.get(priItemQname)
                        conceptNotAbstract = concept is None or not concept.isAbstract
                        from arelle.ValidateXbrlDimensions import isFactDimensionallyValid
                        value = None
                        objectId = None
                        justify = None
                        fp = FactPrototype(self, cellAspectValues)
                        if conceptNotAbstract:
                            # reduce set of matchable facts to those with pri item qname and have dimension aspects
                            facts = self.modelXbrl.factsByQname[priItemQname] if priItemQname else self.modelXbrl.factsInInstance
                            for aspect in matchableAspects:  # trim down facts with explicit dimensions match or just present
                                if isinstance(aspect, QName):
                                    aspectValue = cellAspectValues.get(aspect, None)
                                    if isinstance(aspectValue, ModelDimensionValue):
                                        if aspectValue.isExplicit:
                                            dimMemQname = aspectValue.memberQname # match facts with this explicit value
                                        else:
                                            dimMemQname = None  # match facts that report this dimension
                                    elif isinstance(aspectValue, QName): 
                                        dimMemQname = aspectValue  # match facts that have this explicit value
                                    else:
                                        dimMemQname = None # match facts that report this dimension
                                    facts = facts & self.modelXbrl.factsByDimMemQname(aspect, dimMemQname)
                            for fact in facts:
                                if (all(aspectMatches(rendrCntx, fact, fp, aspect) 
                                        for aspect in matchableAspects) and
                                    all(fact.context.dimMemberQname(dim,includeDefaults=True) in (dimDefaults[dim], None)
                                        for dim in cellDefaultedDims)):
                                    if yStructuralNode.hasValueExpression(xStructuralNode):
                                        value = yStructuralNode.evalValueExpression(fact, xStructuralNode)
                                    else:
                                        value = fact.effectiveValue
                                    objectId = fact.objectId()
                                    justify = "right" if fact.isNumeric else "left"
                                    break
                        if (conceptNotAbstract and
                            (value is not None or ignoreDimValidity or isFactDimensionallyValid(self, fp))):
                            if objectId is None:
                                objectId = "f{0}".format(len(self.factPrototypes))
                                self.factPrototypes.append(fp)  # for property views
                            gridCell(self.gridBody, self.dataFirstCol + i, row, value, justify=justify, 
                                     width=12, # width is in characters, not screen units
                                     objectId=objectId, onClick=self.onClick)
                        else:
                            fp.clear()  # dereference
                            gridSpacer(self.gridBody, self.dataFirstCol + i, row, CENTERCELL)
                        gridSpacer(self.gridBody, self.dataFirstCol + i, row, RIGHTBORDER)
                        gridSpacer(self.gridBody, self.dataFirstCol + i, row, BOTTOMBORDER)
                    row += 1
                if not yChildrenFirst:
                    row = self.bodyCells(row, yStructuralNode, xStructuralNodes, zAspects, yChildrenFirst)
            return row
    def onClick(self, event):
        objId = event.widget.objectId
        if objId and objId[0] == "f":
            viewableObject = self.factPrototypes[int(objId[1:])]
        else:
            viewableObject = objId
        self.modelXbrl.viewModelObject(viewableObject)
        self.modelXbrl.modelManager.cntlr.currentView = self
            
    def cellEnter(self, *args):
        self.blockSelectEvent = 0
        self.modelXbrl.modelManager.cntlr.currentView = self

    def cellLeave(self, *args):
        self.blockSelectEvent = 1

    def cellSelect(self, *args):
        if self.blockSelectEvent == 0 and self.blockViewModelObject == 0:
            self.blockViewModelObject += 1
            #self.modelXbrl.viewModelObject(self.nodeToObjectId[self.treeView.selection()[0]])
            #self.modelXbrl.viewModelObject(self.treeView.selection()[0])
            self.blockViewModelObject -= 1
        
    def viewModelObject(self, modelObject):
        if self.blockViewModelObject == 0:
            self.blockViewModelObject += 1
            '''
            try:
                if isinstance(modelObject, ModelObject.ModelRelationship):
                    conceptId = modelObject.toModelObject.objectId()
                elif isinstance(modelObject, ModelObject.ModelFact):
                    conceptId = self.modelXbrl.qnameConcepts[modelObject.qname].objectId()
                else:
                    conceptId = modelObject.objectId()
                #node = self.objectIdToNode[conceptId]
                node = conceptId
                if self.treeView.exists(node):
                    self.treeView.see(node)
                    self.treeView.selection_set(node)
            except KeyError:
                    self.treeView.selection_set(())
            '''
            self.blockViewModelObject -= 1
    
    def saveInstance(self, newFilename=None):
        if (not self.newFactItemOptions.entityIdentScheme or  # not initialized yet
            not self.newFactItemOptions.entityIdentValue or
            not self.newFactItemOptions.startDateDate or not self.newFactItemOptions.endDateDate):
            if not getNewFactItemOptions(self.modelXbrl.modelManager.cntlr, self.newFactItemOptions):
                return # new instance not set
        # newFilename = None # only used when a new instance must be created
        if self.modelXbrl.modelDocument.type != ModelDocument.Type.INSTANCE and newFilename is None:
            newFilename = self.modelXbrl.modelManager.cntlr.fileSave(view=self, fileType="xbrl")
            if not newFilename:
                return  # saving cancelled
        # continue saving in background
        thread = threading.Thread(target=lambda: self.backgroundSaveInstance(newFilename))
        thread.daemon = True
        thread.start()

    def backgroundSaveInstance(self, newFilename=None):
        cntlr = self.modelXbrl.modelManager.cntlr
        if newFilename and self.modelXbrl.modelDocument.type != ModelDocument.Type.INSTANCE:
            self.modelXbrl.modelManager.showStatus(_("creating new instance {0}").format(os.path.basename(newFilename)))
            self.modelXbrl.modelManager.cntlr.waitForUiThreadQueue() # force status update
            self.modelXbrl.createInstance(newFilename) # creates an instance as this modelXbrl's entrypoing
        instance = self.modelXbrl
        cntlr.showStatus(_("Saving {0}").format(instance.modelDocument.basename))
        cntlr.waitForUiThreadQueue() # force status update
        newCntx = ModelXbrl.AUTO_LOCATE_ELEMENT
        newUnit = ModelXbrl.AUTO_LOCATE_ELEMENT
        # check user keyed changes
        for bodyCell in self.gridBody.winfo_children():
            if isinstance(bodyCell, gridCell) and bodyCell.isChanged:
                value = bodyCell.value
                objId = bodyCell.objectId
                if objId:
                    if objId[0] == "f":
                        factPrototypeIndex = int(objId[1:])
                        factPrototype = self.factPrototypes[factPrototypeIndex]
                        concept = factPrototype.concept
                        entityIdentScheme = self.newFactItemOptions.entityIdentScheme
                        entityIdentValue = self.newFactItemOptions.entityIdentValue
                        periodType = factPrototype.concept.periodType
                        periodStart = self.newFactItemOptions.startDateDate if periodType == "duration" else None
                        periodEndInstant = self.newFactItemOptions.endDateDate
                        qnameDims = factPrototype.context.qnameDims
                        prevCntx = instance.matchContext(
                             entityIdentScheme, entityIdentValue, periodType, periodStart, periodEndInstant, 
                             qnameDims, [], [])
                        if prevCntx is not None:
                            cntxId = prevCntx.id
                        else: # need new context
                            newCntx = instance.createContext(entityIdentScheme, entityIdentValue, 
                                          periodType, periodStart, periodEndInstant, 
                                          concept.qname, qnameDims, [], [],
                                          afterSibling=newCntx)
                            cntxId = newCntx.id
                            # new context
                        if concept.isNumeric:
                            if concept.isMonetary:
                                unitMeasure = qname(XbrlConst.iso4217, self.newFactItemOptions.monetaryUnit)
                                unitMeasure.prefix = "iso4217"  # want to save with a recommended prefix
                                decimals = self.newFactItemOptions.monetaryDecimals
                            elif concept.isShares:
                                unitMeasure = XbrlConst.qnXbrliShares
                                decimals = self.newFactItemOptions.nonMonetaryDecimals
                            else:
                                unitMeasure = XbrlConst.qnXbrliPure
                                decimals = self.newFactItemOptions.nonMonetaryDecimals
                            prevUnit = instance.matchUnit([unitMeasure],[])
                            if prevUnit is not None:
                                unitId = prevUnit.id
                            else:
                                newUnit = instance.createUnit([unitMeasure],[], afterSibling=newUnit)
                                unitId = newUnit.id
                        attrs = [("contextRef", cntxId)]
                        if concept.isNumeric:
                            attrs.append(("unitRef", unitId))
                            attrs.append(("decimals", decimals))
                            value = Locale.atof(self.modelXbrl.locale, value, str.strip)
                        newFact = instance.createFact(concept.qname, attributes=attrs, text=value)
                        bodyCell.objectId = newFact.objectId()  # switch cell to now use fact ID
                        if self.factPrototypes[factPrototypeIndex] is not None:
                            self.factPrototypes[factPrototypeIndex].clear()
                        self.factPrototypes[factPrototypeIndex] = None #dereference fact prototype
                    else: # instance fact, not prototype
                        fact = self.modelXbrl.modelObject(objId)
                        if fact.concept.isNumeric:
                            value = Locale.atof(self.modelXbrl.locale, value, str.strip)
                        if fact.value != value:
                            if fact.concept.isNumeric and fact.isNil != (not value):
                                fact.isNil = not value
                                if value: # had been nil, now it needs decimals
                                    fact.decimals = (self.newFactItemOptions.monetaryDecimals
                                                     if fact.concept.isMonetary else
                                                     self.newFactItemOptions.nonMonetaryDecimals)
                            fact.text = value
                            XmlValidate.validate(instance, fact)
                    bodyCell.isChanged = False  # clear change flag
        instance.saveInstance(newFilename) # may override prior filename for instance from main menu
        cntlr.showStatus(_("Saved {0}").format(instance.modelDocument.basename), clearAfter=3000)
            
예제 #57
0
class ReplicatorMain(VerticalScrolledFrame):
    """The main class for the GUI of the application"""

    merge = None
    """This is the merge object of the application, it holds all settings for the merge operation"""
    filename = None
    """The name of the file containing the merge definition"""
    fr_src_dataset = None
    """The fram of the source dataset, contains a FrameCustomDataset descendant"""
    fr_dest_dataset = None
    """The fram of the source dataset, contains a FrameCustomDataset descendant"""
    suppress_errors = None
    """Do not show any errors"""
    _row_index = None
    """The current row in the dataset"""
    curr_mapping_frame = None
    """The currently selected mapping frame"""

    def __init__(self, _merge=None, _filename=None, *args, **kw):

        self.parent = Tk()

        # Init oneself

        super(ReplicatorMain, self).__init__(self.parent, bd=1, relief=SUNKEN, *args, **kw)
        self.grid(stick=(E, W, N, S))

        self.suppress_errors = None

        self.merge = _merge
        self.filename = _filename

        self.fr_src_dataset = None
        self.fr_dest_dataset = None

        self.grid()
        self.ip_address = StringVar()
        self._row_index = 0
        self.init_GUI()

        if _filename is not None and _merge is not None:
            # _merge._load_datasets()
            self._merge_to_gui()


        self.parent.columnconfigure(0, weight=1)
        self.parent.rowconfigure(0, weight=1)
        self.resize()

        self.parent.mainloop()

    def resize(self):
        """
        Resize the window, set the width what the internal windows need.
        """
        self._canvas.update_idletasks()
        self.fr_top_right.update_idletasks()
        self._canvas.config(width=self.interior.winfo_reqwidth() + 1, height=self.interior.winfo_reqheight())

    def on_dataset_columns_change(self, *args):
        # Columns have changed; force reload columns from structure
        self.fr_src_dataset.get_possible_references(True)
        self.fr_dest_dataset.get_possible_references(True)
        for curr_mapping in self.g_mappings.items:
            curr_mapping.fr_item.reload_references()


    def notify_task(self, _task, _progress):
        """Override as this is the top widget"""
        self.fr_Status_Bar.update_task(_task, _progress)

    def notify_messagebox(self, _title, _message, _kind=None):
        """Override as this is the top class, default is error."""
        if self.suppress_errors is None:
            if _kind == "message":
                messagebox.showinfo(_title, _message)
            elif _kind == "warning":
                messagebox.showwarning(_title, _message)
            else:
                messagebox.showerror(_title, _message)

    def on_post_merge_sql(self, *args):
        # Show post-merge-SQL dialog
        _wdw = Toplevel()
        _wdw.geometry('+400+400')
        _wdw.e = TextExtension(_wdw, textvariable=self.post_execute_sql)
        _wdw.e.pack()
        _wdw.e.focus_set()
        _wdw.transient(self.parent)
        _wdw.grab_set()
        self.parent.wait_window(_wdw)
        _wdw.e.unhook()
        del (_wdw)


    def on_src_connect(self, *args):
        """Event handler for when the source connection is set"""
        self.fr_mapping.src_dal = self.fr_dataset_src.dal

    def on_dest_connect(self, *args):
        """Event handler for when the destination connection is set"""
        self.fr_mapping.dest_dal = self.fr_dataset_dest.dal

    def init_GUI(self):
        """Init main application GUI"""
        print("Initializing GUI...", end="")

        self.parent.title("Optimal Sync - Move that data - a part of Optimal BPM")
        self.interior.notify_task = self.notify_task
        self.interior.notify_messagebox = self.notify_messagebox

        self.fr_top = BPMFrame(self.interior)
        self.fr_top.pack(side=TOP, fill=BOTH, expand=1)

        self.fr_top_left = BPMFrame(self.fr_top)
        self.fr_top_left.pack(side=LEFT, fill=BOTH, expand=1)

        self.fr_rw = BPMFrame(self.fr_top_left)
        self.fr_rw.pack(side=TOP, fill=X)

        self.btn_Load_json_json = ttk.Button(self.fr_rw, text="Load", command=self.on_load_json)
        self.btn_Load_json_json.pack(side=LEFT)
        self.btn_Save_json = ttk.Button(self.fr_rw, text="Save", command=self.on_save_json)
        self.btn_Save_json.pack(side=LEFT)
        self.fr_subnet_sql = BPMFrame(self.fr_rw)
        self.l_ip = ttk.Label(self.fr_subnet_sql, text="IP(for subnet scan):")
        self.l_ip.pack(side=LEFT)
        self.ip_address.set("192.168.0.1")
        self.e_ip_address = ttk.Entry(self.fr_subnet_sql, textvariable=self.ip_address)
        self.e_ip_address.pack(side=RIGHT)
        self.fr_subnet_sql.pack(side=RIGHT)

        # datasets

        self.fr_datasets = BPMFrame(self.fr_top_left)
        self.fr_datasets.pack(side=TOP)

        self.sel_src_dataset_type = Selector(_master=self.fr_datasets,
                                             _values=('RDBMS', 'XPath', 'Flatfile', 'Spreadsheet'),
                                             _caption="Sources dataset type:",
                                             _onchange=self.on_src_dataset_type_change)
        self.sel_src_dataset_type.grid(column=0, row=0, sticky=W)

        self.sel_dest_dataset_type = Selector(_master=self.fr_datasets,
                                              _values=('RDBMS', 'XPath', 'Flatfile', 'Spreadsheet'),
                                              _caption="Destination dataset type:",
                                              _onchange=self.on_dest_dataset_type_change)
        self.sel_dest_dataset_type.grid(column=1, row=0, sticky=W)


        # Mappings

        self.fr_mapping_header = BPMFrame(self.fr_top_left)
        self.fr_mapping_header.pack(side=TOP)

        self.l_mapping = ttk.Label(self.fr_mapping_header, text="Mappings:")
        self.l_mapping.pack(side=TOP)

        self.fr_mapping_header_nav = BPMFrame(self.fr_mapping_header)
        self.fr_mapping_header_nav.pack(side=BOTTOM)

        self.btn_first = Button(self.fr_mapping_header_nav, text="<<", command=self.on_first)
        self.btn_first.pack(side=LEFT)
        self.btn_prev = Button(self.fr_mapping_header_nav, text="<", command=self.on_prev)
        self.btn_prev.pack(side=LEFT)

        self.btn_reload = Button(self.fr_mapping_header_nav, text="Reload data", command=self.on_reload_data)
        self.btn_reload.pack(side=LEFT)

        self.btn_next = Button(self.fr_mapping_header_nav, text=">", command=self.on_next)
        self.btn_next.pack(side=LEFT)
        self.btn_last = Button(self.fr_mapping_header_nav, text=">>", command=self.on_last)
        self.btn_last.pack(side=LEFT)

        self.g_mappings = FrameList(self.fr_top_left, _detail_key_text="Transformations >>", bd=1, relief=SUNKEN)
        self.g_mappings.pack(side=TOP, fill=X)
        self.g_mappings.on_delete = self.mappings_do_on_delete
        self.g_mappings.on_move_up = self.mappings_do_on_move_up
        self.g_mappings.on_move_down = self.mappings_do_on_move_down
        self.g_mappings.on_detail = self.mappings_do_on_detail

        self.btn_append_mapping = Button(self.fr_top_left, text="Append mapping", command=self.on_append_mapping)
        self.btn_append_mapping.pack(side=TOP)

        # Transformation
        self.fr_top_right = BPMFrame(self.fr_top)
        self.fr_top_right.pack(side=RIGHT, fill=Y)

        self.l_transformations = ttk.Label(self.fr_top_right, text="Transformations")
        self.l_transformations.pack(side=TOP)

        self.g_transformations = FrameList(self.fr_top_right, bd=1, relief=SUNKEN)
        self.g_transformations.pack(fill=BOTH, expand=1)
        self.g_transformations.on_delete = self.transformations_do_on_delete
        self.g_transformations.on_move_up = self.transformations_do_on_move_up
        self.g_transformations.on_move_down = self.transformations_do_on_move_down

        self.fr_append_transformation = ttk.Frame(self.fr_top_right)
        self.fr_append_transformation.pack(side=BOTTOM)

        self.btn_append_transformation = Button(self.fr_append_transformation, text="Append Transformation",
                                                command=self.on_append_transformation)
        self.btn_append_transformation.pack(side=LEFT)

        self.transformation_append_type = StringVar()
        self.sel_transformation_append_type = ttk.Combobox(self.fr_append_transformation,
                                                           textvariable=self.transformation_append_type,
                                                           state='readonly')
        self.sel_transformation_append_type['values'] = ["Replace", "Replace regex", "Cast", "If empty", "Trim"]
        self.sel_transformation_append_type.current(0)
        self.sel_transformation_append_type.pack(side=LEFT, fill=X)

        # Merge preview
        self.fr_Preview = ttk.Frame(self.fr_top_left)
        self.fr_Preview.pack(side=TOP, fill=BOTH, expand=1)

        self.fr_merge_actions = ttk.Frame(self.fr_Preview)
        self.fr_merge_actions.pack(side=TOP, fill=X)

        self.btn_execute_preview = Button(self.fr_merge_actions, text="Preview merge", command=self.on_preview_merge)
        self.btn_execute_preview.pack(side=LEFT)
        self.btn_execute_preview = Button(self.fr_merge_actions, text="Commit merge", command=self.on_commit_merge)
        self.btn_execute_preview.pack(side=LEFT)

        # Update
        self.merge_update = BooleanVar()
        self.e_merge_update = ttk.Checkbutton(self.fr_merge_actions, variable=self.merge_update)
        self.e_merge_update.pack(side=RIGHT)
        self.l_merge_update = ttk.Label(self.fr_merge_actions, text="Update: ")
        self.l_merge_update.pack(side=RIGHT)

        # Insert

        self.merge_insert = BooleanVar()
        self.e_merge_insert = ttk.Checkbutton(self.fr_merge_actions, variable=self.merge_insert)
        self.e_merge_insert.pack(side=RIGHT)
        self.l_merge_insert = ttk.Label(self.fr_merge_actions, text="Insert: ")
        self.l_merge_insert.pack(side=RIGHT)

        # Delete
        self.merge_delete = BooleanVar()
        self.e_merge_delete = ttk.Checkbutton(self.fr_merge_actions, variable=self.merge_delete)
        self.e_merge_delete.pack(side=RIGHT)
        self.l_merge_delete = ttk.Label(self.fr_merge_actions, text="Delete: ")
        self.l_merge_delete.pack(side=RIGHT)

        # Set post-merge SQL
        self.post_execute_sql = StringVar()
        self.btn_Post_Merge_SQL = ttk.Button(self.fr_merge_actions, text="Set post-merge SQL",
                                             command=self.on_post_merge_sql)
        self.btn_Post_Merge_SQL.pack(side=RIGHT, padx=30)

        # Preview
        self.gr_preview = ttk.Treeview(self.fr_Preview, columns=('size', 'modified'))
        self.gr_preview.pack(side=TOP, fill=BOTH, expand=1)
        self.gr_preview.bind("<<TreeviewSelect>>", self.on_preview_selected)
        self.preview_detail = StringVar()
        self.e_previev_detail = ttk.Entry(self.fr_Preview, textvariable=self.preview_detail)
        self.e_previev_detail.pack(side=BOTTOM, fill=X, expand=0)

        self.fr_bottom = BPMFrame(self.interior)
        self.fr_bottom.pack(side=BOTTOM, fill=X)

        self.fr_Status_Bar = Status_Bar(self.fr_bottom)
        self.fr_Status_Bar.pack(fill=X)

        print("done.")

    # #########################################################################
    # This section contains functions handling the entire merge(load/save/GUI)
    # #########################################################################

    def _merge_to_gui(self):
        """
        Populate the GUI from the merge class.
        """
        if self.fr_src_dataset is not None:
            self.fr_src_dataset.destroy()
        _src_type = self.dataset_instance_to_dataset_type(self.merge.source)
        self.sel_src_dataset_type.set_but_do_not_propagate(_src_type)
        self.fr_src_dataset = self.dataset_frame_factory(_dataset=self.merge.source, _is_destination=False)
        self.fr_src_dataset.grid(column=0, row=1)

        if self.fr_dest_dataset is not None:
            self.fr_dest_dataset.destroy()

        _dest_type = self.dataset_instance_to_dataset_type(self.merge.destination)
        self.sel_dest_dataset_type.set_but_do_not_propagate(_dest_type)
        self.fr_dest_dataset = self.dataset_frame_factory(_dataset=self.merge.destination, _is_destination=False)
        self.fr_dest_dataset.grid(column=1, row=1)

        self.mappings_to_gui()

        self.merge_insert.set(bool_to_binary_int(self.merge.insert))
        self.merge_delete.set(bool_to_binary_int(self.merge.delete))
        self.merge_update.set(bool_to_binary_int(self.merge.update))
        if self.merge.post_execute_sql is None:
            self.post_execute_sql.set("")
        else:
            self.post_execute_sql.set(self.merge.post_execute_sql)

        # Hereafter, update column list when they change
        self.fr_src_dataset.on_columns_change = self.on_dataset_columns_change
        self.fr_dest_dataset.on_columns_change = self.on_dataset_columns_change

    def _gui_to_merge(self):
        """Copy the data from the GUI to the merge object"""
        self.fr_src_dataset.write_to_dataset()
        self.merge.source = self.fr_src_dataset.dataset
        self.fr_dest_dataset.write_to_dataset()
        self.merge.destination = self.fr_dest_dataset.dataset

        self.gui_to_mappings()

        self.merge.insert = binary_int_to_bool(self.merge_insert.get())
        self.merge.delete = binary_int_to_bool(self.merge_delete.get())
        self.merge.update = binary_int_to_bool(self.merge_update.get())
        self.merge.post_execute_sql = self.post_execute_sql.get()

    def load_json(self, _filename):
        """Load an JSON into the merge object, and populate the GUI"""
        with open(_filename, "r") as _f:
            _json = json.load(_f)

        self.filename = _filename

        self.notify_task('Loading transformation..', 0)
        self.merge = Merge(_json=_json, _base_path=os.path.dirname(_filename))
        try:
            self.merge._load_datasets()
        except Exception as e:
            self.notify_messagebox("Error loading data", str(e))
            # Supress the following errors. There is no real errors that matters.
            self.suppress_errors = True
        self._merge_to_gui()
        self.suppress_errors = None
        self.notify_task('Loading transformation..done', 100)
        self.resize()


    def on_save_json(self, *args):
        """Triggered when save-button is clicked.
        Displays a save dialog, fetches GUI data into merge, and saves as JSON into the selected file."""
        self.notify_task('Saving..', 0)
        _filename = filedialog.asksaveasfilename(initialfile= self.filename, defaultextension=".json",
                                                 filetypes=[('JSON files', '.json'), ('all files', '.*')],
                                                 title="Choose location")
        if _filename:
            self._gui_to_merge()
            self.notify_task('Saving(Generating JS)..', 0)
            _json = self.merge.as_json()
            self.notify_task('Saving(Writing file)..', 50)
            with open (_filename, "w") as _f:
                json.dump(_json, fp=_f, sort_keys=True, indent=4)

            self.notify_task('Saving..done.', 100)
        else:
            self.notify_task('Saving cancelled.', 0)


    def on_load_json(self, *args):
        """Triggered when load-button is clicked.
        Displays a load dialog, clears the GUI, populates the merge and uppdates the GUI"""
        _filename = filedialog.askopenfilename(defaultextension=".json",
                                               filetypes=[('JSON files', '.json'), ('all files', '.*')],
                                               title="Choose file")
        if _filename:
            self.g_transformations.clear()
            self.g_mappings.clear()
            self.clear_preview()
            self.curr_mapping_frame = None
            self._row_index = 0
            self.load_json(_filename)

    def check_prerequisites_for_reload(self):
        """Can a reload be made using the current settings? If not, display cause in status field"""

        if self.fr_src_dataset is None:
            self.notify_task("Cannot reload: Source dataset must be specified.", 0)
            return False
        elif self.fr_dest_dataset is None:
            self.notify_task("Cannot reload: Destination dataset must be specified.", 0)
            return False
        _tmp = self.fr_src_dataset.check_reload()
        if _tmp:
            self.notify_task("Cannot reload source: " + _tmp, 0)
            return False
        _tmp = self.fr_dest_dataset.check_reload()
        if _tmp:
            self.notify_task("Cannot reload destination: " + _tmp, 0)
            return False
        else:
            return True


    def update_data(self, _refresh=None):
        """
        Reload all data into the GUI
        :param _refresh: Force reload of datasets
        :return:
        """

        if self.check_prerequisites_for_reload() is False:
            return

        self.notify_task("", 0)
        if len(self.merge.source.data_table) == 0 or _refresh:
            # Update settings
            self._gui_to_merge()

            # Update XPath references especially, since it addresses an XML structure, not a dataset.
            if isinstance(self.merge.source, XpathDataset):
                self.merge.source.field_xpaths = []
                self.merge.source.field_names = []
                for _curr_mapping_idx in range(0, len(self.g_mappings.items)):
                    self.merge.source.field_xpaths.append(
                        self.g_mappings.items[_curr_mapping_idx].fr_item.src_reference.get())
                    self.merge.source.field_names.append(
                        self.g_mappings.items[_curr_mapping_idx].fr_item.src_reference.get())

            self.merge.source.load()
        # Reset identity values
        self.reset_substitions_identity()
        # Is there any data?
        if len(self.merge.source.data_table) > 0:
            # Try to retain the approximate position in the table.
            if self._row_index < 0:
                self._row_index = 0
            elif self._row_index > len(self.merge.source.data_table) - 1:
                self._row_index = len(self.merge.source.data_table) - 1
            # Loop through mappings, update data and perform transformations
            # TODO: This certainly doesn't seem to belong here, should be extracted
            for _curr_mapping_idx in range(0, len(self.g_mappings.items)):
                _curr_frame = self.g_mappings.items[_curr_mapping_idx].fr_item
                _curr_frame.hide_error()
                _src_ref = _curr_frame.src_reference.get()
                try:
                    if isinstance(self.merge.source, XpathDataset):
                        _col_idx = self.merge.source.field_xpaths.index(_src_ref)
                    else:
                        _col_idx = self.merge.source.field_names.index(_src_ref)
                except ValueError:
                    _col_idx = -1

                if _col_idx > -1:
                    _curr_frame.curr_raw_data = self.merge.source.data_table[self._row_index][_col_idx]
                    try:
                        perform_transformations(_input=_curr_frame.curr_raw_data,
                                                _transformations=_curr_frame.mapping.transformations)
                    except Exception as e:
                        self.notify_task(
                            'Error in one of the transformations, mapping: ' + _src_ref + " error: " + str(e), 0)

                    _curr_frame.curr_data.set(str(_curr_frame.curr_raw_data))

                else:
                    _curr_frame.show_error(_msg="No mapping")
                    _curr_frame.curr_data.set("")

                    try:
                        _curr_frame.curr_raw_data = perform_transformations(_input=None,
                                                                            _transformations=
                                                                            _curr_frame.mapping.transformations)
                    except Exception as e:
                        self.notify_task(
                            'Error in one of the transformations, mapping: ' + _curr_frame.dest_reference.get() +
                            " error: " + str(e), 0)

                    _curr_frame.curr_data.set(str(_curr_frame.curr_raw_data))

                self.g_mappings.items[_curr_mapping_idx].fr_item.reload_references()


    # #########################################################
    # The following events deals with navigating the active dataset
    ##########################################################
    def on_prev(self):
        """Triggered when the "<"-button is pressed."""
        self._row_index -= 1
        self.update_data()

    def on_next(self):
        """Triggered when the ">"-button is pressed."""
        self._row_index += 1
        self.update_data()

    def on_reload_data(self):
        """Triggered when the "Reload data"-button is pressed."""
        self.update_data(_refresh=True)

    def on_first(self):
        """Triggered when the "<<"-button is pressed."""
        self._row_index = 0
        self.update_data()

    def on_last(self):
        """Triggered when the ">>!-button is pressed."""
        if len(self.merge.source.data_table) == 0:
            self.merge.source.load()
        self._row_index = len(self.merge.source.data_table) - 1
        self.update_data()

    def dataset_instance_to_dataset_type(self, _dataset):
        """
        Identify an instance of a dataset and return a string description.
        Used in the dataset type selector.
        :param _dataset: The dataset to identify
        """
        if isinstance(_dataset, RDBMSDataset):
            return "RDBMS"
        elif isinstance(_dataset, XpathDataset):
            return "XPATH"
        elif isinstance(_dataset, FlatfileDataset):
            return "FLATFILE"
        elif isinstance(_dataset, SpreadsheetDataset):
            return "SPREADSHEET"
        else:
            raise Exception("Internal error, unsupported dataset instance type: " + str(_dataset))

    def dataset_frame_factory(self, _dataset=None, _dataset_type=None, _is_destination=False):
        """
        This is a factory function for creating matching frames(visual property editors) for the dataset classes.
        :param _dataset: The dataset, if existing.
        :param _dataset_type: The dataset type string representation ("RDBMS", and so on)
        """
        if _dataset:
            _dataset_type = self.dataset_instance_to_dataset_type(_dataset)

        if _dataset_type == "RDBMS":
            _tmp = FrameRDBMSDataset(self.fr_datasets, _dataset=_dataset, _relief=SUNKEN,
                                     _is_destination=_is_destination)
            _tmp.subnet_ip = self.ip_address
        elif _dataset_type == "FLATFILE":
            _tmp = FrameFlatfileDataset(self.fr_datasets, _dataset=_dataset, _relief=SUNKEN,
                                        _is_destination=_is_destination)
        elif _dataset_type == "XPATH":
            _tmp = FrameXPathDataset(self.fr_datasets, _dataset=_dataset, _relief=SUNKEN,
                                     _is_destination=_is_destination)
        elif _dataset_type == "SPREADSHEET":
            _tmp = FrameSpreadsheetDataset(self.fr_datasets, _dataset=_dataset, _relief=SUNKEN,
                                           _is_destination=_is_destination)
        else:
            raise Exception("Internal error, unsupported dataset type: " + str(_dataset_type))
        if self.filename is not None:
            _tmp.base_path = os.path.dirname(self.filename)
        return _tmp


    def on_src_dataset_type_change(self, _current_value):
        """
        Triggered when a user selects a different dataset type for the source dataset
        :param _current_value: A string describing what dataset type has been selected.
        """
        if self.fr_src_dataset is not None:
            self.fr_src_dataset.destroy()
        self.fr_src_dataset = self.dataset_frame_factory(_dataset_type=_current_value.upper(), _is_destination=False)
        self.merge.source = self.fr_src_dataset.dataset
        self.fr_src_dataset.grid(column=0, row=1)

    def on_dest_dataset_type_change(self, _current_value):
        """
        Triggered when a user selects a different dataset type for the destination dataset
        :param _current_value: A string describing what dataset type has been selected.
        """
        if self.fr_dest_dataset is not None:
            self.fr_dest_dataset.destroy()
        self.fr_dest_dataset = self.dataset_frame_factory(_dataset_type=_current_value.upper(), _is_destination=True)
        self.merge.destination = self.fr_dest_dataset.dataset
        self.fr_dest_dataset.grid(column=1, row=1)

    def get_source_references(self, _force=None):
        """
        Returns the possible field references from the source dataset
        :param _force: If True, forces a reload of the underlying dataset.
        """
        if self.fr_src_dataset is not None:
            try:
                return self.fr_src_dataset.get_possible_references(_force)
            except Exception as e:
                self.notify_messagebox(_title="Failed refreshing source references", _message="Error: " + str(e),
                                       _kind="warning")
                return []


    def get_destination_references(self, _force=None):
        """
        Returns the possible field references from the destination dataset
        :param _force: If True, forces a reload of the underlying dataset.
        """
        if self.fr_dest_dataset is not None:
            try:
                return self.fr_dest_dataset.get_possible_references(_force)
            except Exception as e:
                self.notify_messagebox(_title="Failed refreshing destination references", _message="Error: " + str(e),
                                       _kind="warning")
                return []


    ##########################################################
    # This section contains functions handling field mappings
    ##########################################################
    def mappings_to_gui(self):
        """Populates the GUI from the mappings list of the merge object"""

        self.g_mappings.clear()
        for _curr_mapping in self.merge.mappings:
            _new_item = self.g_mappings.append_item()
            _new_item.make_item(_class=FrameMapping, _mapping=_curr_mapping,
                                _on_get_source_references=self.get_source_references,
                                _on_get_destination_references=self.get_destination_references)


    def gui_to_mappings(self):
        """Gathers data from GUI into the mappings list of the merge object"""

        self.gui_to_transformations()
        for _curr_mapping in self.g_mappings.items:
            _curr_mapping.fr_item.gui_to_mapping()

        self.merge._mappings_to_fields(self.merge.source, _use_dest=False)
        self.merge._mappings_to_fields(self.merge.destination, _use_dest=True)


    def mappings_do_on_delete(self, _g_mappings, _item_frame):
        """Triggered if the "del"-button has been clicked"""
        self.merge.mappings.remove(_item_frame.fr_item.mapping)

    def mappings_do_on_move_up(self, _g_mappings, _item_frame):
        """Triggered if the up arrow-button has been clicked"""
        _curr_idx = self.merge.mappings.index(_item_frame.fr_item.mapping)
        self.merge.mappings.insert(_curr_idx - 1, self.merge.mappings.pop(_curr_idx))

    def mappings_do_on_move_down(self, _g_mappings, _item_frame):
        """Triggered if the down arrow-button has been clicked"""
        _curr_idx = self.merge.mappings.index(_item_frame.fr_item.mapping)
        self.merge.mappings.insert(_curr_idx + 1, self.merge.mappings.pop(_curr_idx))

    def on_append_mapping(self, *args):
        """Triggered if the "Append mapping"-button has been clicked."""
        _new_mapping = Mapping()
        self.merge.mappings.append(_new_mapping)
        _new_item = self.g_mappings.append_item()
        _new_item.make_item(_class=FrameMapping, _mapping=_new_mapping,
                            _on_get_source_references=self.get_source_references,
                            _on_get_destination_references=self.get_destination_references)


    def mappings_do_on_detail(self, _g_mappings, _item_frame):
        self.notify_task("", 0)
        if self.curr_mapping_frame:
            self.gui_to_transformations()
        self.g_transformations.clear()
        for _curr_transformation in _item_frame.fr_item.mapping.transformations:

            _frame_class = self._transformation_frame_class_lookup(_curr_transformation)
            if _frame_class:
                _new_item = self.g_transformations.append_item()
                _new_item.make_item(_class=_frame_class, _transformation=_curr_transformation)
        _item_frame['background'] = "dark grey"

        try:
            if _item_frame.fr_item.curr_raw_data is not None:
                perform_transformations(_input=_item_frame.fr_item.curr_raw_data,
                                        _transformations=_item_frame.fr_item.mapping.transformations)
        except Exception as e:
            self.notify_task(
                'Error in one of the transformations, mapping: ' + _item_frame.fr_item.mapping.src_reference + " error: " + str(
                    e), 0)

        if self.curr_mapping_frame:
            try:
                self.curr_mapping_frame['background'] = self['background']
            except Exception as e:
                raise Exception("Error setting background to: " + self['background'] + ":" + str(e))
        self.curr_mapping_frame = _item_frame

    ##########################################################
    # This section contains functions handling transformations
    ##########################################################
    def gui_to_transformations(self):
        """Gathers data from GUI into the transformation objects"""

        for _curr_transformation in self.g_transformations.items:
            _curr_transformation.fr_item.gui_to_transformation()


    def _transformation_frame_class_lookup(self, _transformation=None, _type=None):
        if _type is None:
            _type, _desc = transformation_to_type(_transformation)

        if _type == "Cast":
            return FrameTransformationCast
        if _type == "Trim":
            return FrameTransformationTrim
        if _type == "If empty":
            return FrameTransformationIfEmpty
        if _type == "Replace":
            return FrameTransformationReplace
        if _type == "Replace regex":
            return FrameTransformationReplaceRegex
        else:
            return None
            #raise Exception("Internal error, unsupported transformation type: " + str(_transformation_type))

    def transformations_do_on_delete(self, _g_transformations, _item_frame):
        self.curr_mapping_frame.fr_item.mapping.transformations.remove(_item_frame.fr_item.transformation)

    def transformations_do_on_move_up(self, _g_transformations, _item_frame):
        _curr_transformations = self.curr_mapping_frame.fr_item.mapping.transformations
        _curr_idx = _curr_transformations.index(_item_frame.fr_item.transformation)
        _curr_transformations.insert(_curr_idx - 1,
                                     _curr_transformations.pop(
                                         _curr_idx))

    def transformations_do_on_move_down(self, _g_transformations, _item_frame):
        _curr_transformations = self.curr_mapping_frame.fr_item.mapping.transformations
        _curr_idx = _curr_transformations.index(_item_frame.fr_item.transformation)
        _curr_transformations.insert(_curr_idx + 1,
                                     _curr_transformations.pop(
                                         _curr_idx))

    def on_append_transformation(self, *args):
        if self.curr_mapping_frame is not None:
            _new_transformation = type_to_transformation(self.sel_transformation_append_type.get())(
                _substitution=self.curr_mapping_frame.fr_item.mapping.substitution)
            self.curr_mapping_frame.fr_item.mapping.transformations.append(_new_transformation)
            _frame_class = self._transformation_frame_class_lookup(_new_transformation)
            if _frame_class:
                _new_item = self.g_transformations.append_item()
                _new_item.make_item(_class=_frame_class, _transformation=_new_transformation)

    def clear_transformation_events(self):
        for _curr_mapping in self.merge.mappings:
            for _curr_transformation in _curr_mapping.transformations:
                _curr_transformation.on_done = None

    ############################################################
    # This section contains functions handling the merge preview
    ############################################################

    def clear_preview(self):
        for _curr_item in self.gr_preview.get_children():
            self.gr_preview.delete(_curr_item)

    def reset_substitions_identity(self):
        """Reset substitions"""

        for _curr_mapping in self.merge.mappings:
            _curr_mapping.substitution.set_identity(0)

    def on_preview_merge(self, *args):
        self.do_merge(_commit=False)

    def on_commit_merge(self, *args):
        if askokcancel(title="Warning: committing merge", message="This will commit actual changes to the destination, "
                                                                  "do you want to proceed?") is True:
            self.do_merge(_commit=True)

    def do_merge(self, _commit=False):
        self._gui_to_merge()
        self.update_data(_refresh=True)
        self.merge.destination_log_level = DATASET_LOGLEVEL_DETAIL
        # Clear GUI events
        self.clear_transformation_events()
        self.merge.clear_log()
        try:
            _data_table, _log, _deletes, _inserts, _updates = self.merge.execute(_commit=_commit)
        except Exception as e:
            self.notify_messagebox("Error while merging", str(e))
            return

        # Call columns src/dest field names if they differ

        if len(self.merge.key_fields) > 0:
            _key_field = self.merge.key_fields[0]
        else:
            _key_field = 0

        self.clear_preview()

        self.gr_preview["columns"] = ["Change_Data"]
        self.gr_preview.column("Change_Data", width=500)

        self.gr_preview.heading("Change_Data", text="Change/Data")

        # Add a main for each action

        # Add deletes
        self.gr_preview.insert(parent="", index="end", iid="obpm_deletes", text="Deletes")
        if self.merge.delete:
            for _curr_row in _deletes:
                _curr_item_idx = self.gr_preview.insert(parent="obpm_deletes", index="end", iid="",
                                                        text=_curr_row[2][_key_field])
                _curr_value = ",".join([str(_item) for _item in _curr_row[2]])
                self.gr_preview.item(_curr_item_idx, values=[_curr_value])
                for _curr_column_idx in range(len(_curr_row[2])):
                    _curr_change_item_idx = self.gr_preview.insert(parent=_curr_item_idx, index="end", iid="", text=str(
                        self.merge.destination.field_names[_curr_column_idx]))
                    self.gr_preview.item(_curr_change_item_idx, values=[str(_curr_row[2][_curr_column_idx])])
        # Add inserts
        self.gr_preview.insert(parent="", index="end", iid="obpm_inserts", text="Inserts")
        if self.merge.insert:
            for _curr_row in _inserts:
                _curr_item_idx = self.gr_preview.insert(parent="obpm_inserts", index="end", iid="",
                                                        text=_curr_row[2][_key_field])
                _curr_value = ",".join([str(_item) for _item in _curr_row[2]])
                self.gr_preview.item(_curr_item_idx, values=[_curr_value])
                for _curr_column_idx in range(len(_curr_row[2])):
                    _curr_change_item_idx = self.gr_preview.insert(parent=_curr_item_idx, index="end", iid="", text=str(
                        self.merge.destination.field_names[_curr_column_idx]))
                    self.gr_preview.item(_curr_change_item_idx, values=[str(_curr_row[2][_curr_column_idx])])
        # Add updates
        self.gr_preview.insert(parent="", index="end", iid="obpm_updates", text="Updates")
        if self.merge.update:
            for _curr_row in _updates:
                _curr_item_idx = self.gr_preview.insert(parent="obpm_updates", index="end", iid="",
                                                        text=_curr_row[2][_key_field])
                _changes = []
                for _curr_column_idx in range(len(_curr_row[2])):
                    if _curr_row[2][_curr_column_idx] != _curr_row[3][_curr_column_idx]:
                        _curr_change_item_idx = self.gr_preview.insert(parent=_curr_item_idx, index="end", iid="",
                                                                       text=str(self.merge.destination.field_names[
                                                                           _curr_column_idx]))
                        self.gr_preview.item(_curr_change_item_idx, values=[
                            str(_curr_row[3][_curr_column_idx]) + "=>" + str(_curr_row[2][_curr_column_idx])])
                        _changes.append(str(self.merge.destination.field_names[_curr_column_idx]))
                _curr_value = ",".join([str(_item) for _item in _changes])
                self.gr_preview.item(_curr_item_idx, values=[_curr_value])

        # Add log
        self.gr_preview.insert(parent="", index="end", iid="obpm_log", text="Log")
        if _log is not None:
            for _curr_row in _log:
                _log_fields = _curr_row.split(";")
                _curr_item_idx = self.gr_preview.insert(parent="obpm_log", index="end", iid="", text=_log_fields[0])
                _curr_value = ",".join([unquote(str(_item)) for _item in _log_fields[1:]])
                self.gr_preview.item(_curr_item_idx, values=[_curr_value])

        # Add data table

        self.gr_preview.insert(parent="", index="end", iid="obpm_data_table", text="Result")
        if _data_table is not None:
            for _curr_row in _data_table:
                _curr_item_idx = self.gr_preview.insert(parent="obpm_data_table", index="end", iid="",
                                                        text=_curr_row[_key_field])
                _curr_value = ",".join([str(_item) for _item in _curr_row])
                self.gr_preview.item(_curr_item_idx, values=[_curr_value])
                for _curr_column_idx in range(len(_curr_row)):
                    _curr_change_item_idx = self.gr_preview.insert(parent=_curr_item_idx, index="end", iid="", text=str(
                        self.merge.destination.field_names[_curr_column_idx]))
                    self.gr_preview.item(_curr_change_item_idx, values=[str(_curr_row[_curr_column_idx])])
        if _commit == True:
            _simulation_expression = "Merge"
        else:
            _simulation_expression = "Simulated merge"

        if not (self.merge.insert or self.merge.delete or self.merge.update):
            self.notify_task(
                _simulation_expression + " done. (Expecting merge results? Neither insert, delete or update is selected)",
                100)
        else:
            self.notify_task(_simulation_expression + " done.", 100)

    def on_preview_selected(self, *args):
        _selection = self.gr_preview.selection()
        if len(_selection) > 0:
            _item = self.gr_preview.item(_selection[0])
            self.preview_detail.set(str(",".join([str(_item) for _item in _item["values"]])))