class model_select(Frame):
    def __init__(self,controller,model_list,current_model,master,*args,**kwargs):
        self.controller = controller
        self.model_list = model_list
        self.current_model = current_model

        # Dibujar widget
        super().__init__(master, *args, **kwargs)
        self.listbox = Listbox(self, exportselection=False)
        self.listbox.bind('<<ListboxSelect>>', self.selection)
        self.listbox.pack()

        for item in self.model_list:
            self.listbox.insert(END, item)

        self.listbox.select_set(0)
        self.listbox.event_generate("<<ListboxSelect>>")

    def selection(self,x):
        w = x.widget
        index = int(w.curselection()[0])
        value = w.get(index)
        print(value)

        # Send message to interface to load another model
        f_path = os.path.join(config_folder, value)
        self.current_model.change_model(f_path)
        self.controller.event_change_model(self.current_model)
        pass
示例#2
0
def openStats(handler):
    statsApi = get(
        "https://raw.githubusercontent.com/revoxhere/duco-statistics/master/api.json",
        data=None)
    if statsApi.status_code == 200:  #Check for reponse
        statsApi = (statsApi.json())
        print(statsApi)

    statsWindow = Toplevel()
    statsWindow.resizable(False, False)
    statsWindow.title("Duino-Coin Wallet - Stats")
    statsWindow.configure(background=backgroundColor)
    statsWindow.transient([root])

    textFont3 = Font(statsWindow, size=14, weight="bold")
    textFont = Font(statsWindow, size=12, weight="normal")

    Label(statsWindow,
          text="Duco Statistics - WIP",
          background=backgroundColor,
          foreground=foregroundColor,
          font=textFont3).grid(row=0, column=0)

    Active_workers_listbox = Listbox(statsWindow,
                                     exportselection=False,
                                     background=backgroundColor,
                                     foreground=foregroundColor,
                                     selectbackground="#7bed9f",
                                     border="0",
                                     font=textFont,
                                     width="20",
                                     height="13")
    Active_workers_listbox.grid(row=1, column=0, sticky=W)
    i = 0
    for worker in statsApi['Active workers']:
        Active_workers_listbox.insert(i, worker)
        i += 1

    Active_workers_listbox.select_set(32)
    Active_workers_listbox.event_generate("<<ListboxSelect>>")

    Top_10_listbox = Listbox(statsWindow,
                             exportselection=False,
                             background=backgroundColor,
                             foreground=foregroundColor,
                             selectbackground="#7bed9f",
                             border="0",
                             font=textFont,
                             width="33",
                             height="13")
    Top_10_listbox.grid(row=1, column=1, sticky=W)
    i = 0
    for rich in statsApi['Top 10 richest miners']:
        Top_10_listbox.insert(i, statsApi['Top 10 richest miners'][i])
        i += 1

    Top_10_listbox.select_set(32)
    Top_10_listbox.event_generate("<<ListboxSelect>>")

    statsWindow.mainloop()
示例#3
0
class HelpWindow(Toplevel):
    def __init__(self, master=None):
        super().__init__(master)
        self.root = master
        self.title = 'Help'
        self.list = Listbox(self)
        self.list.pack(side="left", fill="y")
        self.text = scrolledtext.ScrolledText(self, wrap=WORD)
        self.text.pack(side="right", fill="both", expand=True)
        self.images = []
        self.load_list()
        self.list.bind('<<ListboxSelect>>', self.list_click)
        self.list.select_set(0)
        self.list_click(None)

    def load_list(self):
        self.files = {}

        path = os.path.dirname(os.path.realpath(__file__))
        file_path = os.path.join(path, 'index.json')
        f = open(file_path, 'rt')
        self.files = json.loads(f.read())
        for counter, entry in enumerate(self.files['files']):
            self.list.insert(counter, entry['name'])
        f.close()

    def list_click(self, event):
        index = self.list.curselection()[0]
        item = self.files['files'][index]
        path = os.path.dirname(os.path.realpath(__file__))
        fileName = os.path.normpath(os.path.join(path, item['fileName']))
        self.render_file(fileName)

    def render_file(self, fileName):
        path = os.path.dirname(os.path.realpath(__file__))
        f = open(os.path.join(fileName), 'rt')
        buffer = f.read()
        f.close()
        parser = MarkdownParser()
        tokens = parser.parse(buffer)
        renderer = MarkdownRenderTk(self.text)
        renderer.render(tokens, os.path.normpath(os.path.join(path, '../res')),
                        self.images, self.link_click)

    def link_click(self, url, title):
        if (url.startswith('http:') or url.startswith('https:')):
            # Open a web browser with that link.
            webbrowser.open(url)
        else:
            # Open a markdown file.
            path = os.path.dirname(os.path.realpath(__file__))
            fileName = os.path.normpath(os.path.join(path, url))
            self.render_file(fileName)
示例#4
0
class PRGListBox(Frame):
    def __init__(self, master=None,**args):
        Frame.__init__(self, master,**args)
        scrollbar = Scrollbar(self, orient=VERTICAL) #нужен для отображения длинных списков
        scrollbar.unbind("<Key-Up>")
        scrollbar.unbind("<Key-Down>")
        scrollbar.unbind("<Key-Left>")
        scrollbar.unbind("<Key-Right>")
        scrollbar.pack(side=RIGHT, fill=Y)
        
        self.lst = Listbox(self, yscrollcommand=scrollbar.set, bg="grey", selectmode=SINGLE) 
        self.lst.insert(END,"Hide All")
        self.lst.insert(END,"Show All")
        self.lst.select_set(0)
        self.lst.pack(side=LEFT, fill=BOTH, expand=1)
        
        scrollbar.config(command=self.lst.yview)
class mask_select(Frame):
    def __init__(self, controller, current_model : model_manager_obj, master, *args, **kwargs):
        self.controller = controller


        super().__init__(master, *args, **kwargs)
        self.listbox = Listbox(self, exportselection=False)
        self.listbox.pack(fill="both", expand=True)
        self.listbox.bind("<<ListboxSelect>>",self.selection)
        Label(self,text="New mask file: ").pack()
        self.entry_text = StringVar()
        Entry(self,textvariable=self.entry_text).pack()
        Button(self,text='Create',command=self.add_new).pack()

        self.update_model(current_model)


    def update_model(self, current_model):
        self.model = current_model
        self.mask_file_list = self.model.get_mask_file_list()
        self.current_mask_file=self.model.get_current_mask_file()

        self.listbox.delete(0, END)
        for item in self.mask_file_list:
            self.listbox.insert(END, item)
        self.listbox.select_set(0)
        self.listbox.event_generate("<<ListboxSelect>>")

    def selection(self,event):
        w = event.widget
        index = int(w.curselection()[0])
        value = w.get(index)
        selected = value
        self.controller.event_change_mask_file(selected)
        pass

    def add_new(self):
        new = self.entry_text.get()
        self.controller.event_add_mask_file(new)
        pass
示例#6
0
class ReloadOption(Toplevel):
    def __init__(self):
        super().__init__()
        self.title('重载设置')
        self.reload_mode = None
        self.label = Label(self, text="请选择重新加载的范围:")
        self.lb = Listbox(self, width=40)
        self.fm = Frame(self)
        self.ok = Button(self.fm, text="重载", command=self.select_mode)
        self.cancel = Button(self.fm, text="取消", command=self.destroy)
        for item in ['最近一周', '最近一个月', '最近三个月', '最近半年', '最近一年', '全部重载']:
            self.lb.insert(END, item)
        self.lb.select_set(5)
        self.label.pack(side='top')
        self.lb.pack(side='top', fill='both', expand='YES')
        self.fm.pack(side='top')
        self.ok.pack(side='left')
        self.cancel.pack(side='right')

    def select_mode(self):
        self.reload_mode = self.lb.get(self.lb.curselection())
        self.destroy()
示例#7
0
class GuiTestManager(Tk):
    """Manager for GUI tests. Use `add_test` method to add a test class."""
    def __init__(self):
        """Initialise manager."""
        Tk.__init__(self)
        self.title("GUI Test Manager")
        self.geometry("400x300")

        ## Dictionary of Toplevel tests who are current active.
        self.active_tests = {}

        ## List of all available test classes.
        self.all_tests = []

        # Create widgets to show list of available tests.
        Label(self, text="Available Tests",
              font=("Comic Sans MS", "24")).pack(padx=3, pady=3)

        Label(self,
              text="Click a test to open it, and again to close it.",
              font=["Comic Sans MS"]).pack()

        # Create container for listbox and scrollbar.
        list_frame = Frame(self)
        list_frame.pack(fill="both", expand=1, padx=3, pady=3)

        # Add scrollbar for Listbox.
        list_scrollbar = Scrollbar(list_frame, orient="vertical")
        list_scrollbar.pack(side="right", fill="y")

        # Create Listbox next to scrollbar.
        self.all_tests_list = Listbox(list_frame,
                                      selectmode="multiple",
                                      yscrollcommand=list_scrollbar.set,
                                      selectborderwidth=5,
                                      font=("Comic Sans MS", "16", "italic"),
                                      activestyle="none",
                                      takefocus=1,
                                      cursor="pirate")
        # Bind the event for 0ms after a click, so the listbox can process first.
        self.all_tests_list.bind(
            "<ButtonPress-1>",
            lambda e: self.after(0, lambda e=e: self.on_test_list_pressed(e)))
        self.all_tests_list.pack(side="left", fill="both", expand=1)

        # Link scrollbar and listbox scroll commands.
        list_scrollbar.config(command=self.all_tests_list.yview)

        # Perform initial refresh.
        self.refresh_available()

    def add_test(self, test_class):
        """
        Add a GUI test class to the test manager. Will do nothing if already
        added this test.
        """
        if test_class in self.all_tests:
            return
        self.all_tests.append(test_class)
        self.refresh_available()

    def refresh_available(self):
        """Refresh list of available tests."""

        # Delete old options.
        old_selection = self.all_tests_list.curselection()
        self.all_tests_list.delete(0, "end")

        # Show new options in Listbox from set.
        for test_class in self.all_tests:
            self.all_tests_list.insert("end", test_class.get_test_name())

        # Maintain previous selection.
        for i in old_selection:
            self.all_tests_list.select_set(i)

    def on_test_list_pressed(self, event):
        """Called when mouse button 1 pressed on all_tests_list"""

        # All selected indexes.
        now_selected = set(self.all_tests_list.curselection())

        # Check all options in Listbox.
        for i, test_class in enumerate(self.all_tests):

            if i in now_selected and i not in self.active_tests:

                # Index has been newly selected. Make the widget.
                new_wgt = test_class(self)
                new_wgt.protocol("WM_DELETE_WINDOW",
                                 lambda i=i: self.on_toplevel_destroyed(i))
                self.active_tests[i] = new_wgt

            elif i not in now_selected and i in self.active_tests:

                # Index has been newly deselected. Destroy the widget.
                self.active_tests.pop(i).destroy()

    def on_toplevel_destroyed(self, index):
        """Called when initialised test window is manually destroyed."""
        self.active_tests.pop(index).destroy()
        self.all_tests_list.select_clear(index)
示例#8
0
class PCRLibrarianApp(Tk):
    """
    Main window for thePCR Librarian app
    """
    def __init__(self):
        super(PCRLibrarianApp, self).__init__()

        # Screen metrics
        sw = self.winfo_screenwidth()
        sh = self.winfo_screenheight()

        # TODO Position and size main window
        self.title("PCR Librarian")

        # ttk theme
        # s = ttk.Style()
        # s.theme_use('classic')
        self.background_color = "#ffffff"
        self.highlight_color = "#e0e0e0"

        # Create window widgets
        self._create_widgets(sw, sh)

        # Size the main window according to its contents
        self.update()
        w = self.winfo_width()
        h = self.winfo_height()
        # Centered
        x = int((sw - w) / 2)
        y = int((sh - h) / 2)
        # width x height + x + y
        geo = "{0}x{1}+{2}+{3}".format(w, h, x, y)
        self.geometry(geo)
        # self.resizable(width=True, height=True)
        self.resizable(width=True, height=False)

        # Handle app exit
        self.protocol("WM_DELETE_WINDOW", self._on_close)

        # Restore last used directory
        self._set_directory(Configuration.get_last_recent())

    def _create_widgets(self, sw, sh):
        """
        Create the UI widgets
        :param sw: Screen width
        :param sh: Screen height
        :return:
        """
        MIN_WIDTH = 100

        # Create a menu bar for the current OS
        self._create_menu()

        # Control/widget experimentation
        self.config(padx=10)
        self.config(pady=10)

        # Around control map directory widgets
        self._ctrl_frame = LabelFrame(master=self,
                                      padx=10,
                                      pady=10,
                                      text="Control Map Directory")
        self._ctrl_frame.grid(row=0, column=0, sticky="ew")

        # Container for action buttons
        self._button_frame = Frame(master=self, bd=5, padx=5, pady=5)
        self._button_frame.grid(row=2, column=0, pady=5)

        self.columnconfigure(0, weight=1, minsize=MIN_WIDTH)
        self._ctrl_frame.columnconfigure(0, weight=1)

        # Control frame row tracker
        r = 0

        # Directory entry
        self._ent_directory = Entry(master=self._ctrl_frame, width=MIN_WIDTH)
        self._ent_directory.grid(row=r, column=0, sticky="ew")
        r += 1

        # Frame for directory widgets
        self._fr_dir = Frame(master=self._ctrl_frame)

        # Select a directory
        self._btn_dir_button = Button(master=self._fr_dir,
                                      text="Select Control Map Directory",
                                      command=self._on_select_directory)
        self._btn_dir_button.grid(row=0, column=0, padx=5, pady=5)

        # Recently used directories
        self._cb_recent_dirs = Combobox(master=self._fr_dir,
                                        width=50,
                                        values=Configuration.get_recent())
        self._cb_recent_dirs.grid(row=0, column=1, padx=5, pady=5)
        self._cb_recent_dirs.bind("<<ComboboxSelected>>",
                                  self._on_recent_directory)

        self._fr_dir.grid(row=r, column=0, padx=10)
        r += 1

        # Control map file listbox with scrollbar
        self._lb_frame = LabelFrame(self._ctrl_frame,
                                    text="Control Map Files",
                                    pady=5,
                                    padx=5)
        self._lb_scrollbar = Scrollbar(self._lb_frame, orient=tkinter.VERTICAL)
        self._lb_filelist = Listbox(master=self._lb_frame, width=100)
        self._lb_scrollbar.config(command=self._lb_filelist.yview)
        self._lb_scrollbar.pack(side=tkinter.RIGHT, fill=tkinter.Y)
        self._lb_filelist.pack()
        self._lb_frame.grid(row=r, column=0, pady=5)
        r += 1

        # Action buttons are inside the button frame on one row

        self._btn_receive_current_button = Button(
            master=self._button_frame,
            text="Receive Current Map",
            state=tkinter.DISABLED,
            command=self._on_receive_current_map)
        self._btn_receive_current_button.grid(row=0, column=0, padx=5)

        self._btn_receive_all_button = Button(
            master=self._button_frame,
            text="Receive All Maps",
            state=tkinter.DISABLED,
            command=self._on_receive_all_maps)
        self._btn_receive_all_button.grid(row=0, column=1, padx=5)

        self._btn_send_button = Button(master=self._button_frame,
                                       text="Send Control Map Files",
                                       state=tkinter.DISABLED,
                                       command=self._on_send)
        self._btn_send_button.grid(row=0, column=2, padx=5)

        self._btn_quit_button = Button(master=self._button_frame,
                                       text="Quit",
                                       command=self._on_close)
        self._btn_quit_button.grid(row=0, column=3, padx=5)

        # MIDI in/out ports listboxes
        self._lb_midiports_frame = LabelFrame(self,
                                              text="MIDI Ports",
                                              pady=5,
                                              padx=5)

        self._lbl_inports = Label(master=self._lb_midiports_frame, text="In")
        self._lb_midiin_ports = Listbox(master=self._lb_midiports_frame,
                                        width=30,
                                        height=5,
                                        selectmode=tkinter.SINGLE,
                                        exportselection=0)
        self._lbl_inports.grid(row=0, column=0)
        self._lb_midiin_ports.grid(row=1, column=0, padx=5, pady=5)

        self._lbl_outports = Label(master=self._lb_midiports_frame, text="Out")
        self._lb_midiout_ports = Listbox(master=self._lb_midiports_frame,
                                         width=30,
                                         height=5,
                                         selectmode=tkinter.SINGLE,
                                         exportselection=0)
        self._lbl_outports.grid(row=0, column=1)
        self._lb_midiout_ports.grid(row=1, column=1, padx=5, pady=5)

        self._lb_midiports_frame.grid(row=1, column=0, pady=5)

        # Populate midin ports listbox
        self._in_ports = get_midiin_ports()
        for p in self._in_ports:
            self._lb_midiin_ports.insert(tkinter.END, p)

        # Populate midout ports listbox
        self._out_ports = get_midiout_ports()
        for p in self._out_ports:
            self._lb_midiout_ports.insert(tkinter.END, p)

        # Minimize the height of the ports listboxes
        max_height = max(len(self._in_ports), len(self._out_ports))
        self._lb_midiin_ports.config(height=max_height)
        self._lb_midiout_ports.config(height=max_height)

        # Default midi port selections
        self._lb_midiin_ports.select_set(0)
        self._lb_midiout_ports.select_set(0)

        # Status bar
        self._v_statusbar = StringVar(value="Select control map directory")
        self._lbl_statusbar = Label(master=self,
                                    textvariable=self._v_statusbar,
                                    bd=5,
                                    relief=tkinter.RIDGE,
                                    anchor=tkinter.W)
        self._lbl_statusbar.grid(row=3, column=0, pady=5, padx=5, sticky="ew")

        # Put the focus in the directory text box
        self._ent_directory.focus_set()

    def _create_menu(self):
        # will return x11 (Linux), win32 or aqua (macOS)
        gfx_platform = self.tk.call('tk', 'windowingsystem')

        # App menu bar
        self._menu_bar = Menu(self)

        if gfx_platform == "aqua":
            # macOS app menu covering things specific to macOS X
            self._appmenu = Menu(self._menu_bar, name='apple')
            self._appmenu.add_command(label='About PCR Librarian',
                                      command=self._show_about)
            self._appmenu.add_separator()
            self._menu_bar.add_cascade(menu=self._appmenu,
                                       label='PCRLibrarian')

            self.createcommand('tk::mac::ShowPreferences',
                               self._show_preferences)

            filemenu = Menu(self._menu_bar, tearoff=0)
            filemenu.add_command(label="Clear recent directories list",
                                 command=self._on_clear_recent)
            self._menu_bar.add_cascade(label="File", menu=filemenu)
        elif gfx_platform in ["win32", "x11"]:
            # Build a menu for Windows or Linux
            filemenu = Menu(self._menu_bar, tearoff=0)
            filemenu.add_command(label="Clear recent directories list",
                                 command=self._on_clear_recent)
            filemenu.add_separator()
            filemenu.add_command(label="Exit", command=self._on_close)
            self._menu_bar.add_cascade(label="File", menu=filemenu)

            helpmenu = Menu(self._menu_bar, tearoff=0)
            helpmenu.add_command(label="About", command=self._show_about)
            self._menu_bar.add_cascade(label="Help", menu=helpmenu)

        self.config(menu=self._menu_bar)

    def _set_statusbar(self, text):
        """
        Update the status bar
        :param text:
        :return:
        """
        self._v_statusbar.set(text)
        # Force the widget to update now
        self._lbl_statusbar.update()

    def _on_recent_directory(self, event=None):
        directory = self._cb_recent_dirs.get()
        self._set_directory(directory)

        self._set_statusbar("Ready")

    def _on_select_directory(self):
        """
        Select a directory as the source or target of control map(s)
        :return:
        """
        directory = filedialog.askdirectory(
            initialdir=os.getcwd(), title="Select source/target directory")
        self._set_directory(directory)

        self._set_statusbar("Ready")

    def _on_clear_recent(self):
        Configuration.clear_recent()
        self._cb_recent_dirs.config(values=Configuration.get_recent())

    def _set_directory(self, directory):
        if directory:
            Configuration.set_recent(directory)

            self._ent_directory.delete(0, tkinter.END)
            self._ent_directory.insert(0, directory)

            self._load_files()

            self._btn_receive_current_button["state"] = tkinter.NORMAL
            self._btn_receive_all_button["state"] = tkinter.NORMAL

            self._fill_files_listbox()
            self._cb_recent_dirs.config(values=Configuration.get_recent())

    def _on_send(self):
        """
        Send control map(s). Sends all .syx files from selected directory.
        :return:
        """
        selected_port = self._lb_midiout_ports.curselection()
        dlg = SendDlg(self,
                      title="Send Control Map Sysex Files",
                      port=selected_port[0],
                      files=self._files)

    def _on_receive_current_map(self):
        self._set_statusbar("Ready to receive current control map")
        self._on_receive_control_maps(ReceiveDlg.SINGLE)

    def _on_receive_all_maps(self):
        self._set_statusbar("Ready to receive all 15 control maps")
        self._on_receive_control_maps(ReceiveDlg.ALL)

    def _on_receive_control_maps(self, count):
        # Delete existing .syx files
        self._delete_existing_files()

        selected_port = self._lb_midiin_ports.curselection()
        # Modal dialog box for receiving sysex messages from PCR
        dlg = ReceiveDlg(self,
                         title="Receive Current Control Map",
                         port=selected_port[0],
                         dir=self._ent_directory.get(),
                         control_map=count)

        dlg.begin_modal()

        if dlg.result:
            self._set_statusbar("Current control map(s) received")
        else:
            self._set_statusbar("Canceled")
        self._load_files()
        self._fill_files_listbox()

        del dlg

    def _delete_existing_files(self):
        """
        Delete existing .syx files
        :return:
        """
        for file in self._files:
            os.remove(file)
        self._files.clear()
        self._fill_files_listbox()

    def _load_files(self):
        """
        Load all of the .syx files in the selected directory
        :return:
        """
        self._files = []
        directory = self._ent_directory.get()
        self._files.extend(
            sorted([
                os.path.join(directory, fn) for fn in os.listdir(directory)
                if fn.lower().endswith('.syx')
            ]))
        if len(self._files) >= 50:
            self._btn_send_button["state"] = tkinter.NORMAL
        else:
            self._btn_send_button["state"] = tkinter.DISABLED

    def _fill_files_listbox(self):
        """
        Load the files listbox with all of the .syx files in the selected diretory
        :return:
        """
        self._lb_filelist.delete(0, tkinter.END)
        for f in self._files:
            self._lb_filelist.insert(tkinter.END, f)

    def _on_close(self):
        """
        App is closing. Warn user if unsaved changes.
        :return:
        """
        print(self._ent_directory.get())
        # Save the directory setting?
        Configuration.set_last_recent(self._ent_directory.get())
        # Essentially, this terminates the app by destroying the main window
        self.destroy()
        return True

    def _show_about(self):
        about_text = \
            "© 2020 by Dave Hocker\n" + \
            "\n" + \
            "Source: https://github.com/dhocker/pcr_librarian\n" + \
            "License: GNU General Public License v3\n" + \
            "as published by the Free Software Foundation, Inc. "

        # Locate logo image file
        cwd = os.path.realpath(
            os.path.abspath(
                os.path.split(inspect.getfile(inspect.currentframe()))[0]))
        if os.path.exists(cwd + "/pcr_librarian.gif"):
            image_path = cwd + "/pcr_librarian.gif"
        elif os.path.exists(cwd + "/resources/pcr_librarian.gif"):
            image_path = cwd + "/resources/pcr_librarian.gif"
        else:
            image_path = "pcr_librarian.gif"

        # This is a modal message box
        mb = TextMessageBox(self,
                            title="About PCR Librarian",
                            text=about_text,
                            heading="PCR Librarian {}".format(app_version()),
                            image=image_path,
                            width=150,
                            height=110,
                            orient=tkinter.HORIZONTAL)
        mb.show()
        self.wait_window(window=mb)

    def _show_preferences(self):
        tkinter.messagebox.showinfo("Preferences for PCR Librarian",
                                    "None currently defined")
示例#9
0
class SearchResultsWindow(BaseListMenu):

    # Window title
    TITLE = 'Search Results'

    def __init__(self, manga_scraper_obj: MangaReaderScraper):
        # call parent
        super().__init__(title=self.TITLE)
        # listbox
        self.list_box = Listbox(self.frame,
                                width=50,
                                selectmode='single',
                                yscrollcommand=self.scrollbar.set)
        # add data to listbox
        self.list_box.insert('end', *manga_scraper_obj._text_list_of_series)
        # default selection to first index
        self.list_box.select_set(0)
        # set scrollbar view to listbox
        self.scrollbar.config(command=self.list_box.yview)
        # pack scrollbar
        self.scrollbar.pack(side='right', fill='y')
        # set default icon
        self.iconbitmap(ICON_PATH)
        # pack frame
        self.frame.pack()
        # pack list box
        self.list_box.pack(pady=15)

        # inner method for when ok button is clicked
        def ok_btn_click(self, manga_scraper_obj, series_chosen):
            self.check(manga_scraper_obj, series_chosen)

        # OK Button
        self.ok_btn = Button(self,
                             text='OK',
                             command=lambda: ok_btn_click(
                                 self,
                                 manga_scraper_obj=manga_scraper_obj,
                                 series_chosen=self.list_box.selection_get()))
        self.ok_btn.pack(side='left', padx=(80, 10), pady=10)

        # Cancel Button
        self.cancel_btn = Button(self,
                                 text='Cancel',
                                 command=lambda: self.destroy())
        self.cancel_btn.pack(side='right', padx=(10, 80), pady=10)

    def check(self, manga_scraper_obj, series_chosen):
        if series_chosen is not None:
            # Set series attribute for manga scraper
            manga_scraper_obj.series = series_chosen
            # Initialize chapter list window
            chapter_results = ChapterListWindow(
                prior_window=self, manga_scraper_obj=manga_scraper_obj)
            chapter_results.focus_force()
            self.grab_release()
            chapter_results.grab_set()

        else:
            # Notify that a series hasn't been selected yet.
            messagebox.showinfo(title='Please select',
                                message='No series selected.')
示例#10
0
class FileChoice(object):
    def __init__(self,
                 master=None,
                 title=None,
                 prefix=None,
                 list=[],
                 start='',
                 ext="txt",
                 new=False):
        self.master = master
        self.value = None
        self.prefix = prefix
        self.list = list
        if prefix and start:
            self.start = relpath(start, prefix)
        else:
            self.start = start
        self.ext = ext
        self.new = new

        self.modalPane = Toplevel(self.master,
                                  highlightbackground=BGCOLOR,
                                  background=BGCOLOR)
        if master:
            logger.debug('winfo: {0}, {1}; {2}, {3}'.format(
                master.winfo_rootx(), type(master.winfo_rootx()),
                master.winfo_rooty(), type(master.winfo_rooty())))
            self.modalPane.geometry(
                "+%d+%d" %
                (master.winfo_rootx() + 50, master.winfo_rooty() + 50))

        self.modalPane.transient(self.master)
        self.modalPane.grab_set()

        self.modalPane.bind("<Return>", self._choose)
        self.modalPane.bind("<Escape>", self._cancel)

        if title:
            self.modalPane.title(title)

        if new:
            nameFrame = Frame(self.modalPane,
                              highlightbackground=BGCOLOR,
                              background=BGCOLOR)
            nameFrame.pack(side="top", padx=18, pady=2, fill="x")

            nameLabel = Label(nameFrame,
                              text=_("file:"),
                              bd=1,
                              relief="flat",
                              anchor="w",
                              padx=0,
                              pady=0,
                              highlightbackground=BGCOLOR,
                              background=BGCOLOR)
            nameLabel.pack(side="left")

            self.fileName = StringVar(self.modalPane)
            self.fileName.set("untitled.{0}".format(ext))
            self.fileName.trace_variable("w", self.onSelect)
            self.fname = Entry(nameFrame,
                               textvariable=self.fileName,
                               bd=1,
                               highlightbackground=BGCOLOR)
            self.fname.pack(side="left", fill="x", expand=1, padx=0, pady=0)
            self.fname.icursor(END)
            self.fname.bind("<Up>", self.cursorUp)
            self.fname.bind("<Down>", self.cursorDown)

        filterFrame = Frame(self.modalPane,
                            highlightbackground=BGCOLOR,
                            background=BGCOLOR)
        filterFrame.pack(side="top", padx=18, pady=4, fill="x")

        filterLabel = Label(filterFrame,
                            text=_("filter:"),
                            bd=1,
                            relief="flat",
                            anchor="w",
                            padx=0,
                            pady=0,
                            highlightbackground=BGCOLOR,
                            background=BGCOLOR)
        filterLabel.pack(side="left")

        self.filterValue = StringVar(self.modalPane)
        self.filterValue.set("")
        self.filterValue.trace_variable("w", self.setMatching)
        self.fltr = Entry(filterFrame,
                          textvariable=self.filterValue,
                          bd=1,
                          highlightbackground=BGCOLOR)
        self.fltr.pack(side="left", fill="x", expand=1, padx=0, pady=0)
        self.fltr.icursor(END)

        prefixFrame = Frame(self.modalPane,
                            highlightbackground=BGCOLOR,
                            background=BGCOLOR)
        prefixFrame.pack(side="top", padx=8, pady=2, fill="x")

        self.prefixLabel = Label(prefixFrame,
                                 text=_("{0}:").format(prefix),
                                 bd=1,
                                 highlightbackground=BGCOLOR,
                                 background=BGCOLOR)
        self.prefixLabel.pack(side="left", expand=0, padx=0, pady=0)

        buttonFrame = Frame(self.modalPane,
                            highlightbackground=BGCOLOR,
                            background=BGCOLOR)
        buttonFrame.pack(side="bottom", padx=10, pady=2)

        chooseButton = Button(buttonFrame,
                              text="Choose",
                              command=self._choose,
                              highlightbackground=BGCOLOR,
                              background=BGCOLOR,
                              pady=2)
        chooseButton.pack(side="right", padx=10)

        cancelButton = Button(buttonFrame,
                              text="Cancel",
                              command=self._cancel,
                              highlightbackground=BGCOLOR,
                              background=BGCOLOR,
                              pady=2)
        cancelButton.pack(side="left")

        selectionFrame = Frame(self.modalPane,
                               highlightbackground=BGCOLOR,
                               background=BGCOLOR)
        selectionFrame.pack(side="bottom", padx=8, pady=2, fill="x")

        self.selectionValue = StringVar(self.modalPane)
        self.selectionValue.set("")
        self.selection = Label(selectionFrame,
                               textvariable=self.selectionValue,
                               bd=1,
                               highlightbackground=BGCOLOR,
                               background=BGCOLOR)
        self.selection.pack(side="left", fill="x", expand=1, padx=0, pady=0)

        listFrame = Frame(self.modalPane,
                          highlightbackground=BGCOLOR,
                          background=BGCOLOR,
                          width=40)
        listFrame.pack(side="top", fill="both", expand=1, padx=5, pady=2)

        scrollBar = Scrollbar(listFrame, width=8)
        scrollBar.pack(side="right", fill="y")
        self.listBox = Listbox(listFrame, selectmode=BROWSE, width=36)
        self.listBox.pack(side="left",
                          fill="both",
                          expand=1,
                          ipadx=4,
                          padx=2,
                          pady=0)
        self.listBox.bind('<<ListboxSelect>>', self.onSelect)
        self.listBox.bind("<Double-1>", self._choose)
        self.modalPane.bind("<Return>", self._choose)
        self.modalPane.bind("<Escape>", self._cancel)
        # self.modalPane.bind("<Up>", self.cursorUp)
        # self.modalPane.bind("<Down>", self.cursorDown)
        self.fltr.bind("<Up>", self.cursorUp)
        self.fltr.bind("<Down>", self.cursorDown)
        scrollBar.config(command=self.listBox.yview)
        self.listBox.config(yscrollcommand=scrollBar.set)
        self.setMatching()

    def ignore(self, e=None):
        return "break"

    def onSelect(self, *args):
        # Note here that Tkinter passes an event object to onselect()

        if self.listBox.curselection():
            firstIndex = self.listBox.curselection()[0]
            value = self.matches[int(firstIndex)]
            r = value[1]
            p = os.path.join(self.prefix, r)
            if self.new:
                if os.path.isfile(p):
                    p = os.path.split(p)[0]
                    r = os.path.split(r)[0]
                f = self.fileName.get()
                r = os.path.join(r, f)
                p = os.path.join(p, f)

            self.selectionValue.set(r)
            self.value = p
        return "break"

    def cursorUp(self, event=None):
        cursel = int(self.listBox.curselection()[0])
        newsel = max(0, cursel - 1)
        self.listBox.select_clear(cursel)
        self.listBox.select_set(newsel)
        self.listBox.see(newsel)
        self.onSelect()
        return "break"

    def cursorDown(self, event=None):
        cursel = int(self.listBox.curselection()[0])
        newsel = min(len(self.list) - 1, cursel + 1)
        self.listBox.select_clear(cursel)
        self.listBox.select_set(newsel)
        self.listBox.see(newsel)
        self.onSelect()
        return "break"

    def setMatching(self, *args):
        # disabled = "#BADEC3"
        # disabled = "#91CC9E"
        disabled = "#62B374"
        match = self.filterValue.get()
        if match:
            self.matches = matches = [
                x for x in self.list if x and match.lower() in x[1].lower()
            ]
        else:
            self.matches = matches = self.list
        self.listBox.delete(0, END)
        index = 0
        init_index = 0
        for item in matches:
            if type(item) is tuple:
                # only show the label
                # (label, value, disabled)FF
                self.listBox.insert(END, item[0])
                if self.new:
                    if not item[-1]:
                        self.listBox.itemconfig(index, fg=disabled)
                    else:
                        self.listBox.itemconfig(index, fg="blue")
                        if self.start and item[1] == self.start:
                            init_index = index
                else:
                    if item[-1]:
                        self.listBox.itemconfig(index, fg=disabled)
                    else:
                        self.listBox.itemconfig(index, fg="blue")
                        if self.start and item[1] == self.start:
                            init_index = index
            # elif files:
            else:
                self.listBox.insert(END, item)
            index += 1
        self.listBox.select_set(init_index)
        self.listBox.see(init_index)
        self.fltr.focus_set()
        self.onSelect()

    def _choose(self, event=None):
        try:
            if self.listBox.curselection():
                firstIndex = self.listBox.curselection()[0]
                if self.new:
                    if not self.value or os.path.isfile(self.value):
                        return
                else:
                    tup = self.matches[int(firstIndex)]
                    if tup[-1]:
                        return
                    self.value = os.path.join(self.prefix, tup[1])
            else:
                return
        except IndexError:
            self.value = None
        self.modalPane.destroy()

    def _cancel(self, event=None):
        self.value = None
        self.modalPane.destroy()

    def returnValue(self):
        self.master.wait_window(self.modalPane)
        return self.value
示例#11
0
class Window2(Frame):
    def __init__(self, parent, context):
        super(Window2, self).__init__(parent.Frame)
        context.add_observer(self)
        self.parent = parent
        self.context = context
        self.controller = parent.controller
        self._initialize()

        self.build()

    def _initialize(self):
        self.id = 'task'
        #画面遷移の順番を示す指示物
        self.unit_name_list = []

    def update(self, msg):
        self._gid = msg['gid']
        self.unit_name_list = _global_group[msg['gid'] - 1]

        self._update_unit_name_list()
        self.task_lbx.delete(0, END)

    def convert(self):

        units = self._task_box.get(0, END)
        if not units:
            self.context.notify('root', 'info', "처리할 작업이 없습니다.")
            return

        working_dir = self.context.get('directory')
        if not working_dir:
            self.context.directory()
            working_dir = self.context.get('directory')
            if not working_dir:
                messagebox.showwarning("경고", '작업디렉토리가 설정되어 있지 않습니다.')
                return

        # html변환여부 체크옵션
        _html = self.context.get('html')
        _gid = self._gid

        try:
            self.controller.convert(working_dir, _html, units, _gid)

            self.context.notify('root', 'info', "작업완료")
            messagebox.showinfo("알림", message="작업이 완료되었습니다.")

        except Exception as e:
            print(e)
            messagebox.showerror('포맷오류', '잘못된 포맷을 적용하였습니다.')
            self.context.notify('root', 'info', "작업오류")

    def build(self):
        componets = self.component_list()
        tasks = self.task_list()

        componets.pack(side="left", fill='y')
        componets.config(bg='steel blue3')
        tasks.pack(side='right', fill='both', expand=True)
        tasks.config(bg='light grey', padx=3)

    def _update_unit_name_list(self):
        self._list.delete(0, END)

        for i, name in enumerate(self.unit_name_list):
            self._list.insert(i, name)

    def component_list(self):
        #sandy brown
        fr1 = Frame(self)
        scrollbar = Scrollbar(fr1)
        scrollbar.pack(side="right", fill="y")

        self._list = Listbox(fr1,
                             bg="dim grey",
                             fg="white",
                             width=20,
                             yscrollcommand=scrollbar.set)

        mb1 = Menubutton(fr1, text='선택메뉴', relief='flat', bg='steel blue3')
        mb1.menu = Menu(mb1, tearoff=0)
        mb1['menu'] = mb1.menu
        mb1.menu.add_command(label='등록', command=self.choose_all)
        mb1.pack(side='bottom')
        mb1.menu.add_command(label='선택',
                             command=lambda: self._list.select_set(0, END))
        mb1.menu.add_command(
            label='해제', command=lambda: self._list.selection_clear(0, 'end'))

        self._list.pack(anchor="center",
                        fill="both",
                        expand=True,
                        padx=3,
                        pady=3)

        scrollbar.config(command=self._list.yview)
        self._list.config(highlightcolor='green',
                          font=('나눔고딕', 10),
                          activestyle='none',
                          selectmode='extended')

        self._list.bind('<<ListboxSelect>>', self.select_item)
        self._list.bind('<Button-3>', self.sub_menu1)
        self._list.exportselection = 0

        return fr1

    def select_item(self, event):
        self.clear_submenu()

        widget = event.widget
        #print("select item",widget.curselection())
        # if isinstance(widget,Listbox):
        v = widget.curselection()
        t = [widget.get(i) for i in v]

        self.context.notify('root', 'info', t)

    def clear_submenu(self):
        if hasattr(self, 'sub_fr'):
            self.sub_fr.destroy()

    def _setActivate(self, obj, index):
        obj.selection_set(index)
        # obj.see(index)
        # obj.activate(index)
        # obj.selection_anchor(index)

    def sub_menu1(self, event):
        self.clear_submenu()
        x, y = event.x, event.y

        self._setActivate(self._list, self._list.nearest(y))

        self.sub_fr = Frame(self, height=10)
        b1 = Button(self.sub_fr,
                    text='reg',
                    command=self.choose_task,
                    relief='flat')
        b1.pack(side='top', fill='both')
        self.sub_fr.place(x=x + 15, y=y)

    def choose_all(self):
        self.clear_submenu()
        for el in self._list.get(0, END):
            if not self._isduplicate(el):
                self._task_box.insert(END, el)

    def choose_task(self):
        self.clear_submenu()
        ixs = self._list.curselection()
        for ix in ixs:
            el = self._list.get(ix)
            if not self._isduplicate(el):
                self._task_box.insert(END, el)

    def _isduplicate(self, txt):
        for v in list(self._task_box.get(0, 'end')):
            if v == txt: return True
        return False

    def task_list(self):
        fr = Frame(self)
        fr_top = Frame(fr)
        task_lbx = Listbox(fr_top)
        task_lbx.pack(anchor="center",
                      fill="both",
                      expand=True,
                      padx=3,
                      pady=3)
        self._task_box = task_lbx

        fr_bot = Frame(fr, height='2')
        b1 = Menubutton(fr_bot, text='실행메뉴')
        b1.menu = Menu(b1, tearoff=0)
        b1['menu'] = b1.menu
        b1.menu.add_command(label='실행', command=self.convert)
        b1.menu.add_command(label='비우기', command=self.delete_task_item)
        b1.pack()

        fr_top.pack(side='top', fill='both', expand=True)
        fr_bot.pack(side='bottom', fill='x')
        task_lbx.config(highlightcolor='green',
                        font=('굴림체', 10),
                        activestyle='none',
                        selectmode='extended')

        self.task_lbx = task_lbx

        return fr

    def delete_task_item(self):
        v = self.task_lbx.curselection()
        #print(v)
        if not v:
            self.task_lbx.delete(0, END)
        elif len(v) == 1:
            self.task_lbx.delete(v)
        else:
            self.task_lbx.delete(v[0], v[-1])
示例#12
0
    def initUI(self):

        self.master.title("Py Docker Interface Manager")

        ####################
        # used functions
        ####################
        def getDirectories(event):
            # current directory that we are looking for
            information.see("end")

        def systemprune():
            message = messagebox.askokcancel(
                "Warning", "Would you like to perform a system prune?")
            if message:
                sysPrune(information)

        def inspect():
            if getWarnings():
                for message in getWarnings():
                    information.insert("end", message, "warning")

            index = area.curselection()
            inspectProject(information, area.get(index))

            # checking if composer exists
            information.insert("end", checkIfComposerExists(area.get(index)),
                               "notice")

            information.see("end")

        def clearConsole():
            message = messagebox.askokcancel("Warning", "Clear the console?")
            if message:
                information.delete(1.0, "end")

        def buildProject():
            index = area.curselection()
            if len(getDockerfiles(area.get(index))) > 1:
                message = messagebox.askokcancel(
                    "Attention!",
                    "More than one Dockerfiles found. Build all?")
                if message:
                    buildDockerfiles(information,
                                     getDockerfiles(area.get(index)),
                                     area.get(index), True)
                else:
                    buildDockerfiles(information,
                                     getDockerfiles(area.get(index)),
                                     area.get(index), False)
            else:
                buildDockerfiles(information, getDockerfiles(area.get(index)),
                                 area.get(index), False)

        def runProject():
            message = messagebox.askokcancel("Attention!",
                                             "Start the current project?")
            if message:
                index = area.curselection()
                foldername = area.get(index)
                runTheProject(information, foldername,
                              checkIfComposerExistsBool(foldername))

        def removeContainers():
            message = messagebox.askokcancel(
                "Attention!",
                "Removing the containers for the current project?")
            project = area.get(area.curselection())
            if message:
                removeProject(information, project)

        ####################
        # sidebar area
        ####################
        sidebar = Frame(self.master,
                        width=200,
                        height=500,
                        relief='flat',
                        borderwidth=2)
        sidebar.pack(expand=False, fill='both', side='right', anchor='ne')

        ### Inspect Button
        abtn = Button(sidebar, text="Inspect", command=inspect)
        abtn.grid(row=0, column=0, pady=2)

        ### Build button
        abtn = Button(sidebar, text="Build", command=buildProject)
        abtn.grid(row=1, column=0, pady=2)

        ### Run button
        cbtn = Button(sidebar, text="Run", command=runProject)
        cbtn.grid(row=2, column=0, pady=2)

        ### Remove containers button
        settingsbtn = Button(sidebar, text="Remove", command=removeContainers)
        settingsbtn.grid(row=3, column=0, pady=2)

        ### System Prune button
        cbtn = Button(sidebar, text="Prune", command=systemprune)
        cbtn.grid(row=4, column=0, pady=2)

        ### Clear Button
        hbtn = Button(sidebar, text="Clear", command=clearConsole)
        hbtn.grid(row=5, column=0, padx=5, pady=2)

        ### Close button
        obtn = Button(sidebar, text="Close", command=self.closeWindow)
        obtn.grid(row=6, column=0, pady=2)

        ####################
        # main content area
        ####################
        main_content = Frame(self.master, relief='flat')
        main_content.pack(expand=True, fill='both', side='left')

        lbl = Label(main_content, text="Projects")
        lbl.grid(sticky=W, pady=4, padx=5)

        ### Directories list
        area = Listbox(main_content, width=60)
        for directory in getDirs("../"):
            area.insert(1, directory)

        area.select_set(0)

        area.grid(row=1, column=0, rowspan=4, padx=5, sticky=E + W + N + S)

        area.bind('<ButtonRelease-1>', getDirectories)

        #information area
        information = Text(main_content, width=60, height=15)
        information.tag_config('warning', foreground="red")
        information.tag_config('notice', foreground="white", background="blue")
        information.tag_config('inspect',
                               foreground="black",
                               background="lightgray")
        information.tag_config('danger', foreground="white", background="red")
        information.grid(row=6,
                         column=0,
                         pady=10,
                         padx=5,
                         sticky=E + W + S + N)

        #### Output area
        lb2 = Label(main_content, text="Output >>>")
        lb2.grid(sticky=W, row=7, column=0, pady=4, padx=5)
class index_select(Frame):
    def __init__(self,controller,current_model,master,*args,**kwargs):
        self.controller = controller
        self.current_model = current_model
        self.filtered_list = None
        self.saved_selection = None

        from tkinter import EXTENDED,Scrollbar,Y

        #dibujar widget
        super().__init__(master, *args, **kwargs)

        f_st=Frame(self)
        Label(f_st,text="Current_index: ").pack()
        Label(f_st, text="Current_filter: ").pack()
        f_st.pack()

        frame_index_listbox = Frame(self)
        self.listbox = Listbox(frame_index_listbox, exportselection=False,selectmode=EXTENDED)
        self.listbox.pack(side=LEFT)

        scrollbar = Scrollbar(frame_index_listbox)
        scrollbar.pack(side=LEFT, fill=Y)
        frame_index_listbox.pack()


        # attach listbox to scrollbar
        self.listbox.config(yscrollcommand=scrollbar.set)
        scrollbar.config(command=self.listbox.yview)

        f=Frame(self)
        Label(f,text="Filtro: ").pack(side=LEFT)
        self.entry_w = Entry(f)
        self.entry_w.pack(side=LEFT)
        f.pack()

        f2=Frame(self)
        Button(f2, text='Filter',command=self.filter_indexs).pack(side=LEFT)
        Button(f2,text='Clean Filter',command=self.clean_filter).pack(side=LEFT)
        Button(f2, text='Export sel for gen',command=self.export_selection).pack(side=LEFT)
        f2.pack()

        f3=Frame(self)
        Button(self, text='<<',command=self.next_prev(-1)).pack(side=LEFT)
        Button(self, text='>>',command=self.next_prev(1)).pack(side=LEFT)
        f3.pack()

        self.update_model(current_model)
        self.listbox.select_set(0)
        self.listbox.event_generate("<<ListboxSelect>>")
        self.listbox.bind('<<ListboxSelect>>', self.selection)

    def filter_indexs(self):
        import random
        path_filter = self.entry_w.get()
        with open(path_filter,'r') as f:
            indexs_list_str = f.read().strip()
        random.seed(3)
        indexs_list = list(set(indexs_list_str.split('\n')))
        print(len(indexs_list))
        random.shuffle(indexs_list)

        self.filtered_list = indexs_list
        self.listbox.delete(0, END)
        for item in indexs_list:
            self.listbox.insert(END, item)

    def clean_filter(self):
        self.filtered_list = None
        self.update_model(self.current_model)
        self.listbox.delete(0, END)
        for item in sorted(self.index_list):
            self.listbox.insert(END, item)
        self.saved_selection = None

    def export_selection(self):
        sel_files_folder = os.path.join('config_files','select_files')
        os.makedirs(sel_files_folder,exist_ok=True)

        sel_list = self.listbox.curselection()
        index_list = [self.listbox.get(ind) for ind in sel_list]
        print("Exporting list for image generator. List: {0}".format(index_list))
        now_s = now_string()
        out_selection_file = {'index_list' : index_list,
                              'train_result_path': self.current_model.current_config_file,
                              'details' : '',
                              'mask_file' : self.current_model.current_mask_file}
        sel_file_name = "{0}_{1}_{2}_selection.json".format(self.current_model.classifier_key,self.current_model.dataset_key,now_s)
        sel_path = os.path.join(sel_files_folder,sel_file_name)
        with open(sel_path,'w') as f:
            json.dump(out_selection_file,f)
        print("Select in {0}".format(sel_path))

    def update_model(self, current_model):
        self.model = current_model
        self.index_list = self.model.get_index_list()
        self.current_index = self.model.get_current_index()
        self.mask_list = self.model.get_current_mask_index_list()

        indexs_list = self.filtered_list if self.filtered_list else sorted(self.index_list)

        self.listbox.delete(0, END)
        for item in indexs_list:
            self.listbox.insert(END, item)

        if self.saved_selection:
            ind,ypos = self.saved_selection
            self.listbox.selection_set(ind)
            self.listbox.yview_moveto(ypos[0])  # go back to that position

    def next_prev(self,x):
        def selection():
            ind_l = self.index_list.index(self.current_index)
            n = len(self.index_list)
            n_ind_l = (ind_l+x) % n
            next = self.index_list[n_ind_l]
            self.current_index = next
            self.listbox.selection_clear(0, END)
            self.listbox.select_set(n_ind_l)
            self.controller.event_change_index(next)

        return selection

    def selection(self,event):
        w = event.widget
        index = int(w.curselection()[0])
        value = w.get(index)
        print("v: {0}".format(value))
        selected_index = value
        self.current_index = selected_index
        self.controller.event_change_index(selected_index)
        self.saved_selection = (index,self.listbox.yview())

        pass
示例#14
0
class GridGUI(object):
    """
    tkGridGUI builds a python Tkinter GUI graphic user interface using the grid geometry manager.
    """

    def __init__(self, MainWin):
        """Inits Tkinter window of GridGUI."""
        
        self.root = MainWin
        #MainWin.geometry("800x600") #You want the size of the app to be 500x500
        MainWin.geometry( '+10+30' )
        
        try:
            style = Style(self.root)
            if "win" == platform[:3]:
                style.theme_use('vista')
            elif "darwin" in platform:
                style.theme_use('clam')
            else:
                style.theme_use('clam')
            bg = style.lookup("TLabel", "background")
            self.root.configure(bg=bg)
        except:
            print("OOPS... failed to set style.theme_use... Let's press on.")
        
        self.MainWin = MainWin
        
        MainWin.protocol('WM_DELETE_WINDOW', self.cleanupOnQuit)
        MainWin.allow_subWindows_to_close = 0
        
        self.add_menu_to_MainWin()
        
        topFrame = Frame( MainWin ) # frame for controls
        #topFrame = tx.ScrolledWindow( MainWin )
        
        frame1 = LabelFrame(topFrame, text="Widgets")
        self.place_widget_selection_listbox( frame1 )
        frame1.pack(anchor=NW, side=LEFT)
        
        frame2 = Frame( topFrame ) # frame for radio buttons
        self.place_gui_definition_controls( frame2, MainWin )
        frame2.pack(anchor=N, side=LEFT)

        self.grid_frame = Frame(topFrame) 
        self.grid_notebook = NotebookGridDes(self, self.grid_frame, MainWin, num_cols=5, num_rows=8)
        self.grid_frame.pack(anchor=N, side=LEFT)
                
        topFrame.pack(fill=BOTH, expand=Y)
        
        # make a Status Bar
        statframe = Frame(MainWin)
        MainWin.statusMessage = StringVar()
        MainWin.statusMessage.set('Welcome to TkGridGUI')
        self.statusbar = Label(statframe, textvariable=MainWin.statusMessage, 
            relief=SUNKEN, anchor=W)
        self.statusbar.pack(anchor=SW, fill=X, side=BOTTOM)
        statframe.pack(anchor=SW, fill=X, side=BOTTOM)
        
        # Initialize some GridGUI parameters
        
        self.current_fileFullName = '' # no file for now
        self.current_filePath = '' # no file for now
        self.current_fileName = '' # no file for now

        self.target_app = TargetTkAppDef( name='myApp')
        self.PreviewWin = None # need to initialize later
        
        self.Listbox_1_Click( 'FromInit' ) # execute selection logic

        
        self.in_reading_mode = False # when True, suppresses some automatic trace actions.
        if len( sys.argv ) == 2:
            fName = sys.argv[1]
            if fName.find('.')<0:
                fName += '.def'
                
            fullpath = os.path.abspath(fName)
            
            if os.path.isfile( fullpath ): # if file exists, read it as a definition file
                self.openFile( fName=fullpath )
            else:
                self.MainWin.statusMessage.set('file "%s" does not exist'%fName)
                
        self.grid_notebook.notebook.bind("<<NotebookTabChanged>>", self.tab_of_notebook_changed)

        self.mouse_location = ''
        self.MainWin.bind("<Enter>", self.onMainWindowEnter)

    def onMainWindowEnter(self, event):
        """Only track Enter... Want last known location."""
        #if self.mouse_location != 'main_window':
        #    print('mouse_location = main_window')
        self.mouse_location = 'main_window'

    def refresh_preview_win(self, allow_destroy_children=True):
        """
        Place all of the widgets from grid_notebook onto PreviewWin.
        May need to delete and rebuild current widgets on PreviewWin.
        """
            
        if self.PreviewWin is None:
            self.PreviewWin = PreviewWin( self.MainWin, grid_gui=self )
            self.target_app.set_PreviewWin( self.PreviewWin )
            self.target_app.set_Notebook( self.grid_notebook )
        else:
            if allow_destroy_children:
                self.PreviewWin.destroy_all_children()
                self.target_app.destroy_all_preview_widgets()
            
        
        widgetL = self.grid_notebook.make_complete_list_of_widgets()
        #print("========== PreviewWin Widget Info.")
        for w in widgetL:
            #print( w )
            (widget_type, widget_name, tab_label, row_target, col_target) = w
            
            self.target_app.maybe_add_component( widget_type=widget_type, 
                                                 widget_name=widget_name, 
                                                 tab_label=tab_label, 
                                                 row=row_target, col=col_target)
        self.target_app.show_preview()
        #print("="*55)
        #print('ref crc_reference =',self.target_app.crc_reference, 'current =', self.target_app.get_model_crc() )
            
        
                
    def add_menu_to_MainWin(self):
        
        # make menus
        self.menuBar = Menu(self.MainWin, relief = 'raised', bd=2)

        # create file pulldown menu
        fileMenu = Menu(self.menuBar, tearoff=0)
        fileMenu.add('command', label = 'New', command=self.newForm, underline=0,accelerator="Ctrl+N")
        fileMenu.add('command', label = 'Open', command=self.openFile, underline=0,accelerator="Ctrl+O")
        fileMenu.add('command', label = 'Save', command=self.saveasFile, underline=0,accelerator="Ctrl+S")
        #fileMenu.add('command', label = 'SaveAs', command = self.saveasFile)
        fileMenu.add('command', label = 'Exit', command=self.cleanupOnQuit, underline=0,accelerator="Ctrl+X")
        self.menuBar.add('cascade', label="File", menu=fileMenu)

        # create options pulldown menu
        optMenu = Menu(self.menuBar, tearoff=0)
        optMenu.add('command', label = 'Font to Clipboard', command =self.FontPickButton_Select, underline=0,accelerator="Ctrl+F")
        optMenu.add('command', label = 'Color to Clipboard', command = self.ColorPickButton_Select, underline=0,accelerator="Ctrl+C")
        optMenu.add('command', label = 'Named Color to Clipboard', command = self.NamedColorPickButton_Select, underline=0,accelerator="Ctrl+K")
        self.menuBar.add('cascade', label="Options", menu=optMenu)
        
        # bind accelerator keys (need lambda since functions don't have "event" parameter)
        self.root.bind("<Control-N>", lambda event: self.newForm())
        self.root.bind("<Control-n>", lambda event: self.newForm())
        
        self.root.bind("<Control-O>", lambda event: self.openFile())
        self.root.bind("<Control-o>", lambda event: self.openFile())
        
        self.root.bind("<Control-S>", lambda event: self.saveasFile())
        self.root.bind("<Control-s>", lambda event: self.saveasFile())
        
        self.root.bind("<Control-X>", lambda event: self.cleanupOnQuit())
        self.root.bind("<Control-x>", lambda event: self.cleanupOnQuit())
            
            
        self.root.bind("<Control-F>", self.FontPickButton_Click)
        self.root.bind("<Control-f>", self.FontPickButton_Click)
        
        self.root.bind("<Control-C>", self.ColorPickButton_Click)
        self.root.bind("<Control-c>", self.ColorPickButton_Click)
        
        self.root.bind("<Control-K>", self.NamedColorPickButton_Click)
        self.root.bind("<Control-k>", self.NamedColorPickButton_Click)

        # create About menu
        self.menuBar.add('command', label="About", command = self.About)

        # create Help menu
        self.menuBar.add('command', label="Help", command = self.Help)

        self.root.config(menu=self.menuBar)

    def mainOrDialog_Callback(self, varName, index, mode):
        #print( "mainOrDialog_Callback varName, index, mode",varName, index, mode )
        #print( "    new StringVar value =",self.MainWin.mainOrDialog.get() )
        
        self.refresh_preview_win()
        if self.MainWin.mainOrDialog.get() == 'dialog':
            if self.MainWin.hideOkChkBox_StringVar.get() == "yes":
                self.PreviewWin.remove_mock_OK_Cancel_Buttons()
            else:
                self.PreviewWin.add_mock_OK_Cancel_Buttons()
        else:
            self.PreviewWin.remove_mock_OK_Cancel_Buttons()
    
    def place_gui_definition_controls(self, frame2, MainWin ):
        
        # show option for Main Window or Dialog
        MainWin.mainOrDialog=StringVar()
        lbframe = LabelFrame(frame2, text="GUI Type")
        lbframe.pack(anchor=W)

        b = Radiobutton(lbframe, text="Main Window", value='main', variable=MainWin.mainOrDialog)
        b.pack(anchor=W)
        b = Radiobutton(lbframe, text="Dialog", value='dialog', variable=MainWin.mainOrDialog)
        b.pack(anchor=W)
        MainWin.mainOrDialog.set('main')
        self.mainOrDialog_traceName = MainWin.mainOrDialog.trace_variable("w", self.mainOrDialog_Callback)
        
        MainWin.hideOkChkBox = Checkbutton(lbframe, text="Hide OK Btn", width="15")
        MainWin.hideOkChkBox.pack(anchor=E, side=TOP)
        MainWin.hideOkChkBox_StringVar = StringVar()
        MainWin.hideOkChkBox_StringVar.set("no")
        MainWin.hideOkChkBox.configure(variable=MainWin.hideOkChkBox_StringVar, onvalue="yes", offvalue="no")
        self.hideOkChkBox_traceName = MainWin.hideOkChkBox_StringVar.trace_variable("w", self.hideOkChkBox_Callback)
        
        # show checkbox for menu and status bar
        lbframe = LabelFrame(frame2, text="Window Options")
        lbframe.pack(anchor=W)
        
        MainWin.menuChkBox = Checkbutton(lbframe, text="Main Menu", width="15")
        MainWin.menuChkBox.pack(anchor=W, side=TOP)
        MainWin.menuChkBox_StringVar = StringVar()
        MainWin.menuChkBox_StringVar.set("no")
        MainWin.menuChkBox.configure(variable=MainWin.menuChkBox_StringVar, onvalue="yes", offvalue="no")
        self.menuChkBox_traceName = MainWin.menuChkBox_StringVar.trace_variable("w", self.menuChkBox_Callback)
        
        MainWin.statusBarChkBox = Checkbutton(lbframe, text="Status Bar", width="15")
        MainWin.statusBarChkBox.pack(anchor=W, side=TOP)
        MainWin.statusBarChkBox_StringVar = StringVar()
        MainWin.statusBarChkBox_StringVar.set("no")
        MainWin.statusBarChkBox.configure(variable=MainWin.statusBarChkBox_StringVar, onvalue="yes", offvalue="no")
        self.statusBarChkBox_traceName = MainWin.statusBarChkBox_StringVar.trace_variable("w", self.statusBarChkBox_Callback)
        
        MainWin.resizableChkBox = Checkbutton(lbframe, text="Resizable", width="15")
        MainWin.resizableChkBox.pack(anchor=W, side=TOP)
        MainWin.resizableChkBox_StringVar = StringVar()
        MainWin.resizableChkBox_StringVar.set("yes")
        MainWin.resizableChkBox.configure(variable=MainWin.resizableChkBox_StringVar, onvalue="yes", offvalue="no")
        self.resizableChkBox_traceName = MainWin.resizableChkBox_StringVar.trace_variable("w", self.resizableChkBox_Callback)
        
        # show choices for standard dialogs
        lbframe = LabelFrame(frame2, text="Standard Dialogs")
        lbframe.pack(anchor=W)

        MainWin.stdDialMessChkBox = Checkbutton(lbframe, text="Messages", width="15")
        MainWin.stdDialMessChkBox.pack(anchor=E, side=TOP)
        MainWin.stdDialMessChkBox_StringVar = StringVar()
        MainWin.stdDialMessChkBox_StringVar.set("no")
        MainWin.stdDialMessChkBox.configure(variable=MainWin.stdDialMessChkBox_StringVar, onvalue="yes", offvalue="no")
        

        MainWin.stdDialColorChkBox = Checkbutton(lbframe, text="Color Choose", width="15")
        MainWin.stdDialColorChkBox.pack(anchor=E, side=TOP)
        MainWin.stdDialColorChkBox_StringVar = StringVar()
        MainWin.stdDialColorChkBox_StringVar.set("no")
        MainWin.stdDialColorChkBox.configure(variable=MainWin.stdDialColorChkBox_StringVar, onvalue="yes", offvalue="no")

        MainWin.stdDialFileChkBox = Checkbutton(lbframe, text="File Open/Save", width="15")
        MainWin.stdDialFileChkBox.pack(anchor=E, side=TOP)
        MainWin.stdDialFileChkBox_StringVar = StringVar()
        MainWin.stdDialFileChkBox_StringVar.set("no")
        MainWin.stdDialFileChkBox.configure(variable=MainWin.stdDialFileChkBox_StringVar, onvalue="yes", offvalue="no")

        MainWin.stdAlarmChkBox = Checkbutton(lbframe, text="Alarm Handler", width="15")
        MainWin.stdAlarmChkBox.pack(anchor=E, side=TOP)
        MainWin.stdAlarmChkBox_StringVar = StringVar()
        MainWin.stdAlarmChkBox_StringVar.set("no")
        MainWin.stdAlarmChkBox.configure(variable=MainWin.stdAlarmChkBox_StringVar, onvalue="yes", offvalue="no")
        
        # put color picker button
        self.ColorPickButton = Button(frame2, text="Put Color on Clipboard", width=18)
        self.ColorPickButton.pack(anchor=W, side=TOP)
        self.ColorPickButton.bind("<ButtonRelease-1>", self.ColorPickButton_Click)
        
        # put color picker button
        self.ColorPickButton = Button(frame2, text="   --> Named Color", width=18)
        self.ColorPickButton.pack(anchor=W, side=TOP)
        self.ColorPickButton.bind("<ButtonRelease-1>", self.NamedColorPickButton_Click)
        
        # put Font picker button
        self.FontPickButton = Button(frame2, text="Put Font on Clipboard", width=18)
        self.FontPickButton.pack(anchor=W, side=TOP)
        self.FontPickButton.bind("<ButtonRelease-1>", self.FontPickButton_Click)
        
        # put All widgets on notebook 
        #self.PlaceAllWidgetsButton = Button(frame2, text="Debug All Widgets", width=18)
        #self.PlaceAllWidgetsButton.pack(anchor=W, side=TOP)
        #self.PlaceAllWidgetsButton.bind("<ButtonRelease-1>", self.PlaceAllWidgetsButton_Click)
        
        # append new row or column to current notebook tab
        add_frame = Frame( frame2 )
        self.AddNewRowButton = Button(add_frame, text="Add Row", width=8)
        self.AddNewRowButton.pack(anchor=W, side=LEFT)
        self.AddNewRowButton.bind("<ButtonRelease-1>", self.AddNewRowButton_Click)

        self.AddNewColButton = Button(add_frame, text="Add Col", width=8)
        self.AddNewColButton.pack(anchor=W, side=LEFT)
        self.AddNewColButton.bind("<ButtonRelease-1>", self.AddNewColButton_Click)
        add_frame.pack(anchor=W, side=TOP)

        # dup_widget_label can be used for set_placement_widget_label, or widget duplication
        self.dup_widget_label_desc = Label(frame2, width=16)
        self.dup_widget_label_desc["text"      ] = "\nduplicate widget\nand its properties"
        self.dup_widget_label_desc.pack(anchor=W)
        
        self.dup_widget_label = Label(frame2, width=16)        
        self.dup_widget_label["text"      ] = "\n\n"
        self.dup_widget_label["font"      ] = ("Courier", 8, "normal")
        self.dup_widget_label["relief"] = "groove"
        self.dup_widget_label.pack(anchor=W)
        self.dup_widget_label_plain_bg = self.dup_widget_label["background"]
        self.dup_widget_label["background"] = "#FFFACD"  # lemonchiffon
        
        # Refresh Preview Window
        #self.PlaceAllWidgetsButton = Button(frame2, text="Refresh Preview", width=18)
        #self.PlaceAllWidgetsButton.pack(anchor=W, side=TOP)
        #self.PlaceAllWidgetsButton.bind("<ButtonRelease-1>", self.GeneralDebugButton_Click)

    def GeneralDebugButton_Click(self, event):
        self.grid_notebook.repaint_all_labels()
        self.refresh_preview_win()

    def AddNewRowButton_Click(self, event):
        self.grid_notebook.append_row()
        
    def AddNewColButton_Click(self, event):
        self.grid_notebook.append_column()
        

    def PlaceAllWidgetsButton_Click(self, event):
        """As DEBUG TOOL, show all widgets in Notebook"""
        
        saved_sel = self.MainWin.placementWidgetType_svar.get()
        saved_tab = self.grid_notebook.current_tab_label()
        
        row = 1 # row_interface
        col = 1 # col_interface
        
        self.grid_notebook.set_current_tab_by_label( "Main" )
        
        for wname, wcolor in CONTROLS:
            self.MainWin.placementWidgetType_svar.set( wname )
            event.widget = self.grid_notebook.interface_gridBoxWidgetD[("Main", row, col)]# row_interface, col_interface
            self.grid_notebook.onGridBoxClicked( event )
            
            if wname in ContainerControlsL:
                new_tab_name = wname + "_%i"%(CONTROL_NEXT_NUMBER_D[wname] -1,)
                self.grid_notebook.set_current_tab_by_label( new_tab_name )
                
                # place some widgets on ContainerControlsL tab
                if wname == 'RadioGroup':
                    self.MainWin.placementWidgetType_svar.set( "Label" )
                    event.widget = self.grid_notebook.interface_gridBoxWidgetD[(new_tab_name, 2, 2)]# row_interface, col_interface
                    self.grid_notebook.onGridBoxClicked( event )
                    
                    for n_radio in range(3):
                        self.MainWin.placementWidgetType_svar.set( "Radiobutton" )
                        event.widget = self.grid_notebook.interface_gridBoxWidgetD[(new_tab_name, 3+n_radio, 2)]# row_interface, col_interface
                        self.grid_notebook.onGridBoxClicked( event )
                        
                    
                else:
                    self.MainWin.placementWidgetType_svar.set( "Button" )
                    event.widget = self.grid_notebook.interface_gridBoxWidgetD[(new_tab_name, 2, 2)]# row_interface, col_interface
                    self.grid_notebook.onGridBoxClicked( event )
                    
                    self.MainWin.placementWidgetType_svar.set( "Label" )
                    event.widget = self.grid_notebook.interface_gridBoxWidgetD[(new_tab_name, 3, 2)]# row_interface, col_interface
                    self.grid_notebook.onGridBoxClicked( event )
                    
                    self.MainWin.placementWidgetType_svar.set( "Entry" )
                    event.widget = self.grid_notebook.interface_gridBoxWidgetD[(new_tab_name, 4, 2)]# row_interface, col_interface
                    self.grid_notebook.onGridBoxClicked( event )
                    
                # restore notebook to Main tab
                self.grid_notebook.set_current_tab_by_label( "Main" )
                
            
            col += 1
            if col % 5 == 0:
                col = 1
                row += 1
                
        # Return Listbox_1 selection to original value
        self.MainWin.placementWidgetType_svar.set( saved_sel )
        self.grid_notebook.set_current_tab_by_label( saved_tab )
        
    def set_status_msg(self, msg):
        self.MainWin.statusMessage.set( msg )

    def gray_out_listbox(self, omit_list=None):
        """if omit_list is None, gray all."""
        if omit_list is None:
            omit_list = []
            
        n = -1
        for index, (wname, wcolor) in enumerate(CONTROLS):
            if wname in omit_list:
                self.Listbox_1.itemconfig(index, fg="black")
                n = index
            else:
                self.Listbox_1.itemconfig(index, fg="gray")
            self.Listbox_1.selection_clear(index)
            
        if n >= 0:
            self.Listbox_1.selection_set(n)
            self.Listbox_1_Click( 'FromGrayOut' ) # event is not used in Listbox_1_Click
    
    def restore_black_listbox(self):
        """Make sure all listbox options show up for all other tabs."""
        
        n = 0
        for i in self.Listbox_1.curselection():
            n = i
            break # set to 1st value encountered
    
        for index, (wname, wcolor) in enumerate(CONTROLS):
            self.Listbox_1.itemconfig(index, fg="black")
            self.Listbox_1.selection_clear(index)
            
        self.Listbox_1.selection_set(n)
        self.Listbox_1_Click( 'FromRestoreBlack' ) # event is not used in Listbox_1_Click

    def select_preview_tab(self, tab_name_inp):
        
        if not self.PreviewWin:
            self.refresh_preview_win() # make PreviewWin if not already done.
            
        tab_comp = self.target_app.compObjD[tab_name_inp]
        notebook_name = tab_comp.tab_label
        nb_obj = self.target_app.compObjD[ notebook_name ]
        
        # get index of tab on preview_win        
        for itab, (row, col, tab_name, tab_label) in enumerate( nb_obj.tab_nameL ):
            if tab_name_inp == tab_name:
                nb_obj.pw_widget.native_widget.select( itab )
                #print('grid_gui.tab_of_notebook_changed: set PreviewWin Tab to:', itab)
                break

    def tab_of_notebook_changed(self, event):
        
        if self.mouse_location == 'preview_win':
            return
        
        # look at the dup widget to see if it's a full widget duplication
        s_dup = self.dup_widget_label["text"].strip()
        if s_dup and s_dup.startswith('('): # i.e. widget has a (row,col) position
            saved_dup_text_on_tab_change = self.dup_widget_label["text"]        
            saved_dup_bg_on_tab_change   = self.dup_widget_label["background"]
        else:
            saved_dup_text_on_tab_change = ''
            saved_dup_bg_on_tab_change   = ''
        
        nb = self.grid_notebook.notebook
        #i = nb.index(nb.select())
        nb_tab_label = nb.tab(nb.select(), "text")
        #print("GridGUI Notebook Tab Set to:", nb_tab_label )

        self.Listbox_1.config( state=NORMAL )

        # gray out some listbox options for RadioGroup
        if nb_tab_label.startswith('RadioGroup'):
            self.gray_out_listbox( omit_list=("Radiobutton","Label") )
                        
        elif nb_tab_label.startswith('Notebook'):
            #print('=========>  Need to add Notebook logic.')
            
            self.gray_out_listbox( omit_list=None )
            self.set_placement_widget_label( 'Tab' )
            self.set_status_msg( "Only Tabs can be added to Notebook" )
            
        else:
            # Make sure all listbox options show up for all other tabs.
            self.restore_black_listbox()
            
            if saved_dup_text_on_tab_change:
                self.dup_widget_label["text"      ] = saved_dup_text_on_tab_change
                self.dup_widget_label["background"] = saved_dup_bg_on_tab_change
                self.dup_widget_label_desc["text"      ] = "\nduplicate widget\nand its properties"
                

        # Cause PreviewWin to switch to same Tab
        if nb_tab_label in self.target_app.compObjD: # i.e. the tab is in the TargetTkAppDef
            w = self.target_app.compObjD[ nb_tab_label ]
            treeL = w.get_tab_label_tree()
            #print('New widget tab_label_tree =', treeL )
            for name in treeL:
                if name.startswith('Tab_'):
                    self.select_preview_tab( name ) # nb_tab_label is tab_name
            
            

    def place_widget_selection_listbox(self, frame1):
        """frame1 in topFrame contains Widgets selection ListBox"""
        
        self.MainWin.placementWidgetType_svar=StringVar()
        self.MainWin.placementWidgetType_svar.set('Button')
        
        # Notebooks handled seperately

        self.Listbox_1 = Listbox(frame1,width=15 ,height=str(len(CONTROLS)), selectmode='single')#, selectmode="extended")
        self.Listbox_1.bind("<ButtonRelease-1>", self.Listbox_1_Click)

        for wname, wcolor in CONTROLS:
            #b = Radiobutton(frame1, text=text, value=cont, variable=self.MainWin.placementWidgetType_svar)
            #b.pack(anchor=W)
            #print("inserting wname into Listbox_1 "+wname)
            self.Listbox_1.insert(END, wname)
        
        self.Listbox_1.pack(anchor=W)
        self.Listbox_1.select_set(0) # make Top Item highlighted
            
    def cleanupOnQuit(self):
                
        if self.target_app.model_has_changed():
            dialog = maybe_save_dialog(self.MainWin, "Save Before Exit?")
            
            if (dialog.result is not None) and ( dialog.result['save_file'] == "yes"):
                self.saveasFile()
                return
            else:
                # ignore any other warnings
                self.target_app.reset_crc_reference() # for detecting changes to model
        
        
        #print( 'Doing final cleanup before quitting' )
        self.MainWin.allow_subWindows_to_close = 1
        self.MainWin.destroy()
    
    def set_duplication_widget_label(self, label_obj):
        """Given the widget Label object, set up for making duplicates."""
        
        self.dup_widget_label["text"      ] = label_obj["text"]
        self.dup_widget_label["background"] = label_obj["background"]
        self.dup_widget_label_desc["text"      ] = "\nduplicate widget\nand its properties"
        
    
    def set_placement_widget_label(self, widget_type):
        """Sets dup_widget_label for a simple Place of widget_type."""
        
        self.dup_widget_label["text"      ] = "\n%s\n"%widget_type
        #self.dup_widget_label["background"] = self.dup_widget_label_plain_bg # "#FFFACD"  # lemonchiffon
        self.dup_widget_label["background"] = CONTROL_COLOR_D[widget_type]
        self.dup_widget_label_desc["text"      ] = "\n\nPlace %s"%widget_type

        self.grid_notebook.dup_source_widget_name = '' # not a dup_widget_label event so no dup_source_widget_name
        
        
    def Listbox_1_Click(self, event): #click method for component ID=1
        
        val = 'Button'
        for i in self.Listbox_1.curselection():
            val = self.Listbox_1.get(i)# .lower()
        
        self.set_status_msg("Selected Widget: "+ val )
                
        self.MainWin.placementWidgetType_svar.set(val)

        tab_label = self.grid_notebook.current_tab_label()
        if not tab_label.startswith('Notebook'):
            # set duplicate widget text and background to indicate normal placement
            self.set_placement_widget_label( val )

    def hideOkChkBox_Callback(self, varName, index, mode):
        #print( 'Hide OK Button in Dialog =',self.MainWin.hideOkChkBox_StringVar.get(), end="\n")
        
        try:
            self.target_app.setSpecialOption('hideokbutton', self.MainWin.hideOkChkBox_StringVar.get())
        except:
            pass

        if self.MainWin.hideOkChkBox_StringVar.get() == "yes":
            self.PreviewWin.remove_mock_OK_Cancel_Buttons()
        else:
            self.PreviewWin.add_mock_OK_Cancel_Buttons()

    def menuChkBox_Callback(self, varName, index, mode):
        #print( 'make menu =',self.MainWin.menuChkBox_StringVar.get(), end="\n")
        
        try:
            self.target_app.setSpecialOption('hasmenu', self.MainWin.menuChkBox_StringVar.get())
            #print('Setting Menu "hasmenu" Option To:',self.MainWin.menuChkBox_StringVar.get())
        except:
            print('WARNING... Failed To Properly Set "hasmenu" Option.')
        
        if not self.in_reading_mode:
            if self.MainWin.menuChkBox_StringVar.get()=='yes' and self.target_app:
                dialog = Menumaker(self.MainWin, "Define Menu Structure",
                    self.target_app.getSpecialOption('menu'))
                #print( dialog.result, end="\n")
                
                if type(dialog.result) == type({}):

                    add_menu_ctrl_keys = dialog.result.get('add_menu_ctrl_keys','yes')
                    self.target_app.setSpecialOption('add_menu_ctrl_keys', add_menu_ctrl_keys)

                    menuStr = dialog.result.get('menu','').strip()
                    if len( menuStr ) > 0:
                        self.target_app.setSpecialOption('menu',menuStr)
                        #print( 'Recording new Menu Definition', end="\n")
                        
                        
        if not self.PreviewWin:
            self.refresh_preview_win() # make PreviewWin if not already done.

        # delete menuBar
        if self.MainWin.menuChkBox_StringVar.get()=='no' and self.target_app:
            if (self.PreviewWin is not None):
                if self.PreviewWin.menuBar:
                    self.PreviewWin.delete_menu()

        # create menuBar
        if self.MainWin.menuChkBox_StringVar.get()=='yes' and self.target_app:
            if (self.PreviewWin is not None):
                if self.PreviewWin.menuBar:
                    self.PreviewWin.delete_menu() # delete so menuBar can be recreated
                    
                menuL = buildMenuSource( self.target_app.getSpecialOption( 'menu' ) )
                menuSrcL = getMenuSource( menuL, rootName='self'  )
                    
                self.PreviewWin.add_menu( menuSrcL )
        
        self.refresh_preview_win() # redraw the form window showing menu state.

        
    def statusBarChkBox_Callback(self, varName, index, mode):
        #print( 'Status Bar =',self.MainWin.statusBarChkBox_StringVar.get(), end="\n")
        
        try:
            self.target_app.setSpecialOption('hasstatusbar', self.MainWin.statusBarChkBox_StringVar.get())
        except:
            pass
            
        if not self.PreviewWin:
            self.refresh_preview_win() # make PreviewWin if not already done.
        
        # add statusbar to PreviewWin
        if self.MainWin.statusBarChkBox_StringVar.get()=='yes' and self.target_app:
            if (self.PreviewWin is not None):
                if not self.PreviewWin.statusbar:
                    self.PreviewWin.add_mock_statusbar()
                    
        # remove statusbar from PreviewWin
        if self.MainWin.statusBarChkBox_StringVar.get()=='no' and self.target_app:
            if (self.PreviewWin is not None):
                if  self.PreviewWin.statusbar:
                    self.PreviewWin.remove_mock_statusbar()
                    
        self.refresh_preview_win() # redraw the form window showing menu state.

    def resizableChkBox_Callback(self, varName, index, mode):
        #print( 'Status Bar =',self.MainWin.resizableChkBox_StringVar.get(), end="\n")
        
        try:
            self.target_app.setSpecialOption('resizable', self.MainWin.resizableChkBox_StringVar.get())
        except:
            pass
                    
        self.refresh_preview_win() # redraw the form window showing menu state.
        
                
    def ColorPickButton_Click(self, event): #put selected color on clipboard
        self.ColorPickButton_Select()
        
    def ColorPickButton_Select(self): #put selected color on clipboard
        self.set_status_msg('Place Selected Color on Clipboard')
        ctup,cstr = tkinter.colorchooser.askcolor(title='Place Selected Color on Clipboard')
        if cstr != None:
            self.set_status_msg('%s is on Clipboard'%cstr)
            self.ColorPickButton.clipboard_clear()
            self.ColorPickButton.clipboard_append(cstr)
            
            #print( 'color chosen=',cstr, end="\n")
                
    def NamedColorPickButton_Click(self, event): #put selected color on clipboard
        self.NamedColorPickButton_Select()
        
    def NamedColorPickButton_Select(self): #put selected color on clipboard
        self.set_status_msg('Place Named Color on Clipboard')
        
        dialog = named_color_picker(self.MainWin, title="Place Named Color on Clipboard")
        if dialog.result is not None:
            (_, _, _, _, _, _, cstr, name) = dialog.result["named_color"]
            
            self.set_status_msg('%s %s is on Clipboard'%(name, cstr) )
            self.ColorPickButton.clipboard_clear()
            self.ColorPickButton.clipboard_append(cstr)
            
    def FontPickButton_Click(self, event):
        self.FontPickButton_Select()
    
    def FontPickButton_Select(self):
        self.set_status_msg('Place Selected Font on Clipboard')
        dialog = get_cross_platform_font(self.MainWin, title="Get Font")
        if dialog.result is not None:
            font_str = dialog.result['full_font_str']
            
            # for example:    Comic\ Sans\ MS 20 bold roman
                
            self.set_status_msg('%s is on Clipboard'%font_str)
            self.ColorPickButton.clipboard_clear()
            self.ColorPickButton.clipboard_append(font_str)
            
            #print( 'font chosen=',font_str, end="\n")
            

    def Help(self):
        
        usage = """
        
Basic Usage: 
  Select Widget in Listbox with Left Click.
  Place Widget with Left Click in grid.

Edit Widget:
  Right Click Widget in Grid or Preview Window.

Move Widget:
  Left Button Drag and Drop in Grid.

Duplicate Widget: 
  Left Click Widget in Grid.
  Left Click in grid to place the duplicate.

Insert Row or Column 
    Left Click on "+" control.

Add Weight to row or column 
    Left Click "wt" control.

Container Widgets
    Select Grid Tab for Main, Frames, RadioGroups etc.
"""
        
        myshowinfo(self.MainWin, title="Help for TkGridGUI",
                   dialogOptions={'info':usage, 'bg':'#EAFFFE'})

    def About(self):
        tkinter.messagebox.showinfo(
            "About TkGridGUI v(%s)"%__version__,
            "TkGridGUI v(%s) is:\n\n"%__version__+\
            "A quick approach to\n"+\
            "building Tkinter applications.\n"+\
            "Written by Charlie Taylor\n"
        )
    
    def newForm(self):
        #print( "New Form" )
        
        if self.target_app.model_has_changed():
            dialog = maybe_save_dialog(self.MainWin, "Save Current File?")
            
            if (dialog.result is not None) and ( dialog.result['save_file'] == "yes" ):
                self.saveasFile()
                return

        self.current_fileFullName = '' # no file for now
        # leave path alone... self.current_filePath = '' # no file for now
        self.current_fileName = '' # no file for now

        self.MainWin.title( 'TkGridGUI: ' + self.current_fileName )
        
        if self.PreviewWin:
            self.PreviewWin.delete_menu()
            self.PreviewWin.remove_mock_statusbar()

        self.target_app.reinitialize()
        self.grid_notebook.initialize_NotebookGridDes()
        self.grid_notebook.notebook.bind("<<NotebookTabChanged>>", self.tab_of_notebook_changed)
        
        self.refresh_preview_win()
        
        # ignore any other warnings
        self.target_app.reset_crc_reference() # for detecting changes to model
        

    def openFile(self, fName=None):
        #print( 'Open File' )
                
        if self.target_app.model_has_changed():
            dialog = maybe_save_dialog(self.MainWin, "Save Current File?")
            
            if (dialog.result is not None) and (dialog.result['save_file'] == "yes"):
                self.saveasFile()
                return
            else:
                # ignore any other warnings
                self.target_app.reset_crc_reference() # for detecting changes to model

        
        self.in_reading_mode = True # when True, suppresses some automatic trace actions.
        if fName is None:
            
            if self.current_filePath:
                initialdir = self.current_filePath
            else:
                initialdir = '.'
            
            filetypes = [
                ('tkGridGUI definition','*.def'),
                ('Any File','*.*')]
            self.pathopen = tkinter.filedialog.askopenfilename(parent=self.MainWin, title='Open tkGridGUI file', 
                filetypes=filetypes, initialdir=initialdir)
            #print('self.pathopen =',self.pathopen)
        else:
            self.pathopen = os.path.abspath(fName)
        
        if self.pathopen:
            
            self.newForm() # clean up any leftovers from another job
            
            full_fname = os.path.abspath( self.pathopen )
            head,tail = os.path.split( full_fname )
            
            self.current_fileFullName = full_fname
            self.current_filePath = head
            self.current_fileName = tail
                        
            self.target_app.readAppDefFile( self.pathopen )

            #'hasmenu':'no', 
            self.MainWin.menuChkBox_StringVar.set( self.target_app.getSpecialOption( 'hasmenu' ) )

            #'hasstatusbar':'no',
            self.MainWin.statusBarChkBox_StringVar.set( self.target_app.getSpecialOption( 'hasstatusbar' ) )

            #'resizable':'no'
            self.MainWin.resizableChkBox_StringVar.set( self.target_app.getSpecialOption( 'resizable' ) )
            
            #'hideokbutton':'no'
            self.MainWin.hideOkChkBox_StringVar.set( self.target_app.getSpecialOption( 'hideokbutton' ) )

            #'guitype':'main',
            self.MainWin.mainOrDialog.set( self.target_app.getSpecialOption( 'guitype' ) )

            #'hasstddialmess':'no', 
            self.MainWin.stdDialMessChkBox_StringVar.set( self.target_app.getSpecialOption( 'hasstddialmess' ) )

            #'hasstddialcolor':'no', 
            self.MainWin.stdDialColorChkBox_StringVar.set( self.target_app.getSpecialOption( 'hasstddialcolor' ) )

            #'hasstddialfile':'no', 
            self.MainWin.stdDialFileChkBox_StringVar.set( self.target_app.getSpecialOption( 'hasstddialfile' ) )

            #'hasstdalarm':'no', 
            self.MainWin.stdAlarmChkBox_StringVar.set( self.target_app.getSpecialOption( 'hasstdalarm' ) )


            #for key,val in self.target_app.app_attrD.items():
            #    print('%20s %s'%(key, str(val).replace('\t','    ')))
            
            widgetL = [(c.widget_type, widget_name, c.tab_label, c.row, c.col) for widget_name,c in list(self.target_app.compObjD.items())]
            self.grid_notebook.set_complete_list_of_widgets( widgetL )
            
            if not self.PreviewWin:
                self.refresh_preview_win() # make PreviewWin if not already done.
            
            # maybe create menuBar
            if self.MainWin.menuChkBox_StringVar.get()=='yes' and self.target_app:
                if (self.PreviewWin is not None):
                    if self.PreviewWin.menuBar:
                        self.PreviewWin.delete_menu() # delete so menuBar can be recreated
                        
                    menuL = buildMenuSource( self.target_app.getSpecialOption( 'menu' ) )
                    menuSrcL = getMenuSource( menuL, rootName='self'  )
                        
                    self.PreviewWin.add_menu( menuSrcL )
            
            
            # maybe add statusbar to PreviewWin
            if self.MainWin.statusBarChkBox_StringVar.get()=='yes' and self.target_app:
                if (self.PreviewWin is not None):
                    if not self.PreviewWin.statusbar:
                        self.PreviewWin.add_mock_statusbar()
            
            if self.PreviewWin:
                w = self.target_app.getSpecialOption( 'width' )
                h = self.target_app.getSpecialOption( 'height' )
                x = self.target_app.getSpecialOption( 'x' )
                y = self.target_app.getSpecialOption( 'y' )
                
                if self.PreviewWin.statusbar:
                    y += 30
                
                self.PreviewWin.geometry( '%ix%i+%i+%i'%(w,h,x,y))
                #self.PreviewWin.geometry( '' ) # allow to resize after set to x,y
                self.PreviewWin.update_idletasks()
                
            self.MainWin.title( 'TkGridGUI: ' + self.current_fileName )

            self.target_app.reset_crc_reference() # for detecting changes to model

        self.in_reading_mode = False # when True, suppresses some automatic trace actions.
        
        self.refresh_preview_win() # redraw the form window showing menu state
        
        self.grid_notebook.notebook.bind("<<NotebookTabChanged>>", self.tab_of_notebook_changed)
        

        
    def saveasFile(self):
        #print( 'Save File to Disk' )
        self.set_status_msg('Save File to Disk')
        
        filetypes = [
            ('TkGridGUI','*.def'),
            ('Any File','*.*')]
        
        if self.current_fileName:
            fname = self.current_fileName
        else:
            fname = ''
                        
        if self.current_filePath:
            initialdir = self.current_filePath
        else:
            initialdir = '.'
            
        fsave = tkinter.filedialog.asksaveasfilename(parent=self.MainWin, title='Saving TkGridGUI Definition File', 
            initialfile=fname, filetypes=filetypes, initialdir=initialdir)
        
        if fsave:
            if not fsave.lower().endswith('.def'):
                fsave += '.def'
                    
            full_fname = os.path.abspath( fsave )
            head,tail = os.path.split( full_fname )
            
            self.current_fileFullName = full_fname
            self.current_filePath = head
            self.current_fileName = tail
            
            # set values in target_app

            #'hasmenu':'no', 
            self.target_app.setSpecialOption( 'hasmenu', self.MainWin.menuChkBox_StringVar.get() )

            #'hasstatusbar':'no',
            self.target_app.setSpecialOption( 'hasstatusbar' , self.MainWin.statusBarChkBox_StringVar.get() )

            #'resizable':'no'
            self.target_app.setSpecialOption( 'resizable', self.MainWin.resizableChkBox_StringVar.get() )

            #'guitype':'main',
            self.target_app.setSpecialOption( 'guitype', self.MainWin.mainOrDialog.get() )
            
            #'hideokbutton':'no'
            self.target_app.setSpecialOption( 'hideokbutton', self.MainWin.hideOkChkBox_StringVar.get() )

            #'hasstddialmess':'no', 
            self.target_app.setSpecialOption( 'hasstddialmess', self.MainWin.stdDialMessChkBox_StringVar.get() )

            #'hasstddialcolor':'no', 
            self.target_app.setSpecialOption( 'hasstddialcolor', self.MainWin.stdDialColorChkBox_StringVar.get() )

            #'hasstddialfile':'no', 
            self.target_app.setSpecialOption( 'hasstddialfile', self.MainWin.stdDialFileChkBox_StringVar.get() )

            #'hasstdalarm':'no', 
            self.target_app.setSpecialOption( 'hasstdalarm', self.MainWin.stdAlarmChkBox_StringVar.get() )
            
            # first save *.def file
            if self.target_app.saveAppDefFile( savePathName=self.current_fileFullName ):
                # if that goes OK, then save *.py file
                                
                self.MainWin.title( 'TkGridGUI: ' + self.current_fileName )
                
                sf = FormSource( self.target_app, self.MainWin, self )
                sf.saveToFile() # save *.py file
                
                head, tail = os.path.split( sf.sourceFile.pathopen )
                self.set_status_msg('Saved File: "%s" and "%s" in "%s"'%(self.current_fileName, tail, head) )
                
                self.target_app.reset_crc_reference() # for detecting changes to model
                
            else:
                self.set_status_msg("WARNING... *.def file save failed.  NO SAVE PERFORMED.")
示例#15
0
class HoursBankGUI():
    def __init__(self, window):
        # define the window
        self.window = window
        window.title("Hours Management Tool")
        # define the size of the main window
        window.geometry('{}x{}'.format(700, 500))

        self.window.grid_rowconfigure(1, weight=1)
        self.window.grid_columnconfigure(0, weight=1)
        # pretends the window from being resized
        self.window.resizable(0, 0)

        # font test
        # appHighlightFont = font.Font(family='Helvetica', size=12, weight='bold')

        # define the panels ##############################################################################
        # LEFT PANEL
        # This panel houses the list box which allows the user to select the employee
        self.leftFrame = Frame(self.window,
                               bg="white",
                               width=300,
                               height=500,
                               pady=3,
                               borderwidth=1,
                               relief="solid")
        self.leftFrame.grid(row=0, sticky="nsw")
        # keep the frame the same size even if the widgets chnage size
        self.leftFrame.grid_propagate(False)
        # label
        self.listLabel = Label(self.leftFrame,
                               text="Select User",
                               bg="white",
                               font="Ariel")
        self.listLabel.grid(row=0, sticky="nwe")
        # Listbox
        self.list_box = Listbox(self.leftFrame,
                                width=23,
                                height=18,
                                bg="white",
                                font=("Ariel", 14))
        self.list_box.grid(row=1, sticky="wes", padx=10, pady=20)
        # scroll Bar
        self.scrollbar = Scrollbar(self.leftFrame)
        self.list_box.config(yscrollcommand=self.scrollbar.set)
        self.scrollbar.config(command=self.list_box.yview)
        self.scrollbar.grid(column=2, row=1, sticky="ns")
        # fire an event when a employee in the list box is selected
        self.list_box.bind('<<ListboxSelect>>', self.showDetailsLive)

        # RIGHT PANEL TOP
        # When a user clicks on an employee in the employee list box then their details will be shown in the panel
        self.rightFrame1 = Frame(self.window,
                                 bg="white",
                                 width=400,
                                 height=300,
                                 relief="solid",
                                 borderwidth=1,
                                 padx=20,
                                 pady=5)
        self.rightFrame1.grid(row=0, sticky="ne")
        # keep the frame the same size even if the widgets change size
        self.rightFrame1.grid_propagate(False)

        # Label Widgets for the right top Frame
        self.details_title = Label(self.rightFrame1,
                                   text="Employee Details",
                                   font="Ariel",
                                   bg="white")
        self.details_title.grid(row=0, column=0, columnspan=4, sticky="nw")
        self.name_label = Label(self.rightFrame1,
                                text="Name",
                                font="Arial",
                                bg="white")
        self.name_label.grid(row=3, column=1, sticky="w")
        self.ID_label = Label(self.rightFrame1,
                              text="ID",
                              font="Arial",
                              bg="white")
        self.ID_label.grid(row=2, column=1, sticky="w")
        self.Rate_label = Label(self.rightFrame1,
                                text="Rate",
                                font="Arial",
                                bg="white")
        self.Rate_label.grid(row=4, column=1, sticky="w")
        self.Hol_Rate_label = Label(self.rightFrame1,
                                    text="Holiday Rate",
                                    font="Arial",
                                    bg="white")
        self.Hol_Rate_label.grid(row=5, column=1, sticky="w")
        self.Banked_Hours_label = Label(self.rightFrame1,
                                        text="Banked Hours",
                                        font="Arial",
                                        bg="white")
        self.Banked_Hours_label.grid(row=6, column=1, sticky="w")
        self.Banked_Salary_label = Label(self.rightFrame1,
                                         text="Banked Salary",
                                         font="Arial",
                                         bg="white")
        self.Banked_Salary_label.grid(row=7, column=1, sticky="w")

        # RIGHT BOTTOM PANEL
        # This panel contains the buttons the user can select to perform operations on the employees data
        self.rightFrame2 = Frame(self.window,
                                 bg="white",
                                 width=400,
                                 height=200)
        self.rightFrame2.grid(row=0, sticky="se")
        # organises the grid of the panel to look good
        self.rightFrame2.grid_propagate(
            False)  #Stops the frame resizing to widget
        self.rightFrame2.grid_columnconfigure(0, weight=1)
        self.rightFrame2.grid_columnconfigure(1, weight=1)
        self.rightFrame2.grid_rowconfigure(0, weight=1)
        self.rightFrame2.grid_rowconfigure(1, weight=1)
        self.rightFrame2.grid_rowconfigure(2, weight=1)

        # Define the buttons of the bottom right panel
        self.add_user_button = Button(self.rightFrame2,
                                      text="New Employee",
                                      font="Arial",
                                      relief="groove",
                                      command=self.addTodB)
        self.add_user_button.grid(row=0, column=0, sticky="nsew")
        self.add_hours_button = Button(self.rightFrame2,
                                       text="Add Hours",
                                       font="Arial",
                                       relief="groove",
                                       command=lambda: self.ChangeHours(False))
        self.add_hours_button.grid(row=0, column=1, sticky="nsew")
        self.delete_employee_button = Button(self.rightFrame2,
                                             text="Delete Employee",
                                             relief="groove",
                                             font="Arial",
                                             command=self.deleteUser)
        self.delete_employee_button.grid(row=1, column=0, sticky="nsew")
        self.edit_user_info_bt = Button(self.rightFrame2,
                                        text="Edit Employee",
                                        relief="groove",
                                        font="Arial",
                                        command=self.editEmployeeDetials)
        self.edit_user_info_bt.grid(row=1, column=1, sticky="nsew")
        self.remove_hours_btn = Button(self.rightFrame2,
                                       text="Remove Hours",
                                       relief="groove",
                                       font="Arial",
                                       command=lambda: self.ChangeHours(True))
        self.remove_hours_btn.grid(row=2, column=0, sticky="nsew")

        self.number = 0

        # check if there are any employees in the database
        # if there is not then display no employees in the list list_box
        # If there are then display the employees
        dbList = dbFunctionsV2.getAllUsers()
        print(dbList)
        if len(dbList) > 0:
            # lets get a list of employees and display them
            self.viewAll()
            self.list_box.selection_set(0)
            self.showDetails(self.list_box.curselection()[0])
        else:
            self.list_box.insert(END, "No Employees in Database")

    # When a item in the list is clicked then show the data in the RIGHT TOP FRAME
    def showDetailsLive(self, event):
        # get list item number
        index = self.list_box.curselection()[0]
        # pass to showDetails function
        self.showDetails(index)

    # gets the information of the employee selected in the listbox and loads it into the right panel
    def showDetails(self, index):
        #get tme employee details from the selection
        name = self.names[index]
        ID = self.IDs[index]
        rate = self.rates[index]
        hol_rate = self.hol_rate[index]
        banked_hours = self.banked_hours[index]
        banked_salary = round(self.banked_salary[index], 2)
        #note event is passed but is not needed
        print("Hello dynamic label")
        try:
            # if the labels have already been created than destroy them so that another employees details can be
            # displayed
            self.employee_name.destroy()
            self.employee_ID.destroy()
            self.employee_rate.destroy()
            self.employee_hol_rate.destroy()
            self.employee_banked_hours.destroy()
            self.employee_banked_salary.destroy()
            print("Destroyed")
            # Now display the newly selected employees details in the right top panel
            # name
            self.employee_name = Label(self.rightFrame1,
                                       text=name,
                                       font="Ariel",
                                       bg="white")
            self.employee_name.grid(row=3, column=2, sticky="w")
            # ID
            self.employee_ID = Label(self.rightFrame1,
                                     text=ID,
                                     font="Ariel",
                                     bg="white")
            self.employee_ID.grid(row=2, column=2, sticky="w")
            # Rate
            self.employee_rate = Label(self.rightFrame1,
                                       text="£ {} per hour".format(rate),
                                       font="Ariel",
                                       bg="white")
            self.employee_rate.grid(row=4, column=2, sticky="w")
            # holiday Hours
            self.employee_hol_rate = Label(
                self.rightFrame1,
                text="£ {} per hour".format(hol_rate),
                font="Ariel",
                bg="white")
            self.employee_hol_rate.grid(row=5, column=2, sticky="w")
            # non holiday hours
            self.employee_banked_hours = Label(self.rightFrame1,
                                               text=banked_hours,
                                               font="Ariel",
                                               bg="white")
            self.employee_banked_hours.grid(row=6, column=2, sticky="w")
            # total hours
            self.employee_banked_salary = Label(
                self.rightFrame1,
                text="£ {}".format(banked_salary),
                font="Ariel",
                bg="white")
            self.employee_banked_salary.grid(row=7, column=2, sticky="w")

        except:
            # If it the first employee to be selected since the program was opened then you do not need to deastroy the
            # labels
            print("First Time")
            # name
            self.employee_name = Label(self.rightFrame1,
                                       text=name,
                                       font="Ariel",
                                       bg="white")
            self.employee_name.grid(row=3, column=2, sticky="w")
            # ID
            self.employee_ID = Label(self.rightFrame1,
                                     text=ID,
                                     font="Ariel",
                                     bg="white")
            self.employee_ID.grid(row=2, column=2, sticky="w")
            # Rate
            self.employee_rate = Label(self.rightFrame1,
                                       text="£ {} per hour".format(rate),
                                       font="Ariel",
                                       bg="white")
            self.employee_rate.grid(row=4, column=2, sticky="w")
            # holiday Hours
            self.employee_hol_rate = Label(
                self.rightFrame1,
                text="£ {} per hour".format(hol_rate),
                font="Ariel",
                bg="white")
            self.employee_hol_rate.grid(row=5, column=2, sticky="w")
            # non holiday hours
            self.employee_banked_hours = Label(self.rightFrame1,
                                               text=banked_hours,
                                               font="Ariel",
                                               bg="white")
            self.employee_banked_hours.grid(row=6, column=2, sticky="w")
            # total hours
            self.employee_banked_salary = Label(
                self.rightFrame1,
                text="£ {}".format(banked_salary),
                font="Ariel",
                bg="white")
            self.employee_banked_salary.grid(row=7, column=2, sticky="w")

    # When a window that has been previously called by the user e.g. new employee has been closed this function is
    # called. It grabs all the employees from the database and displays them in the list box (especially good if a new
    # employee has just been added). It then sets the previous selection in the listbox to the current selction and
    # grabs the data from the database and displays it in the top right panel
    def destroyTest(self, event):
        print("Testing Destroyed")
        self.viewAll()
        # self.showDetails(True)
        self.showDetails(self.currentSelectionIndex)
        self.list_box.select_set(self.currentSelectionIndex)

    # This function calls to the database and gets all the employee data from the database. It then puts thsi information
    # into lists, it then creates a list of lists and returns that to the caller
    def getLatestData(self):
        usersList = dbFunctionsV2.getAllUsers()
        self.names = []
        self.IDs = []
        self.rates = []
        self.hol_rate = []
        self.banked_hours = []
        self.banked_salary = []
        # put that into some List
        for a in usersList:
            self.names.append(a[1])
            self.IDs.append(a[0])
            self.rates.append(a[2])
            self.hol_rate.append(a[3])
            self.banked_hours.append(a[4])
            self.banked_salary.append(a[5])

        return (self.names, self.IDs, self.rates, self.hol_rate,
                self.banked_hours, self.banked_salary)

    # This function displays all the employees in the database into the list box
    def viewAll(self):
        # clear the list first
        self.list_box.delete(0, END)
        # get a list of the users from the database
        self.getLatestData()
        # the emumerate function gets the index from the list value, this index
        # is then used to get the corresponding ID value
        # This loop puts the employee name and ID into the list box for the user to select
        for (i, e) in enumerate(self.names):
            self.list_box.insert(END, "{} {}".format(self.IDs[i], e))

    # function that was used for some basic testing
    def add(self):
        self.number = self.number + 1
        #print(self.number)

    # function that was used for some basic testing
    def printNumber(self):
        return self.number

    # This function is called when the new Employee button is pressed in the bottom right panel
    def addTodB(self):
        # Get the value from the list_box
        selected = self.list_box.curselection()
        if selected:
            print(selected)
            for index in selected:
                print(self.list_box.get(index))
                name = self.list_box.get(index)
        else:
            name = "No Name"

        print("Open New Window")

        # Toplevel creates a window dependent on the Tk window
        root = Toplevel(self.window)
        # creates an instance of the UGUI class which opens the window to add an new employee
        userUpdateGUI = UGUI(root, name)
        # When the new employee window is closed the destroyNewUserWindow function is called
        root.bind("<Destroy>", self.destroyNewUserWindow)

    # When the add new employee window is closed this function is called
    # It selects the last employee in the listbox, which should be the new user and then shows their details
    def destroyNewUserWindow(self, message):
        self.viewAll()
        # self the last last item in the list which is the new users
        self.list_box.selection_set(len(self.names) - 1)
        print(len(self.names))
        self.showDetails(self.list_box.curselection()[0])

    # This functions deletes the employee that is selected in the listbox
    def deleteUser(self):
        print("Are you sure???")
        # get the ID of the current employee selected
        currentID = str(self.IDs[self.list_box.curselection()[0]])
        # check is the user meant to hit the cancel button
        answer = messagebox.askyesno(
            "Delete",
            "Are you user you want to delete employee {}?".format(currentID))
        # if the user does not want to delete the user than exit without deleting
        if not answer:
            return
        # call the database delete function passing the employee to be deleted ID
        dbFunctionsV2.deleteUser(currentID)
        # display the updated list of employees
        self.viewAll()
        # if there are no employees left in the database need to blank the details labels in the
        # right top panel
        print("Length of ID Array: ", len(self.IDs))
        if len(self.IDs) == 0:
            self.employee_name.destroy()
            self.employee_ID.destroy()
            self.employee_rate.destroy()
            self.employee_hol_rate.destroy()
            self.employee_banked_hours.destroy()
            self.employee_banked_salary.destroy()
        else:
            # select first item in list
            self.list_box.selection_set(0)
            # show data for current selection
            self.showDetails(self.list_box.curselection()[0])

    # this function is called when the employee details are to be editted
    def editEmployeeDetials(self):
        # get the details of the current selected employee
        BankedHours = float(self.banked_hours[self.list_box.curselection()[0]])
        BankedSalary = float(
            self.banked_salary[self.list_box.curselection()[0]])
        currentID = self.IDs[self.list_box.curselection()[0]]
        rate = float(self.rates[self.list_box.curselection()[0]])
        hol_rate = float(self.hol_rate[self.list_box.curselection()[0]])
        currentName = self.names[self.list_box.curselection()[0]]
        root = Toplevel(self.window)
        # create an instance of the editEmployeeDetails class and pass the employees details to it
        # this will launch an edit employee window for the user
        newWindow = editEmployeeDetails(root, currentID, currentName, rate,
                                        hol_rate)
        # save the position of the current selected employee in the list box
        self.currentSelectionIndex = self.list_box.curselection()[0]
        # When the window for the edit employee is closed run detroyTest function
        root.bind("<Destroy>", self.destroyTest)

    def finish(self):
        self.window.destroy()

    # this function is called when the user wants to add or subtract hours from the employees Hours Bank.
    # when the add hours button is pressed this function is called with remove = False, if the remove hours
    # button is pressed then remove = True.
    def ChangeHours(self, remove):
        # get the data for the selected employee
        BankedHours = float(self.banked_hours[self.list_box.curselection()[0]])
        BankedSalary = float(
            self.banked_salary[self.list_box.curselection()[0]])
        currentID = self.IDs[self.list_box.curselection()[0]]
        rate = float(self.rates[self.list_box.curselection()[0]])
        hol_rate = float(self.hol_rate[self.list_box.curselection()[0]])
        #if remove True then remove hours, if false then add hours
        # open a new window
        root = Toplevel(self.window)
        # create an instance of the class ChnageHoursWindow where the change hours window is launched
        ChangeHours = ChangeHoursWindow(root, BankedHours, BankedSalary,
                                        currentID, rate, hol_rate, remove)
        # have the slection in the list box that the user make`
        self.currentSelectionIndex = self.list_box.curselection()[0]
        # when the window to change hours is destroyed run the destroyTest function
        root.bind("<Destroy>", self.destroyTest)
class ChooseFilesPage(Frame):
    """Page for output files choice"""
    def __init__(self, parent, controller, *files):
        """
        Arguments:
            `parent` (Frame):
                Parent page

            `controller` (Tk):
                Main controller page

            `files` (list):
                Available .out files

        """

        super().__init__(parent)
        self.controller = controller
        self.files = sorted(files[0][0])
        self.init_UI()

    # Create main GUI window
    def init_UI(self):

        txt = "Select the file(s) you want to post-process"
        label = Label(self, text=txt, font=LARGE_FONT)
        label.grid(row=0, columnspan=2, sticky='w')

        label_entry = Label(self, text='Filter:')
        label_entry.grid(row=1, column=0, sticky='w')

        self.search_var = StringVar()
        self.search_var.trace("w",
                              lambda name, index, mode: self.update_list())
        self.entry = Entry(self, textvariable=self.search_var, width=13)
        self.entry.grid(row=1, column=1, sticky='w')

        self.lbox = Listbox(self, width=45, height=15, selectmode='multiple')
        self.lbox.grid(row=2, columnspan=2)

        bu = ttk.Button(self, text='Select all', command=self.select_all)
        bu.grid(row=3, columnspan=2, sticky='w')

        bu = ttk.Button(self, text='Unselect all', command=self.unselect_all)
        bu.grid(row=4, columnspan=2, sticky='w')

        txt = "Display selected files"
        # Command allowing comunication to controller (Tk), calling
        # raise_displayer_files method with selected files in self.data
        cmd = partial(self.controller.raise_displayer_files)
        bu = ttk.Button(self, text=txt, command=cmd)
        bu.grid(row=5, columnspan=2, sticky='w')

        # update_list needs to be called here to populate the listbox
        self.update_list()

    def update_list(self):
        """
        Update the list while doing the search with the filter Warning: the
        selection is reset when the listbox is updated!

        """

        search_term = self.search_var.get()

        # Generic list to populate the listbox
        lbox_list = self.files

        self.lbox.delete(0, END)

        for item in lbox_list:
            if search_term.lower() in item.lower():
                self.lbox.insert(END, item)

    def select_all(self):
        """Select all the file names"""

        self.lbox.select_set(0, END)

    def unselect_all(self):
        """Unselect all the file names"""

        self.lbox.select_clear(0, END)
示例#17
0
class LintGui(object):
    """Build and control a window to interact with pylint"""

    def __init__(self, root=None):
        """init"""
        self.root = root or Tk()
        self.root.title('Pylint')
        #reporter
        self.reporter = None
        #message queue for output from reporter
        self.msg_queue = queue.Queue()
        self.msgs = []
        self.visible_msgs = []
        self.filenames = []
        self.rating = StringVar()
        self.tabs = {}
        self.report_stream = BasicStream(self)
        #gui objects
        self.lb_messages = None
        self.showhistory = None
        self.results = None
        self.btnRun = None
        self.information_box = None
        self.convention_box = None
        self.refactor_box = None
        self.warning_box = None
        self.error_box = None
        self.fatal_box = None
        self.txtModule = None
        self.status = None
        self.msg_type_dict = None
        self.init_gui()

    def init_gui(self):
        """init helper"""
        #setting up frames
        top_frame = Frame(self.root)
        mid_frame = Frame(self.root)
        radio_frame = Frame(self.root)
        res_frame = Frame(self.root)
        msg_frame = Frame(self.root)
        check_frame = Frame(self.root)
        history_frame = Frame(self.root)
        btn_frame = Frame(self.root)
        rating_frame = Frame(self.root)
        top_frame.pack(side=TOP, fill=X)
        mid_frame.pack(side=TOP, fill=X)
        history_frame.pack(side=TOP, fill=BOTH, expand=True)
        radio_frame.pack(side=TOP, fill=BOTH, expand=True)
        rating_frame.pack(side=TOP, fill=BOTH, expand=True)
        res_frame.pack(side=TOP, fill=BOTH, expand=True)
        check_frame.pack(side=TOP, fill=BOTH, expand=True)
        msg_frame.pack(side=TOP, fill=BOTH, expand=True)
        btn_frame.pack(side=TOP, fill=X)

        # Binding F5 application-wide to run lint
        self.root.bind('<F5>', self.run_lint)

        #Message ListBox
        rightscrollbar = Scrollbar(msg_frame)
        rightscrollbar.pack(side=RIGHT, fill=Y)
        bottomscrollbar = Scrollbar(msg_frame, orient=HORIZONTAL)
        bottomscrollbar.pack(side=BOTTOM, fill=X)
        self.lb_messages = Listbox(msg_frame,
                  yscrollcommand=rightscrollbar.set,
                  xscrollcommand=bottomscrollbar.set,
                  bg="white")
        self.lb_messages.bind("<Double-Button-1>", self.show_sourcefile)
        self.lb_messages.pack(expand=True, fill=BOTH)
        rightscrollbar.config(command=self.lb_messages.yview)
        bottomscrollbar.config(command=self.lb_messages.xview)

        #History ListBoxes
        rightscrollbar2 = Scrollbar(history_frame)
        rightscrollbar2.pack(side=RIGHT, fill=Y)
        bottomscrollbar2 = Scrollbar(history_frame, orient=HORIZONTAL)
        bottomscrollbar2.pack(side=BOTTOM, fill=X)
        self.showhistory = Listbox(history_frame,
                    yscrollcommand=rightscrollbar2.set,
                    xscrollcommand=bottomscrollbar2.set,
                    bg="white")
        self.showhistory.pack(expand=True, fill=BOTH)
        rightscrollbar2.config(command=self.showhistory.yview)
        bottomscrollbar2.config(command=self.showhistory.xview)
        self.showhistory.bind('<Double-Button-1>', self.select_recent_file)
        self.set_history_window()

        #status bar
        self.status = Label(self.root, text="", bd=1, relief=SUNKEN, anchor=W)
        self.status.pack(side=BOTTOM, fill=X)

        #labelbl_ratingls
        lbl_rating_label = Label(rating_frame, text='Rating:')
        lbl_rating_label.pack(side=LEFT)
        lbl_rating = Label(rating_frame, textvariable=self.rating)
        lbl_rating.pack(side=LEFT)
        Label(mid_frame, text='Recently Used:').pack(side=LEFT)
        Label(top_frame, text='Module or package').pack(side=LEFT)

        #file textbox
        self.txt_module = Entry(top_frame, background='white')
        self.txt_module.bind('<Return>', self.run_lint)
        self.txt_module.pack(side=LEFT, expand=True, fill=X)

        #results box
        rightscrollbar = Scrollbar(res_frame)
        rightscrollbar.pack(side=RIGHT, fill=Y)
        bottomscrollbar = Scrollbar(res_frame, orient=HORIZONTAL)
        bottomscrollbar.pack(side=BOTTOM, fill=X)
        self.results = Listbox(res_frame,
                  yscrollcommand=rightscrollbar.set,
                  xscrollcommand=bottomscrollbar.set,
                  bg="white", font="Courier")
        self.results.pack(expand=True, fill=BOTH, side=BOTTOM)
        rightscrollbar.config(command=self.results.yview)
        bottomscrollbar.config(command=self.results.xview)

        #buttons
        Button(top_frame, text='Open', command=self.file_open).pack(side=LEFT)
        Button(top_frame, text='Open Package',
               command=(lambda: self.file_open(package=True))).pack(side=LEFT)

        self.btnRun = Button(top_frame, text='Run', command=self.run_lint)
        self.btnRun.pack(side=LEFT)
        Button(btn_frame, text='Quit', command=self.quit).pack(side=BOTTOM)

        #radio buttons
        self.information_box = IntVar()
        self.convention_box = IntVar()
        self.refactor_box = IntVar()
        self.warning_box = IntVar()
        self.error_box = IntVar()
        self.fatal_box = IntVar()
        i = Checkbutton(check_frame, text="Information", fg=COLORS['(I)'],
                        variable=self.information_box, command=self.refresh_msg_window)
        c = Checkbutton(check_frame, text="Convention", fg=COLORS['(C)'],
                        variable=self.convention_box, command=self.refresh_msg_window)
        r = Checkbutton(check_frame, text="Refactor", fg=COLORS['(R)'],
                        variable=self.refactor_box, command=self.refresh_msg_window)
        w = Checkbutton(check_frame, text="Warning", fg=COLORS['(W)'],
                        variable=self.warning_box, command=self.refresh_msg_window)
        e = Checkbutton(check_frame, text="Error", fg=COLORS['(E)'],
                        variable=self.error_box, command=self.refresh_msg_window)
        f = Checkbutton(check_frame, text="Fatal", fg=COLORS['(F)'],
                        variable=self.fatal_box, command=self.refresh_msg_window)
        i.select()
        c.select()
        r.select()
        w.select()
        e.select()
        f.select()
        i.pack(side=LEFT)
        c.pack(side=LEFT)
        r.pack(side=LEFT)
        w.pack(side=LEFT)
        e.pack(side=LEFT)
        f.pack(side=LEFT)

        #check boxes
        self.box = StringVar()
        # XXX should be generated
        report = Radiobutton(
            radio_frame, text="Report", variable=self.box,
            value="Report", command=self.refresh_results_window)
        raw_met = Radiobutton(
            radio_frame, text="Raw metrics", variable=self.box,
            value="Raw metrics", command=self.refresh_results_window)
        dup = Radiobutton(
            radio_frame, text="Duplication", variable=self.box,
            value="Duplication", command=self.refresh_results_window)
        ext = Radiobutton(
            radio_frame, text="External dependencies",
            variable=self.box, value="External dependencies",
            command=self.refresh_results_window)
        stat = Radiobutton(
            radio_frame, text="Statistics by type",
            variable=self.box, value="Statistics by type",
            command=self.refresh_results_window)
        msg_cat = Radiobutton(
            radio_frame, text="Messages by category",
            variable=self.box, value="Messages by category",
            command=self.refresh_results_window)
        msg = Radiobutton(
            radio_frame, text="Messages", variable=self.box,
            value="Messages", command=self.refresh_results_window)
        source_file = Radiobutton(
            radio_frame, text="Source File", variable=self.box,
            value="Source File", command=self.refresh_results_window)
        report.select()
        report.grid(column=0, row=0, sticky=W)
        raw_met.grid(column=1, row=0, sticky=W)
        dup.grid(column=2, row=0, sticky=W)
        msg.grid(column=3, row=0, sticky=W)
        stat.grid(column=0, row=1, sticky=W)
        msg_cat.grid(column=1, row=1, sticky=W)
        ext.grid(column=2, row=1, sticky=W)
        source_file.grid(column=3, row=1, sticky=W)

        #dictionary for check boxes and associated error term
        self.msg_type_dict = {
            'I': lambda: self.information_box.get() == 1,
            'C': lambda: self.convention_box.get() == 1,
            'R': lambda: self.refactor_box.get() == 1,
            'E': lambda: self.error_box.get() == 1,
            'W': lambda: self.warning_box.get() == 1,
            'F': lambda: self.fatal_box.get() == 1
        }
        self.txt_module.focus_set()


    def select_recent_file(self, event):
        """adds the selected file in the history listbox to the Module box"""
        if not self.showhistory.size():
            return

        selected = self.showhistory.curselection()
        item = self.showhistory.get(selected)
        #update module
        self.txt_module.delete(0, END)
        self.txt_module.insert(0, item)

    def refresh_msg_window(self):
        """refresh the message window with current output"""
        #clear the window
        self.lb_messages.delete(0, END)
        self.visible_msgs = []
        for msg in self.msgs:
            if self.msg_type_dict.get(msg.C)():
                self.visible_msgs.append(msg)
                msg_str = convert_to_string(msg)
                self.lb_messages.insert(END, msg_str)
                fg_color = COLORS.get(msg_str[:3], 'black')
                self.lb_messages.itemconfigure(END, fg=fg_color)

    def refresh_results_window(self):
        """refresh the results window with current output"""
        #clear the window
        self.results.delete(0, END)
        try:
            for res in self.tabs[self.box.get()]:
                self.results.insert(END, res)
        except:
            pass

    def process_incoming(self):
        """process the incoming messages from running pylint"""
        while self.msg_queue.qsize():
            try:
                msg = self.msg_queue.get(0)
                if msg == "DONE":
                    self.report_stream.output_contents()
                    return False

                #adding message to list of msgs
                self.msgs.append(msg)

                #displaying msg if message type is selected in check box
                if self.msg_type_dict.get(msg.C)():
                    self.visible_msgs.append(msg)
                    msg_str = convert_to_string(msg)
                    self.lb_messages.insert(END, msg_str)
                    fg_color = COLORS.get(msg_str[:3], 'black')
                    self.lb_messages.itemconfigure(END, fg=fg_color)

            except queue.Empty:
                pass
        return True

    def periodic_call(self):
        """determine when to unlock the run button"""
        if self.process_incoming():
            self.root.after(100, self.periodic_call)
        else:
            #enabling button so it can be run again
            self.btnRun.config(state=NORMAL)

    def mainloop(self):
        """launch the mainloop of the application"""
        self.root.mainloop()

    def quit(self, _=None):
        """quit the application"""
        self.root.quit()

    def halt(self):
        """program halt placeholder"""
        return

    def file_open(self, package=False, _=None):
        """launch a file browser"""
        if not package:
            filename = askopenfilename(parent=self.root, filetypes=[('pythonfiles', '*.py'),
                                                    ('allfiles', '*')], title='Select Module')
        else:
            filename = askdirectory(title="Select A Folder", mustexist=1)

        if filename == ():
            return

        self.txt_module.delete(0, END)
        self.txt_module.insert(0, filename)

    def update_filenames(self):
        """update the list of recent filenames"""
        filename = self.txt_module.get()
        if not filename:
            filename = os.getcwd()
        if filename+'\n' in self.filenames:
            index = self.filenames.index(filename+'\n')
            self.filenames.pop(index)

        #ensure only 10 most recent are stored
        if len(self.filenames) == 10:
            self.filenames.pop()
        self.filenames.insert(0, filename+'\n')

    def set_history_window(self):
        """update the history window with info from the history file"""
        #clear the window
        self.showhistory.delete(0, END)
        # keep the last 10 most recent files
        try:
            view_history = open(HOME+HISTORY, 'r')
            for hist in view_history.readlines():
                if not hist in self.filenames:
                    self.filenames.append(hist)
                self.showhistory.insert(END, hist.split('\n')[0])
            view_history.close()
        except IOError:
            # do nothing since history file will be created later
            return

    def run_lint(self, _=None):
        """launches pylint"""
        self.update_filenames()
        self.root.configure(cursor='watch')
        self.reporter = GUIReporter(self, output=self.report_stream)
        module = self.txt_module.get()
        if not module:
            module = os.getcwd()

        #cleaning up msgs and windows
        self.msgs = []
        self.visible_msgs = []
        self.lb_messages.delete(0, END)
        self.tabs = {}
        self.results.delete(0, END)
        self.btnRun.config(state=DISABLED)

        #setting up a worker thread to run pylint
        worker = Thread(target=lint_thread, args=(module, self.reporter, self,))
        self.periodic_call()
        worker.start()

        # Overwrite the .pylint-gui-history file with all the new recently added files
        # in order from filenames but only save last 10 files
        write_history = open(HOME+HISTORY, 'w')
        write_history.writelines(self.filenames)
        write_history.close()
        self.set_history_window()

        self.root.configure(cursor='')

    def show_sourcefile(self, event=None):
        selected = self.lb_messages.curselection()
        if not selected:
            return

        msg = self.visible_msgs[int(selected[0])]
        scroll = msg.line - 3
        if scroll < 0:
            scroll = 0

        self.tabs["Source File"] = open(msg.path, "r").readlines()
        self.box.set("Source File")
        self.refresh_results_window()
        self.results.yview(scroll)
        self.results.select_set(msg.line - 1)
示例#18
0
def openStats(handler):
    statsApi = get(
        "https://raw.githubusercontent.com/revoxhere/duco-statistics/master/api.json",
        data=None)
    if statsApi.status_code == 200:  #Check for reponse
        statsApi = (statsApi.json())
        print(statsApi)

    statsWindow = Toplevel()
    statsWindow.resizable(False, False)
    statsWindow.title("Duino-Coin Wallet - Stats")
    statsWindow.configure(background=backgroundColor)
    statsWindow.transient([root])

    textFont3 = Font(statsWindow, size=14, weight="bold")
    textFont = Font(statsWindow, size=12, weight="normal")

    Label(statsWindow,
          text="Duco Statistics",
          background=backgroundColor,
          foreground=foregroundColor,
          font=textFont3).grid(row=0, column=0)

    i = 3
    i2 = 3
    for key in statsApi.keys():
        if str(key) == 'Active workers' or str(
                key) == 'Top 10 richest miners' or str(
                    key) == 'Total supply' or str(
                        key) == 'Full last block hash' or str(
                            key) == 'GitHub API file update count' or str(
                                key) == 'Diff increases per':
            pass
        else:
            if len(statsApi.get(str(key))) > 8:
                Label(statsWindow,
                      text=f"{key}: {statsApi.get(str(key))}",
                      background=backgroundColor,
                      foreground=foregroundColor,
                      font=textFont).grid(row=i2, column=1, sticky=W)
                i2 += 1
            else:
                Label(statsWindow,
                      text=f"{key}: {statsApi.get(str(key))}",
                      background=backgroundColor,
                      foreground=foregroundColor,
                      font=textFont).grid(row=i, column=0, sticky=W)
                i += 1

    Active_workers_listbox = Listbox(statsWindow,
                                     exportselection=False,
                                     background=backgroundColor,
                                     foreground=foregroundColor,
                                     selectbackground="#7bed9f",
                                     border="0",
                                     font=textFont,
                                     width="20",
                                     height="13")
    Active_workers_listbox.grid(row=1, column=0, sticky=W)
    i = 0
    for worker in (statsApi['Active workers']).split(', '):
        Active_workers_listbox.insert(i, worker)
        i = i + 1

    Active_workers_listbox.select_set(32)
    Active_workers_listbox.event_generate("<<ListboxSelect>>")

    Top_10_listbox = Listbox(statsWindow,
                             exportselection=False,
                             background=backgroundColor,
                             foreground=foregroundColor,
                             selectbackground="#7bed9f",
                             border="0",
                             font=textFont,
                             width="33",
                             height="13")
    Top_10_listbox.grid(row=1, column=1, sticky=W)
    i = 0
    for rich in (statsApi['Top 10 richest miners']).split(', '):
        Top_10_listbox.insert(i, rich)
        i = i + 1

    Top_10_listbox.select_set(32)
    Top_10_listbox.event_generate("<<ListboxSelect>>")

    statsWindow.mainloop()
示例#19
0
class AlbumsPanel(Frame):

    def __init__(self, parent, albumsController: IAlbumsController):
        super().__init__(parent)
        self.albumsController = albumsController

        self.albumList: List[AlbumDb] = []
        self.selectedAlbumName: str = None

        self.musicFromDisc: List[Music] = []

        self.displayedMusicOnComputer = None
        self.displayedMusicInAlbum = None

        self.__initView()

    def __initView(self):
        self.grid_columnconfigure(0, weight=1)
        self.grid_rowconfigure(3, weight=1)

        self.albumsListBox = Listbox(self, exportselection=0)
        self.albumsListBox.grid(row=0, column=0, sticky='WE', padx=(10, 0), pady=10)
        self.albumsListBox.bind('<Double-1>', self.__albumDoubleClicked)
        self.albumsListBox.bind("<<ListboxSelect>>", self.__albumSelected)

        albumsScrollbar = Scrollbar(self, command=self.albumsListBox.yview)
        albumsScrollbar.grid(row=0, column=1, sticky='NS', padx=(0, 10), pady=10)

        self.albumsListBox.configure(yscrollcommand=albumsScrollbar.set)

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

        buttonsFrame = Frame(self)
        buttonsFrame.grid(row=1, column=0, sticky='W', padx=10)

        self.albumDeleteButton = Button(buttonsFrame, text=ALBUM_DELETE_TEXT, command=self.__deleteAlbum)
        self.albumDeleteButton.grid(row=0, column=0, padx=5)

        self.albumExportButton = Button(buttonsFrame, text=ALBUM_EXPORT_TEXT, command=self.__exportAlbumClicked)
        self.albumExportButton.grid(row=0, column=1, padx=5)

        self.albumImportButton = Button(buttonsFrame, text=ALBUM_IMPORT_TEXT, command=self.__importAlbumClicked)
        self.albumImportButton.grid(row=0, column=2, padx=5)

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

        createFrame = Frame(self)
        createFrame.grid(row=2, column=0, sticky='W', padx=10)

        label = Label(createFrame, text=ALBUM_CREATE_LABEL_TEXT)
        label.grid(row=0, column=0)

        self.createAlbumNameEntry = Entry(createFrame)
        self.createAlbumNameEntry.grid(row=0, column=1)

        self.createAlbumButton = Button(createFrame, text=ALBUM_CREATE_BUTTON_TEXT, command=self.__createAlbum)
        self.createAlbumButton.grid(row=0, column=2)

        ######################################################################################################
        # Music on computer

        musicFrame = Frame(self, padx=10, pady=10)
        musicFrame.grid(row=3, column=0, columnspan=2, sticky='WENS')
        musicFrame.grid_columnconfigure(0, weight=1)
        musicFrame.grid_columnconfigure(3, weight=1)
        musicFrame.grid_rowconfigure(1, weight=1)

        label = Label(musicFrame, text=MUSIC_ON_COMPUTER_TEXT)
        label.grid(row=0, column=0, sticky='W')

        self.musicOnComputerListBox = Listbox(musicFrame)
        self.musicOnComputerListBox.grid(row=1, column=0, sticky='WENS')

        musicOnComputerScrollbar = Scrollbar(musicFrame, command=self.musicOnComputerListBox.yview)
        musicOnComputerScrollbar.grid(row=1, column=1, sticky='NS')

        self.musicOnComputerListBox.configure(yscrollcommand=musicOnComputerScrollbar.set)

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

        buttonFrame = Frame(musicFrame, padx=10)
        buttonFrame.grid(row=1, column=2)

        self.removeFromAlbumButton = Button(buttonFrame, text='<<', command=self.__removeMusicFromAlbumClicked)
        self.removeFromAlbumButton.grid(row=0, column=0)

        self.addToAlbumButton = Button(buttonFrame, text='>>', command=self.__addMusicToAlbumClicked)
        self.addToAlbumButton.grid(row=1, column=0)

        ######################################################################################################
        #Music in album

        label = Label(musicFrame, text=MUSIC_IN_ALBUM_TEXT)
        label.grid(row=0, column=3, sticky='W')

        self.musicInAlbumListBox = Listbox(musicFrame)
        self.musicInAlbumListBox.grid(row=1, column=3, sticky='WENS')

        musicInAlbumScrollbar = Scrollbar(musicFrame, command=self.musicInAlbumListBox.yview)
        musicInAlbumScrollbar.grid(row=1, column=4, sticky='NS')

        self.musicInAlbumListBox.configure(yscrollcommand=musicInAlbumScrollbar.set)

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

    def displayAlbums(self, albums: List[AlbumDb], musicFromDisc: List[Music]):
        self.albumList = albums
        self.musicFromDisc = musicFromDisc

        self.albumsListBox.delete(0, 'end')
        for i in range(len(self.albumList)):
            a = self.albumList[i]
            self.albumsListBox.insert(i, a.name)

        if self.selectedAlbumName is not None:
            selectedIndex = -1
            for i in range(len(self.albumList)):
                if self.albumList[i].name == self.selectedAlbumName:
                    selectedIndex = i
                    break

            if selectedIndex >= 0:
                self.albumsListBox.select_set(selectedIndex)
                self.albumsListBox.event_generate("<<ListboxSelect>>")

    def __deleteAlbum(self):
        selection = self.albumsListBox.curselection()

        if len(selection) <= 0:
            messagebox.showwarning('Warning', DELETE_ALBUM_SELECT_TEXT)
            return

        self.albumsListBox.selection_clear(0, END)
        self.albumsListBox.event_generate("<<ListboxSelect>>")

        album = self.albumList[selection[0]]
        self.albumsController.deleteAlbum(album.name)

    def __createAlbum(self):
        name = self.createAlbumNameEntry.get()

        if name is None or name == '':
            messagebox.showwarning('Warning', CRATE_ALBUM_INSERT_NAME_TEXT)
            return

        self.albumsController.createAlbum(name)

    def __albumSelected(self, event):
        self.musicOnComputerListBox.delete(0, 'end')
        self.musicInAlbumListBox.delete(0, 'end')

        selection = self.albumsListBox.curselection()
        if len(selection) <= 0:
            return

        selectedAlbum = self.albumList[selection[0]]
        self.selectedAlbumName = selectedAlbum.name

        self.__lisMusicOnComputer(selectedAlbum)
        self.__lisMusicInAlbum(selectedAlbum)

    def __lisMusicOnComputer(self, album):
        musicInAlbum = set()
        for m in album.music:
            musicInAlbum.add(m.path)

        if self.musicFromDisc is None:
            return

        music = self.musicFromDisc.copy()
        music = filter(lambda m: m.path not in musicInAlbum, music)
        self.displayedMusicOnComputer = list(music)

        i = 0
        for m in self.displayedMusicOnComputer:
            self.musicOnComputerListBox.insert(i, m.filename)
            i = i + 1

    def __lisMusicInAlbum(self, album):
        musicOnDisc = set()
        if self.musicFromDisc is not None:
            for m in self.musicFromDisc:
                musicOnDisc.add(m.path)

        self.displayedMusicInAlbum = list(album.music)

        i = 0
        for m in self.displayedMusicInAlbum:
            description = os.path.basename(m.path)
            if m.path not in musicOnDisc:
                description = '<missing> ' + m.path

            self.musicInAlbumListBox.insert(i, description)
            i = i + 1

    def __addMusicToAlbumClicked(self):
        selection = self.albumsListBox.curselection()
        if len(selection) <= 0:
            return

        selectedAlbum = self.albumList[selection[0]]

        selection = self.musicOnComputerListBox.curselection()
        if len(selection) <= 0:
            messagebox.showwarning('Warning', ADD_TO_ALBUM_SELECT_TEXT)
            return

        selectedMusic = self.displayedMusicOnComputer[selection[0]]

        self.albumsController.addMusicToAlbum(selectedAlbum.name, selectedMusic.path)

    def __removeMusicFromAlbumClicked(self):
        selection = self.albumsListBox.curselection()
        if len(selection) <= 0:
            return

        selectedAlbum = self.albumList[selection[0]]

        selection = self.musicInAlbumListBox.curselection()
        if len(selection) <= 0:
            messagebox.showwarning('Warning', REMOVE_FROM_ALBUM_SELECT_TEXT)
            return

        selectedMusic = self.displayedMusicInAlbum[selection[0]]

        self.albumsController.removeMusicFromAlbum(selectedAlbum.name, selectedMusic.path)

    def __exportAlbumClicked(self):
        selection = self.albumsListBox.curselection()
        if len(selection) <= 0:
            messagebox.showwarning('Warning', EXPORT_ALBUM_SELECT_TEXT)
            return

        selectedAlbum = self.albumList[selection[0]]
        self.albumsController.exportAlbum(selectedAlbum.name)

    def __importAlbumClicked(self):
        self.albumsController.importAlbum()

    def __albumDoubleClicked(self, event):
        album = self.albumList[self.albumsListBox.curselection()[0]]
        self.albumsController.addAlbumToQueue(album)
示例#20
0
class ImageZip(Frame):
    def __init__(self, parent):

        # Bind Frame to self and begin UI
        Frame.__init__(self, parent)

        self.parent = parent

        self.onGetZipResults = {}
        self.imagetypes = [("Image file", "*.jpg"), ("Image file", "*.jpeg"),
                           ("Image file", "*.jfif"), ("Image file", "*.jpe"),
                           ("Image file", "*.jfi"), ("Image file", "*.jif")]

        self.initUI()

    def initUI(self):

        # Creating UI elements and action calls
        self.parent.title("JPEG 2 Zip Code")
        self.pack(fill=BOTH, expand=True)

        # Menu
        menubar = Menu(self.parent)

        fileMenu = Menu(menubar, tearoff=False)
        fileMenu.add_command(label="Open File(s)", command=self.onOpenFile)
        fileMenu.add_command(label="Exit", command=self.parent.quit)
        menubar.add_cascade(label="File", menu=fileMenu)

        self.editMenu = Menu(menubar, tearoff=False)
        self.editMenu.add_command(label="Select All", command=self.onSelectAll)
        self.editMenu.add_command(label="Deselect All",
                                  command=self.onDeselectAll)
        menubar.add_cascade(label="Edit", menu=self.editMenu)

        self.actionMenu = Menu(menubar, tearoff=False)
        self.actionMenu.add_command(label="Get ZIP Codes",
                                    command=self.onGetZIP)
        menubar.add_cascade(label="Action", menu=self.actionMenu)

        self.parent.config(menu=menubar)
        self.menuItemAccess(
            False)  # Disable unneeded menu items until files loaded

        # Listbox which will hold opened file names and allow selection
        self.listboxFiles = Listbox(self.parent, selectmode=EXTENDED)
        self.listboxFiles.pack(fill=BOTH, expand=True)

    def onDeselectAll(self):
        self.listboxFiles.select_clear(0, END)

    def onSelectAll(self):
        self.listboxFiles.select_set(0, END)

    # Takes in boolean, TRUE = allow access, FALSE = disable access
    def menuItemAccess(self, viewable):
        if viewable == True:
            self.editMenu.entryconfig(0, state=NORMAL)
            self.editMenu.entryconfig(1, state=NORMAL)
            self.actionMenu.entryconfig(0, state=NORMAL)
        if viewable == False:
            self.editMenu.entryconfig(0, state=DISABLED)
            self.editMenu.entryconfig(1, state=DISABLED)
            self.actionMenu.entryconfig(0, state=DISABLED)

    def badImageDialog(self, badimagefiles):

        # Takes in a list of files and produces a warning dialog
        fileerrors = ""

        for file in badimagefiles:
            fileerrors += str(file) + '\n'
        messagebox.showwarning(
            "Error Loading All Images",
            "Not all images were found to be valid. The following files will not be loaded...\n"
            + fileerrors)

    def onGetZIP(self):

        # Produces GPS, then ZIP codes for all selected files in the UI.
        geolocator = Nominatim(user_agent="JPEG2ZIP")
        selectedfiles = self.listboxFiles.curselection()
        for item in selectedfiles:
            currentFile = self.listboxFiles.get(item)
            currentGPS = getEXIF().load(currentFile)
            print(currentGPS)
            try:
                temp = geolocator.reverse(currentGPS)
                currentZIP = temp.raw['address']['postcode']

            except:  # If ZIP code not found or coords are (0.0, 0.0)
                currentZIP = "Error"

            # Unused right now but still saved.
            # Adds {index: FileName, GPS Coords, ZIP code} to dictionary
            self.onGetZipResults.update(
                {item: (currentFile, getEXIF().load(currentFile), currentZIP)})

            #Update UI
            self.listboxFiles.delete(item)
            self.listboxFiles.insert(item, currentFile + '    ' + currentZIP)

        #print(self.onGetZipResults)

    def onOpenFile(self):

        # TODO: Grab and display thumbnails with file name.

        fl = filedialog.askopenfilenames(filetypes=self.imagetypes)

        # Image validity check and update UI with file names
        print('Opening...')
        badimagefiles = []
        if fl != '':
            for file in fl:
                if (self.isValidJPEG(file) == True):  # is valid
                    print('\t' + file)
                    self.listboxFiles.insert(END, file)

                if (self.isValidJPEG(file) == False):  # is invalid
                    badimagefiles.append(file)

        if len(badimagefiles) > 0:  # push bad images to dialog box
            self.badImageDialog(badimagefiles)

        # Enable Menu items
        self.menuItemAccess(True)

    def isValidJPEG(self, imageFile):

        # TODO: use library to check validity of image. No need to reinvent the wheel.
        try:
            data = open(imageFile, 'rb').read(11)  #read first 11 bytes

            # All JPEG image files start off with SOI '0xff 0xd8'.
            # This is slightly unnecessary. See TODO above.
            if data[:2] != b'\xff\xd8':  #Bad SOI
                return False
            return True

        except:
            print("Image Validation Error: Unable to open image " +
                  imageFile)  # sanity check (print to console)
            return False
示例#21
0
class InstanceEditor(Toplevel):

    def __init__(self):
        Toplevel.__init__(self)
        self.focus_set()
        self.grab_set()

        self.result = None
        self.module_data = None
        self.mod_applis = None
        self.title(ugettext("Instance editor"))
        self.grid_columnconfigure(0, weight=1)
        self.grid_rowconfigure(0, weight=1)

        self.ntbk = ttk.Notebook(self)
        self.ntbk.grid(row=0, column=0, columnspan=1, sticky=(N, S, E, W))

        self.frm_general = Frame(self.ntbk, width=350, height=150)
        self.frm_general.grid_columnconfigure(0, weight=0)
        self.frm_general.grid_columnconfigure(1, weight=1)
        self._general_tabs()
        self.ntbk.add(self.frm_general, text=ugettext('General'))

        self.frm_database = Frame(self.ntbk, width=350, height=150)
        self.frm_database.grid_columnconfigure(0, weight=0)
        self.frm_database.grid_columnconfigure(1, weight=1)
        self._database_tabs()
        self.ntbk.add(self.frm_database, text=ugettext('Database'))

        btnframe = Frame(self, bd=1)
        btnframe.grid(row=1, column=0, columnspan=1)
        Button(btnframe, text=ugettext("OK"), width=10, command=self.apply).grid(
            row=0, column=0, sticky=(N, S, E))
        Button(btnframe, text=ugettext("Cancel"), width=10, command=self.destroy).grid(
            row=0, column=1, sticky=(N, S, W))

    def _database_tabs(self):
        Label(self.frm_database, text=ugettext("Type")).grid(
            row=0, column=0, sticky=(N, W), padx=5, pady=3)
        self.typedb = ttk.Combobox(
            self.frm_database, textvariable=StringVar(), state=READLONY)
        self.typedb.bind("<<ComboboxSelected>>", self.typedb_selection)
        self.typedb.grid(row=0, column=1, sticky=(N, S, E, W), padx=5, pady=3)
        Label(self.frm_database, text=ugettext("Name")).grid(
            row=1, column=0, sticky=(N, W), padx=5, pady=3)
        self.namedb = Entry(self.frm_database)
        self.namedb.grid(row=1, column=1, sticky=(N, S, E, W), padx=5, pady=3)
        Label(self.frm_database, text=ugettext("User")).grid(
            row=2, column=0, sticky=(N, W), padx=5, pady=3)
        self.userdb = Entry(self.frm_database)
        self.userdb.grid(row=2, column=1, sticky=(N, S, E, W), padx=5, pady=3)
        Label(self.frm_database, text=ugettext("Password")).grid(
            row=3, column=0, sticky=(N, W), padx=5, pady=3)
        self.pwddb = Entry(self.frm_database)
        self.pwddb.grid(row=3, column=1, sticky=(N, S, E, W), padx=5, pady=3)

    def _general_tabs(self):
        Label(self.frm_general, text=ugettext("Name")).grid(
            row=0, column=0, sticky=(N, W), padx=5, pady=3)
        self.name = Entry(self.frm_general)
        self.name.grid(row=0, column=1, sticky=(N, S, E, W), padx=5, pady=3)
        Label(self.frm_general, text=ugettext("Appli")).grid(
            row=1, column=0, sticky=(N, W), padx=5, pady=3)
        self.applis = ttk.Combobox(
            self.frm_general, textvariable=StringVar(), state=READLONY)
        self.applis.bind("<<ComboboxSelected>>", self.appli_selection)
        self.applis.grid(row=1, column=1, sticky=(N, S, E, W), padx=5, pady=3)
        Label(self.frm_general, text=ugettext("Modules")).grid(
            row=2, column=0, sticky=(N, W), padx=5, pady=3)
        self.modules = Listbox(self.frm_general, selectmode=EXTENDED)
        self.modules.configure(exportselection=False)
        self.modules.grid(row=2, column=1, sticky=(N, S, E, W), padx=5, pady=3)
        Label(self.frm_general, text=ugettext("Language")).grid(
            row=3, column=0, sticky=(N, W), padx=5, pady=3)
        self.language = ttk.Combobox(
            self.frm_general, textvariable=StringVar(), state=READLONY)
        self.language.grid(
            row=3, column=1, sticky=(N, S, E, W), padx=5, pady=3)
        Label(self.frm_general, text=ugettext("CORE-connectmode")
              ).grid(row=4, column=0, sticky=(N, W), padx=5, pady=3)
        self.mode = ttk.Combobox(
            self.frm_general, textvariable=StringVar(), state=READLONY)
        self.mode.bind("<<ComboboxSelected>>", self.mode_selection)
        self.mode.grid(row=4, column=1, sticky=(N, S, E, W), padx=5, pady=3)
        Label(self.frm_general, text=ugettext("Password")).grid(
            row=5, column=0, sticky=(N, W), padx=5, pady=3)
        self.password = Entry(self.frm_general, show="*")
        self.password.grid(
            row=5, column=1, sticky=(N, S, E, W), padx=5, pady=3)

    def typedb_selection(self, event):

        visible = list(self.typedb[VALUES]).index(self.typedb.get()) != 0
        for child_cmp in self.frm_database.winfo_children()[2:]:
            if visible:
                child_cmp.config(state=NORMAL)
            else:
                child_cmp.config(state=DISABLED)

    def appli_selection(self, event):
        if self.applis.get() != '':
            appli_id = list(self.applis[VALUES]).index(self.applis.get())
            luct_glo = LucteriosGlobal()
            current_inst_names = luct_glo.listing()
            appli_root_name = self.mod_applis[appli_id][0].split('.')[-1]
            default_name_idx = 1
            while appli_root_name + six.text_type(default_name_idx) in current_inst_names:
                default_name_idx += 1
            self.name.delete(0, END)
            self.name.insert(
                0, appli_root_name + six.text_type(default_name_idx))
            mod_depended = self.mod_applis[appli_id][2]
            self.modules.select_clear(0, self.modules.size())
            for mod_idx in range(len(self.module_data)):
                current_mod = self.module_data[mod_idx]
                if current_mod in mod_depended:
                    self.modules.selection_set(mod_idx)

    def mode_selection(self, event):
        visible = list(self.mode[VALUES]).index(self.mode.get()) != 2
        for child_cmp in self.frm_general.winfo_children()[-2:]:
            if visible:
                child_cmp.config(state=NORMAL)
            else:
                child_cmp.config(state=DISABLED)

    def apply(self):
        from lucterios.framework.settings import DEFAULT_LANGUAGES, get_locale_lang
        if self.name.get() == '':
            showerror(ugettext("Instance editor"), ugettext("Name empty!"))
            return
        if self.applis.get() == '':
            showerror(ugettext("Instance editor"), ugettext("No application!"))
            return
        db_param = "%s:name=%s,user=%s,password=%s" % (
            self.typedb.get(), self.namedb.get(), self.userdb.get(), self.pwddb.get())
        security = "MODE=%s" % list(
            self.mode[VALUES]).index(self.mode.get())
        if self.password.get() != '':
            security += ",PASSWORD=%s" % self.password.get()
        module_list = [
            self.module_data[int(item)] for item in self.modules.curselection()]
        appli_id = list(self.applis[VALUES]).index(self.applis.get())
        current_lang = get_locale_lang()
        for lang in DEFAULT_LANGUAGES:
            if lang[1] == self.language.get():
                current_lang = lang[0]
        self.result = (self.name.get(), self.mod_applis[appli_id][
                       0], ",".join(module_list), security, db_param, current_lang)
        self.destroy()

    def _load_current_data(self, instance_name):
        from lucterios.framework.settings import DEFAULT_LANGUAGES, get_locale_lang
        lct_inst = LucteriosInstance(instance_name)
        lct_inst.read()
        self.name.delete(0, END)
        self.name.insert(0, lct_inst.name)
        self.name.config(state=DISABLED)
        applis_id = 0
        for appli_iter in range(len(self.mod_applis)):
            if self.mod_applis[appli_iter][0] == lct_inst.appli_name:
                applis_id = appli_iter
                break
        self.applis.current(applis_id)
        if lct_inst.extra['']['mode'] is not None:
            self.mode.current(lct_inst.extra['']['mode'][0])
        else:
            self.mode.current(2)
        self.mode_selection(None)
        typedb_index = 0
        for typedb_idx in range(len(self.typedb[VALUES])):
            if self.typedb[VALUES][typedb_idx].lower() == lct_inst.database[0].lower():
                typedb_index = typedb_idx
                break
        self.typedb.current(typedb_index)
        self.typedb.config(state=DISABLED)
        self.typedb_selection(None)
        self.namedb.delete(0, END)
        if 'name' in lct_inst.database[1].keys():
            self.namedb.insert(0, lct_inst.database[1]['name'])
        self.userdb.delete(0, END)
        if 'user' in lct_inst.database[1].keys():
            self.userdb.insert(0, lct_inst.database[1]['user'])
        self.pwddb.delete(0, END)
        if 'password' in lct_inst.database[1].keys():
            self.pwddb.insert(0, lct_inst.database[1]['password'])
        self.modules.select_clear(0, self.modules.size())
        for mod_idx in range(len(self.module_data)):
            current_mod = self.module_data[mod_idx]
            if current_mod in lct_inst.modules:
                self.modules.select_set(mod_idx)
        current_lang = get_locale_lang()
        if 'LANGUAGE_CODE' in lct_inst.extra.keys():
            current_lang = lct_inst.extra['LANGUAGE_CODE']
        for lang in DEFAULT_LANGUAGES:
            if lang[0] == current_lang:
                self.language.current(self.language[VALUES].index(lang[1]))

    def execute(self, instance_name=None):
        from lucterios.framework.settings import DEFAULT_LANGUAGES, get_locale_lang
        self.mode[VALUES] = [ugettext(
            "CORE-connectmode.0"), ugettext("CORE-connectmode.1"), ugettext("CORE-connectmode.2")]
        self.language[VALUES] = [lang[1] for lang in DEFAULT_LANGUAGES]
        self.typedb[VALUES] = ["SQLite", "MySQL", "PostgreSQL"]
        lct_glob = LucteriosGlobal()
        _, self.mod_applis, mod_modules = lct_glob.installed()
        self.mod_applis.sort(key=lambda item: get_module_title(item[0]))
        self.modules.delete(0, END)
        self.module_data = []
        module_list = []
        for mod_module_item in mod_modules:
            module_list.append(
                (get_module_title(mod_module_item[0]), mod_module_item[0]))
        module_list.sort(key=lambda module: module[0])
        for module_title, module_name in module_list:
            self.modules.insert(END, module_title)
            self.module_data.append(module_name)
        appli_list = []
        for mod_appli_item in self.mod_applis:
            appli_list.append(get_module_title(mod_appli_item[0]))
        self.applis[VALUES] = appli_list
        if instance_name is not None:
            self._load_current_data(instance_name)
        else:
            self.typedb.current(0)
            self.mode.current(2)
            if len(appli_list) > 0:
                self.applis.current(0)
            self.appli_selection(None)
            self.mode_selection(None)
            self.typedb_selection(None)
            for lang in DEFAULT_LANGUAGES:
                if lang[0] == get_locale_lang():
                    self.language.current(self.language[VALUES].index(lang[1]))
        center(self)
示例#22
0
class InstanceEditor(Toplevel, EditorInstance):
    def __init__(self):
        Toplevel.__init__(self)
        EditorInstance.__init__(self)
        self.focus_set()
        self.grab_set()

        self.result = None
        self.module_data = None
        self.mod_applis = None
        self.title(ugettext("Instance editor"))
        self.grid_columnconfigure(0, weight=1)
        self.grid_rowconfigure(0, weight=1)

        self.ntbk = ttk.Notebook(self)
        self.ntbk.grid(row=0, column=0, columnspan=1, sticky=(N, S, E, W))

        self.frm_general = Frame(self.ntbk, width=350, height=150)
        self.frm_general.grid_columnconfigure(0, weight=0)
        self.frm_general.grid_columnconfigure(1, weight=1)
        self._general_tabs()
        self.ntbk.add(self.frm_general, text=ugettext('General'))

        self.frm_database = Frame(self.ntbk, width=350, height=150)
        self.frm_database.grid_columnconfigure(0, weight=0)
        self.frm_database.grid_columnconfigure(1, weight=1)
        self._database_tabs()
        self.ntbk.add(self.frm_database, text=ugettext('Database'))

        btnframe = Frame(self, bd=1)
        btnframe.grid(row=1, column=0, columnspan=1)
        Button(btnframe, text=ugettext("OK"), width=10,
               command=self.apply).grid(row=0, column=0, sticky=(N, S, E))
        Button(btnframe,
               text=ugettext("Cancel"),
               width=10,
               command=self.destroy).grid(row=0, column=1, sticky=(N, S, W))

    def _database_tabs(self):
        Label(self.frm_database, text=ugettext("Type")).grid(row=0,
                                                             column=0,
                                                             sticky=(N, W),
                                                             padx=5,
                                                             pady=3)
        self.typedb = ttk.Combobox(self.frm_database,
                                   textvariable=StringVar(),
                                   state=READLONY)
        self.typedb.bind("<<ComboboxSelected>>", self.typedb_selection)
        self.typedb.grid(row=0, column=1, sticky=(N, S, E, W), padx=5, pady=3)
        Label(self.frm_database, text=ugettext("Name")).grid(row=1,
                                                             column=0,
                                                             sticky=(N, W),
                                                             padx=5,
                                                             pady=3)
        self.namedb = Entry(self.frm_database)
        self.namedb.grid(row=1, column=1, sticky=(N, S, E, W), padx=5, pady=3)
        Label(self.frm_database, text=ugettext("User")).grid(row=2,
                                                             column=0,
                                                             sticky=(N, W),
                                                             padx=5,
                                                             pady=3)
        self.userdb = Entry(self.frm_database)
        self.userdb.grid(row=2, column=1, sticky=(N, S, E, W), padx=5, pady=3)
        Label(self.frm_database, text=ugettext("Password")).grid(row=3,
                                                                 column=0,
                                                                 sticky=(N, W),
                                                                 padx=5,
                                                                 pady=3)
        self.pwddb = Entry(self.frm_database)
        self.pwddb.grid(row=3, column=1, sticky=(N, S, E, W), padx=5, pady=3)

    def _general_tabs(self):
        Label(self.frm_general, text=ugettext("Name")).grid(row=0,
                                                            column=0,
                                                            sticky=(N, W),
                                                            padx=5,
                                                            pady=3)
        self.name = Entry(self.frm_general)
        self.name.grid(row=0, column=1, sticky=(N, S, E, W), padx=5, pady=3)
        Label(self.frm_general, text=ugettext("Appli")).grid(row=1,
                                                             column=0,
                                                             sticky=(N, W),
                                                             padx=5,
                                                             pady=3)
        self.applis = ttk.Combobox(self.frm_general,
                                   textvariable=StringVar(),
                                   state=READLONY)
        self.applis.bind("<<ComboboxSelected>>", self.appli_selection)
        self.applis.grid(row=1, column=1, sticky=(N, S, E, W), padx=5, pady=3)
        Label(self.frm_general, text=ugettext("Modules")).grid(row=2,
                                                               column=0,
                                                               sticky=(N, W),
                                                               padx=5,
                                                               pady=3)
        self.modules = Listbox(self.frm_general, selectmode=EXTENDED)
        self.modules.configure(exportselection=False)
        self.modules.grid(row=2, column=1, sticky=(N, S, E, W), padx=5, pady=3)
        Label(self.frm_general, text=ugettext("Language")).grid(row=3,
                                                                column=0,
                                                                sticky=(N, W),
                                                                padx=5,
                                                                pady=3)
        self.language = ttk.Combobox(self.frm_general,
                                     textvariable=StringVar(),
                                     state=READLONY)
        self.language.grid(row=3,
                           column=1,
                           sticky=(N, S, E, W),
                           padx=5,
                           pady=3)
        Label(self.frm_general,
              text=ugettext("CORE-connectmode")).grid(row=4,
                                                      column=0,
                                                      sticky=(N, W),
                                                      padx=5,
                                                      pady=3)
        self.mode = ttk.Combobox(self.frm_general,
                                 textvariable=StringVar(),
                                 state=READLONY)
        self.mode.bind("<<ComboboxSelected>>", self.mode_selection)
        self.mode.grid(row=4, column=1, sticky=(N, S, E, W), padx=5, pady=3)
        Label(self.frm_general, text=ugettext("Password")).grid(row=5,
                                                                column=0,
                                                                sticky=(N, W),
                                                                padx=5,
                                                                pady=3)
        self.password = Entry(self.frm_general, show="*")
        self.password.grid(row=5,
                           column=1,
                           sticky=(N, S, E, W),
                           padx=5,
                           pady=3)

    def typedb_selection(self, event):

        visible = list(self.typedb[VALUES]).index(self.typedb.get()) != 0
        for child_cmp in self.frm_database.winfo_children()[2:]:
            if visible:
                child_cmp.config(state=NORMAL)
            else:
                child_cmp.config(state=DISABLED)

    def appli_selection(self, event):
        if self.applis.get() != '':
            appli_id = list(self.applis[VALUES]).index(self.applis.get())
            luct_glo = LucteriosGlobal()
            current_inst_names = luct_glo.listing()
            appli_root_name = self.mod_applis[appli_id][0].split('.')[-1]
            default_name_idx = 1
            while appli_root_name + six.text_type(
                    default_name_idx) in current_inst_names:
                default_name_idx += 1
            self.name.delete(0, END)
            self.name.insert(0,
                             appli_root_name + six.text_type(default_name_idx))
            mod_depended = self.mod_applis[appli_id][2]
            self.modules.select_clear(0, self.modules.size())
            for mod_idx in range(len(self.module_data)):
                current_mod = self.module_data[mod_idx]
                if current_mod in mod_depended:
                    self.modules.selection_set(mod_idx)

    def mode_selection(self, event):
        visible = list(self.mode[VALUES]).index(self.mode.get()) != 2
        for child_cmp in self.frm_general.winfo_children()[-2:]:
            if visible:
                child_cmp.config(state=NORMAL)
            else:
                child_cmp.config(state=DISABLED)

    def apply(self):
        from lucterios.framework.settings import DEFAULT_LANGUAGES, get_locale_lang
        if self.is_new_instance and (
            (self.name.get() == '') or
            (self.name_rull.match(self.name.get()) is None)):
            showerror(ugettext("Instance editor"), ugettext("Name invalid!"))
            return
        if self.applis.get() == '':
            showerror(ugettext("Instance editor"), ugettext("No application!"))
            return
        db_param = "%s:name=%s,user=%s,password=%s" % (
            self.typedb.get(), self.namedb.get(), self.userdb.get(),
            self.pwddb.get())
        security = "MODE=%s" % list(self.mode[VALUES]).index(self.mode.get())
        if self.password.get() != '':
            security += ",PASSWORD=%s" % self.password.get()
        module_list = [
            self.module_data[int(item)]
            for item in self.modules.curselection()
        ]
        appli_id = list(self.applis[VALUES]).index(self.applis.get())
        current_lang = get_locale_lang()
        for lang in DEFAULT_LANGUAGES:
            if lang[1] == self.language.get():
                current_lang = lang[0]
        self.result = (self.name.get(), self.mod_applis[appli_id][0],
                       ",".join(module_list), security, db_param, current_lang)
        self.destroy()

    def _load_current_data(self, instance_name):
        from lucterios.framework.settings import DEFAULT_LANGUAGES
        lct_inst, applis_id, mode_id, typedb_index, current_lang = self._get_instance_elements(
            instance_name)

        self.is_new_instance = False
        self.name.delete(0, END)
        self.name.insert(0, lct_inst.name)
        self.name.config(state=DISABLED)
        self.applis.current(applis_id)
        self.mode.current(mode_id)
        self.mode_selection(None)
        self.typedb.current(typedb_index)
        self.typedb.config(state=DISABLED)
        self.typedb_selection(None)
        self.namedb.delete(0, END)
        if 'name' in lct_inst.database[1].keys():
            self.namedb.insert(0, lct_inst.database[1]['name'])
        self.userdb.delete(0, END)
        if 'user' in lct_inst.database[1].keys():
            self.userdb.insert(0, lct_inst.database[1]['user'])
        self.pwddb.delete(0, END)
        if 'password' in lct_inst.database[1].keys():
            self.pwddb.insert(0, lct_inst.database[1]['password'])
        self.modules.select_clear(0, self.modules.size())
        for mod_idx in range(len(self.module_data)):
            current_mod = self.module_data[mod_idx]
            if current_mod in lct_inst.modules:
                self.modules.select_set(mod_idx)
        for lang in DEFAULT_LANGUAGES:
            if lang[0] == current_lang:
                self.language.current(self.language[VALUES].index(lang[1]))

    def execute(self, instance_name=None):
        from lucterios.framework.settings import DEFAULT_LANGUAGES, get_locale_lang
        self._define_values()

        self.module_data = []
        self.modules.delete(0, END)
        for module_title, module_name in self.module_list:
            self.modules.insert(END, module_title)
            self.module_data.append(module_name)

        self.mode[VALUES] = self.mode_values
        self.language[VALUES] = self.lang_values
        self.typedb[VALUES] = self.dbtype_values
        self.applis[VALUES] = self.appli_list
        if instance_name is not None:
            self._load_current_data(instance_name)
        else:
            self.typedb.current(0)
            self.mode.current(2)
            if len(self.appli_list) > 0:
                self.applis.current(0)
            self.appli_selection(None)
            self.mode_selection(None)
            self.typedb_selection(None)
            for lang in DEFAULT_LANGUAGES:
                if lang[0] == get_locale_lang():
                    self.language.current(self.language[VALUES].index(lang[1]))
        center(self)
示例#23
0
class SettingsFrame(Frame):
    """
    Frame inheritance class for application settings and controls.
    """
    def __init__(self, app, *args, **kwargs):
        """
        Constructor
        """

        self.__app = app  # Reference to main application class
        self.__master = self.__app.get_master()  # Reference to root class (Tk)
        Frame.__init__(self, self.__master, *args, **kwargs)

        #  Initialise up key variables
        self._image_num = 0
        self._image_name = "image"
        self._settype = StringVar()
        self._zoom = DoubleVar()
        self._radius = DoubleVar()
        self._exponent = IntVar()
        self._zx_off = DoubleVar()
        self._zy_off = DoubleVar()
        self._cx_off = DoubleVar()
        self._cy_off = DoubleVar()
        self._maxiter = IntVar()
        self._zx_coord = DoubleVar()
        self._zy_coord = DoubleVar()
        self._theme = StringVar()
        self._shift = IntVar()
        self._themes = None
        self._filename = StringVar()
        self._filepath = None
        self._frames = IntVar()
        self._zoominc = DoubleVar()
        self._autoiter = IntVar()
        self._autosave = IntVar()
        self._validsettings = True

        self.body()

    def body(self):
        """
        Set up frame and widgets.
        """

        # Create settings panel widgets
        # pylint: disable=W0108
        self.lbl_settype = Label(self, text=LBLMODE)
        self.spn_settype = Spinbox(
            self,
            values=("BurningShip", "Tricorn", "Julia", "Mandelbrot"),
            width=8,
            bg=GOOD,
            wrap=True,
            textvariable=self._settype,
        )
        self.lbl_zoom = Label(self, text=LBLZOOM)
        self.ent_zoom = Entry(
            self,
            border=2,
            relief="sunken",
            width=12,
            bg=GOOD,
            justify=RIGHT,
            textvariable=self._zoom,
        )
        self.lbl_zoominc = Label(self, text=LBLZOOMINC, justify=LEFT)
        self.ent_zoominc = Entry(self,
                                 width=5,
                                 border=2,
                                 bg=GOOD,
                                 justify=RIGHT,
                                 textvariable=self._zoominc)
        self.lbl_zx_off = Label(self, text=LBLZXOFF)
        self.ent_zx_off = Entry(
            self,
            border=2,
            relief="sunken",
            width=12,
            bg=GOOD,
            justify=RIGHT,
            textvariable=self._zx_off,
        )
        self.lbl_zy_off = Label(self, text=LBLZYOFF)
        self.ent_zy_off = Entry(
            self,
            border=2,
            relief="sunken",
            width=12,
            bg=GOOD,
            justify=RIGHT,
            textvariable=self._zy_off,
        )
        self.lbl_cx_off = Label(self, text=LBLCX)
        self.ent_cx_off = Entry(
            self,
            border=2,
            relief="sunken",
            width=12,
            bg=GOOD,
            justify=RIGHT,
            textvariable=self._cx_off,
            state=DISABLED,
        )
        self.lbl_cy_off = Label(self, text=LBLCY)
        self.ent_cy_off = Entry(
            self,
            border=2,
            relief="sunken",
            width=12,
            bg=GOOD,
            justify=RIGHT,
            textvariable=self._cy_off,
            state=DISABLED,
        )
        self.lbl_niter = Label(self, text=LBLITER, justify=LEFT)
        self.ent_maxiter = Entry(
            self,
            border=2,
            relief="sunken",
            bg=GOOD,
            width=8,
            justify=RIGHT,
            textvariable=self._maxiter,
        )
        self.chk_autoiter = Checkbutton(self,
                                        text="Auto",
                                        variable=self._autoiter,
                                        onvalue=1,
                                        offvalue=0)
        self.lbl_theme = Label(self, text=LBLTHEME, justify=LEFT)
        self.lbl_radius = Label(self, text=LBLRAD, justify=LEFT)
        self.ent_radius = Entry(
            self,
            border=2,
            relief="sunken",
            bg=GOOD,
            width=8,
            justify=RIGHT,
            textvariable=self._radius,
        )
        self.lbl_exp = Label(self, text=LBLEXP)
        self.spn_exp = Spinbox(
            self,
            border=2,
            relief="sunken",
            bg=GOOD,
            width=4,
            from_=2,
            to=20,
            wrap=True,
            textvariable=self._exponent,
        )
        self.sep_1 = ttk.Separator(
            self,
            orient=HORIZONTAL,
        )
        self.lbx_theme = Listbox(
            self,
            border=2,
            relief="sunken",
            bg=GOOD,
            width=6,
            height=5,
            justify=LEFT,
            exportselection=False,
        )
        self.lbl_shift = Label(self, text=LBLSHIFT, justify=LEFT)
        self.scl_shift = Scale(
            self,
            from_=0,
            to=100,
            orient=HORIZONTAL,
            variable=self._shift,
            border=2,
            relief="sunken",
            sliderlength=20,
            troughcolor=GOOD,
        )
        self.scrollbar = Scrollbar(self, orient=VERTICAL)
        self.lbx_theme.config(yscrollcommand=self.scrollbar.set)
        self.scrollbar.config(command=self.lbx_theme.yview)
        self.lbx_theme.select_set(0)
        self.lbx_theme.event_generate("<<ListboxSelect>>")
        self.lbl_coords = Label(self, text="Re, Im", fg="grey")
        self.btn_plot = Button(
            self,
            text=BTNPLOT,
            width=8,
            fg="green",
            command=lambda: self.__app.frm_fractal.plot(),
        )
        self.btn_cancel = Button(
            self,
            text=BTNCAN,
            width=8,
            command=lambda: self.__app.frm_fractal.cancel_press(),
        )
        self.btn_reset = Button(self, text=BTNRST, width=8, command=self.reset)
        self.ent_save = Entry(
            self,
            textvariable=self._filename,
            width=6,
            border=2,
            relief="sunken",
            bg=GOOD,
            justify=LEFT,
        )
        self._filename.set(self._image_name + str(self._image_num))
        self.btn_save = Button(self,
                               text=BTNSAVE,
                               width=8,
                               command=self.save_image)
        self.lbl_auto = Label(self, text=LBLAUTO, justify=LEFT)
        self.btn_autozoom = Button(
            self,
            text=BTNZOOM,
            width=8,
            command=lambda: self.__app.frm_fractal.animate_zoom(),
        )
        self.btn_autospin = Button(
            self,
            text=BTNSPIN,
            width=8,
            command=lambda: self.__app.frm_fractal.animate_spin(),
            state=DISABLED,
        )
        self.chk_autosave = Checkbutton(self,
                                        text=BTNSAVE,
                                        variable=self._autosave,
                                        onvalue=1,
                                        offvalue=0)
        self.lbl_frames = Label(self, text=FRMSTXT)
        self.ent_frames = Entry(self,
                                width=5,
                                border=2,
                                bg=GOOD,
                                justify=RIGHT,
                                textvariable=self._frames)

        # Get list of available themes
        for idx, theme in enumerate(THEMES):
            self.lbx_theme.insert(idx, theme)

        self.body_arrange()  # Position all widgets in frame

        self.reset()  # Reset all settings to their defaults

        self.set_traces(
        )  # Trace entry variables for validation and event handling

    def body_arrange(self):
        """
        Position widgets in frame
        """

        # Position all widgets in their parent frames
        self.btn_plot.grid(column=0,
                           row=1,
                           ipadx=3,
                           ipady=3,
                           sticky=(W),
                           padx=3,
                           pady=3)
        self.btn_cancel.grid(column=1,
                             row=1,
                             ipadx=3,
                             ipady=3,
                             sticky=(W),
                             padx=3,
                             pady=3)
        self.btn_reset.grid(column=2,
                            row=1,
                            ipadx=3,
                            ipady=3,
                            sticky=(W),
                            padx=3,
                            pady=3)
        self.ent_save.grid(column=0,
                           row=2,
                           columnspan=2,
                           sticky=(W, E),
                           padx=3,
                           pady=3)
        self.btn_save.grid(column=2,
                           row=2,
                           ipadx=3,
                           ipady=3,
                           sticky=(W),
                           padx=3,
                           pady=3)
        self.lbl_auto.grid(column=0, row=3, sticky=(W))
        self.btn_autozoom.grid(column=1,
                               row=3,
                               ipadx=3,
                               ipady=3,
                               sticky=(W),
                               padx=3,
                               pady=3)
        self.btn_autospin.grid(column=2,
                               row=3,
                               ipadx=3,
                               ipady=3,
                               sticky=(W),
                               padx=3,
                               pady=3)
        self.lbl_frames.grid(column=0, row=4, sticky=(W))
        self.ent_frames.grid(column=1, row=4, sticky=(W), padx=3, pady=3)
        self.chk_autosave.grid(column=2, row=4, sticky=(W), padx=3, pady=3)
        self.sep_1.grid(column=0, row=5, columnspan=3, pady=5, sticky=(W, E))
        self.lbl_settype.grid(column=0, row=6, sticky=(W))
        self.spn_settype.grid(column=1,
                              row=6,
                              columnspan=2,
                              sticky=(W, E),
                              padx=3,
                              pady=3)
        self.lbl_zoom.grid(column=0, row=7, sticky=(W))
        self.ent_zoom.grid(column=1,
                           row=7,
                           columnspan=2,
                           sticky=(W, E),
                           padx=3,
                           pady=3)
        self.lbl_zoominc.grid(column=0, row=8, sticky=(W))
        self.ent_zoominc.grid(column=1, row=8, sticky=(W), padx=3, pady=3)
        self.lbl_zx_off.grid(column=0, row=9, sticky=(W))
        self.ent_zx_off.grid(column=1,
                             row=9,
                             columnspan=2,
                             sticky=(W, E),
                             padx=3,
                             pady=3)
        self.lbl_zy_off.grid(column=0, row=10, sticky=(W))
        self.ent_zy_off.grid(column=1,
                             row=10,
                             columnspan=2,
                             sticky=(W, E),
                             padx=3,
                             pady=3)
        self.lbl_cx_off.grid(column=0, row=11, sticky=(W))
        self.ent_cx_off.grid(column=1,
                             row=11,
                             columnspan=2,
                             sticky=(W, E),
                             padx=3,
                             pady=3)
        self.lbl_cy_off.grid(column=0, row=12, sticky=(W))
        self.ent_cy_off.grid(column=1,
                             row=12,
                             columnspan=2,
                             sticky=(W, E),
                             padx=3,
                             pady=3)
        self.lbl_niter.grid(column=0, row=13, sticky=(W))
        self.ent_maxiter.grid(column=1, row=13, sticky=(W), padx=3, pady=3)
        self.chk_autoiter.grid(column=2, row=13, sticky=(W), padx=3, pady=3)
        self.lbl_radius.grid(column=0, row=14, sticky=(W))
        self.ent_radius.grid(column=1, row=14, sticky=(W), padx=3, pady=3)
        self.lbl_exp.grid(column=0, row=15, sticky=(W))
        self.spn_exp.grid(column=1, row=15, sticky=(W), padx=3, pady=3)
        self.lbl_theme.grid(column=0, row=16, sticky=(W))
        self.lbx_theme.grid(column=1,
                            row=16,
                            padx=3,
                            pady=3,
                            columnspan=2,
                            sticky=(N, S, W, E))
        self.scrollbar.grid(column=2, row=16, sticky=(N, S, E))
        self.lbl_shift.grid(column=0, row=17, sticky=(W))
        self.scl_shift.grid(column=1,
                            row=17,
                            columnspan=2,
                            padx=3,
                            pady=3,
                            sticky=(W, E))
        self.lbx_theme.bind("<<ListboxSelect>>", self.get_sel_theme)

    def set_traces(self):
        """
        Set up entry variable traces for validation and event handling
        """

        self._validsettings = True
        self._settype.trace("w", self.val_settings)
        self._zoom.trace("w", self.val_settings)
        self._zx_off.trace("w", self.val_settings)
        self._zy_off.trace("w", self.val_settings)
        self._cx_off.trace("w", self.val_settings)
        self._cy_off.trace("w", self.val_settings)
        self._maxiter.trace("w", self.val_settings)
        self._radius.trace("w", self.val_settings)
        self._exponent.trace("w", self.val_settings)
        self._filename.trace("w", self.val_settings)
        self._frames.trace("w", self.val_settings)
        self._zoominc.trace("w", self.val_settings)

    def val_settings(self, *args, **kwargs):
        """
        Validate all user-entered settings.
        (A personal choice but I find this user experience more intuitive
        than the standard validatecommand method for Entry widgets)
        """

        self._validsettings = True
        self.__app.set_status("")

        if self.is_float(self.ent_zoom.get()) and self._zoom.get() > 0:
            flg = GOOD
        else:
            flg = BAD
        self.flag_entry(self.ent_zoom, flg)

        if self.is_float(self.ent_zx_off.get()):
            flg = GOOD
        else:
            flg = BAD
        self.flag_entry(self.ent_zx_off, flg)

        if self.is_float(self.ent_zy_off.get()):
            flg = GOOD
        else:
            flg = BAD
        self.flag_entry(self.ent_zy_off, flg)

        if self.is_float(self.ent_cx_off.get()):
            flg = GOOD
        else:
            flg = BAD
        self.flag_entry(self.ent_cx_off, flg)

        if self.is_float(self.ent_cy_off.get()):
            flg = GOOD
        else:
            flg = BAD
        self.flag_entry(self.ent_cy_off, flg)

        if self.is_integer(self.ent_maxiter.get()) and self._maxiter.get() > 0:
            flg = GOOD
        else:
            flg = BAD
        self.flag_entry(self.ent_maxiter, flg)

        if self.is_float(self.ent_radius.get()) and self._radius.get() > 0:
            flg = GOOD
        else:
            flg = BAD
        self.flag_entry(self.ent_radius, flg)

        if self.is_integer(self.spn_exp.get()) and self._exponent.get() > 1:
            flg = GOOD
        else:
            flg = BAD
        self.flag_entry(self.spn_exp, flg)

        if self.is_integer(self.ent_frames.get()) and self._frames.get() > 0:
            flg = GOOD
        else:
            flg = BAD
        self.flag_entry(self.ent_frames, flg)

        if self.is_float(self.ent_zoominc.get()) and self._zoominc.get() > 0:
            flg = GOOD
        else:
            flg = BAD
        self.flag_entry(self.ent_zoominc, flg)

        if self.is_filename(self.ent_save.get()):
            flg = GOOD
        else:
            flg = BAD
        self.flag_entry(self.ent_save, flg)

        if self.spn_settype.get() in {"Mandelbrot", "Tricorn", "BurningShip"}:
            self.btn_autospin.config(state=DISABLED)
            self.ent_cx_off.config(state=DISABLED)
            self.ent_cy_off.config(state=DISABLED)
            self._cx_off.set(0)
            self._cy_off.set(0)
            flg = GOOD
        elif self.spn_settype.get() == "Julia":
            self.btn_autospin.config(state=NORMAL)
            self.ent_cx_off.config(state=NORMAL)
            self.ent_cy_off.config(state=NORMAL)
            flg = GOOD
        else:
            flg = BAD
        self.flag_entry(self.spn_settype, flg)

    def flag_entry(self, ent, flag):
        """
        Flag entry field as valid or invalid and set global validity status flag.
        This flag is used throughout to determine whether functions can proceed
        or not.
        """

        ent.config(bg=flag)
        if flag == BAD:
            self._validsettings = False
            self.__app.set_status(VALERROR, "red")

    def is_float(self, flag):
        """
        Validate if entry is a float.
        """

        try:
            float(flag)
            return True
        except ValueError:
            return False

    def is_integer(self, flag):
        """
        Validate if entry is a positive integer.
        """

        try:
            int(flag)
            if int(flag) > 0:
                return True
            return False
        except ValueError:
            return False

    def is_filename(self, flag):
        """
        Validate if entry represents a valid filename using a regexp.
        """

        return match("^[\w\-. ]+$", flag) and flag != ""

    def reset(self):
        """
        Reset settings to defaults.
        """

        self._settype.set("Mandelbrot")
        self._zoom.set(0.75)
        self._zx_off.set(-0.5)
        self._zy_off.set(0.0)
        self._cx_off.set(0.0)
        self._cy_off.set(0.0)
        self._maxiter.set(128)
        self._radius.set(2.0)
        self._exponent.set(2)
        self._frames.set(10)
        self._zoominc.set(2.0)
        self._autoiter.set(1)
        self._autosave.set(0)
        self._theme.set("Default")
        self._filename.set("image0")
        self._shift.set(0)
        self.set_sel_theme()

        self.__app.set_status(SETINITTXT)

    def get_sel_theme(self, *args, **kwargs):
        """
        Get selected theme from listbox and set global variable.
        """

        idx = self.lbx_theme.curselection()
        if idx == "":
            idx = 0
        self._theme.set(self.lbx_theme.get(idx))

    def set_sel_theme(self):
        """
        Lookup index of selected theme and highlight that listbox position.
        NB: this requires 'exportselection=False' option to be set on listbox to
        work properly.
        """

        for idx, theme in enumerate(THEMES):
            if theme == self._theme.get():
                self.lbx_theme.activate(idx)
                self.lbx_theme.see(idx)
                break

    def get_settings(self):
        """
        Return all current settings as a dict.
        """

        if not self._validsettings:
            settings = {"valid": self._validsettings}
            return settings

        settings = {
            "settype": self._settype.get(),
            "zoom": self._zoom.get(),
            "zxoffset": self._zx_off.get(),
            "zyoffset": self._zy_off.get(),
            "cxoffset": self._cx_off.get(),
            "cyoffset": self._cy_off.get(),
            "maxiter": self._maxiter.get(),
            "autoiter": self._autoiter.get(),
            "autosave": self._autosave.get(),
            "radius": self._radius.get(),
            "exponent": self._exponent.get(),
            "theme": self._theme.get(),
            "shift": self._shift.get(),
            "filepath": self._filepath,
            "filename": self._filename.get(),
            "frames": self._frames.get(),
            "zoominc": self._zoominc.get(),
            "valid": self._validsettings,
        }
        return settings

    def update_settings(self, **kwargs):
        """
        Update settings from keyword parms.
        """

        if "settype" in kwargs:
            self._settype.set(kwargs["settype"])
        if "zoom" in kwargs:
            self._zoom.set(kwargs["zoom"])
        if "zxoffset" in kwargs:
            self._zx_off.set(kwargs["zxoffset"])
        if "zyoffset" in kwargs:
            self._zy_off.set(kwargs["zyoffset"])
        if "cxoffset" in kwargs:
            self._cx_off.set(kwargs["cxoffset"])
        if "cyoffset" in kwargs:
            self._cy_off.set(kwargs["cyoffset"])
        if "maxiter" in kwargs:
            self._maxiter.set(kwargs["maxiter"])
        if "autoiter" in kwargs:
            self._autoiter.set(kwargs["autoiter"])
        if "autosave" in kwargs:
            self._autosave.set(kwargs["autosave"])
        if "radius" in kwargs:
            self._radius.set(kwargs["radius"])
        if "exponent" in kwargs:
            self._exponent.set(kwargs["exponent"])
        if "filepath" in kwargs:
            self._filepath.set(kwargs["filepath"])
        if "filename" in kwargs:
            self._filename.set(kwargs["filename"])
        if "frames" in kwargs:
            self._frames.set(kwargs["frames"])
        if "zoominc" in kwargs:
            self._zoominc.set(kwargs["zoominc"])
        if "theme" in kwargs:
            self._theme.set(kwargs["theme"])
            self.set_sel_theme()
        if "shift" in kwargs:
            self._shift.set(kwargs["shift"])

    def set_filepath(self):
        """
        Sets filepath for saved files for the duration of this session.
        """

        default = os.getcwd()  # Default _filepath is current working directory
        if self._filepath is None:
            self._filepath = filedialog.askdirectory(title=SAVETITLE,
                                                     initialdir=default,
                                                     mustexist=True)
            if self._filepath == "":
                self._filepath = None  # User cancelled

        return self._filepath

    def save_image(self):
        """
        Save image as PNG file to selected filepath and automatically increment default
        image name. NB: currently this will overwrite any existing file of the same
        name without warning.
        """

        # Bug out if the settings are invalid
        settings = self.__app.frm_settings.get_settings()
        if not settings["valid"]:
            return

        # Check if image has been created
        image = self.__app.frm_fractal.mandelbrot.get_image()
        if image is None:
            self.__app.set_status(NOIMGERROR, "red")
            return

        # Set _filename and path
        if self.set_filepath() is None:  # User cancelled
            return
        fname = self._filename.get()
        fqname = self._filepath + "/" + fname

        # Save the image along with its metadata
        try:
            # image.write(fqname + ".png", format="png")
            image.save(fqname + ".png", format="png")
            self.save_metadata()
        except OSError:
            self.__app.set_status(SAVEERROR, "red")
            self._filepath = None
            return

        self._image_num += 1
        self._filename.set(self._image_name + str(self._image_num))
        self.__app.set_status(IMGSAVETXT + fqname + ".png", "green")

        # Return focus to image frame
        self.__app.frm_fractal.focus_set()

    def save_metadata(self):
        """
        Save json file containing meta data associated with image,
        allowing it to be imported and reproduced.
        """

        if self._filepath is None:
            if self.set_filepath() is None:  # User cancelled
                return

        fname = self._filename.get()
        fqname = self._filepath + "/" + fname
        filename = fqname + ".json"
        createtime = strftime("%b %d %Y %H:%M:%S %Z", gmtime())

        jsondata = {
            MODULENAME: {
                "filename": fqname + ".png",
                "created": createtime,
                "settype": self._settype.get(),
                "zoom": self._zoom.get(),
                "zoominc": self._zoominc.get(),
                "frames": self._frames.get(),
                "escradius": self._radius.get(),
                "exponent": self._exponent.get(),
                "maxiter": self._maxiter.get(),
                "zxoffset": self._zx_off.get(),
                "zyoffset": self._zy_off.get(),
                "cxoffset": self._cx_off.get(),
                "cyoffset": self._cy_off.get(),
                "theme": self._theme.get(),
                "shift": self._shift.get(),
            }
        }

        try:
            with open(filename, "w") as outfile:
                dump(jsondata, outfile)
        except OSError:
            self.__app.set_status(METASAVEERROR, "red")
            self._filepath = None

        # Return focus to image frame
        self.__app.frm_fractal.focus_set()

    def import_metadata(self):
        """
        Update settings from imported json metadata file.
        """

        # Select and read file
        try:
            default = os.getcwd()
            filepath = filedialog.askopenfilename(
                initialdir=default,
                title=SELTITLE,
                filetypes=(("json files", "*.json"), ("all files", "*.*")),
            )
            if filepath == "":  # User cancelled
                return
            with open(filepath, "r") as infile:
                jsondata = infile.read()
        except OSError:
            self.__app.set_status(OPENFILEERROR, "red")
            return

        # Parse file
        try:

            settings = loads(jsondata).get(MODULENAME)

            # Set plot parameters
            self._settype.set(settings.get("settype", "Mandelbrot"))
            self._zoom.set(settings.get("zoom", 1))
            self._zoominc.set(settings.get("zoominc", 2.0))
            self._frames.set(settings.get("frames", 10))
            self._radius.set(settings.get("escradius", 2.0))
            self._exponent.set(settings.get("exponent", 2))
            self._maxiter.set(settings.get("maxiter", 256))
            self._zx_off.set(settings.get("zxoffset", 0))
            self._zy_off.set(settings.get("zyoffset", 0))
            self._cx_off.set(settings.get("cxoffset", 0))
            self._cy_off.set(settings.get("cyoffset", 0))
            self._theme.set(settings.get("theme", "Default"))
            self._shift.set(settings.get("shift", 0))

        except OSError:
            self.__app.set_status(BADJSONERROR, "red")
            return

        self.set_sel_theme()

        fbase = os.path.basename(filepath)
        filename, fileext = os.path.splitext(fbase)
        self.__app.set_status(
            "Metadata file " + filename + fileext + METAPROMPTTXT, "green")

        # Return focus to image frame
        self.__app.frm_fractal.focus_set()
示例#24
0
def openCalculator(handler):
	global conversionresulttext, fromCurrencyInput, toCurrencyInput, amountInput, calculatorWindow

	currencyapi = get("https://api.exchangeratesapi.io/latest", data=None)
	if currencyapi.status_code == 200: #Check for reponse
		exchangerates = loads(currencyapi.content.decode())
		exchangerates["rates"]["DUCO"] = float(ducofiat)

	calculatorWindow = Toplevel()
	calculatorWindow.resizable(False, False)
	calculatorWindow.title("Duino-Coin Wallet - Calculator")
	calculatorWindow.configure(background = backgroundColor)
	calculatorWindow.transient([root])

	textFont2 = Font(calculatorWindow, size=12,weight="bold")
	textFont3 = Font(calculatorWindow, size=14,weight="bold")
	textFont = Font(calculatorWindow, size=12,weight="normal")

	Label(calculatorWindow, text="CURRENCY CONVERTER",
		background = backgroundColor,
		foreground = foregroundColor,
		font = textFont3).grid(row=0, column=0)

	Label(calculatorWindow, text="FROM",
		background = backgroundColor,
		foreground = foregroundColor,
		font = textFont2).grid(row=1, column=0)

	fromCurrencyInput = Listbox(calculatorWindow,
								exportselection=False,
								background = backgroundColor,
								foreground = foregroundColor,
								selectbackground = "#7bed9f",
								border="0", font=textFont,
								width="20", height="13")
	fromCurrencyInput.grid(row=2, column=0)
	i=0
	for currency in exchangerates["rates"]:
		fromCurrencyInput.insert(i, currency)
		i = i+1

	Label(calculatorWindow, text="TO",
		background = backgroundColor,
		foreground = foregroundColor,
		font = textFont2).grid(row=1, column=1)

	toCurrencyInput = Listbox(calculatorWindow,
								exportselection=False,
								foreground = foregroundColor,
								background = backgroundColor,
								selectbackground = "#7bed9f",
								border="0", font=textFont,
								width="20", height="13")
	toCurrencyInput.grid(row=2, column=1)
	i=0
	for currency in exchangerates["rates"]:
		toCurrencyInput.insert(i, currency)
		i = i+1

	toCurrencyInput.select_set(0)
	toCurrencyInput.event_generate("<<ListboxSelect>>")
	fromCurrencyInput.select_set(32)
	fromCurrencyInput.event_generate("<<ListboxSelect>>")

	Label(calculatorWindow, text="AMOUNT",
		background = backgroundColor,
		foreground = foregroundColor,
		font = textFont2).grid(row=3, column=0)

	def clear_ccamount_placeholder(self):
			amountInput.delete("0", "100")

	amountInput = Entry(calculatorWindow,
						background = "#7bed9f", foreground=foregroundColor,
						border="0", font=textFont,
						width="20")
	amountInput.grid(row=4, column=0)
	amountInput.insert("0", str(getBalance()))
	amountInput.bind("<FocusIn>", clear_ccamount_placeholder)

	Button(calculatorWindow, text="Convert",
			background = "#FEEEDA", foreground=foregroundColor,
			command=currencyConvert, width="22").grid(row=3, column=1, pady=(5, 0))

	conversionresulttext = StringVar(calculatorWindow)
	conversionresulttext.set("RESULT: 0.0")
	conversionresultLabel = Label(calculatorWindow,
								textvariable=conversionresulttext,
								background = backgroundColor,
								foreground = foregroundColor,
								font = textFont2)
	conversionresultLabel.grid(row=4, column=1)

	Label(calculatorWindow, text=" ",
		background = backgroundColor,
		foreground = foregroundColor,
		font = textFont2).grid(row=5, column=0)

	calculatorWindow.mainloop()
示例#25
0
class BattleshipsDemoClient(Frame):
    def __init__(self, tk, args):
        Frame.__init__(self, tk)
        # empty string for platform's default settings
        locale.setlocale(locale.LC_ALL, '')
        self.master = tk
        tk.title(APP_TITLE)
        tk.resizable(False, False)
        try:
            if WINDOWS:
                tk.iconbitmap("200x200/icon.ico")
            else:
                tk.iconbitmap("@200x200/icon.xbm")
        except Exception as e:
            print(e)
        atexit.register(self.cancel_game)

        # Init class data fields that we use for storing info that we need for using the API
        self.bot_id = None
        self.bot_password = None
        self.logged_in = False
        self.game_style_ids = []
        self.gameChips = 0
        self.gameDeals = 0
        self.gameStake = 0
        self.gamePrize = 0
        self.player_key = None
        self.play_again = BooleanVar()
        self.do_not_play_same_user = BooleanVar()
        self.close_after_game = False
        self.game_cancelled = False
        self.in_game = False

        self.topFrame = Frame(tk, padx=12, pady=12)
        self.middleFrame = Frame(tk, padx=12)
        self.middleFrameLeft = Frame(self.middleFrame)
        self.middleFrameRight = Frame(self.middleFrame)
        self.middleFrameRighter = Frame(self.middleFrame)

        self.topFrame.grid(row=0, sticky=W + E)

        self.middleFrame.grid(row=1, sticky=W)
        self.middleFrameLeft.grid(row=1, column=0)
        self.middleFrameRight.grid(row=1, column=1)
        self.middleFrameRighter.grid(row=1, column=2)

        # ===================================
        # Create form elements

        # Top Frame Elements
        self.botNameLabel = Label(self.topFrame, text="Bot Name:")
        self.bot_id_entry = Entry(self.topFrame)
        self.bot_id_entry.bind('<Return>', self.log_in_if_not)
        self.bot_id_entry.focus()
        self.passwordLabel = Label(self.topFrame, text="Password:"******"Login",
                                        command=self.log_in_out_clicked)

        self.balanceLabel = Label(self.topFrame, text="Bot Balance:")
        self.balance = Label(self.topFrame, text="0")
        self.close_button = Button(self.topFrame,
                                   text="Close",
                                   padx=2,
                                   command=tk.destroy)

        # Middle Frame Elements
        # Middle Frame LEFT Elements
        self.gameStyleLabel = Label(self.middleFrameLeft,
                                    font=(None, 18),
                                    pady=0,
                                    text="Game Style Selection")

        self.opponentLabel = Label(self.middleFrameLeft,
                                   text="Specify Opponent (optional):")
        self.specify_opponent_entry = Entry(self.middleFrameLeft)

        self.do_not_play_same_user_check = Checkbutton(
            self.middleFrameLeft,
            text='Don\'t play another bot in same user account as me',
            var=self.do_not_play_same_user)

        self.game_styles_listbox = Listbox(self.middleFrameLeft,
                                           background='#FFFFFF',
                                           height=8)
        self.game_styles_listbox.bind('<Double-1>',
                                      self.find_game_double_clicked)
        self.game_styles_listbox.bind(
            '<Return>', self.find_game_double_clicked
        )  # Not a double click but we want it to do the same thing

        self.refresh_game_styles_button = Button(
            self.middleFrameLeft,
            text="Refresh Game Styles",
            command=self.refresh_game_styles_clicked)

        self.thinkingTimeLabel = Label(self.middleFrameLeft,
                                       text="Add \"Thinking Time\" (ms):")
        self.thinking_time_entry = Entry(self.middleFrameLeft)

        self.auto_play_next_game_check = Checkbutton(
            self.middleFrameLeft,
            text='Play another game when complete',
            var=self.play_again)

        self.cancel_stop_game_button = Button(
            self.middleFrameLeft,
            text=CANCEL_GAME_TEXT,
            command=self.cancel_stop_game_clicked)
        self.find_game_button = Button(self.middleFrameLeft,
                                       text="Find Game",
                                       command=self.find_game_clicked)

        self.resultText = Message(
            self.middleFrameLeft,
            width=300,
            text="This is where the informational messages will appear")
        self.spacerLabel = Label(self.middleFrameLeft, text=" ")

        # Middle Frame RIGHT Elements

        self.gameTitleLabel = Label(self.middleFrameRight, text="Game Title")
        self.gameTitleText = Text(self.middleFrameRight,
                                  height=3,
                                  background='white',
                                  spacing1=3,
                                  pady=0)

        self.player = battleships_visuals.BattleshipsVisuals(
            self.middleFrameRight)  # Game Display Table
        self.opponent = battleships_visuals.BattleshipsVisuals(
            self.middleFrameRight)  # Game Display Table
        self.gameActionLabel = Label(self.middleFrameRight, text="")

        # ===================================
        # Set initial element states

        self.set_gamestyle_controls_states(DISABLED)
        self.cancel_stop_game_button.config(state=DISABLED)
        self.game_styles_listbox.config(background='white')
        self.thinking_time_entry.insert(0, 100)
        self.gameTitleText.config(state=DISABLED)
        self.set_balance(0)
        self.gameTitleText.tag_configure("center", justify='center')
        self.gameTitleText.tag_configure("bold", font='-weight bold')

        # ===================================
        # Form Layout

        # Top Frame Form Layout
        self.topFrame.grid_rowconfigure(0, weight=1)
        self.botNameLabel.grid(row=0, column=0, sticky=E)
        self.bot_id_entry.grid(row=0, column=1, sticky=W)
        self.passwordLabel.grid(row=0, column=2, sticky=E)
        self.bot_password_entry.grid(row=0, column=3, sticky=W)
        self.log_in_out_button.grid(row=0, column=4, sticky=E)
        self.topFrame.grid_columnconfigure(5, weight=1)
        self.balanceLabel.grid(row=0, column=5, sticky=E)
        self.balance.grid(row=0, column=6, sticky=W)
        self.close_button.grid(row=0, column=7, sticky=E, padx=(50, 0))

        # Middle Frame Form Layout
        self.middleFrame.grid_rowconfigure(0, weight=1)
        self.gameStyleLabel.grid(row=0, column=0, columnspan=1, sticky=W + E)
        self.spacerLabel.grid(row=0, column=2, sticky=E)

        self.opponentLabel.grid(row=2, column=0, sticky=W, pady=4)
        self.specify_opponent_entry.grid(row=2, column=0, sticky=E, pady=4)

        self.do_not_play_same_user_check.grid(row=3,
                                              column=0,
                                              columnspan=1,
                                              sticky='we',
                                              pady=4)
        self.game_styles_listbox.grid(row=4,
                                      column=0,
                                      columnspan=1,
                                      sticky='we',
                                      pady=4)
        self.find_game_button.grid(row=5, column=0, pady=4, sticky=W)
        self.refresh_game_styles_button.grid(row=5,
                                             column=0,
                                             columnspan=1,
                                             sticky='',
                                             pady=4)
        self.cancel_stop_game_button.grid(row=5, column=0, sticky=E)

        self.thinkingTimeLabel.grid(row=6, column=0, sticky=W, pady=4)
        self.thinking_time_entry.grid(row=6, column=0, sticky=E, pady=4)

        self.auto_play_next_game_check.grid(row=7,
                                            column=0,
                                            columnspan=1,
                                            sticky=W,
                                            pady=4)
        self.resultText.grid(row=9, column=0, columnspan=2, sticky=W, pady=4)
        self.middleFrame.grid_columnconfigure(9, weight=1)

        self.gameTitleLabel.grid(row=0, column=3)
        self.gameTitleText.grid(row=0, column=3, columnspan=2)
        self.player.grid(row=1, column=3)
        self.opponent.grid(row=1, column=4)
        self.gameActionLabel.grid(row=11, column=3, sticky='w')

        if args.botid is not None:
            self.auto_play(args)

    def auto_play(self, args):
        self.bot_id_entry.insert(0, args.botid)
        self.bot_password_entry.insert(0, args.password)
        self.log_in_out_clicked()
        self.thinking_time_entry.insert(0, args.timeout)
        if args.playanothergame:
            self.auto_play_next_game_check.select()
        if args.dontplaysameuserbot:
            self.do_not_play_same_user_check.select()
        if args.closeaftergame:
            self.close_after_game = True
        i = 0
        for i in range(self.game_styles_listbox.size()):
            if args.gamestyle in str(self.game_styles_listbox.get(i)):
                break
        self.game_styles_listbox.select_set(i, i)
        self.find_game_clicked()

    def log_in_out_clicked(self):
        """Click handler for the 'Login'/'Logout' button."""

        # This means we're logging out
        if self.logged_in:
            self.resultText.config(text='Logged Out')

            self.master.title(APP_TITLE + " (Not Logged In)")

            self.cancel_game()

            self.bot_id = 'housebot-competition'
            self.bot_password = None
            self.clear_game_title_text()
            self.gameActionLabel.config(text="")
            self.reset_game_styles_listbox()
            self.clear_all_boards()
            self.opponent.delete("all")

            self.log_in_out_button.config(text='Login')

            self.set_login_controls_states(ENABLED)
            self.set_gamestyle_controls_states(DISABLED)

            self.logged_in = False
            self.bot_password_entry.delete(0, 'end')
            self.set_balance(0)

        # This means we're logging in
        else:
            self.bot_id = self.bot_id_entry.get()
            self.bot_password = '******'

            res = self.get_list_of_game_styles()
            if res['Result'] == 'SUCCESS':
                self.resultText.config(text='Logged In')

                game_styles = res['GameStyles']
                self.master.title(self.bot_id + " - " + APP_TITLE)

                self.set_login_controls_states(DISABLED)
                self.set_gamestyle_controls_states(ENABLED)

                self.set_game_styles_listbox(game_styles)
                self.set_balance(res['Balance'])

                self.log_in_out_button.config(text='Logout')

                self.logged_in = True

            else:
                messagebox.showerror(
                    'Error',
                    'Invalid login attempt. Please check the username and password entered.'
                )

    def log_in_if_not(self, _):
        if not self.logged_in:
            self.log_in_out_clicked()

    def clear_all_boards(self):
        self.player.delete("all")
        self.opponent.delete("all")
        self.player.myBoard = None
        self.opponent.oppBoard = None

    def set_in_game(self, value):
        self.in_game = value

    def set_game_title_text(self, text, tag):
        self.gameTitleText.config(state=ENABLED)
        self.gameTitleText.insert("end", text, ("center", tag))
        self.gameTitleText.config(state=DISABLED)

    def clear_game_title_text(self):
        self.gameTitleText.config(state=ENABLED)
        self.gameTitleText.delete("1.0", "end")
        self.gameTitleText.config(state=DISABLED)

    def set_login_controls_states(self, state):
        self.bot_id_entry.config(state=state)
        self.bot_password_entry.config(state=state)

    def set_gamestyle_controls_states(self, state):
        self.specify_opponent_entry.config(state=state)
        self.do_not_play_same_user_check.config(state=state)
        self.game_styles_listbox.config(state=state)
        self.find_game_button.config(state=state)
        self.refresh_game_styles_button.config(state=state)
        self.auto_play_next_game_check.config(state=state)
        self.thinking_time_entry.config(state=state)
        self.opponentLabel.config(state=state)
        self.thinkingTimeLabel.config(state=state)
        self.balanceLabel.config(state=state)
        self.balance.config(state=state)
        self.gameStyleLabel.config(state=state)
        self.game_styles_listbox.config(state=state)
        self.player.config(state=state)
        self.opponent.config(state=state)

    def set_balance(self, balance):
        """Set the balance field"""
        self.balance['text'] = int_with_commas(balance)
        self.balance['text'] += ' sat'

    def get_list_of_game_styles(self):
        """Get list of game styles from the server."""

        req = {
            'BotId': self.bot_id,
            'BotPassword': self.bot_password,
            'GameTypeId': BATTLESHIPS_GAME_TYPE_ID
        }

        url = BASE_URL + GET_LIST_OF_GAME_STYLES_EXTENSION

        return BattleshipsDemoClient.make_api_call(url, req)

    def set_game_styles_listbox(self, game_styles):
        """Set the content of the game styles listbox with a list of GameStyle dictionaries.
        Keyword Arguments:
        game_styles -- The list of GameStyle dictionaries, this should be obtained through get_list_of_game_styles().
        """
        self.reset_game_styles_listbox()
        for index, game_style in enumerate(game_styles):
            self.game_styles_listbox.insert(
                index,
                GAME_STYLE_LISTBOX_TEXT.format(
                    game_style['GameStyleId'], game_style['Stake'],
                    game_style['GameTypeSpecificInfo']['Ships'],
                    game_style['GameTypeSpecificInfo']['Board Size'],
                    game_style['GameTypeSpecificInfo']['Timeout ms'],
                    game_style['GameTypeSpecificInfo']['DealsTotal'],
                    game_style['GameTypeSpecificInfo']['PercentageLand'],
                    game_style['GameTypeSpecificInfo']['RandomLand']))
            self.game_style_ids.append(game_style['GameStyleId'])

            # self.game_styles_listbox.select_set(GAME_STYLE_LISTBOX_DEFAULT_SELECTION)

    def reset_game_styles_listbox(self):
        """Clear the content of the game styles listbox."""

        if self.game_styles_listbox.size() != 0:
            self.game_styles_listbox.delete(0, 'end')

            self.game_style_ids = []

    def refresh_game_styles_clicked(self):
        """Click handler for the 'Refresh Game Styles' button."""

        res = self.get_list_of_game_styles()
        game_styles = res['GameStyles']
        self.set_game_styles_listbox(game_styles)

    def find_game_clicked(self):
        """Click handler for the 'Find Game' button"""

        self.find_game_button.config(state=DISABLED)
        self.cancel_stop_game_button.config(state=ENABLED)
        self.clear_all_boards()

        # Here we dispatch the work to a separate thread, to keep the GUI responsive.
        if not MAC:
            threading.Thread(target=self.game_loop, daemon=True).start()
        else:
            self.game_loop()  # Doesn't work on MACs

    def find_game_double_clicked(self, _):
        self.find_game_clicked()

    def game_loop(self):
        """Loop through finding and playing games."""

        while True:
            self.clear_all_boards()
            self.find_game()
            if self.game_cancelled:
                break
            self.play_game()
            if self.close_after_game:
                self.close_button.invoke()
            if self.game_cancelled:
                break
            if not self.play_again.get():
                break

        self.find_game_button.config(state=ENABLED)
        self.cancel_stop_game_button.config(state=DISABLED,
                                            text=CANCEL_GAME_TEXT)
        self.game_cancelled = False

    def find_game(self):
        """Find a game."""

        offer_game_res = self.offer_game()

        if offer_game_res['Result'] == 'INVALID_LOGIN_OR_PASSWORD':
            self.cancel_stop_game_clicked()
            if 'ErrorMessage' in offer_game_res and offer_game_res[
                    'ErrorMessage'] == 'Check of OpponentId failed':
                self.resultText.config(text='Invalid Opponent ID')
            else:
                self.resultText.config(text='Invalid login or password')
        elif offer_game_res['Result'] == 'INSUFFICIENT_BALANCE':
            self.cancel_stop_game_clicked()
            self.resultText.config(text='Insufficient balance')
        elif offer_game_res['Result'] == 'BOT_IS_INACTIVE':
            self.cancel_stop_game_clicked()
            self.resultText.config(text='Bot is inactive')
        else:
            self.player_key = offer_game_res['PlayerKey']
            if offer_game_res['Result'] == 'WAITING_FOR_GAME':
                self.wait_for_game()

    def offer_game(self):
        """Offer a game."""

        opponent_id = self.specify_opponent_entry.get()
        if len(opponent_id) == 0:
            opponent_id = None
        try:
            game_style_id = self.game_style_ids[int(
                self.game_styles_listbox.curselection()[0])]
        except IndexError:
            self.game_styles_listbox.select_set(
                GAME_STYLE_LISTBOX_DEFAULT_SELECTION)
            game_style_id = self.game_style_ids[0]

        req = {
            'BotId': self.bot_id,
            'BotPassword': self.bot_password,
            'MaximumWaitTime': 1000,
            'GameStyleId': game_style_id,
            'DontPlayAgainstSameUser': self.do_not_play_same_user.get(),
            'DontPlayAgainstSameBot': False,
            'OpponentId': opponent_id
        }
        url = BASE_URL + OFFER_GAME_EXTENSION

        return BattleshipsDemoClient.make_api_call(url, req)

    def wait_for_game(self):
        """Wait for game to start."""
        self.resultText.config(text='Waiting for game')
        while True:
            if self.game_cancelled:
                self.cancel_game()
                self.find_game_button.config(state=ENABLED)
                self.cancel_stop_game_button.config(state=DISABLED,
                                                    text=CANCEL_GAME_TEXT)
                break
            poll_results = self.poll_for_game_state()

            if poll_results['Result'] == 'SUCCESS':
                break
            if poll_results['Result'] == 'INVALID_PLAYER_KEY' or poll_results[
                    'Result'] == 'GAME_HAS_ENDED' or poll_results[
                        'Result'] == 'GAME_WAS_STOPPED':
                self.game_cancelled = True
            time.sleep(2)

    def play_game(self):
        """Play a game."""
        self.resultText.config(text='Playing game')
        self.in_game = True

        poll_results = self.poll_for_game_state()

        if poll_results["Result"] != "SUCCESS":
            return

        game_state = poll_results['GameState']

        title = format('Game ID: ' + str(game_state['GameId']))
        game_style_details = self.game_styles_listbox.get('active').split(
            " | ")
        title += format(' / Style: ' + str(self.game_style_ids[int(
            self.game_styles_listbox.curselection()[0])]))
        title += format(' / Land: ' + game_style_details[6].split(" ")[2] +
                        '%')
        title += format(' / Deals: ' + game_style_details[5].split(" ")[1])
        title += format(' / ' + game_style_details[7])
        title += "\n"
        versus = format(self.bot_id + ' vs ' + game_state['OpponentId'])

        self.clear_game_title_text()
        self.set_game_title_text(title, "")
        self.set_game_title_text(versus, "bold")

        self.middleFrame.update()

        while True:
            if self.game_cancelled:
                break

            if game_state['IsMover']:
                self.resultText.config(text='Playing Game - Your Turn')
                move = battleships_move.calculateMove(game_state)
                move_results = self.make_move(move)

                if move_results['Result'] == 'INVALID_MOVE':
                    self.resultText.config(text="Invalid Move")
                elif move_results['Result'] != 'SUCCESS':
                    self.resultText.config(text='Game has ended: ' +
                                           move_results['Result'])
                    print("Game ended")
                    break
                else:
                    game_state = move_results['GameState']
            else:
                self.resultText.config(text="Playing Game - Opponent's Turn")

                # ---- Code here will be called on your opponent's turn ----

                # ----------------------------------------------------------

                poll_results = self.poll_for_game_state()

                if poll_results['Result'] != 'SUCCESS':
                    self.resultText.config(text='Game has ended: ' +
                                           poll_results['Result'])
                    break
                game_state = poll_results['GameState']

            if game_state['GameStatus'] != 'RUNNING':
                break

            self.middleFrameRight.update()

            try:
                if int(self.thinking_time_entry.get()) > 0:
                    time.sleep((int(self.thinking_time_entry.get()) / 1000))
                else:
                    time.sleep(0.1)
            except ValueError:
                time.sleep(0.1)

        self.set_in_game(False)

    def make_move(self, move):
        """Make a move."""

        req = {
            'BotId': self.bot_id,
            'BotPassword': self.bot_password,
            'PlayerKey': self.player_key,
            'Move': move
        }
        url = BASE_URL + MAKE_MOVE_EXTENSION

        result = BattleshipsDemoClient.make_api_call(url, req)

        if result['Result'] == 'SUCCESS' or "GAME_HAS_ENDED" in result[
                'Result']:
            print(result)
            try:
                self.player.draw_game_state(result['GameState'], True)
                self.opponent.draw_game_state(result['GameState'], False)
            except Exception as e:
                print("Gamestate error: " + str(e))

        return result

    def poll_for_game_state(self):
        """Poll the server for the latest GameState."""

        req = {
            'BotId': self.bot_id,
            'BotPassword': self.bot_password,
            'MaximumWaitTime': 1000,
            'PlayerKey': self.player_key
        }
        url = BASE_URL + POLL_FOR_GAME_STATE_EXTENSION

        result = BattleshipsDemoClient.make_api_call(url, req)
        if result['Result'] == 'SUCCESS' or "GAME_HAS_ENDED" in result[
                'Result']:
            self.player.draw_game_state(result['GameState'], True)
            self.opponent.draw_game_state(result['GameState'], False)

        return result

    def cancel_stop_game_clicked(self):
        self.game_cancelled = True
        self.cancel_game()
        self.find_game_button.config(state=ENABLED)
        self.cancel_stop_game_button.config(state=DISABLED,
                                            text=CANCEL_GAME_TEXT)

    def cancel_game(self):
        if self.player_key is None:
            return
        req = {
            'BotId': self.bot_id,
            'BotPassword': self.bot_password,
            'PlayerKey': self.player_key
        }

        url = BASE_URL + CANCEL_GAME_OFFER_EXTENSION
        BattleshipsDemoClient.make_api_call(url, req)
        try:
            self.resultText.config(text='Cancelled game')
        except Exception as e:
            print(str(e) + " -- resultText Message object no longer exists")

    @staticmethod
    def make_api_call(url, req):
        """Make an API call."""
        while True:
            try:
                res = requests.post(url,
                                    json=req,
                                    headers=API_CALL_HEADERS,
                                    timeout=60.0)
                try:
                    jres = res.json()
                    if 'Result' in jres:
                        return jres
                    time.sleep(0.1)
                except ValueError:
                    time.sleep(0.1)
            except requests.ConnectionError:
                time.sleep(0.1)
            except requests.Timeout:
                time.sleep(0.1)
            except requests.HTTPError:
                time.sleep(0.1)
            except BaseException as e:  # Bad code but needed for testing purposes
                print(e)
                time.sleep(0.1)
示例#26
0
lbl_SelAut = Label(menuCrearBasico,
                   text='Seleccione una opción',
                   fg='white',
                   bg="#354154",
                   font=("Helvetica", 16))
lbl_SelAut.pack(fill="x", pady=(0, 10))

lstbox_Crear = Listbox(menuCrearBasico,
                       width=25,
                       height=4,
                       font=("Helvetica", 16))
lstbox_Crear.pack(pady=(0, 10))

for item in ["F1", "F2", "F3", "F4"]:
    lstbox_Crear.insert(END, item)
lstbox_Crear.select_set(1)

bttn_CrearBasico = myButton("Seleccionar", menuCrearBasico)
bttn_CrearBasico.button.config(
    command=lambda: basico(lstbox_Crear.get(ACTIVE), inExp.get()))

bttn_back_CrearBasico = myButton("Volver al menú", menuCrearBasico)
bttn_back_CrearBasico.button.config(command=lambda: raise_frame(menuPrincipal),
                                    bg="#39547f")

err_lbl_CrearBasico = Label(menuCrearBasico,
                            text=" ",
                            fg="red",
                            bg="#496ba0",
                            font=("Helvetica", 16))
err_lbl_CrearBasico.pack()
示例#27
0
class ChapterListWindow(BaseListMenu):
    # Window title
    TITLE = 'Chapter Results'

    def __init__(self, prior_window, manga_scraper_obj: MangaReaderScraper):
        # call parent object
        super().__init__(title=self.TITLE)
        # set scraper attribute
        self.scraper = manga_scraper_obj
        # listbox
        self.list_box = Listbox(self.frame,
                                width=50,
                                selectmode='single',
                                yscrollcommand=self.scrollbar.set)
        # Update scraper object with current list of chapters for series.
        self.scraper.get_chapters_for_series()
        # Add each chapter number to list box
        [
            self.list_box.insert('end', i)
            for i in self.scraper.get_chapters.keys()
        ]
        # default selection to first index
        self.list_box.select_set(0)
        # set scrollbar view to listbox
        self.scrollbar.config(command=self.list_box.yview)
        # pack scrollbar
        self.scrollbar.pack(side='right', fill='y')
        # set default icon
        self.iconbitmap(ICON_PATH)
        # pack frame
        self.frame.pack()
        # pack list box
        self.list_box.pack(pady=15)

        # inner method for retrieving chapter image files
        def get_chapter(self, chapter_chosen, chapter_text):
            try:

                # Update chapter attribute
                self.scraper.chapter = chapter_chosen
                self.scraper.chapter_name = utils.FileRenaming.strip_unwanted_characters(
                    chapter_text)
                # Download image
                LoadingBar(func=self.scraper.get_pages)

            except Exception as e:
                messagebox.showerror(title='ERROR', message=e)
            finally:
                return

        # OK Button
        self.ok_btn = Button(self,
                             text='OK',
                             command=lambda: get_chapter(
                                 self,
                                 chapter_chosen=self.scraper.get_chapters[
                                     self.list_box.selection_get()],
                                 chapter_text=self.list_box.selection_get()))
        self.ok_btn.pack(side='left', padx=(80, 10), pady=10)

        # closes the current window and restores focus to the prior open window (in this instance, the series results)
        def close_and_restore_focus(self, prior_window):
            self.destroy()
            prior_window.focus_force()
            prior_window.grab_set()

        # Cancel Button
        self.cancel_btn = Button(
            self,
            text='Cancel',
            command=lambda: close_and_restore_focus(self, prior_window))
        self.cancel_btn.pack(side='right', padx=(10, 80), pady=10)
示例#28
0
class AllNumbers(Frame):

    def __init__(self, parent, controller):
        Frame.__init__(self, parent)
        self.controller = controller
        self.left_value = StringVar()        # the input on the left
        self.right_value = StringVar()       # the input on the right

        self.OPTIONS = {'binary': 2, 'octal': 8, 'decimal': 10, 'hexadecimal': 16, 'base-2': 2, 'base-3': 3,
                        'base-4': 4, 'base-5': 5, 'base-6': 6, 'base-7': 7, 'base-8': 8, 'base-9': 9, 'base-10': 10,
                        'base-11': 11, 'base-12': 12, 'base-13': 13, 'base-14': 14, 'base-15': 15, 'base-16': 16,
                        'base-17': 17, 'base-18': 18, 'base-19': 19, 'base-20': 20, 'base-21': 21, 'base-22': 22,
                        'base-23': 23, 'base-24': 24, 'base-25': 25, 'base-26': 26, 'base-27': 27, 'base-28': 28,
                        'base-29': 29, 'base-30': 30, 'base-31': 31, 'base-32': 32, 'base-33': 33, 'base-34': 34,
                        'base-35': 35, 'base-36': 36}

        self.columnconfigure(0, weight=1, pad=5)
        self.columnconfigure(1, weight=1, pad=5)

        self.rowconfigure(0, pad=5)
        self.rowconfigure(1, pad=5)
        self.rowconfigure(2, pad=5)
        self.rowconfigure(3, weight=1, pad=5)

        # Title
        bbutton = Button(self, text="<", command=lambda: controller.show_frame("MainPage"))
        bbutton.grid(row=0, column=0, padx=10, sticky=W)
        title = Label(self, text="All Numbers")
        title.grid(row=0, columnspan=4, padx=10)

        # Labels
        flabel = Label(self, text="From:")
        flabel.grid(row=1, column=0, padx=10, sticky=W)

        tlabel = Label(self, text="To:")
        tlabel.grid(row=1, column=1, padx=10, sticky=W)

        # In/Outputs
        self.left = Entry(self, textvariable=self.left_value)
        self.left.grid(row=2, column=0, padx=10, sticky=E+W)

        self.right = Entry(self, textvariable=self.right_value)
        self.right.grid(row=2, column=1, padx=10, sticky=E+W)

        # Options
        self.loptions = Listbox(self, exportselection=0)
        self.loptions.grid(row=3, column=0, padx=12, pady=8, sticky=N+E+S+W)
        self.roptions = Listbox(self, exportselection=0)
        self.roptions.grid(row=3, column=1, padx=12, pady=8, sticky=N+E+S+W)

        self.loptions.bind('<<ListboxSelect>>', lambda a: self.update_outputs(1))
        lscroll = Scrollbar(self, command=self.loptions.yview)
        lscroll.grid(row=3, column=0, pady=8, sticky=N+S+E)
        self.loptions.configure(yscrollcommand=lscroll.set)

        self.roptions.bind('<<ListboxSelect>>', lambda a: self.update_outputs(0))
        rscroll = Scrollbar(self, command=self.roptions.yview)
        rscroll.grid(row=3, column=1, pady=8, sticky=N+S+E)
        self.roptions.configure(yscrollcommand=rscroll.set)

        # Insert all keys in the dictionary in the listboxes
        l = ['binary', 'octal', 'decimal', 'hexadecimal']
        for i in range(0, 4):
            self.loptions.insert('end', l[i])
            self.roptions.insert('end', l[i])

        for i in range(2, 37):
            self.loptions.insert('end', "base-" + str(i))
            self.roptions.insert('end', "base-" + str(i))

        self.loptions.select_set(0)  # select first item on the left
        self.roptions.select_set(0)  # select first item on the right

        # If the contents of an entry box change, update each box
        self.update_in_progress = False
        self.left_value.trace("w", lambda a,b,c: self.update_outputs(0))
        self.right_value.trace("w", lambda a,b,c: self.update_outputs(1))

    def update_outputs(self, *args):
        if self.update_in_progress:
            return
        try:
            self.update_in_progress = True
            temp_left = self.left_value.get()
            temp_right = self.right_value.get()

            lselection = self.loptions.curselection()
            left_type = self.loptions.get(lselection[0])
            rselection = self.roptions.curselection()
            right_type = self.roptions.get(rselection[0])

            x = self.OPTIONS[left_type]
            y = self.OPTIONS[right_type]

            if args[0] == 0:
                self.right_value.set(convert_numbers(temp_left, x, y))
            else:
                self.left_value.set(convert_numbers(temp_right, y, x))

        except ValueError:
            if args[0] == 0:
                self.right_value.set("Invalid input!")
            else:
                self.left_value.set("Invalid input!")
        except:
            print("Unexpected error:", sys.exc_info()[0])
            raise
        self.update_in_progress = False
示例#29
0
class MusicPanel(Frame):
    def __init__(self, parent, musicController: IMusicController):
        super().__init__(parent)
        self.musicController = musicController
        self.musicList: List[Music] = []

        self.selectedMusicPath: str = None

        self.__initView()

    def __initView(self):
        self.grid_columnconfigure(0, weight=1)

        self.musicListBox = Listbox(self)
        self.musicListBox.grid(row=0,
                               column=0,
                               sticky='WE',
                               padx=(10, 0),
                               pady=10)
        self.musicListBox.bind('<Double-1>', self.musicDoubleClicked)
        self.musicListBox.bind("<<ListboxSelect>>", self.musicSelected)

        musicScrollbar = Scrollbar(self, command=self.musicListBox.yview)
        musicScrollbar.grid(row=0,
                            column=1,
                            sticky='NS',
                            padx=(0, 10),
                            pady=10)

        self.musicListBox.configure(yscrollcommand=musicScrollbar.set)

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

        skipLabel = Label(self, text=SKIP_TEXT)
        skipLabel.grid(row=1, column=0)

        self.skipListBox = Listbox(self, exportselection=0)
        self.skipListBox.grid(row=2,
                              column=0,
                              sticky='WE',
                              padx=(10, 0),
                              pady=10)

        skipScrollbar = Scrollbar(self, command=self.skipListBox.yview)
        skipScrollbar.grid(row=2, column=1, sticky='NS', padx=(0, 10), pady=10)

        self.skipListBox.configure(yscrollcommand=skipScrollbar.set)

        self.deleteSkipButton = Button(self,
                                       text=DELETE_SKIP_TEXT,
                                       command=self.onSkipDelete)
        self.deleteSkipButton.grid(row=3, column=0, sticky='W', padx=10)

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

        self.addSkipFrame = Frame(self)
        self.addSkipFrame.grid(row=4, column=0, padx=10, sticky='W')

        self.addSkipLabel = Label(self.addSkipFrame, text=ADD_SKIP_LABEL_TEXT)
        self.addSkipLabel.grid(row=0, column=0)

        self.addSkipStartMinutesTE = Entry(self.addSkipFrame,
                                           width=5,
                                           exportselection=0)
        self.addSkipStartMinutesTE.insert(END, '0')
        self.addSkipStartMinutesTE.grid(row=0, column=1)

        label = Label(self.addSkipFrame, text=':')
        label.grid(row=0, column=2)

        self.addSkipStartSecondsTE = Entry(self.addSkipFrame,
                                           width=5,
                                           exportselection=0)
        self.addSkipStartSecondsTE.insert(END, '0')
        self.addSkipStartSecondsTE.grid(row=0, column=3)

        label = Label(self.addSkipFrame, text=ADD_SKIP_TO_LABEL_TEXT)
        label.grid(row=0, column=4)

        self.addSkipEndMinutesTE = Entry(self.addSkipFrame,
                                         width=5,
                                         exportselection=0)
        self.addSkipEndMinutesTE.insert(END, '0')
        self.addSkipEndMinutesTE.grid(row=0, column=5)

        label = Label(self.addSkipFrame, text=':')
        label.grid(row=0, column=6)

        self.addSkipEndSecondsTE = Entry(self.addSkipFrame,
                                         width=5,
                                         exportselection=0)
        self.addSkipEndSecondsTE.insert(END, '0')
        self.addSkipEndSecondsTE.grid(row=0, column=7)

        self.addSkipButton = Button(self.addSkipFrame,
                                    text=ADD_SKIP_BUTTON_TEXT,
                                    command=self.__addSkip)
        self.addSkipButton.grid(row=0, column=8, padx=2)

    def displayMusic(self, music: List[Music]):
        self.musicList = music

        self.musicListBox.delete(0, 'end')
        for i in range(len(music)):
            m = music[i]
            self.musicListBox.insert(i, m)

        if self.selectedMusicPath is not None:
            selectedIndex = -1
            for i in range(len(self.musicList)):
                if self.musicList[i].path == self.selectedMusicPath:
                    selectedIndex = i
                    break

            if selectedIndex >= 0:
                self.musicListBox.select_set(selectedIndex)
                self.musicListBox.event_generate("<<ListboxSelect>>")

    def musicDoubleClicked(self, event):
        music = self.musicList[self.musicListBox.curselection()[0]]
        self.musicController.onMusicDoubleClicked(music)

    def onSkipDelete(self):
        musicSelection = self.musicListBox.curselection()
        skipSelection = self.skipListBox.curselection()

        if len(skipSelection) <= 0 or len(musicSelection) <= 0:
            messagebox.showwarning('Warning', DELETE_SKIP_SELECT_MUSIC)
            return

        music = self.musicList[musicSelection[0]]
        self.musicController.onSkipDeleteClicked(music.skips[skipSelection[0]])

    def musicSelected(self, event):
        self.skipListBox.delete(0, 'end')

        selection = self.musicListBox.curselection()
        if len(selection) <= 0:
            return

        selectedMusic = self.musicList[selection[0]]
        self.selectedMusicPath = selectedMusic.path

        if selectedMusic.skips is not None:
            for i in range(len(selectedMusic.skips)):
                s = selectedMusic.skips[i]

                startMinute = int(s.start / 60)
                startSecond = s.start % 60
                stopMinute = int(s.end / 60)
                stopSecond = s.end % 60

                text = f'Skip from {startMinute:02d}:{startSecond:02d} to {stopMinute:02d}:{stopSecond:02d}'
                self.skipListBox.insert(i, text)

    def __addSkip(self):
        selection = self.musicListBox.curselection()

        if len(selection) <= 0:
            messagebox.showwarning('Warning', ADD_SKIP_SELECT_MUSIC)
            return

        music = self.musicList[selection[0]]

        try:
            startMinutes = int(self.addSkipStartMinutesTE.get())
            startSeconds = int(self.addSkipStartSecondsTE.get())
            endMinutes = int(self.addSkipEndMinutesTE.get())
            endSeconds = int(self.addSkipEndSecondsTE.get())
        except:
            messagebox.showwarning('Warning', ADD_SKIP_PARSE_ERROR_TEXT)
            return

        start = startMinutes * 60 + startSeconds
        end = endMinutes * 60 + endSeconds

        if end <= start:
            messagebox.showwarning('Warning', ADD_SKIP_END_LOWER_THAN_START)
            return

        self.musicController.onSkipAddClicked(music.path, start, end)
示例#30
0
class Trace(Module):
    '''
    Module to manage all of the different traces (with unique names/colors) and the
    Crosshairs objects associated to each one.  In particular, handles creation/modfication
    of traces and crosshairs.
    '''
    def __init__(self, app):
        info(' - initializing module: Trace')

        self.app = app

        # some images for the buttons
        # Source for icons: https://material.io/tools/icons/?style=outline
        # License: Apache Version 2.0 www.apache.org/licenses/LICENSE-2.0.txt
        data_copy = '''R0lGODlhGAAYAPAAAAAAAAAAACH5BAEAAAEALAAAAAAYABgAAAJHjI+pCe3/1oHUSdOunmDvHFTWBYrjUnbMuWIqAqEqCMdt+HI25yrVTZMEcT3NMPXJEZckJdKorCWbU2H0JqvKTBErl+XZFAAAOw'''
        data_paste = '''R0lGODlhGAAYAPAAAAAAAAAAACH5BAEAAAEALAAAAAAYABgAAAJBjI+pq+DAonlPToqza7rv9FlBeJCSOUJpd3EXm7piDKoi+nkqvnttPaMhUAzeiwJMapJDm8U44+kynCkmiM1qZwUAOw'''

        self.img_copy = PhotoImage(data=data_copy)
        self.img_paste = PhotoImage(data=data_paste)

        self.displayedColour = None
        #self.app.Data.getCurrentTraceColor()

        # array of trace names for this directory
        self.available = self.app.Data.getTopLevel('traces')
        self.available = [] if self.available == None else self.available

        # dictionary to hold trace -> [crosshairs] data
        self.crosshairs = {}

        # set of currently selected crosshairs
        self.selected = set()

        # set of copied crosshairs
        self.copied = []

        # declare & init trace string variable
        self.traceSV = StringVar()
        self.traceSV.set('')

        # frame for (most of) our widgets
        self.frame = Frame(self.app.LEFT)  #, pady=7, padx=7)
        self.frame.grid(row=4)

        # listbox to contain all of our traces
        lbframe = Frame(self.frame)
        self.scrollbar = Scrollbar(lbframe)
        self.listbox = Listbox(lbframe,
                               yscrollcommand=self.scrollbar.set,
                               width=12,
                               exportselection=False,
                               takefocus=0)
        self.scrollbar.config(command=self.listbox.yview)
        for trace in self.available:
            self.listbox.insert('end', trace)
        for i, item in enumerate(self.listbox.get(0, 'end')):
            # select our "default trace"
            if item == self.app.Data.getTopLevel('defaultTraceName'):
                self.listbox.selection_clear(0, 'end')
                self.listbox.select_set(i)

        # this module is responsible for so many widgets that we need a different
        # strategy for keeping track of everything that needs constistent grid() /
        # grid_remove() behavior
        self.TkWidgets = [
            self.getWidget(Header(self.frame, text="Choose a trace"),
                           row=5,
                           column=0,
                           columnspan=4),
            self.getWidget(lbframe, row=10, column=0, rowspan=50),
            self.getWidget(Button(self.frame,
                                  text='Set as default',
                                  command=self.setDefaultTraceName,
                                  takefocus=0),
                           row=10,
                           column=2,
                           columnspan=2),
            self.getWidget(Button(self.frame,
                                  text='Select all',
                                  command=self.selectAll,
                                  takefocus=0),
                           row=11,
                           column=2,
                           columnspan=2),
            self.getWidget(Button(self.frame,
                                  image=self.img_copy,
                                  command=self.copy,
                                  takefocus=0),
                           row=12,
                           column=2),  # FIXME: add tooltip for "Copy"
            self.getWidget(Button(self.frame,
                                  image=self.img_paste,
                                  command=self.paste,
                                  takefocus=0),
                           row=12,
                           column=3),  # FIXME: add tooltip for "Paste"
            self.getWidget(Entry(self.frame,
                                 width=8,
                                 textvariable=self.displayedColour),
                           row=13,
                           column=1,
                           columnspan=2,
                           sticky='w'),
            self.getWidget(Button(self.frame,
                                  text='Recolor',
                                  command=self.recolor,
                                  takefocus=0),
                           row=13,
                           column=3),
            self.getWidget(Button(self.frame,
                                  text='Clear',
                                  command=self.clear,
                                  takefocus=0),
                           row=15,
                           column=2,
                           columnspan=2),
            self.getWidget(Entry(self.frame,
                                 width=12,
                                 textvariable=self.traceSV),
                           row=100,
                           column=0,
                           sticky='w'),
            self.getWidget(Button(self.frame,
                                  text='New',
                                  command=self.newTrace,
                                  takefocus=0),
                           row=100,
                           column=2),
            self.getWidget(Button(self.frame,
                                  text='Rename',
                                  command=self.renameTrace,
                                  takefocus=0),
                           row=100,
                           column=3)
        ]

        # there's probably a better way to do this than indexing into self.TkWidgets
        self.TkWidgets[6]['widget'].bind(
            '<Return>', lambda ev: self.TkWidgets[0]['widget'].focus())
        self.TkWidgets[6]['widget'].bind(
            '<Escape>', lambda ev: self.TkWidgets[0]['widget'].focus())
        self.TkWidgets[9]['widget'].bind(
            '<Return>', lambda ev: self.TkWidgets[0]['widget'].focus())
        self.TkWidgets[9]['widget'].bind(
            '<Escape>', lambda ev: self.TkWidgets[0]['widget'].focus())

        if util.get_platform() == 'Linux':
            self.app.bind('<Control-r>', self.recolor)
            self.app.bind('<Control-c>', self.copy)
            self.app.bind('<Control-v>', self.paste)
        else:
            self.app.bind('<Command-r>', self.recolor)
            self.app.bind('<Command-c>', self.copy)
            self.app.bind('<Command-v>', self.paste)
        self.grid()

    def update(self):
        ''' on change frames '''
        # self.grid()
        #NOTE this is called during zoom and pan
        #this means the crosshairs are redrawn for every <Motion> call, which is a lot
        #we could probably just move them instead
        self.reset()  # clear our crosshairs
        self.read()  # read from file
        #self.frame.update()
        #debug("TraceModule", self.frame.winfo_width())
    def reset(self):
        ''' on change files '''
        # undraw all the crosshairs
        for trace in self.crosshairs:
            for ch in self.crosshairs[trace]:
                ch.undraw()
        # and empty out our trackers
        self.crosshairs = {}
        self.selected = set()

    def add(self, x, y, _trace=None, transform=True):
        '''
        add a crosshair to the zoom frame canvas
        '''

        trace = self.getCurrentTraceName() if _trace == None else _trace
        color = self.available[trace]['color']
        ch = Crosshairs(self.app.Dicom.zframe, x, y, color, transform)
        if trace not in self.crosshairs:
            self.crosshairs[trace] = []
        self.crosshairs[trace].append(ch)
        return ch

    def remove(self, ch, write=True):
        '''
        remove a crosshair from the zoom frame canvas ... doesn't actually remove it
        but instead just makes it "invisible"
        '''

        ch.undraw()
        if write:
            self.write()
        return ch

    def move(self):
        ''' called when window resizes to move to correct relative locations'''
        # trace = self.getCurrentTraceName()
        if self.crosshairs:
            for trace in self.crosshairs:
                for ch in self.crosshairs[trace]:
                    truex, truey = ch.getTrueCoords()
                    ch.x, ch.y = ch.transformTrueToCoords(truex, truey)
                    ch.dragTo((ch.x, ch.y))

    def read(self):
        '''
        read a list of crosshair coordinates from the metadata file
        '''
        frame = self.app.frame
        for trace in self.available:
            try:
                newCrosshairs = []
                for item in self.app.Data.getTraceCurrentFrame(trace):
                    ch = self.add(item['x'],
                                  item['y'],
                                  _trace=trace,
                                  transform=False)
                    if trace not in self.crosshairs:
                        self.crosshairs[trace] = []
                    self.crosshairs[trace].append(ch)
                    newCrosshairs.append(ch)
                self.app.Control.push({'type': 'add', 'chs': newCrosshairs})
            except KeyError:
                pass

    def write(self):
        '''
        write out the coordinates of all of our crosshairs to the metadata file:
        '''

        trace = self.getCurrentTraceName()
        traces = []

        # prepare trace data in format for metadata array
        if trace in self.crosshairs:
            for ch in self.crosshairs[trace]:
                if ch.isVisible:
                    x, y = ch.getTrueCoords()
                    data = {'x': x, 'y': y}
                    if data not in traces:
                        # add trace to temporary array for including in metadata array
                        traces.append(data)
        # add to metadata array and update file
        self.app.Data.setCurrentTraceCurrentFrame(traces)
        # update tier labels for number of annotated frames
        self.app.TextGrid.updateTierLabels()

    def getCurrentTraceName(self):
        '''
        return string of current trace name
        '''

        try:
            return self.listbox.get(self.listbox.curselection())
        except Exception as e:  # tkinter.TclError?
            error('Can\'t select from empty listbox!', e)

    def setDefaultTraceName(self):
        '''
        wrapper for changing the default trace
        '''
        self.app.Data.setTopLevel('defaultTraceName',
                                  self.getCurrentTraceName())

    def select(self, ch):
        ''' select a crosshairs '''
        ch.select()
        self.selected.add(ch)

    def selectAll(self):
        ''' select all crosshairs '''
        if self.getCurrentTraceName() in self.crosshairs:
            for ch in self.crosshairs[self.getCurrentTraceName()]:
                self.select(ch)

    def unselect(self, ch):
        ''' unselect a crosshairs '''
        ch.unselect()
        self.selected.remove(ch)

    def unselectAll(self):
        ''' unselect all crosshairs '''
        for ch in self.selected:
            ch.unselect()
        self.selected = set()

    def getNearClickAllTraces(self, click):
        '''
        takes a click object ( (x,y) tuple ) and returns a list of crosshairs
        within _CROSSHAIR_SELECT_RADIUS

        first searches for crosshairs matching the current trace iterates
        thru the other traces if it doesnt find anything

        if nothing is found for any trace, returns None
        '''
        # get nearby crosshairs from this trace
        nearby = self.getNearClickOneTrace(click, self.getCurrentTraceName())
        if nearby != None:
            return nearby

        # otherwise
        else:
            # ... check our other traces to see if they contain any nearby guys
            for trace in self.available:
                nearby = self.getNearClickOneTrace(click, trace)
                # if we got something
                if nearby != None:
                    # switch to that trace and exit the loop
                    for i, item in enumerate(self.listbox.get(0, 'end')):
                        if item == trace:
                            self.listbox.selection_clear(0, 'end')
                            self.listbox.select_set(i)
                    return nearby

        return None

    def getNearClickOneTrace(self, click, trace):
        '''
        takes a click object and a trace and returns a list of crosshairs within
        util.CROSSHAIR_SELECT_RADIUS of that click
        '''

        # see if we clicked near any existing crosshairs
        possibleSelections = {}
        if trace in self.crosshairs:
            for ch in self.crosshairs[trace]:
                d = ch.getDistance(click)
                if d < util.CROSSHAIR_SELECT_RADIUS:
                    if d in possibleSelections:
                        possibleSelections[d].append(ch)
                    else:
                        possibleSelections[d] = [ch]

        # if we did ...
        if possibleSelections != {}:
            # ... get the closest one ...
            dMin = sorted(possibleSelections.keys())[0]
            # ... in case of a tie, select a random one
            ch = random.choice(possibleSelections[dMin])
            return ch

        return None

    def copy(self, event=None):
        ''' copies relative positions of selected crosshairs for pasting'''
        # debug('copy')
        self.copied = []
        if len(self.selected) > 0:
            for ch in self.selected:
                self.copied.append(ch.getTrueCoords())

    def paste(self, event=None):
        ''' pastes copied crosshairs and add them to undo/redo buffer '''
        if len(self.copied) > 0:
            newChs = []
            for xy in self.copied:
                ch = self.add(xy[0], xy[1], transform=False)
                newChs.append(ch)
            self.write()
            self.app.Control.push({'type': 'add', 'chs': newChs})

    def recolor(self, event=None, trace=None, color=None):
        ''' change the color of a particular trace '''

        trace = self.getCurrentTraceName() if trace == None else trace

        # grab a new color and save our old color (for generating Control data)
        newColor = self.getRandomHexColor() if color == None else color
        oldColor = self.app.Data.getCurrentTraceColor()

        self.available[trace]['color'] = newColor
        self.app.Data.setTraceColor(trace, newColor)

        if trace in self.crosshairs:
            for ch in self.crosshairs[trace]:
                ch.recolor(newColor)

        if trace == None or color == None:
            self.app.Control.push({
                'type': 'recolor',
                'trace': self.getCurrentTraceName(),
                'color': oldColor
            })
            self.redoQueue = []
            # FIXME: get this to update the widget
            self.app.Trace.displayedColour = newColor
            # FIXME: also get the widget to update the colour!

        return oldColor

    def clear(self):
        ''' remove all crosshairs for the current trace '''

        # now we remove all the traces and save
        deleted = []
        trace = self.getCurrentTraceName()
        if trace in self.crosshairs:
            for ch in self.crosshairs[trace]:
                if ch.isVisible:
                    deleted.append(ch)
                self.remove(ch, write=False)
            self.write()

        self.app.Control.push({'type': 'delete', 'chs': deleted})

    def newTrace(self):
        ''' add a new trace to our listbox '''

        # max length 12 chars (so it displays nicely)
        name = self.traceSV.get()[:12]

        # don't want to add traces we already have or empty strings
        if name not in self.available and len(name) > 0:

            # choose a random color
            color = self.getRandomHexColor()

            # save the new trace name and color to metadata & update vars
            self.available[name] = {'color': color, 'files': {}}
            self.app.Data.setTopLevel('traces', self.available)
            self.traceSV.set('')

            # update our listbox
            self.listbox.insert('end', name)
            self.listbox.selection_clear(0, 'end')
            self.listbox.select_set(len(self.available) - 1)

    def renameTrace(self, oldName=None, newName=None):
        ''' change a trace name from oldName -> newName '''

        fromUndo = (oldName != None or newName != None)
        oldName = self.getCurrentTraceName() if oldName == None else oldName
        newName = self.traceSV.get()[:12] if newName == None else newName

        # don't overwrite anything
        if newName not in self.available and len(newName) > 0:

            # get data from the old name and change the dictionary key in the metadata
            data = self.available.pop(oldName)
            self.available[newName] = data
            self.app.Data.setTopLevel('traces', self.available)
            if oldName == self.app.Data.getTopLevel('defaultTraceName'):
                self.app.Data.setTopLevel('defaultTraceName', newName)
            self.traceSV.set('')

            # update our listbox
            index = self.listbox.curselection()
            self.listbox.delete(index)
            self.listbox.insert(index, newName)
            self.listbox.selection_clear(0, 'end')
            self.listbox.select_set(index)

            if not (fromUndo):
                self.app.Control.push({
                    'type': 'rename',
                    'old': oldName,
                    'new': newName
                })

    def getRandomHexColor(self):
        ''' helper for getting a random color '''
        return '#%06x' % random.randint(0, 0xFFFFFF)

    def getWidget(self,
                  widget,
                  row=0,
                  column=0,
                  rowspan=1,
                  columnspan=1,
                  sticky=()):
        ''' helper for managing all of our widgets '''
        return {
            'widget': widget,
            'row': row,
            'rowspan': rowspan,
            'column': column,
            'columnspan': columnspan,
            'sticky': sticky
        }

    def grid(self):
        ''' grid all of our widgets '''
        for item in self.TkWidgets:
            item['widget'].grid(row=item['row'],
                                column=item['column'],
                                rowspan=item['rowspan'],
                                columnspan=item['columnspan'],
                                sticky=item['sticky'])
        self.listbox.pack(side='left', fill='y')
        self.scrollbar.pack(side='right', fill='y')

    def grid_remove(self):
        ''' remove all of our widgets from the grid '''
        for item in self.TkWidgets:
            item['widget'].grid_remove()
        self.listbox.packforget()
        self.scrollbar.packforget()
示例#31
0
class DemoClient(Frame):
    def __init__(self, tk, args):
        Frame.__init__(self, tk)
        locale.setlocale(locale.LC_ALL,
                         '')  # empty string for platform's default settings
        self.master = tk
        self.config = json.load(open('config.json', 'r'))
        self.config['COMBOBOX_INDEX'] = sorted(self.config['COMBOBOX_INDEX'],
                                               key=lambda x: x[0])
        self.game_type = int(
            args.gametype
        ) if args.gametype else self.config["DEFAULT_GAME_TYPE_ID"]
        tk.title(self.config["APP_TITLE"])
        tk.resizable(False, False)
        self.get_icon()
        atexit.register(self.cancel_game)

        # Init class data fields that we use for storing info that we need for using the API
        self.bot_id = None
        self.bot_password = None
        self.logged_in = False
        self.game_style_ids = []
        self.gameChips = 0
        self.gameDeals = 0
        self.gameStake = 0
        self.gamePrize = 0
        self.player_key = None
        self.play_again = BooleanVar()
        self.do_not_play_same_user = BooleanVar()
        self.close_after_game = False
        self.game_cancelled = False
        self.in_game = False

        self.topFrame = Frame(tk, padx=12, pady=12)
        self.middleFrame = Frame(tk, padx=12)
        self.middleFrameLeft = Frame(self.middleFrame)
        self.middleFrameRight = Frame(self.middleFrame)
        self.middleFrameRighter = Frame(self.middleFrame)

        self.topFrame.grid(row=0, sticky=W + E)

        self.middleFrame.grid(row=1, sticky=W)
        self.middleFrameLeft.grid(row=1, column=0)
        self.middleFrameRight.grid(row=1, column=1)
        self.middleFrameRighter.grid(row=1, column=2)

        # ===================================
        # Create form elements

        # Top Frame Elements
        self.botNameLabel = Label(self.topFrame, text="Bot Name:")
        self.bot_id_entry = Entry(self.topFrame)
        self.bot_id_entry.bind('<Return>', self.log_in_if_not)
        self.bot_id_entry.focus()
        self.passwordLabel = Label(self.topFrame, text="Password:"******"Login",
                                        command=self.log_in_out_clicked)

        self.balanceLabel = Label(self.topFrame, text="Bot Balance:")
        self.balance = Label(self.topFrame, text="0")
        self.close_button = Button(self.topFrame,
                                   text="Close",
                                   padx=2,
                                   command=tk.destroy)

        # Middle Frame Elements
        # Middle Frame LEFT Elements
        self.gameTypeCmb = ttk.Combobox(
            self.middleFrameLeft,
            state="disabled",
            values=tuple((game[0]) for game in self.config['COMBOBOX_INDEX']))
        if self.game_type != self.config['NULL_GAME_TYPE_ID']:
            index = [
                i for i in range(len(self.config['COMBOBOX_INDEX']))
                if self.config['COMBOBOX_INDEX'][i][1] == self.game_type
            ][0]
            self.gameTypeCmb.current(
                index)  # Default selection matches default game type id
        self.gameTypeCmb.bind("<<ComboboxSelected>>", self.game_type_selected)

        self.gameStyleLabel = Label(self.middleFrameLeft,
                                    font=(None, 18),
                                    pady=0,
                                    text="Game Style Selection")

        self.opponentLabel = Label(self.middleFrameLeft,
                                   text="Specify Opponent (optional):")
        self.specify_opponent_cmb = ttk.Combobox(
            self.middleFrameLeft, values=self.config['AVAILABLE_OPPONENTS'])

        self.do_not_play_same_user_check = Checkbutton(
            self.middleFrameLeft,
            text='Don\'t play another bot in same user account as me',
            var=self.do_not_play_same_user)

        self.game_styles_listbox = Listbox(self.middleFrameLeft,
                                           background='#FFFFFF',
                                           height=8)
        self.game_styles_listbox.bind('<Double-1>',
                                      self.find_game_double_clicked)
        self.game_styles_listbox.bind(
            '<Return>', self.find_game_double_clicked
        )  # Not a double click but we want it to do the same thing

        self.refresh_game_styles_button = Button(
            self.middleFrameLeft,
            text="Refresh Game Styles",
            command=self.refresh_game_styles_clicked)

        self.thinkingTimeLabel = Label(self.middleFrameLeft,
                                       text="Add \"Thinking Time\" (ms):")
        self.thinking_time_entry = Entry(self.middleFrameLeft)

        self.auto_play_next_game_check = Checkbutton(
            self.middleFrameLeft,
            text='Play another game when complete',
            var=self.play_again)

        self.cancel_stop_game_button = Button(
            self.middleFrameLeft,
            text=CANCEL_GAME_TEXT,
            command=self.cancel_stop_game_clicked)
        self.find_game_button = Button(self.middleFrameLeft,
                                       text="Find Game",
                                       command=self.find_game_clicked)

        self.resultText = Message(
            self.middleFrameLeft,
            width=300,
            text="This is where the informational messages will appear")
        self.spacerLabel = Label(self.middleFrameLeft, text=" ")

        # Middle Frame RIGHT Elements

        self.gameTitleLabel = Label(self.middleFrameRight, text="Game Title")
        self.gameTitleText = Text(self.middleFrameRight,
                                  height=3,
                                  background='white',
                                  spacing1=3,
                                  pady=0)

        self.player = None  # Initialise as none before updating in create_visuals()
        self.opponent = None  # Initialise as none before updating in create_visuals()
        self.create_visuals()

        self.gameActionLabel = Label(self.middleFrameRight, text="")

        # ===================================
        # Set initial element states

        self.set_gamestyle_controls_states(DISABLED)
        self.cancel_stop_game_button.config(state=DISABLED)
        self.game_styles_listbox.config(background='white')
        self.thinking_time_entry.insert(0, 100)
        self.gameTitleText.config(state=DISABLED)
        self.set_balance(0)
        self.gameTitleText.tag_configure("center", justify='center')
        self.gameTitleText.tag_configure("bold", font='-weight bold')

        # ===================================
        # Form Layout

        # Top Frame Form Layout
        self.topFrame.grid_rowconfigure(0, weight=1)
        self.botNameLabel.grid(row=0, column=0, sticky=E)
        self.bot_id_entry.grid(row=0, column=1, sticky=W)
        self.passwordLabel.grid(row=0, column=2, sticky=E)
        self.bot_password_entry.grid(row=0, column=3, sticky=W)
        self.log_in_out_button.grid(row=0, column=4, sticky=E)
        self.topFrame.grid_columnconfigure(5, weight=1)
        self.balanceLabel.grid(row=0, column=5, sticky=E)
        self.balance.grid(row=0, column=6, sticky=W)
        self.close_button.grid(row=0, column=7, sticky=E, padx=(50, 0))

        # Middle Frame Form Layout
        self.middleFrame.grid_rowconfigure(0, weight=1)
        self.gameTypeCmb.grid(row=0, column=0, columnspan=1, sticky=W + E)
        self.gameStyleLabel.grid(row=1, column=0, columnspan=1, sticky=W + E)
        self.spacerLabel.grid(row=1, column=2, sticky=E)

        self.opponentLabel.grid(row=2, column=0, sticky=W, pady=4)
        self.specify_opponent_cmb.grid(row=2, column=0, sticky=E, pady=4)

        self.do_not_play_same_user_check.grid(row=3,
                                              column=0,
                                              columnspan=1,
                                              sticky='we',
                                              pady=4)
        self.game_styles_listbox.grid(row=4,
                                      column=0,
                                      columnspan=1,
                                      sticky='we',
                                      pady=4)
        self.find_game_button.grid(row=5, column=0, pady=4, sticky=W)
        self.refresh_game_styles_button.grid(row=5,
                                             column=0,
                                             columnspan=1,
                                             sticky='',
                                             pady=4)
        self.cancel_stop_game_button.grid(row=5, column=0, sticky=E)

        self.thinkingTimeLabel.grid(row=6, column=0, sticky=W, pady=4)
        self.thinking_time_entry.grid(row=6, column=0, sticky=E, pady=4)

        self.auto_play_next_game_check.grid(row=7,
                                            column=0,
                                            columnspan=1,
                                            sticky=W,
                                            pady=4)
        self.resultText.grid(row=9, column=0, columnspan=2, sticky=W, pady=4)
        self.middleFrame.grid_columnconfigure(9, weight=1)

        self.gameTitleLabel.grid(row=0, column=3)
        self.gameTitleText.grid(row=0, column=3, columnspan=2)
        self.gameActionLabel.grid(row=11, column=3, sticky='w')

        if args.botid is not None and args.password is not None:
            self.auto_play(args)

    def auto_play(self, args):
        self.bot_id_entry.insert(0, args.botid)
        self.bot_password_entry.insert(0, args.password)
        self.log_in_out_clicked()
        self.thinking_time_entry.insert(0, args.timeout)
        if args.playanothergame:
            self.auto_play_next_game_check.select()
        if args.dontplaysameuserbot:
            self.do_not_play_same_user_check.select()
        if args.closeaftergame:
            self.close_after_game = True
        if args.gamestyle is not None:
            i = 0
            for i in range(self.game_styles_listbox.size()):
                if args.gamestyle in str(self.game_styles_listbox.get(i)):
                    break
            self.game_styles_listbox.select_set(i, i)
            self.find_game_clicked()

    def log_in_out_clicked(self):
        """Click handler for the 'Login'/'Logout' button."""

        # This means we're logging out
        if self.logged_in:
            self.resultText.config(text='Logged Out')

            self.master.title(self.config["APP_TITLE"] + " (Not Logged In)")

            self.cancel_game()

            self.bot_id = None
            self.bot_password = None
            self.clear_game_title_text()
            self.gameActionLabel.config(text="")
            self.reset_game_styles_listbox()
            self.clear_all_boards()
            self.opponent.delete("all")

            self.log_in_out_button.config(text='Login')

            self.set_login_controls_states(ENABLED)
            self.set_gamestyle_controls_states(DISABLED)
            self.gameTypeCmb.config(state="disabled")

            self.logged_in = False
            self.bot_password_entry.delete(0, 'end')
            self.set_balance(0)

        # This means we're logging in
        else:
            self.bot_id = self.bot_id_entry.get()
            self.bot_password = self.bot_password_entry.get()

            res = self.get_list_of_game_styles()
            if res['Result'] == 'SUCCESS':
                self.resultText.config(text='Logged In')

                game_styles = res['GameStyles']
                self.master.title(self.bot_id + " - " +
                                  self.config["APP_TITLE"])

                self.set_login_controls_states(DISABLED)
                self.set_gamestyle_controls_states(ENABLED)
                self.gameTypeCmb.config(state="readonly")

                self.set_game_styles_listbox(game_styles)
                self.set_balance(res['Balance'])

                self.log_in_out_button.config(text='Logout')

                self.logged_in = True

            else:
                messagebox.showerror(
                    'Error',
                    'Invalid login attempt. Please check the username and password entered.'
                )

    def log_in_if_not(self, _):
        if not self.logged_in:
            self.log_in_out_clicked()

    def clear_all_boards(self):
        self.player.clear_board()
        self.opponent.clear_board()
        self.player.delete("all")
        self.opponent.delete("all")
        self.player.myBoard = None
        self.opponent.oppBoard = None

    def set_in_game(self, value):
        self.in_game = value

    def set_game_title_text(self, text, tag):
        self.gameTitleText.config(state=ENABLED)
        self.gameTitleText.insert("end", text, ("center", tag))
        self.gameTitleText.config(state=DISABLED)

    def clear_game_title_text(self):
        self.gameTitleText.config(state=ENABLED)
        self.gameTitleText.delete("1.0", "end")
        self.gameTitleText.config(state=DISABLED)

    def set_login_controls_states(self, state):
        self.bot_id_entry.config(state=state)
        self.bot_password_entry.config(state=state)

    def set_gamestyle_controls_states(self, state):
        self.specify_opponent_cmb.config(state=state)
        self.do_not_play_same_user_check.config(state=state)
        self.game_styles_listbox.config(state=state)
        self.find_game_button.config(state=state)
        self.refresh_game_styles_button.config(state=state)
        self.auto_play_next_game_check.config(state=state)
        self.thinking_time_entry.config(state=state)
        self.opponentLabel.config(state=state)
        self.thinkingTimeLabel.config(state=state)
        self.balanceLabel.config(state=state)
        self.balance.config(state=state)
        self.gameStyleLabel.config(state=state)
        self.game_styles_listbox.config(state=state)
        self.player.config(state=state)
        self.opponent.config(state=state)

    def set_balance(self, balance):
        """Set the balance field"""
        self.balance['text'] = int_with_commas(balance)

    def get_list_of_game_styles(self):
        """Get list of game styles from the server."""

        req = {
            'BotId': self.bot_id,
            'BotPassword': self.bot_password,
            'GameTypeId': self.game_type
        }

        url = self.config["BASE_URL"] + self.config[
            "GET_LIST_OF_GAME_STYLES_EXTENSION"]

        return DemoClient.make_api_call(url, req)

    def set_game_styles_listbox(self, game_styles):
        """Set the content of the game styles listbox with a list of GameStyle dictionaries.
        Keyword Arguments:
        game_styles -- The list of GameStyle dictionaries, this should be obtained through get_list_of_game_styles().
        """
        self.reset_game_styles_listbox()
        for index, game_style in enumerate(game_styles):
            if self.game_type == self.config["BATTLESHIPS_GAME_TYPE_ID"]:
                self.game_styles_listbox.insert(
                    index,
                    self.config["BATTLESHIPS_GAME_STYLE_LISTBOX_TEXT"].format(
                        game_style['GameStyleId'], game_style['Stake'],
                        game_style['GameTypeSpecificInfo']['Ships'],
                        game_style['GameTypeSpecificInfo']['Board Size'],
                        game_style['GameTypeSpecificInfo']['Timeout ms'],
                        game_style['GameTypeSpecificInfo']['DealsTotal'],
                        game_style['GameTypeSpecificInfo']['PercentageLand'],
                        game_style['GameTypeSpecificInfo']['RandomLand']))
            elif self.game_type == self.config[
                    "NOUGHTS_AND_CROSSES_GAME_TYPE_ID"]:
                self.game_styles_listbox.insert(
                    index,
                    self.config["NOUGHTS_AND_CROSSES_GAME_STYLE_LISTBOX_TEXT"].
                    format(game_style['GameStyleId'], game_style['Stake'],
                           game_style['GameTypeSpecificInfo']['DealsTotal'],
                           game_style['GameTypeSpecificInfo']['Timeout ms']))
            elif self.game_type == self.config[
                    "TRAVELLING_SALESDRONE_GAME_TYPE_ID"]:
                self.game_styles_listbox.insert(
                    index, self.
                    config["TRAVELLING_SALESDRONE_GAME_STYLE_LISTBOX_TEXT"].
                    format(game_style['GameStyleId'], game_style['Stake'],
                           game_style['GameTypeSpecificInfo']['TotalCities'],
                           game_style['GameTypeSpecificInfo']['DealLength']))
            elif self.game_type == self.config["PREDICTIVE_TEXT_GAME_TYPE_ID"]:
                self.game_styles_listbox.insert(
                    index, self.
                    config["PREDICTIVE_TEXT_GAME_STYLE_LISTBOX_TEXT"].format(
                        game_style['GameStyleId'], game_style['Stake'],
                        game_style['GameTypeSpecificInfo']
                        ['Number of Sentences'],
                        game_style['GameTypeSpecificInfo']
                        ['Switched Words Game'],
                        game_style['GameTypeSpecificInfo']['Timeout ms']))
            elif self.game_type == self.config["TWIST_CUBE_GAME_TYPE_ID"]:
                self.game_styles_listbox.insert(
                    index,
                    self.config["TWIST_CUBE_GAME_STYLE_LISTBOX_TEXT"].format(
                        game_style['GameStyleId'], game_style['Stake'],
                        game_style['GameTypeSpecificInfo']['cubeSize'],
                        game_style['GameTypeSpecificInfo']['GameLength']))
            elif self.game_type == self.config["SLIDING_PUZZLE_GAME_TYPE_ID"]:
                self.game_styles_listbox.insert(
                    index,
                    self.config["SLIDING_PUZZLE_GAME_STYLE_LISTBOX_TEXT"].
                    format(game_style['GameStyleId'], game_style['Stake'],
                           game_style['GameTypeSpecificInfo']['RowSize'],
                           game_style['GameTypeSpecificInfo']['ColumnSize'],
                           game_style['GameTypeSpecificInfo']['TimeLimit']))
            elif self.game_type == self.config["BLURRY_WORD_GAME_TYPE_ID"]:
                self.game_styles_listbox.insert(
                    index,
                    self.config["BLURRY_WORD_GAME_STYLE_LISTBOX_TEXT"].format(
                        game_style['GameStyleId'], game_style['Stake'],
                        game_style['GameTypeSpecificInfo']['NumImages'],
                        game_style['GameTypeSpecificInfo']['GameLength']))
            elif self.game_type == self.config["MASTERMIND_GAME_TYPE_ID"]:
                self.game_styles_listbox.insert(
                    index,
                    self.config["MASTERMIND_GAME_STYLE_LISTBOX_TEXT"].format(
                        game_style['GameStyleId'], game_style['Stake'],
                        game_style['GameTypeSpecificInfo']['NumPegs'],
                        game_style['GameTypeSpecificInfo']['NumColours'],
                        game_style['GameTypeSpecificInfo']
                        ['DuplicatesAllowed']))
            elif self.game_type == self.config[
                    "WAREHOUSE_LOGISTICS_GAME_TYPE_ID"]:
                self.game_styles_listbox.insert(
                    index,
                    self.config["WAREHOUSE_LOGISTICS_GAME_STYLE_LISTBOX_TEXT"].
                    format(
                        game_style['GameStyleId'], game_style['Stake'],
                        game_style['GameTypeSpecificInfo']
                        ['WarehouseDimensions'][0],
                        game_style['GameTypeSpecificInfo']
                        ['WarehouseDimensions'][1]))
            elif self.game_type == self.config["FOUR_IN_A_ROW_GAME_TYPE_ID"]:
                self.game_styles_listbox.insert(
                    index,
                    self.config["FOUR_IN_A_ROW_GAME_STYLE_LISTBOX_TEXT"].
                    format(game_style['GameStyleId'], game_style['Stake'],
                           game_style['GameTypeSpecificInfo']['Dimensions'][0],
                           game_style['GameTypeSpecificInfo']['Dimensions'][1],
                           game_style['GameTypeSpecificInfo']['Connections']))
            elif self.game_type == self.config["WHO_IS_WHO_GAME_TYPE_ID"]:
                self.game_styles_listbox.insert(
                    index,
                    self.config["WHO_IS_WHO_GAME_STYLE_LISTBOX_TEXT"].format(
                        game_style['GameStyleId'], game_style['Stake'],
                        game_style['GameTypeSpecificInfo']['NumCharacters'],
                        game_style['GameTypeSpecificInfo']['ComparisonRound']))
            elif self.game_type == self.config[
                    "REVERSING_STONES_GAME_TYPE_ID"]:
                self.game_styles_listbox.insert(
                    index,
                    self.config["REVERSING_STONES_GAME_STYLE_LISTBOX_TEXT"].
                    format(game_style['GameStyleId'], game_style['Stake'],
                           game_style['GameTypeSpecificInfo']['Dimensions'][0],
                           game_style['GameTypeSpecificInfo']['Dimensions'][1],
                           game_style['GameTypeSpecificInfo']['Holes'],
                           game_style['GameTypeSpecificInfo']['Timeout ms']))
            elif self.game_type == self.config["CHECKERS_GAME_TYPE_ID"]:
                self.game_styles_listbox.insert(
                    index,
                    self.config["CHECKERS_GAME_STYLE_LISTBOX_TEXT"].format(
                        game_style['GameStyleId'], game_style['Stake'],
                        game_style['GameTypeSpecificInfo']['Dimensions'][0],
                        game_style['GameTypeSpecificInfo']['Dimensions'][1],
                        game_style['GameTypeSpecificInfo']['Timeout ms']))
            elif self.game_type == self.config["GO_GAME_TYPE_ID"]:
                self.game_styles_listbox.insert(
                    index, self.config["GO_GAME_STYLE_LISTBOX_TEXT"].format(
                        game_style['GameStyleId'], game_style['Stake'],
                        game_style['GameTypeSpecificInfo']['Dimensions'][0],
                        game_style['GameTypeSpecificInfo']['Dimensions'][1],
                        "CAPTURE" if
                        game_style['GameTypeSpecificInfo']['IsCaptureGo'] else
                        game_style['GameTypeSpecificInfo']['ScoringMethod'],
                        game_style['GameTypeSpecificInfo']['Timeout ms']))
            elif self.game_type == self.config["LEXICO_GAME_TYPE_ID"]:
                self.game_styles_listbox.insert(
                    index,
                    self.config["LEXICO_GAME_STYLE_LISTBOX_TEXT"].format(
                        game_style['GameStyleId'], game_style['Stake'],
                        game_style['GameTypeSpecificInfo']['Dimensions'][0],
                        game_style['GameTypeSpecificInfo']['Dimensions'][1],
                        game_style['GameTypeSpecificInfo']['TileMultipliers'],
                        game_style['GameTypeSpecificInfo']['Timeout ms']))
            elif self.game_type == self.config["DOMINOES_GAME_TYPE_ID"]:
                self.game_styles_listbox.insert(
                    index,
                    self.config["DOMINOES_GAME_STYLE_LISTBOX_TEXT"].format(
                        game_style['GameStyleId'], game_style['Stake'],
                        game_style['GameTypeSpecificInfo']['SpotNo'],
                        game_style['GameTypeSpecificInfo']['Timeout ms']))
            else:
                raise ValueError('INVALID GAME TYPE PARAMETER')

            self.game_style_ids.append(game_style['GameStyleId'])
            # self.game_styles_listbox.select_set(GAME_STYLE_LISTBOX_DEFAULT_SELECTION)

    def reset_game_styles_listbox(self):
        """Clear the content of the game styles listbox."""

        if self.game_styles_listbox.size() != 0:
            self.game_styles_listbox.delete(0, 'end')

            self.game_style_ids = []

    def refresh_game_styles_clicked(self):
        """Click handler for the 'Refresh Game Styles' button."""

        res = self.get_list_of_game_styles()
        game_styles = res['GameStyles']
        self.set_game_styles_listbox(game_styles)

    def find_game_clicked(self):
        """Click handler for the 'Find Game' button"""

        self.find_game_button.config(state=DISABLED)
        self.cancel_stop_game_button.config(state=ENABLED)
        self.game_styles_listbox.unbind('<Double-1>')
        self.game_styles_listbox.unbind('<Return>')
        self.game_styles_listbox.config(state=DISABLED)
        self.clear_all_boards()

        # Here we dispatch the work to a separate thread, to keep the GUI responsive.
        if not MAC:
            threading.Thread(target=self.game_loop, daemon=True).start()
        else:
            self.game_loop()  # Doesn't work on MACs

    def find_game_double_clicked(self, _):
        self.find_game_clicked()

    def game_type_selected(self, _):
        self.game_type = self.config["COMBOBOX_INDEX"][
            self.gameTypeCmb.current()][1]
        res = self.get_list_of_game_styles()
        if res['Result'] == 'SUCCESS':
            game_styles = res['GameStyles']
            self.set_game_styles_listbox(game_styles)
            self.get_icon()
            self.player.destroy()
            self.opponent.destroy()
            self.create_visuals()

    def get_icon(self):
        try:
            if WINDOWS:
                self.master.iconbitmap("assets/{0}/icon.ico".format(
                    self.game_type))
            else:
                self.master.iconbitmap("./assets/{0}/icon.xbm".format(
                    self.game_type))
        except Exception as e:
            print(e)

    def create_visuals(self):
        if self.game_type == self.config["NULL_GAME_TYPE_ID"]:
            self.player = null_visuals.NullVisuals(
                self.middleFrameRight)  # Game Display Table
            self.opponent = null_visuals.NullVisuals(
                self.middleFrameRight)  # Game Display Table
        elif self.game_type == self.config["BATTLESHIPS_GAME_TYPE_ID"]:
            self.player = battleships_visuals.BattleshipsVisuals(
                self.middleFrameRight)  # Game Display Table
            self.opponent = battleships_visuals.BattleshipsVisuals(
                self.middleFrameRight)  # Game Display Table
        elif self.game_type == self.config["NOUGHTS_AND_CROSSES_GAME_TYPE_ID"]:
            self.player = noughts_and_crosses_visuals.NoughtsAndCrossesVisuals(
                self.middleFrameRight)  # Game Display Table
            self.opponent = noughts_and_crosses_visuals.NoughtsAndCrossesVisuals(
                self.middleFrameRight)  # Game Display Table
        elif self.game_type == self.config[
                "TRAVELLING_SALESDRONE_GAME_TYPE_ID"]:
            self.player = travelling_salesdrone_visuals.TravellingSalesdroneVisuals(
                self.middleFrameRight)  # Game Display Table
            self.opponent = travelling_salesdrone_visuals.TravellingSalesdroneVisuals(
                self.middleFrameRight)  # Game Display Table
        elif self.game_type == self.config["PREDICTIVE_TEXT_GAME_TYPE_ID"]:
            self.player = predictive_text_visuals.PredictiveTextVisuals(
                self.middleFrameRight)  # Game Display Table
            self.opponent = predictive_text_visuals.PredictiveTextVisuals(
                self.middleFrameRight)  # Game Display Table
        elif self.game_type == self.config["TWIST_CUBE_GAME_TYPE_ID"]:
            self.player = twist_cube_visuals.TwistCubeVisuals(
                self.middleFrameRight)  # Game Display Table
            self.opponent = twist_cube_visuals.TwistCubeVisuals(
                self.middleFrameRight)  # Game Display Table
        elif self.game_type == self.config["SLIDING_PUZZLE_GAME_TYPE_ID"]:
            self.player = sliding_puzzle_visuals.SlidingPuzzleVisuals(
                self.middleFrameRight)  # Game Display Table
            self.opponent = sliding_puzzle_visuals.SlidingPuzzleVisuals(
                self.middleFrameRight)  # Game Display Table
        elif self.game_type == self.config["BLURRY_WORD_GAME_TYPE_ID"]:
            self.player = blurry_word_visuals.MicrosoftCognitiveChallengeVisuals(
                self.middleFrameRight)  # Game Display Table
            self.opponent = blurry_word_visuals.MicrosoftCognitiveChallengeVisuals(
                self.middleFrameRight)  # Game Display Table
        elif self.game_type == self.config["MASTERMIND_GAME_TYPE_ID"]:
            self.player = mastermind_visuals.MastermindVisuals(
                self.middleFrameRight)  # Game Display Table
            self.opponent = mastermind_visuals.MastermindVisuals(
                self.middleFrameRight)  # Game Display Table
        elif self.game_type == self.config["WAREHOUSE_LOGISTICS_GAME_TYPE_ID"]:
            self.player = warehouse_logistics_visuals.WarehouseLogisticsVisuals(
                self.middleFrameRight)  # Game Display Table
            self.opponent = warehouse_logistics_visuals.WarehouseLogisticsVisuals(
                self.middleFrameRight)  # Game Display Table
        elif self.game_type == self.config["FOUR_IN_A_ROW_GAME_TYPE_ID"]:
            self.player = four_in_a_row_visuals.FourInARowVisuals(
                self.middleFrameRight)  # Game Display Table
            self.opponent = four_in_a_row_visuals.FourInARowVisuals(
                self.middleFrameRight)  # Game Display Table
        elif self.game_type == self.config["WHO_IS_WHO_GAME_TYPE_ID"]:
            self.player = who_is_who_visuals.WhoIsWhoVisuals(
                self.middleFrameRight)  # Game Display Table
            self.opponent = who_is_who_visuals.WhoIsWhoVisuals(
                self.middleFrameRight)  # Game Display Table
        elif self.game_type == self.config["REVERSING_STONES_GAME_TYPE_ID"]:
            self.player = reversing_stones_visuals.ReversingStonesVisuals(
                self.middleFrameRight)  # Game Display Table
            self.opponent = reversing_stones_visuals.ReversingStonesVisuals(
                self.middleFrameRight)  # Game Display Table
        elif self.game_type == self.config["CHECKERS_GAME_TYPE_ID"]:
            self.player = checkers_visuals.CheckersVisuals(
                self.middleFrameRight)  # Game Display Table
            self.opponent = checkers_visuals.CheckersVisuals(
                self.middleFrameRight)  # Game Display Table
        elif self.game_type == self.config["GO_GAME_TYPE_ID"]:
            self.player = go_visuals.GoVisuals(
                self.middleFrameRight)  # Game Display Table
            self.opponent = go_visuals.GoVisuals(
                self.middleFrameRight)  # Game Display Table
        elif self.game_type == self.config["LEXICO_GAME_TYPE_ID"]:
            self.player = lexico_visuals.LexicoVisuals(
                self.middleFrameRight)  # Game Display Table
            self.opponent = lexico_visuals.LexicoVisuals(
                self.middleFrameRight)  # Game Display Table
        elif self.game_type == self.config["DOMINOES_GAME_TYPE_ID"]:
            self.player = dominoes_visuals.DominoesVisuals(
                self.middleFrameRight)  # Game Display Table
            self.opponent = dominoes_visuals.DominoesVisuals(
                self.middleFrameRight)  # Game Display Table
        else:
            raise ValueError('INVALID GAME TYPE PARAMETER')
        self.player.grid(row=1, column=3)
        self.opponent.grid(row=1, column=4)

    def game_loop(self):
        """Loop through finding and playing games."""

        while True:
            self.clear_all_boards()
            mover.persistentData = {}
            self.find_game()
            self.update_balance()
            if self.game_cancelled:
                break
            self.play_game()
            self.update_balance()
            if self.close_after_game:
                self.close_button.invoke()
            if self.game_cancelled:
                break
            if not self.play_again.get():
                break

        self.find_game_button.config(state=ENABLED)
        self.cancel_stop_game_button.config(state=DISABLED,
                                            text=CANCEL_GAME_TEXT)
        self.game_styles_listbox.bind('<Double-1>',
                                      self.find_game_double_clicked)
        self.game_styles_listbox.bind('<Return>',
                                      self.find_game_double_clicked)
        self.game_styles_listbox.config(state=ENABLED)
        self.game_cancelled = False

    def find_game(self):
        """Find a game."""

        offer_game_res = self.offer_game()

        if offer_game_res['Result'] == 'INVALID_LOGIN_OR_PASSWORD':
            self.cancel_stop_game_clicked()
            if 'ErrorMessage' in offer_game_res and offer_game_res[
                    'ErrorMessage'] == 'Check of OpponentId failed':
                self.resultText.config(text='Invalid Opponent ID')
            else:
                self.resultText.config(text='Invalid login or password')
        elif offer_game_res['Result'] == 'INSUFFICIENT_BALANCE':
            self.cancel_stop_game_clicked()
            self.resultText.config(text='Insufficient balance')
        elif offer_game_res['Result'] == 'BOT_IS_INACTIVE':
            self.cancel_stop_game_clicked()
            self.resultText.config(text='Bot is inactive')
        else:
            self.player_key = offer_game_res['PlayerKey']
            if offer_game_res['Result'] == 'WAITING_FOR_GAME':
                self.wait_for_game()

    def offer_game(self):
        """Offer a game."""

        self.cancel_game(
        )  # Cancel the last outstanding game offer that was made

        opponent_id = self.specify_opponent_cmb.get()
        if len(opponent_id) == 0:
            opponent_id = None
        try:
            game_style_id = self.game_style_ids[int(
                self.game_styles_listbox.curselection()[0])]
        except IndexError:
            self.game_styles_listbox.select_set(
                GAME_STYLE_LISTBOX_DEFAULT_SELECTION)
            game_style_id = self.game_style_ids[0]

        req = {
            'BotId': self.bot_id,
            'BotPassword': self.bot_password,
            'MaximumWaitTime': 1000,
            'GameStyleId': game_style_id,
            'DontPlayAgainstSameUser': self.do_not_play_same_user.get(),
            'DontPlayAgainstSameBot': False,
            'OpponentId': opponent_id
        }
        url = self.config["BASE_URL"] + self.config["OFFER_GAME_EXTENSION"]

        return DemoClient.make_api_call(url, req)

    def wait_for_game(self):
        """Wait for game to start."""
        self.resultText.config(text='Waiting for game')
        while True:
            if self.game_cancelled:
                self.cancel_game()
                self.find_game_button.config(state=ENABLED)
                self.cancel_stop_game_button.config(state=DISABLED,
                                                    text=CANCEL_GAME_TEXT)
                self.game_styles_listbox.bind('<Double-1>',
                                              self.find_game_double_clicked)
                self.game_styles_listbox.bind('<Return>',
                                              self.find_game_double_clicked)
                self.game_styles_listbox.config(state=ENABLED)
                break
            poll_results = self.poll_for_game_state()

            if poll_results['Result'] == 'SUCCESS':
                break
            if poll_results['Result'] == 'INVALID_PLAYER_KEY' or poll_results[
                    'Result'] == 'GAME_HAS_ENDED' or poll_results[
                        'Result'] == 'GAME_WAS_STOPPED':
                self.game_cancelled = True
            time.sleep(2)

    def play_game(self):
        """Play a game."""
        self.resultText.config(text='Playing game')
        self.in_game = True

        poll_results = self.poll_for_game_state()

        if poll_results["Result"] != "SUCCESS":
            return

        game_state = poll_results['GameState']

        title = format('Game ID: ' + str(game_state['GameId']))
        title += format(' / Style: ' + str(self.game_style_ids[int(
            self.game_styles_listbox.curselection()[0])]))
        title += "\n"
        versus = format(self.bot_id + ' vs ' + game_state['OpponentId'])

        self.clear_game_title_text()
        self.set_game_title_text(title, "")
        self.set_game_title_text(versus, "bold")

        self.middleFrame.update()

        while True:
            if self.game_cancelled:
                break

            if game_state['IsMover']:
                self.resultText.config(text='Playing Game - Your Turn')
                move = mover.calculate_move(self.game_type, game_state)
                move_results = self.make_move(move)

                if move_results['Result'] == 'INVALID_MOVE':
                    self.resultText.config(text="Invalid Move")
                elif move_results['Result'] != 'SUCCESS':
                    self.resultText.config(text='Game has ended: ' +
                                           move_results['Result'])
                    print(str(move_results))
                    print("Game ended")
                    break
                else:
                    game_state = move_results['GameState']
            else:
                self.resultText.config(text="Playing Game - Opponent's Turn")

                # ---- Code here will be called on your opponent's turn ----

                # ----------------------------------------------------------

                poll_results = self.poll_for_game_state()

                if poll_results['Result'] != 'SUCCESS':
                    self.resultText.config(text='Game has ended: ' +
                                           poll_results['Result'])
                    break
                game_state = poll_results['GameState']

            if game_state['GameStatus'] != 'RUNNING':
                break

            self.middleFrameRight.update()

            try:
                if int(self.thinking_time_entry.get()) > 0:
                    time.sleep((int(self.thinking_time_entry.get()) / 1000))
                else:
                    time.sleep(0.1)
            except ValueError:
                time.sleep(0.1)

        self.set_in_game(False)

    def make_move(self, move):
        """Make a move."""

        req = {
            'BotId': self.bot_id,
            'BotPassword': self.bot_password,
            'PlayerKey': self.player_key,
            'Move': move
        }
        url = self.config["BASE_URL"] + self.config["MAKE_MOVE_EXTENSION"]

        result = DemoClient.make_api_call(url, req)

        if result['Result'] == 'SUCCESS' or "GAME_HAS_ENDED" in result[
                'Result']:
            print(result)
            try:
                self.player.draw_game_state(result['GameState'], True)
                self.opponent.draw_game_state(result['GameState'], False)
            except Exception as e:
                print("Gamestate error: " + str(e))

        return result

    def poll_for_game_state(self):
        """Poll the server for the latest GameState."""

        req = {
            'BotId': self.bot_id,
            'BotPassword': self.bot_password,
            'MaximumWaitTime': 1000,
            'PlayerKey': self.player_key
        }
        url = self.config["BASE_URL"] + self.config[
            "POLL_FOR_GAME_STATE_EXTENSION"]

        result = DemoClient.make_api_call(url, req)
        if result['Result'] == 'SUCCESS' or "GAME_HAS_ENDED" in result[
                'Result']:
            self.player.draw_game_state(result['GameState'], True)
            self.opponent.draw_game_state(result['GameState'], False)

        return result

    def cancel_stop_game_clicked(self):
        self.game_cancelled = True
        self.cancel_game()
        self.find_game_button.config(state=ENABLED)
        self.cancel_stop_game_button.config(state=DISABLED,
                                            text=CANCEL_GAME_TEXT)
        self.game_styles_listbox.bind('<Double-1>',
                                      self.find_game_double_clicked)
        self.game_styles_listbox.bind('<Return>',
                                      self.find_game_double_clicked)
        self.game_styles_listbox.config(state=ENABLED)

    def cancel_game(self):
        print("Cancelling last game offer")
        if self.player_key is None:
            return
        req = {
            'BotId': self.bot_id,
            'BotPassword': self.bot_password,
            'PlayerKey': self.player_key
        }

        url = self.config["BASE_URL"] + self.config[
            "CANCEL_GAME_OFFER_EXTENSION"]
        DemoClient.make_api_call(url, req)
        try:
            self.resultText.config(text='Cancelled game')
        except Exception as e:
            print(str(e) + " -- Demo client has been closed")

    def update_balance(self):
        res = self.get_list_of_game_styles()
        self.set_balance(res['Balance'])

    @staticmethod
    def make_api_call(url, req):
        """Make an API call."""
        while True:
            try:
                res = requests.post(url,
                                    json=req,
                                    headers=API_CALL_HEADERS,
                                    timeout=60.0)
                try:
                    jres = res.json()
                    if 'Result' in jres:
                        return jres
                    time.sleep(0.1)
                except ValueError:
                    time.sleep(0.1)
            except requests.ConnectionError:
                time.sleep(0.1)
            except requests.Timeout:
                time.sleep(0.1)
            except requests.HTTPError:
                time.sleep(0.1)
            except BaseException as e:  # Bad code but needed for testing purposes
                print(e)
                time.sleep(0.1)
示例#32
0
文件: LD.py 项目: omarbou14/LD
            if bb_[nn][1] == 1:
                list2[bb_[nn][0]].coords(can, x, y, N2.x, N2.y)
            else:
                list2[bb_[nn][0]].coords(can, N1.x, N1.y, x, y)
        itr += 1


root = Tk()
root.geometry("900x700")
root.title("Distribution")

can = Canvas(root, width=w, height=h, bg='grey')
can.pack(side=RIGHT)

list1 = Listbox(root)
list1.select_set(0)
list1.pack()

list2 = []  #line list
list3 = []  #source list
list4 = []  #recepteur list
list5 = []  #point de rencontre
list6 = []  #resultat

b3 = Button(root, text="new source")
b3.pack()
b4 = Button(root, text="new recever")
b4.pack()
b5 = Button(root, text="new line")
#b5.pack()
b52 = Button(root, text="new line 2")
示例#33
0
class FilePane:
    def __init__(self,
                 root,
                 items=list(),
                 on_selection=list(),
                 on_close=list()):
        self.items = items
        self.item_count = len(items)
        self.on_selection = on_selection
        self.on_close = on_close

        self.window = Toplevel()
        self.window.title('Files')
        self.window.transient(root)
        self.window.protocol("WM_DELETE_WINDOW", self.on_window_close)

        self.menubar = Menu(self.window)
        self.menubar.add_command(label='Previous', command=self.previous)
        self.menubar.add_command(label='Next', command=self.next)

        # Display the menu
        self.window.config(menu=self.menubar)

        self.scrollbar = Scrollbar(self.window, orient='vertical')
        self.listbox = Listbox(self.window,
                               yscrollcommand=self.scrollbar.set,
                               exportselection=False)
        self.set_items(items)
        self.scrollbar.config(command=self.listbox.yview)
        self.scrollbar.pack(side='right', fill='y')
        self.listbox.pack(side='left', fill='both', expand=1)

        self.listbox.bind('<<ListboxSelect>>', self.on_select)

    def on_window_close(self):
        for callback in self.on_close:
            callback()
        self.window.withdraw()

    def hide(self):
        self.window.withdraw()

    def show(self):
        self.window.deiconify()

    def selected_item(self):
        return self.items[self.listbox.curselection()[0]]

    def select_index(self, index):
        self.listbox.selection_clear(0, END)

        # From https://stackoverflow.com/a/25451279/11628429
        self.listbox.select_set(
            index)  #This only sets focus on the first item.
        self.listbox.event_generate("<<ListboxSelect>>")

    def set_items(self, items):
        self.items = items
        self.item_count = len(items)
        self.listbox.delete(0, END)

        for item in items:
            item = path.split(item)[1]
            self.listbox.insert(END, item)

        self.select_index(0)

    def previous(self):
        index = self.listbox.curselection()[0] - 1
        if index < 0:
            index = self.item_count - 1
        self.select_index(index)

    def next(self):
        index = self.listbox.curselection()[0] + 1
        if index >= self.item_count:
            index = 0
        self.select_index(index)

    def on_select(self, event):
        if self.on_selection:
            for callback in self.on_selection:
                callback(self.selected_item())
示例#34
0
class GUIChecker(Frame):
    def __init__(self, master=None):
        Frame.__init__(self, master)
        self.master = master
        self.grid(columnspan=2000)

        self.__set_default_value()
        self.__create_widgets()
        self.__locate_widges()

        self.setting_on = False

    def __set_default_value(self):
        self.ALL_FIELDS = ["系號", "序號", "餘額", "課程名稱(連結課程地圖)",
                           "學分", "時間", "教師姓名*:主負責老師"
                           "已選課人數", "教室", "選必修", "限選條件",
                           "系所名稱", "年級", "組別", "類別", "班別",
                           "業界專家參與", "英語授課", "Moocs", "跨領域學分學程",
                           "備註", "課程碼", "分班碼", "屬性碼"]
        self.default_choosen_field = ["系號", "序號", "餘額", "課程名稱(連結課程地圖)",
                                      "學分", "時間", "教師姓名*:主負責老師"]
        self.choosen_field = deepcopy(self.default_choosen_field)

    def __create_widgets(self):
        self.input_label = Label(self, text="系所代碼 : ")
        self.input_field = Entry(self, width=30)
        self.search_btn = Button(self, text="搜尋", command=self.__search_method)
        self.clear_btn = Button(self, text="清除", command=self.__clear_method)
        self.setting_btn = Button(self, text="設定", command=self.__setting_method)
        self.msg_text = Label(self)

    def __locate_widges(self):
        self.input_label.grid(row=0, column=0)
        self.input_field.grid(row=0, column=1, columnspan=6)
        self.search_btn.grid(row=1, column=0)
        self.clear_btn.grid(row=1, column=2)
        self.setting_btn.grid(row=1, column=4)
        self.msg_text.grid(row=2, column=0)

    def __search_method(self):
        department_no = self.input_field.get()
        self.msg_text['text'] = '查詢中'
        try:
            self.__attach_course_table(department_no)
        except NoCourseAvailableError as e:
            logging.debug(e)
            self.msg_text['text'] = '沒有這個系所'
        except Exception as e:
            logging.exception('Seach Method: ')
            self.msg_text['text'] = '未知的錯誤'
        else:
            self.msg_text['text'] = ''

    def __attach_course_table(self, dept_no):
        courses = self.__search_courses(dept_no)
        title = list(courses.columns.values)

        self.__clear_method()
        self.__set_up_tree_widget(title, len(courses))

        for field in title:
            self.tree.heading(field, text=field)
            self.tree.column(field, width=font.Font().measure(field))

        for index, course in courses.iterrows():
            self.tree.insert('', 'end', values=tuple(course.values))
            for ix, val in enumerate(course.values):
                col_w = font.Font().measure(val) + 10
                if self.tree.column(title[ix], width=None) < col_w:
                    self.tree.column(title[ix], width=col_w)

    def __search_courses(self, dept_no):
        crawler = NckuCourseCrawler(dept_no=dept_no)
        html = crawler.get_raw_HTML()
        parser = NckuCourseParser(html)
        parser.include_fields = self.choosen_field
        logging.info("Choosen Field: {}".format(self.choosen_field))
        courses = parser.parse(sort=True)
        print(courses)
        courses['餘額'] = courses['餘額'].apply(int)
        return courses

    def __clear_method(self):
        try:
            self.__remove_tree_widget()
        except Exception as e:
            logging.debug(
                'Widget not yet created. Not and Error. {}'.format(e)
            )

    def __remove_tree_widget(self):
        self.tree_vsb.grid_remove()
        self.tree_hsb.grid_remove()
        self.tree.grid_remove()

    def __set_up_tree_widget(self, title, courses_num):
        tree_height = min(30, courses_num)
        self.tree = ttk.Treeview(columns=title, show="headings",
                                 height=tree_height)
        self.tree_vsb = ttk.Scrollbar(orient="vertical",
                                      command=self.tree.yview)
        self.tree_hsb = ttk.Scrollbar(orient="horizontal",
                                      command=self.tree.xview)
        self.tree.configure(yscrollcommand=self.tree_vsb.set,
                            xscrollcommand=self.tree_hsb.set)

        self.tree.grid(row=3, column=0)
        self.tree_vsb.grid(row=3, column=1, sticky="ns")
        self.tree_hsb.grid(row=4, column=0, sticky="we")

    def __setting_method(self):
        if not self.setting_on:
            self.setting_on = True

            self.setting_win = Toplevel(self)
            self.setting_win.wm_title("Settings")
            self.__create_setting_win_widget()

    def __create_setting_win_widget(self):
        choose_field_label = Label(self.setting_win, text="選擇欄位")
        self.__create_choose_field_listbox()
        confirm_btn = Button(self.setting_win, text="確定", command=self.__confirm_setting)
        default_btn = Button(self.setting_win, text="回復預設值", command=self.__restore_setting)

        confirm_btn.grid(row=0, column=0)
        default_btn.grid(row=0, column=1)
        choose_field_label.grid(row=1, column=0)

    def __create_choose_field_listbox(self):
        self.choose_field_listbox = Listbox(self.setting_win,
                                            selectmode=MULTIPLE,
                                            height=len(self.ALL_FIELDS))
        for i in self.ALL_FIELDS:
            self.choose_field_listbox.insert(END, i)
        for index, choosen in enumerate(self.choosen_field):
            if choosen:
                self.choose_field_listbox.select_set(index)

        self.choose_field_listbox.grid(row=1, column=1, sticky="nsew")

    def __confirm_setting(self):
        print(self.choose_field_listbox)
        print(self.choose_field_listbox.curselection())
        selections = self.choose_field_listbox.curselection()
        self.choosen_field = [
            self.ALL_FIELDS[col_index] for col_index in selections
        ]
        self.setting_win.withdraw()
        self.setting_on = False

    def __restore_setting(self):
        self.choose_field_listbox.grid_remove()
        self.choosen_field = self.default_choosen_field
        self.__create_choose_field_listbox()