Exemplo n.º 1
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)
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)
Exemplo n.º 3
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)
Exemplo n.º 4
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
Exemplo n.º 5
0
class TShapesWindow(Frame):
    """
    Class represents auxiliary window containg shapes information.

    :param master: master window object.
    :type master: tkinter.Tk
    :param app: main app object.
    :type app: TApp
    """
    def __init__(self, master, TApp):
        """
        Call the parent class constructor and initialise object variables.
        """
        super().__init__()
        self.TApp = TApp
        self.round_digits = TTicksSettings.ROUND_DIGITS
        self.init_widgets()

    def init_widgets(self):
        """
        Init frame widgets.
        """
        # Listbox
        self.shapes_list = Listbox(self,
                                   exportselection=False,
                                   selectmode=EXTENDED)
        self.grid_columnconfigure(0, weight=1, minsize=300)
        self.grid_rowconfigure(0, weight=1)
        self.shapes_list.grid(row=0,
                              column=0,
                              sticky=NSEW,
                              padx=(5, 25),
                              pady=5)
        self.shapes_list.bind("<<ListboxSelect>>",
                              self.shapes_list_selected_item)

        # Listbox's yscrollbar
        self.shapes_list_scrollbar = Scrollbar(self, orient = VERTICAL, \
                                               command = self.shapes_list.yview)
        self.shapes_list_scrollbar.grid(row=0,
                                        column=0,
                                        sticky=NS + E,
                                        padx=(0, 5),
                                        pady=5)
        self.shapes_list.config(yscrollcommand=self.shapes_list_scrollbar.set)

        # Drop down menu with materials
        self.material_box = Combobox(self, values=["pec", "free_space"])
        self.material_box.grid(row=1, column=0, sticky=EW, padx=5, pady=5)
        self.material_box.bind("<<ComboboxSelected>>",
                               self.assign_material_to_shape)

        # Right click popup menu
        self.init_popup_menu()
        self.shapes_list.bind("<Button-3>", self.show_popoup_menu)

        # Delete key removes selected shape(s)
        self.shapes_list.bind("<Delete>", self.remove_shape)

    def update_list(self, shapes, *, swap=False):
        """
        Update shapes list.

        :param swap: shapes list selection swap toggle.
        :type swap: boolean
        """
        selection = self.shapes_list.curselection()
        try:
            shape_num = selection[0]
        except:
            shape_num = 0
        self.shapes_list.delete(0, END)
        coord_string = ""
        for i, single_shape in enumerate(shapes):
            if (single_shape.type == "Rectangle"):
                coord_string = "(" + str(round(single_shape.point1_mod.x, self.round_digits)) + \
                               ", " + str(round(single_shape.point1_mod.y, self.round_digits)) + \
                               "), (" + str(round (single_shape.point2_mod.x, self.round_digits)) + \
                               ", " + str(round(single_shape.point2_mod.y, self.round_digits)) + ")"
            elif (single_shape.type == "Cylinder"):
                coord_string = "(" + str(round(single_shape.centre_mod.x, self.round_digits)) + \
                                ", " + str(round(single_shape.centre_mod.y, self.round_digits)) + \
                                "), " + str(round(single_shape.radius_mod, self.round_digits))
            elif (single_shape.type == "CylinSector"):
                coord_string = "(" + str(round(single_shape.centre_mod.x, self.round_digits)) + \
                               ", " + str(round(single_shape.centre_mod.y, self.round_digits)) + \
                               "), " + str(round(single_shape.radius_mod, self.round_digits)) + \
                               ", " + str(round(single_shape.start, self.round_digits)) + \
                               ", " + str(round(single_shape.extent, self.round_digits))
            elif (single_shape.type == "Polygon"):
                coord_string = str(len(single_shape.points))
            self.shapes_list.insert(
                i,
                str(i + 1) + ". " + single_shape.type + ": " + coord_string)
            coord_string = ""
        if (not swap):
            self.shapes_list.select_clear(0, END)
            if (shape_num >= self.shapes_list.size()):
                self.shapes_list.selection_set(shape_num - 1)
                self.shapes_list.activate(shape_num)
            else:
                for item in selection:
                    self.shapes_list.selection_set(item)
                self.shapes_list.activate(shape_num)

    def assign_material_to_shape(self, event):
        """
        Assign material to a shape.

        :param event: event evoking this method (listbox select).
        :type event: tkinter.Event
        """
        material = self.material_box.get()
        try:
            shape_num = (self.shapes_list.curselection())[0]
        except:
            return
        else:
            if (shape_num < 0 or material == ""):
                return
            else:
                try:
                    self.TApp.shapes[shape_num].material = material
                except Exception as message:
                    messagebox.showerror("Material assignment error!", message)
                    return

    def shapes_list_selected_item(self, event):
        """
        Handle listbox selection event.

        :param event: event evoking this method (listbox select).
        :type event: tkinter.Event
        """
        # Add multiple selection
        self.shapes_list.focus_force()
        try:
            shape_num = (self.shapes_list.curselection())[0]
            selection = self.shapes_list.curselection()
        except IndexError:
            return
        except Exception as message:
            messagebox.showerror("Error while picking shape!", message)
        if (shape_num < 0):
            return
        else:
            try:
                shape = self.TApp.shapes[shape_num]
            except Exception as message:
                messagebox.showerror("Materials list error", message)
                return

        self.material_box.set(str(shape.material))

        for single_shape in self.TApp.shapes:
            single_shape.width = 1

        for item in selection:
            self.TApp.shapes[item].width = 2
        self.TApp.main_canvas.delete("all")
        for item in selection:
            self.shapes_list.selection_set(item)
        self.TApp.canvas_refresh()

    def init_popup_menu(self):
        """
        Init shapes pane pup-up menu.
        """
        self.popup_menu = Menu(self, tearoff=0)
        self.popup_menu.add_command(label="Edit shape",
                                    command=self.edit_shape)
        self.popup_menu.add_command(label="Change shape colour",
                                    command=self.change_shape_colour)
        self.popup_menu.add_command(label="Remove shape(s)",
                                    command=self.remove_shape)
        self.popup_menu.add_separator()
        self.popup_menu.add_command(label="Add vertex to polygon",
                                    command=self.add_vertex_to_polygon)
        self.popup_menu.add_separator()
        self.popup_menu.add_command(label="Copy shape",
                                    command=self.copy_shape)
        self.popup_menu.add_command(label="Paste shape",
                                    command=self.paste_shape)
        self.popup_menu.add_separator()
        self.popup_menu.add_command(label="Move up",
                                    command=self.move_shape_up)
        self.popup_menu.add_command(label="Move down",
                                    command=self.move_shape_down)
        self.popup_menu.add_command(label="Move to top",
                                    command=self.move_shape_top)
        self.popup_menu.add_command(label="Move to bottom",
                                    command=self.move_shape_bottom)

    def show_popoup_menu(self, event):
        """
        Show shapes list pop-up menu.

        :param event: event evoking this method (RMB click).
        :type event: tkinter.Event
        """
        try:
            self.popup_menu.post(event.x_root, event.y_root)
        finally:
            self.popup_menu.grab_release()

    def move_shape_up(self):
        """
        Move a shape one place up the shapes list.
        """
        try:
            shape_num = (self.shapes_list.curselection())[0]
        except IndexError:
            return
        if (shape_num < 0):
            return
        else:
            try:
                self.TApp.shapes.insert(shape_num - 1,
                                        self.TApp.shapes.pop(shape_num))
                self.update_list(self.TApp.shapes)
                self.TApp.main_canvas.delete("all")
                self.TApp.canvas_refresh(swap=True)
                self.shapes_list.selection_set(shape_num - 1)
                self.shapes_list.activate(shape_num - 1)
            except Exception as message:
                messagebox.showerror("Error while manipulating shapes list!",
                                     message)
                return

    def move_shape_down(self):
        """
        Move a shape one place down the shapes list.
        """
        try:
            shape_num = (self.shapes_list.curselection())[0]
        except IndexError:
            return
        if (shape_num < 0):
            return
        else:
            try:
                self.TApp.shapes.insert(shape_num + 1,
                                        self.TApp.shapes.pop(shape_num))
                self.update_list(self.TApp.shapes)
                self.TApp.main_canvas.delete("all")
                self.TApp.canvas_refresh(swap=True)
                self.shapes_list.selection_set(shape_num + 1)
                self.shapes_list.activate(shape_num + 1)
            except Exception as message:
                messagebox.showerror("Error while manipulating shapes list!",
                                     message)
                return

    def move_shape_top(self):
        """
        Move a shape to the top of the shapes list.
        """
        try:
            shape_num = (self.shapes_list.curselection())[0]
        except IndexError:
            return
        if (shape_num < 0):
            return
        else:
            try:
                self.TApp.shapes.insert(0, self.TApp.shapes.pop(shape_num))
                self.update_list(self.TApp.shapes)
                self.TApp.main_canvas.delete("all")
                self.TApp.canvas_refresh(swap=True)
                self.shapes_list.selection_set(0)
                self.shapes_list.activate(0)
                # self.shapes_list.focus_set ()
            except Exception as message:
                messagebox.showerror("Error while manipulating shapes list!",
                                     message)
                return

    def move_shape_bottom(self):
        """
        Move a shape to the bottom of the shapes list.
        """
        try:
            shape_num = (self.shapes_list.curselection())[0]
        except IndexError:
            return
        if (shape_num < 0):
            return
        else:
            try:
                self.TApp.shapes.append(self.TApp.shapes.pop(shape_num))
                self.update_list(self.TApp.shapes)
                self.TApp.main_canvas.delete("all")
                self.TApp.canvas_refresh(swap=True)
                self.shapes_list.selection_set(END)
                self.shapes_list.activate(END)
            except Exception as message:
                messagebox.showerror("Error while manipulating shapes list!",
                                     message)
                return

    def edit_shape(self):
        """
        Edit selected shape on the shapes list.
        """
        try:
            shape_num = (self.shapes_list.curselection())[0]
        except IndexError:
            return
        if (shape_num < 0):
            return
        else:
            self.TApp.operations.append(TOperation("edit", shape = \
                                                   deepcopy(self.TApp.shapes[shape_num]), \
                                                   num = shape_num))
            if (self.TApp.shapes[shape_num].type == "Rectangle"):
                self.TApp.edit_rectangle(shape_num)
            elif (self.TApp.shapes[shape_num].type == "Cylinder"):
                self.TApp.edit_cylin(shape_num)
            elif (self.TApp.shapes[shape_num].type == "CylinSector"):
                self.TApp.edit_cylin_sector(shape_num)
            elif (self.TApp.shapes[shape_num].type == "Polygon"):
                self.TApp.edit_polygon(shape_num)

    def change_shape_colour(self):
        """
        Change selected shape on the shapes list colour.
        """
        try:
            shape_num = (self.shapes_list.curselection())[0]
        except IndexError:
            return
        if (shape_num < 0):
            return
        else:
            self.TApp.change_shape_colour(shape_num=shape_num)

    def remove_shape(self, event=None):
        """
        Remove selected shape on the shapes list.
        """
        try:
            selection = self.shapes_list.curselection()
        except IndexError:
            return
        if (len(selection) == 0):
            return
        else:
            try:
                for item in reversed(selection):
                    del self.TApp.shapes[item]
                self.update_list(self.TApp.shapes)
                self.TApp.main_canvas.delete("all")
                self.TApp.canvas_refresh()
            except Exception as message:
                messagebox.showerror("Error while manipulating shapes list!",
                                     message)
                return

    def add_vertex_to_polygon(self):
        """
        Add a vertex to selected polygon on the shapes list.
        """
        try:
            shape_num = (self.shapes_list.curselection())[0]
        except IndexError:
            return
        input_str = simpledialog.askstring("Input coordinates",
                                           "Give mew vertex's coordinates")
        point_mod_x, point_mod_y = [float(val) for val in input_str.split()]
        if (self.TApp.shapes[shape_num].type == "Polygon" and shape_num > -1):
            self.TApp.shapes[shape_num].add_vertex(x_mod=point_mod_x,
                                                   y_mod=point_mod_y)
        self.TApp.main_canvas.delete("all")
        self.TApp.canvas_refresh()

    def copy_shape(self):
        """
        Copy selected shape on the shapes list.
        """
        try:
            shape_num = self.shapes_list.curselection()[0]
        except:
            shape_num = -1
        if (shape_num > -1):
            try:
                self.TApp.copy_shape(shape_num=shape_num)
            except Exception as message:
                messagebox.showerror("Error while manipulating shapes list!",
                                     message)

    def paste_shape(self, *, deltax=15, deltay=15):
        """
        Paste selected shape from buffer.
        
        :param deltax: pasted shape offset in x direction in pixels.
        :type deltax: integer
        :param deltay: pasted shape offset in y direction in pixels.
        :type deltay: integer
        """
        self.TApp.paste_ctrl_v(Event())
Exemplo n.º 6
0
class GetKeysDialog(Toplevel):

    # Dialog title for invalid key sequence
    keyerror_title = 'Key Sequence Error'

    def __init__(self,
                 parent,
                 title,
                 action,
                 current_key_sequences,
                 *,
                 _htest=False,
                 _utest=False):
        """
        parent - parent of this dialog
        title - string which is the title of the popup dialog
        action - string, the name of the virtual event these keys will be
                 mapped to
        current_key_sequences - list, a list of all key sequence lists
                 currently mapped to virtual events, for overlap checking
        _htest - bool, change box location when running htest
        _utest - bool, do not wait when running unittest
        """
        Toplevel.__init__(self, parent)
        self.withdraw()  # Hide while setting geometry.
        self.configure(borderwidth=5)
        self.resizable(height=False, width=False)
        self.title(title)
        self.transient(parent)
        self.grab_set()
        self.protocol("WM_DELETE_WINDOW", self.cancel)
        self.parent = parent
        self.action = action
        self.current_key_sequences = current_key_sequences
        self.result = ''
        self.key_string = StringVar(self)
        self.key_string.set('')
        # Set self.modifiers, self.modifier_label.
        self.set_modifiers_for_platform()
        self.modifier_vars = []
        for modifier in self.modifiers:
            variable = StringVar(self)
            variable.set('')
            self.modifier_vars.append(variable)
        self.advanced = False
        self.create_widgets()
        self.update_idletasks()
        self.geometry("+%d+%d" %
                      (parent.winfo_rootx() +
                       (parent.winfo_width() / 2 - self.winfo_reqwidth() / 2),
                       parent.winfo_rooty() +
                       ((parent.winfo_height() / 2 -
                         self.winfo_reqheight() / 2) if not _htest else 150))
                      )  # Center dialog over parent (or below htest box).
        if not _utest:
            self.deiconify()  # Geometry set, unhide.
            self.wait_window()

    def showerror(self, *args, **kwargs):
        # Make testing easier.  Replace in #30751.
        messagebox.showerror(*args, **kwargs)

    def create_widgets(self):
        self.frame = frame = Frame(self, borderwidth=2, relief='sunken')
        frame.pack(side='top', expand=True, fill='both')

        frame_buttons = Frame(self)
        frame_buttons.pack(side='bottom', fill='x')

        self.button_ok = Button(frame_buttons,
                                text='OK',
                                width=8,
                                command=self.ok)
        self.button_ok.grid(row=0, column=0, padx=5, pady=5)
        self.button_cancel = Button(frame_buttons,
                                    text='Cancel',
                                    width=8,
                                    command=self.cancel)
        self.button_cancel.grid(row=0, column=1, padx=5, pady=5)

        # Basic entry key sequence.
        self.frame_keyseq_basic = Frame(frame, name='keyseq_basic')
        self.frame_keyseq_basic.grid(row=0,
                                     column=0,
                                     sticky='nsew',
                                     padx=5,
                                     pady=5)
        basic_title = Label(self.frame_keyseq_basic,
                            text=f"New keys for '{self.action}' :")
        basic_title.pack(anchor='w')

        basic_keys = Label(self.frame_keyseq_basic,
                           justify='left',
                           textvariable=self.key_string,
                           relief='groove',
                           borderwidth=2)
        basic_keys.pack(ipadx=5, ipady=5, fill='x')

        # Basic entry controls.
        self.frame_controls_basic = Frame(frame)
        self.frame_controls_basic.grid(row=1, column=0, sticky='nsew', padx=5)

        # Basic entry modifiers.
        self.modifier_checkbuttons = {}
        column = 0
        for modifier, variable in zip(self.modifiers, self.modifier_vars):
            label = self.modifier_label.get(modifier, modifier)
            check = Checkbutton(self.frame_controls_basic,
                                command=self.build_key_string,
                                text=label,
                                variable=variable,
                                onvalue=modifier,
                                offvalue='')
            check.grid(row=0, column=column, padx=2, sticky='w')
            self.modifier_checkbuttons[modifier] = check
            column += 1

        # Basic entry help text.
        help_basic = Label(self.frame_controls_basic,
                           justify='left',
                           text="Select the desired modifier keys\n" +
                           "above, and the final key from the\n" +
                           "list on the right.\n\n" +
                           "Use upper case Symbols when using\n" +
                           "the Shift modifier.  (Letters will be\n" +
                           "converted automatically.)")
        help_basic.grid(row=1, column=0, columnspan=4, padx=2, sticky='w')

        # Basic entry key list.
        self.list_keys_final = Listbox(self.frame_controls_basic,
                                       width=15,
                                       height=10,
                                       selectmode='single')
        self.list_keys_final.insert('end', *AVAILABLE_KEYS)
        self.list_keys_final.bind('<ButtonRelease-1>', self.final_key_selected)
        self.list_keys_final.grid(row=0, column=4, rowspan=4, sticky='ns')
        scroll_keys_final = Scrollbar(self.frame_controls_basic,
                                      orient='vertical',
                                      command=self.list_keys_final.yview)
        self.list_keys_final.config(yscrollcommand=scroll_keys_final.set)
        scroll_keys_final.grid(row=0, column=5, rowspan=4, sticky='ns')
        self.button_clear = Button(self.frame_controls_basic,
                                   text='Clear Keys',
                                   command=self.clear_key_seq)
        self.button_clear.grid(row=2, column=0, columnspan=4)

        # Advanced entry key sequence.
        self.frame_keyseq_advanced = Frame(frame, name='keyseq_advanced')
        self.frame_keyseq_advanced.grid(row=0,
                                        column=0,
                                        sticky='nsew',
                                        padx=5,
                                        pady=5)
        advanced_title = Label(
            self.frame_keyseq_advanced,
            justify='left',
            text=f"Enter new binding(s) for '{self.action}' :\n" +
            "(These bindings will not be checked for validity!)")
        advanced_title.pack(anchor='w')
        self.advanced_keys = Entry(self.frame_keyseq_advanced,
                                   textvariable=self.key_string)
        self.advanced_keys.pack(fill='x')

        # Advanced entry help text.
        self.frame_help_advanced = Frame(frame)
        self.frame_help_advanced.grid(row=1, column=0, sticky='nsew', padx=5)
        help_advanced = Label(
            self.frame_help_advanced,
            justify='left',
            text="Key bindings are specified using Tkinter keysyms as\n" +
            "in these samples: <Control-f>, <Shift-F2>, <F12>,\n"
            "<Control-space>, <Meta-less>, <Control-Alt-Shift-X>.\n"
            "Upper case is used when the Shift modifier is present!\n\n" +
            "'Emacs style' multi-keystroke bindings are specified as\n" +
            "follows: <Control-x><Control-y>, where the first key\n" +
            "is the 'do-nothing' keybinding.\n\n" +
            "Multiple separate bindings for one action should be\n" +
            "separated by a space, eg., <Alt-v> <Meta-v>.")
        help_advanced.grid(row=0, column=0, sticky='nsew')

        # Switch between basic and advanced.
        self.button_level = Button(frame,
                                   command=self.toggle_level,
                                   text='<< Basic Key Binding Entry')
        self.button_level.grid(row=2, column=0, stick='ew', padx=5, pady=5)
        self.toggle_level()

    def set_modifiers_for_platform(self):
        """Determine list of names of key modifiers for this platform.

        The names are used to build Tk bindings -- it doesn't matter if the
        keyboard has these keys; it matters if Tk understands them.  The
        order is also important: key binding equality depends on it, so
        config-keys.def must use the same ordering.
        """
        if sys.platform == "darwin":
            self.modifiers = ['Shift', 'Control', 'Option', 'Command']
        else:
            self.modifiers = ['Control', 'Alt', 'Shift']
        self.modifier_label = {'Control': 'Ctrl'}  # Short name.

    def toggle_level(self):
        "Toggle between basic and advanced keys."
        if self.button_level.cget('text').startswith('Advanced'):
            self.clear_key_seq()
            self.button_level.config(text='<< Basic Key Binding Entry')
            self.frame_keyseq_advanced.lift()
            self.frame_help_advanced.lift()
            self.advanced_keys.focus_set()
            self.advanced = True
        else:
            self.clear_key_seq()
            self.button_level.config(text='Advanced Key Binding Entry >>')
            self.frame_keyseq_basic.lift()
            self.frame_controls_basic.lift()
            self.advanced = False

    def final_key_selected(self, event=None):
        "Handler for clicking on key in basic settings list."
        self.build_key_string()

    def build_key_string(self):
        "Create formatted string of modifiers plus the key."
        keylist = modifiers = self.get_modifiers()
        final_key = self.list_keys_final.get('anchor')
        if final_key:
            final_key = translate_key(final_key, modifiers)
            keylist.append(final_key)
        self.key_string.set(f"<{'-'.join(keylist)}>")

    def get_modifiers(self):
        "Return ordered list of modifiers that have been selected."
        mod_list = [variable.get() for variable in self.modifier_vars]
        return [mod for mod in mod_list if mod]

    def clear_key_seq(self):
        "Clear modifiers and keys selection."
        self.list_keys_final.select_clear(0, 'end')
        self.list_keys_final.yview('moveto', '0.0')
        for variable in self.modifier_vars:
            variable.set('')
        self.key_string.set('')

    def ok(self, event=None):
        keys = self.key_string.get().strip()
        if not keys:
            self.showerror(title=self.keyerror_title,
                           parent=self,
                           message="No key specified.")
            return
        if (self.advanced or self.keys_ok(keys)) and self.bind_ok(keys):
            self.result = keys
        self.grab_release()
        self.destroy()

    def cancel(self, event=None):
        self.result = ''
        self.grab_release()
        self.destroy()

    def keys_ok(self, keys):
        """Validity check on user's 'basic' keybinding selection.

        Doesn't check the string produced by the advanced dialog because
        'modifiers' isn't set.
        """
        final_key = self.list_keys_final.get('anchor')
        modifiers = self.get_modifiers()
        title = self.keyerror_title
        key_sequences = [
            key for keylist in self.current_key_sequences for key in keylist
        ]
        if not keys.endswith('>'):
            self.showerror(title, parent=self, message='Missing the final Key')
        elif (not modifiers and final_key not in FUNCTION_KEYS + MOVE_KEYS):
            self.showerror(title=title,
                           parent=self,
                           message='No modifier key(s) specified.')
        elif (modifiers == ['Shift']) \
                 and (final_key not in
                      FUNCTION_KEYS + MOVE_KEYS + ('Tab', 'Space')):
            msg = 'The shift modifier by itself may not be used with'\
                  ' this key symbol.'
            self.showerror(title=title, parent=self, message=msg)
        elif keys in key_sequences:
            msg = 'This key combination is already in use.'
            self.showerror(title=title, parent=self, message=msg)
        else:
            return True
        return False

    def bind_ok(self, keys):
        "Return True if Tcl accepts the new keys else show message."
        try:
            binding = self.bind(keys, lambda: None)
        except TclError as err:
            self.showerror(
                title=self.keyerror_title,
                parent=self,
                message=(f'The entered key sequence is not accepted.\n\n'
                         f'Error: {err}'))
            return False
        else:
            self.unbind(keys, binding)
            return True
Exemplo n.º 7
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
Exemplo n.º 8
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)
Exemplo n.º 9
0
class StaffFrame(LabelFrame):
    """Contains data of staffmeeteng"""
    def __init__(self, window, base, **kwargs):
        super().__init__(window, **kwargs)
        self.base = base
        self.staff_id = None
        self.all_staff = [i.name for i in Staff.select()]
        self.data_label = Label(self, text="Data zespołu")
        self.data_label.grid(row=0, column=0, padx=5, pady=1, sticky='e')
        self.data_entry = Entry(self, width=20)
        self.data_entry.grid(row=0, column=1, padx=5, pady=1, sticky='w')

        self.table = Treeview(self, columns=("name", "speciality"))
        self.table.heading('#1', text='imię i nazwisko')
        self.table.heading('#2', text='specjalizacja')
        self.table.column('#1', width=200)
        self.table.column('#2', width=200)

        self.table.grid(row=1,
                        column=0,
                        rowspan=1,
                        columnspan=2,
                        padx=5,
                        pady=5)
        self.table['show'] = 'headings'
        self.table.bind('<<TreeviewSelect>>', self.on_treeview_selected)

        self.another_stuff_frame = LabelFrame(self, text="Inni specjaliści")
        self.another_stuff_frame.grid(row=2, column=0, columnspan=2, pady=5)

        self.another_staff = Listbox(self.another_stuff_frame,
                                     width=48,
                                     height=12)
        self.another_staff.grid(row=0, column=0, rowspan=2, padx=5, pady=5)
        self.another_staff.bind('<<ListboxSelect>>', self.on_listbox_select)
        self.add_button = Button(self,
                                 text="Dodaj członka",
                                 command=self.add_member)
        self.add_button.grid(row=3, column=0, padx=5, pady=5)
        self.delete_button = Button(self,
                                    text="Usuń członka",
                                    command=self.remove_member)
        self.delete_button.grid(row=3, column=1, padx=5, pady=5)

    def get_staff_from_table(self):
        '''return list of member of staff_meeting from table
        eg. [[name, speciality],[name, speciality]]'''
        staff_meeting_list = []
        for child in self.table.get_children():
            staff_meeting_list.append(self.table.item(child)["values"])
        return staff_meeting_list

    def insert_staff(self, base, staff):
        self.base = base
        self.staff = staff
        self.staff_id = staff['id']
        if not self.staff_id:
            self.tables_tidying()
            return
        self.data_entry.delete(0, 'end')
        self.data_entry.insert(0, staff['date'])
        self.table.delete(*self.table.get_children())
        self.another_staff.delete(0, 'end')
        for i in staff['team']:
            self.table.insert('', 'end', values=(i[0], i[1]))
        self.tables_tidying()

    def on_listbox_select(self, event):
        '''Remove selection from table after clicking listbox.'''
        if self.table.selection():
            self.table.selection_remove(self.table.selection()[0])

    def on_treeview_selected(self, event):
        '''Remove selection from lisbox after clicking table'''
        self.another_staff.select_clear(0, 'end')

    def tables_tidying(self):
        '''Remove unused staff from table.'''
        self.another_staff.delete(0, 'end')
        used_staff = [x[0] for x in self.get_staff_from_table()]
        for member in Staff.select():
            if member.name not in used_staff:
                self.another_staff.insert('end', member.name)

    def add_member(self):
        '''Add member from listbox to table.'''
        if not self.another_staff.curselection():
            pass
        else:
            self.table.insert(
                '',
                'end',
                values=(self.another_staff.selection_get(),
                        Staff.get(Staff.name == self.another_staff.
                                  selection_get()).speciality))

            self.tables_tidying()

    def remove_member(self):
        '''Removes member from table to listbox.'''
        selected_item = self.table.selection()
        if selected_item:
            self.table.delete(selected_item)
        self.tables_tidying()

    def clear(self):
        self.table.delete(*self.table.get_children())
        self.tables_tidying()
Exemplo n.º 10
0
class Player:
    def __init__(self, master):
        self.master = master
        pygame.init()
        pygame.mixer.init()

        #===Empty thread list=====#
        self.threads = []

        #=====show an icon for the player===#
        def get_icon():
            self.winicon = PhotoImage(file="best (2).png")
            master.iconphoto(False, self.winicon)

        #=====run the get_icon on a different thread from the gui=====#

        def icon():
            mythreads = threading.Thread(target=get_icon)
            self.threads.append(mythreads)
            mythreads.start()

        icon()

        #=======all Button symbols and variables======#

        PLAY = "►"
        PAUSE = "║║"
        RWD = "⏮"
        FWD = "⏭"
        STOP = "■"
        UNPAUSE = "||"
        mute = "🔇"
        unmute = u"\U0001F50A"
        vol_mute = 0.0
        vol_unmute = 1

        #==========music playlist listbox=========#
        self.scroll = Scrollbar(master)
        self.play_list = Listbox(master,
                                 font="Sansarif 12 bold",
                                 bd=5,
                                 bg="white",
                                 width=37,
                                 height=19,
                                 selectbackground="black")
        self.play_list.place(x=600, y=77)
        self.scroll.place(x=946, y=80, height=389, width=15)
        self.scroll.config(command=self.play_list.yview)
        self.play_list.config(yscrollcommand=self.scroll.set)

        files = 'best (2).png'
        self.img1 = Image.open(files)
        self.img1 = self.img1.resize((600, 470), Image.ANTIALIAS)
        self.img = ImageTk.PhotoImage(self.img1)
        self.lab = Label(master)
        self.lab.grid(row=0, column=0)
        self.lab["compound"] = LEFT
        self.lab["image"] = self.img

        #=====show the song playing==========#
        self.var = StringVar()
        self.var.set(
            ".............................................................................."
        )
        self.song_title = Label(master,
                                font="Helvetica 12 bold",
                                bg="black",
                                fg="white",
                                width=60,
                                textvariable=self.var)
        self.song_title.place(x=3, y=0)

        # =====add a music list to the listbox======"

        def append_listbox():
            global song_list
            try:
                directory = askdirectory()
                os.chdir(directory)  # it permits to change the current dir
                song_list = os.listdir()
                song_list.reverse()
                for item in song_list:  # it returns the list of files song
                    pos = 0
                    self.play_list.insert(pos, item)
                    pos += 1

                global size
                index = 0
                size = len(song_list)
                self.play_list.selection_set(index)
                self.play_list.see(index)
                self.play_list.activate(index)
                self.play_list.selection_anchor(index)

            except:
                showerror("File selected error",
                          "Please choose a file correctly")

        # =====run the append_listbox function on separate thread====== #

        def add_songs_playlist():
            mythreads = threading.Thread(target=append_listbox)
            self.threads.append(mythreads)
            mythreads.start()

        #=====show music time=========#

        def get_time():
            current_time = pygame.mixer.music.get_pos() / 1000
            formated_time = time.strftime("%H:%M:%S",
                                          time.gmtime(current_time))
            next_one = self.play_list.curselection()
            song = self.play_list.get(next_one)
            song_timer = MP3(song)
            song_length = int(song_timer.info.length)
            format_for_length = time.strftime("%H:%M:%S",
                                              time.gmtime(song_length))
            self.label_time.config(
                text=f"{ format_for_length} / {formated_time}")
            self.progress["maximum"] = song_length
            self.progress["value"] = int(current_time)
            master.after(100, get_time)

        #=====play the music====#

        def Play_music():
            try:
                track = self.play_list.get(ACTIVE)
                pygame.mixer.music.load(track)
                self.var.set(track)
                pygame.mixer.music.play()
                get_time()

                # iterate through all the songs in the playlist
                # there is a bug when closing the window

            except:
                showerror("No Music", "Please load the music you want to play")

        def playAll():
            try:
                index = 0
                for i in range(size):
                    self.play_list.select_clear(0, END)
                    self.play_list.selection_set(index, last=None)
                    self.play_list.see(index)
                    self.play_list.activate(index)
                    self.play_list.selection_anchor(index)
                    track = self.play_list.get(index)
                    pygame.mixer.music.load(track)
                    self.var.set(track)
                    pygame.mixer.music.play()
                    current_song = self.play_list.curselection()
                    song = self.play_list.get(current_song)
                    song_timer = MP3(song)
                    song_length = int(song_timer.info.length) * 1000
                    get_time()
                    index += 1
            except:
                showerror("No songs in playlist", "Please add music")

        def play_all():
            mythreads = threading.Thread(target=playAll)
            self.threads.append(mythreads)
            mythreads.start()

        # ===pause and unpause == #

        def pause_unpause():
            if self.button_pause['text'] == PAUSE:
                pygame.mixer.music.pause()
                self.button_pause['text'] = UNPAUSE

            elif self.button_pause['text'] == UNPAUSE:
                pygame.mixer.music.unpause()
                self.button_pause['text'] = PAUSE

        # ==play the music on a diffent thread from the gui == #

        def play_thread():
            mythreads = threading.Thread(target=Play_music)
            self.threads.append(mythreads)
            mythreads.start()

        master.bind("<space>", lambda x: play_thread())

        # ===stop===

        def stop():
            pygame.mixer.music.stop()

        #====increase and decrease volume when slider is moved()==#

        def volume(x):
            pygame.mixer.music.set_volume(self.volume_slider.get())

        # ====mute and unmute the song while the song plays== #

        def muted():
            if self.button_mute['text'] == unmute:
                pygame.mixer.music.set_volume(vol_mute)
                self.volume_slider.set(vol_mute)
                self.button_mute['fg'] = "red"
                self.button_mute['text'] = mute
            elif self.button_mute['text'] == mute:
                pygame.mixer.music.set_volume(vol_unmute)
                self.volume_slider.set(vol_unmute)
                self.button_mute['fg'] = "white"
                self.button_mute['text'] = unmute

        #===move to the next song===#

        def nextSong():
            try:
                next_one = self.play_list.curselection()
                next_one = next_one[0] + 1
                song = self.play_list.get(next_one)
                pygame.mixer.music.load(song)
                pygame.mixer.music.play()
                self.play_list.select_clear(0, END)
                self.play_list.activate(next_one)
                self.play_list.selection_set(next_one, last=None)
                self.var.set(song)
                get_time()
                self.play_list.see(next_one)
            except:
                showerror("No Next Song", "Please press the previous button")

        def next():
            mythreads = threading.Thread(target=nextSong)
            self.threads.append(mythreads)
            mythreads.start()

        #===move to the previous song===#

        def prevSong():
            try:
                next_one = self.play_list.curselection()
                next_one = next_one[0] - 1
                song = self.play_list.get(next_one)
                pygame.mixer.music.load(song)
                pygame.mixer.music.play()
                self.play_list.select_clear(0, END)
                self.play_list.activate(next_one)
                self.play_list.selection_set(next_one, last=None)
                self.var.set(song)
                get_time()
                self.play_list.see(next_one)
            except:
                showerror("No previous Song", "Please press the Next button")

        def prev():
            mythreads = threading.Thread(target=prevSong)
            self.threads.append(mythreads)
            mythreads.start()

        self.master.bind('<Left>', lambda x: prev())
        self.master.bind('<Right>', lambda x: next())

        #=====exit the application=====#

        def exit():
            MsgBox = askquestion(
                'Exit Application',
                'Are you sure you want to exit the music player.',
                icon='warning')
            if MsgBox == 'yes':
                master.quit()
                master.after(100, exit)
            else:
                showinfo('Return', 'Continue playing your awesome music')
            return

        #=====Help window=====#

        def help():
            top = Toplevel()
            top.title("Help")
            top.geometry("350x554+500+80")
            top.resizable(width=0, height=0)
            user_manual = [
                " MUSIC PLAYER USER MANUAL: \n", "1. play button =  ( ► )",
                "2. pause button = ║║ ", "3. unpause symbol = ||",
                "4. next button = ⏭ ", "5. previous button = ⏮",
                "6. mute button = '\U0001F50A' ", "7. unmute symbol = 🔇",
                "8. stop button = ■ ",
                "\n\n| Made by manucho | Copyright @ 2021 |\n"
            ]
            for i in user_manual:
                manual = Label(top,
                               text=i,
                               width=50,
                               height=3,
                               font="Helvetica, 11",
                               bg="black",
                               fg="white")
                manual.pack(side=TOP, fill=BOTH)

        #==============================================================================================#
        #   THis part contains the menu, volume slider , music playlist label and the volume slider  #
        #===============================================================================================#

        self.menu = Menu(
            self.lab,
            font="helvetica, 3",
        )
        master.config(menu=self.menu)
        self.menu.add_command(label="HELP", command=help)
        self.menu.add_command(label="EXIT", command=exit)

        self.separator = ttk.Separator(self.lab, orient='horizontal')
        self.separator.place(relx=0, rely=0.87, relwidth=1, relheight=1)
        self.button_play = Button(master,
                                  text=PLAY,
                                  width=5,
                                  bd=5,
                                  bg="black",
                                  fg="white",
                                  font="Helvetica, 15",
                                  command=play_thread)
        self.button_play.place(x=150, y=415)
        self.button_stop = Button(master,
                                  text=STOP,
                                  width=5,
                                  bd=5,
                                  font="Helvetica, 15",
                                  bg="black",
                                  fg="white",
                                  command=stop)
        self.button_stop.place(x=225, y=415)
        self.button_prev = Button(master,
                                  text=FWD,
                                  width=5,
                                  bd=5,
                                  font="Helvetica, 15",
                                  bg="black",
                                  fg="white",
                                  command=next)
        self.button_prev.place(x=300, y=415)

        self.buttonPlayall = Button(self.master,
                                    text='\U0001F500',
                                    bg='black',
                                    fg='white',
                                    font='Helvetica, 15',
                                    bd=5,
                                    width=3,
                                    command=play_all)
        self.buttonPlayall.place(x=375, y=415)

        self.button_next = Button(master,
                                  text=RWD,
                                  width=5,
                                  bd=5,
                                  bg="black",
                                  fg="white",
                                  font="Helvetica, 15",
                                  command=prev)
        self.button_next.place(x=10, y=415)
        self.button_pause = Button(master,
                                   text=PAUSE,
                                   width=4,
                                   bd=5,
                                   font="Helvetica, 15",
                                   bg="black",
                                   fg="white",
                                   command=pause_unpause)
        self.button_pause.place(x=85, y=415)

        self.button_mute = Button(master,
                                  text=unmute,
                                  width=2,
                                  bd=5,
                                  font="Helvetica, 15",
                                  bg="black",
                                  fg="white",
                                  command=muted)
        self.button_mute.place(x=430, y=415)

        self.label_playlist = Label(master,
                                    text=u"♫ Music Playlist ♫ ",
                                    width=31,
                                    font="Helvetica, 15")
        self.label_playlist.place(x=610, y=5)

        self.button_load_music = Button(
            master,
            text="♫ Click Here To Load The Music ♫",
            width=43,
            bd=5,
            font="Helvetica, 10",
            bg="black",
            fg="white",
            command=add_songs_playlist)
        self.button_load_music.place(x=605, y=45)

        self.style = ttk.Style()

        self.style.configure("myStyle.Horizontal.TScale", background="#505050")

        self.volume_slider = ttk.Scale(self.lab,
                                       from_=0,
                                       to=1,
                                       orient=HORIZONTAL,
                                       value=1,
                                       length=120,
                                       command=volume,
                                       style="myStyle.Horizontal.TScale")
        self.volume_slider.place(x=475, y=424)

        self.progress = ttk.Progressbar(self.lab,
                                        orient=HORIZONTAL,
                                        value=0,
                                        length=453,
                                        mode='determinate')
        self.progress.place(x=0, y=385)

        self.label_time = Label(master,
                                text="00:00:00 / 00:00:00",
                                width=17,
                                font="Helvetica, 10",
                                bg="black",
                                fg="white")
        self.label_time.place(x=460, y=387)
Exemplo n.º 11
0
class GetKeysDialog(Toplevel):

    # Dialog title for invalid key sequence
    keyerror_title = 'Key Sequence Error'

    def __init__(self, parent, title, action, current_key_sequences,
                 *, _htest=False, _utest=False):
        """
        parent - parent of this dialog
        title - string which is the title of the popup dialog
        action - string, the name of the virtual event these keys will be
                 mapped to
        current_key_sequences - list, a list of all key sequence lists
                 currently mapped to virtual events, for overlap checking
        _htest - bool, change box location when running htest
        _utest - bool, do not wait when running unittest
        """
        Toplevel.__init__(self, parent)
        self.withdraw()  # Hide while setting geometry.
        self.configure(borderwidth=5)
        self.resizable(height=False, width=False)
        self.title(title)
        self.transient(parent)
        self.grab_set()
        self.protocol("WM_DELETE_WINDOW", self.cancel)
        self.parent = parent
        self.action = action
        self.current_key_sequences = current_key_sequences
        self.result = ''
        self.key_string = StringVar(self)
        self.key_string.set('')
        # Set self.modifiers, self.modifier_label.
        self.set_modifiers_for_platform()
        self.modifier_vars = []
        for modifier in self.modifiers:
            variable = StringVar(self)
            variable.set('')
            self.modifier_vars.append(variable)
        self.advanced = False
        self.create_widgets()
        self.update_idletasks()
        self.geometry(
                "+%d+%d" % (
                    parent.winfo_rootx() +
                    (parent.winfo_width()/2 - self.winfo_reqwidth()/2),
                    parent.winfo_rooty() +
                    ((parent.winfo_height()/2 - self.winfo_reqheight()/2)
                    if not _htest else 150)
                ) )  # Center dialog over parent (or below htest box).
        if not _utest:
            self.deiconify()  # Geometry set, unhide.
            self.wait_window()

    def showerror(self, *args, **kwargs):
        # Make testing easier.  Replace in #30751.
        messagebox.showerror(*args, **kwargs)

    def create_widgets(self):
        self.frame = frame = Frame(self, borderwidth=2, relief='sunken')
        frame.pack(side='top', expand=True, fill='both')

        frame_buttons = Frame(self)
        frame_buttons.pack(side='bottom', fill='x')

        self.button_ok = Button(frame_buttons, text='OK',
                                width=8, command=self.ok)
        self.button_ok.grid(row=0, column=0, padx=5, pady=5)
        self.button_cancel = Button(frame_buttons, text='Cancel',
                                   width=8, command=self.cancel)
        self.button_cancel.grid(row=0, column=1, padx=5, pady=5)

        # Basic entry key sequence.
        self.frame_keyseq_basic = Frame(frame, name='keyseq_basic')
        self.frame_keyseq_basic.grid(row=0, column=0, sticky='nsew',
                                      padx=5, pady=5)
        basic_title = Label(self.frame_keyseq_basic,
                            text=f"New keys for '{self.action}' :")
        basic_title.pack(anchor='w')

        basic_keys = Label(self.frame_keyseq_basic, justify='left',
                           textvariable=self.key_string, relief='groove',
                           borderwidth=2)
        basic_keys.pack(ipadx=5, ipady=5, fill='x')

        # Basic entry controls.
        self.frame_controls_basic = Frame(frame)
        self.frame_controls_basic.grid(row=1, column=0, sticky='nsew', padx=5)

        # Basic entry modifiers.
        self.modifier_checkbuttons = {}
        column = 0
        for modifier, variable in zip(self.modifiers, self.modifier_vars):
            label = self.modifier_label.get(modifier, modifier)
            check = Checkbutton(self.frame_controls_basic,
                                command=self.build_key_string, text=label,
                                variable=variable, onvalue=modifier, offvalue='')
            check.grid(row=0, column=column, padx=2, sticky='w')
            self.modifier_checkbuttons[modifier] = check
            column += 1

        # Basic entry help text.
        help_basic = Label(self.frame_controls_basic, justify='left',
                           text="Select the desired modifier keys\n"+
                                "above, and the final key from the\n"+
                                "list on the right.\n\n" +
                                "Use upper case Symbols when using\n" +
                                "the Shift modifier.  (Letters will be\n" +
                                "converted automatically.)")
        help_basic.grid(row=1, column=0, columnspan=4, padx=2, sticky='w')

        # Basic entry key list.
        self.list_keys_final = Listbox(self.frame_controls_basic, width=15,
                                       height=10, selectmode='single')
        self.list_keys_final.insert('end', *AVAILABLE_KEYS)
        self.list_keys_final.bind('<ButtonRelease-1>', self.final_key_selected)
        self.list_keys_final.grid(row=0, column=4, rowspan=4, sticky='ns')
        scroll_keys_final = Scrollbar(self.frame_controls_basic,
                                      orient='vertical',
                                      command=self.list_keys_final.yview)
        self.list_keys_final.config(yscrollcommand=scroll_keys_final.set)
        scroll_keys_final.grid(row=0, column=5, rowspan=4, sticky='ns')
        self.button_clear = Button(self.frame_controls_basic,
                                   text='Clear Keys',
                                   command=self.clear_key_seq)
        self.button_clear.grid(row=2, column=0, columnspan=4)

        # Advanced entry key sequence.
        self.frame_keyseq_advanced = Frame(frame, name='keyseq_advanced')
        self.frame_keyseq_advanced.grid(row=0, column=0, sticky='nsew',
                                         padx=5, pady=5)
        advanced_title = Label(self.frame_keyseq_advanced, justify='left',
                               text=f"Enter new binding(s) for '{self.action}' :\n" +
                                     "(These bindings will not be checked for validity!)")
        advanced_title.pack(anchor='w')
        self.advanced_keys = Entry(self.frame_keyseq_advanced,
                                   textvariable=self.key_string)
        self.advanced_keys.pack(fill='x')

        # Advanced entry help text.
        self.frame_help_advanced = Frame(frame)
        self.frame_help_advanced.grid(row=1, column=0, sticky='nsew', padx=5)
        help_advanced = Label(self.frame_help_advanced, justify='left',
            text="Key bindings are specified using Tkinter keysyms as\n"+
                 "in these samples: <Control-f>, <Shift-F2>, <F12>,\n"
                 "<Control-space>, <Meta-less>, <Control-Alt-Shift-X>.\n"
                 "Upper case is used when the Shift modifier is present!\n\n" +
                 "'Emacs style' multi-keystroke bindings are specified as\n" +
                 "follows: <Control-x><Control-y>, where the first key\n" +
                 "is the 'do-nothing' keybinding.\n\n" +
                 "Multiple separate bindings for one action should be\n"+
                 "separated by a space, eg., <Alt-v> <Meta-v>." )
        help_advanced.grid(row=0, column=0, sticky='nsew')

        # Switch between basic and advanced.
        self.button_level = Button(frame, command=self.toggle_level,
                                  text='<< Basic Key Binding Entry')
        self.button_level.grid(row=2, column=0, stick='ew', padx=5, pady=5)
        self.toggle_level()

    def set_modifiers_for_platform(self):
        """Determine list of names of key modifiers for this platform.

        The names are used to build Tk bindings -- it doesn't matter if the
        keyboard has these keys; it matters if Tk understands them.  The
        order is also important: key binding equality depends on it, so
        config-keys.def must use the same ordering.
        """
        if sys.platform == "darwin":
            self.modifiers = ['Shift', 'Control', 'Option', 'Command']
        else:
            self.modifiers = ['Control', 'Alt', 'Shift']
        self.modifier_label = {'Control': 'Ctrl'}  # Short name.

    def toggle_level(self):
        "Toggle between basic and advanced keys."
        if  self.button_level.cget('text').startswith('Advanced'):
            self.clear_key_seq()
            self.button_level.config(text='<< Basic Key Binding Entry')
            self.frame_keyseq_advanced.lift()
            self.frame_help_advanced.lift()
            self.advanced_keys.focus_set()
            self.advanced = True
        else:
            self.clear_key_seq()
            self.button_level.config(text='Advanced Key Binding Entry >>')
            self.frame_keyseq_basic.lift()
            self.frame_controls_basic.lift()
            self.advanced = False

    def final_key_selected(self, event=None):
        "Handler for clicking on key in basic settings list."
        self.build_key_string()

    def build_key_string(self):
        "Create formatted string of modifiers plus the key."
        keylist = modifiers = self.get_modifiers()
        final_key = self.list_keys_final.get('anchor')
        if final_key:
            final_key = translate_key(final_key, modifiers)
            keylist.append(final_key)
        self.key_string.set(f"<{'-'.join(keylist)}>")

    def get_modifiers(self):
        "Return ordered list of modifiers that have been selected."
        mod_list = [variable.get() for variable in self.modifier_vars]
        return [mod for mod in mod_list if mod]

    def clear_key_seq(self):
        "Clear modifiers and keys selection."
        self.list_keys_final.select_clear(0, 'end')
        self.list_keys_final.yview('moveto', '0.0')
        for variable in self.modifier_vars:
            variable.set('')
        self.key_string.set('')

    def ok(self, event=None):
        keys = self.key_string.get().strip()
        if not keys:
            self.showerror(title=self.keyerror_title, parent=self,
                           message="No key specified.")
            return
        if (self.advanced or self.keys_ok(keys)) and self.bind_ok(keys):
            self.result = keys
        self.grab_release()
        self.destroy()

    def cancel(self, event=None):
        self.result = ''
        self.grab_release()
        self.destroy()

    def keys_ok(self, keys):
        """Validity check on user's 'basic' keybinding selection.

        Doesn't check the string produced by the advanced dialog because
        'modifiers' isn't set.
        """
        final_key = self.list_keys_final.get('anchor')
        modifiers = self.get_modifiers()
        title = self.keyerror_title
        key_sequences = [key for keylist in self.current_key_sequences
                             for key in keylist]
        if not keys.endswith('>'):
            self.showerror(title, parent=self,
                           message='Missing the final Key')
        elif (not modifiers
              and final_key not in FUNCTION_KEYS + MOVE_KEYS):
            self.showerror(title=title, parent=self,
                           message='No modifier key(s) specified.')
        elif (modifiers == ['Shift']) \
                 and (final_key not in
                      FUNCTION_KEYS + MOVE_KEYS + ('Tab', 'Space')):
            msg = 'The shift modifier by itself may not be used with'\
                  ' this key symbol.'
            self.showerror(title=title, parent=self, message=msg)
        elif keys in key_sequences:
            msg = 'This key combination is already in use.'
            self.showerror(title=title, parent=self, message=msg)
        else:
            return True
        return False

    def bind_ok(self, keys):
        "Return True if Tcl accepts the new keys else show message."
        try:
            binding = self.bind(keys, lambda: None)
        except TclError as err:
            self.showerror(
                    title=self.keyerror_title, parent=self,
                    message=(f'The entered key sequence is not accepted.\n\n'
                             f'Error: {err}'))
            return False
        else:
            self.unbind(keys, binding)
            return True
Exemplo n.º 12
0
class TPolygonWindow(simpledialog.Dialog):
    """
    Class represents a polygon vertices edit window.

    :param master: master window object.
    :type master: tkinter.Tk
    :param app: main app object.
    :type app: TApp
    :param polygon: edited polygon object.
    :type polygon: TPolygon
    """
    def __init__(self, master, app, polygon):
        """
        Initialise object variables and call the parent class constructor.
        """
        self._app = app
        self._polygon = polygon
        super().__init__(master)

    def body(self, master):
        """
        Initialise widgets.

        :param master: master window object.
        :type master: tkinter.Tk
        """
        # Frame for widgets
        self.main_frame = Frame(self)
        # Listbox
        self.vertices_list = Listbox(self.main_frame, exportselection = False, \
                                     width = 40)
        self.vertices_list.config(exportselection=0)
        self.vertices_list.pack(expand=True, fill=BOTH, side=LEFT)
        self.vertices_list.bind("<Double-Button-1>",
                                self.vertices_list_selected_item)
        # Listbox's yscrollbar
        self.vertices_list_scrollbar = Scrollbar(self.main_frame, orient = VERTICAL, \
                                                 command = self.vertices_list.yview)
        self.vertices_list_scrollbar.pack(expand=True, fill=Y, side=LEFT)
        self.vertices_list.config(
            yscrollcommand=self.vertices_list_scrollbar.set)
        self.main_frame.pack(expand=True, fill=BOTH)
        # Fill list with vertices data
        self.update_vertices_list()

    def buttonbox(self):
        """
        Redefine default Ok/Cancel buttons in the bottom of the window with
        Apply/Add/Delete.
        """
        self.bbox = Frame(self)
        self.apply_button = Button(self.bbox, text = "Apply", width = 10, \
                                   command = self.apply)
        self.apply_button.pack(side=LEFT, padx=5, pady=5)
        self.add_button = Button(self.bbox, text = "Add", width = 10, \
                                 command = self.add_vertex)
        self.add_button.pack(side=LEFT, padx=5, pady=5)
        self.delete_button = Button(self.bbox, text = "Delete", width = 10, \
                                    command = self.delete_vertex)
        self.delete_button.pack(side=LEFT, padx=5, pady=5)
        self.bbox.pack()

    def get_current_selection(self):
        """
        Retrieve the selected vertex index. 

        :rtype: integer
        """
        try:
            cursel = self.vertices_list.curselection()[0]
        except:
            cursel = 0
        return cursel

    def vertices_list_selected_item(self, event):
        """
        Display and edit selected vertex parameters.

        :param event: listbox LMB click event.
        :type event: tkinter.Event
        """
        try:
            vertex_num = (self.vertices_list.curselection())[0]
        except IndexError:
            return
        except Exception as message:
            messagebox.showerror("Error while picking shape!", message)
        if (vertex_num < 0):
            return
        else:
            try:
                vertex = self._polygon.points_mod[vertex_num]
            except Exception as message:
                messagebox.showerror("Materials list error", message)
                return
        initialvalue = str(vertex.x) + " " + str(vertex.y)
        input_str = simpledialog.askstring("Input coordinates", "Give vertex coordinates", \
                                           initialvalue = initialvalue)
        try:
            new_x, new_y = input_str.split()
        except AttributeError:
            pass
        except ValueError as e:
            messagebox.showerror("Wrong input!", e)
        else:
            edited_point = self._polygon.points_mod[vertex_num]
            edited_point.x, edited_point.y = float(new_x), float(new_y)
            self._polygon.update_window_positions()
            self._app.main_canvas.delete("all")
            self._app.canvas_refresh()
        finally:
            self.update_vertices_list()
            self.vertices_list.select_clear(0, END)
            self.vertices_list.selection_set(vertex_num)
            self.vertices_list.activate(vertex_num)
            self.vertices_list.focus_set()

    def update_vertices_list(self):
        """
        Update entries in the vertices listbox.
        """
        cursel = self.get_current_selection()
        self.vertices_list.delete(0, END)
        for i, v in enumerate(self._polygon.points_mod):
            self.vertices_list.insert(i, str(i + 1) + ". (" + str(v.x) + ", " + \
                                      str(v.y) + ")")
        self.vertices_list.select_clear(0, END)
        if (cursel >= self.vertices_list.size()):
            self.vertices_list.selection_set(cursel - 1)
            self.vertices_list.activate(cursel)
        else:
            self.vertices_list.selection_set(cursel)
            self.vertices_list.activate(cursel)

    def add_vertex(self):
        """
        Add a vertex to the polygon.
        """
        cursel = self.get_current_selection()
        input_str = simpledialog.askstring("Input coordinates",
                                           "Give vertex coordinates")
        try:
            new_x, new_y = input_str.split()
        except AttributeError:
            pass
        except ValueError as e:
            messagebox.showerror("Wrong input", e)
        else:
            self._polygon.add_vertex(x_mod=float(new_x), y_mod=float(new_y))
            self._app.main_canvas.delete("all")
            self._app.canvas_refresh()
        finally:
            self.update_vertices_list()
            self.vertices_list.select_clear(0, END)
            self.vertices_list.selection_set(cursel)
            self.vertices_list.activate(cursel)
            self.vertices_list.focus_set()

    def delete_vertex(self):
        """
        Delete a vertex from the polygon.
        """
        cursel = self.get_current_selection()
        self._polygon.remove_vertex(cursel)
        self._app.main_canvas.delete("all")
        self._app.canvas_refresh()
        self.update_vertices_list()
        self.vertices_list.select_clear(0, END)
        self.vertices_list.selection_set(cursel)
        self.vertices_list.activate(cursel)
        self.vertices_list.focus_set()

    def apply(self):
        """
        Destroy window upon clicking Apply button.
        """
        self.destroy()
class MainApplication(tk.Frame):
    """Main class of application"""

    def __init__(self, master):
        super().__init__(master)
        self.master = master
        self.configure_gui()
        self.create_widgets()
        self.setup_layout()
        self.bind_widgets()
        # Init selected item var
        self.selected_item = 0
        # Populate initial list
        self.populate_list()

    def configure_gui(self):
        """Setting general configurations of the application"""
        self.master.title("Hardware Manager")
        self.master.geometry("700x350")
        self.master.resizable(0, 0)

    def create_widgets(self):
        """Creating the widgets of the application"""
        # Part
        self.part_text = StringVar()
        self.part_label = Label(
            self.master, text="Part Name", font=("bold", 14), pady=20)
        self.part_entry = Entry(self.master, textvariable=self.part_text)
        # Customer
        self.customer_text = StringVar()
        self.customer_label = Label(
            self.master, text="Customer", font=("bold", 14))
        self.customer_entry = Entry(
            self.master, textvariable=self.customer_text)
        # Retailer
        self.retailer_text = StringVar()
        self.retailer_label = Label(
            self.master, text="Retailer", font=("bold", 14))
        self.retailer_entry = Entry(
            self.master, textvariable=self.retailer_text)
        # Price
        self.price_text = StringVar()
        self.price_label = Label(self.master, text="Price", font=("bold", 14))
        self.price_entry = Entry(self.master, textvariable=self.price_text)
        # Part List (ListBox)
        self.parts_list = Listbox(self.master, height=8, width=100, border=0)
        # Create scrollbar
        self.scrollbar = Scrollbar(self.master)
        # Buttons
        self.add_btn = Button(self.master, text="Add Part",
                              width=12, command=self.add_item)
        self.remove_btn = Button(self.master, text="Remove Part",
                                 width=12, command=self.remove_item)
        self.update_btn = Button(self.master, text="Update Part",
                                 width=12, command=self.update_item)
        self.clear_btn = Button(self.master, text="Clear Input",
                                width=12, command=self.clear_text)

    def setup_layout(self):
        """Setup grid system"""
        self.part_label.grid(row=0, column=0, sticky=tk.W)
        self.part_entry.grid(row=0, column=1)
        self.customer_label.grid(row=0, column=2, sticky=tk.W)
        self.customer_entry.grid(row=0, column=3)
        self.retailer_label.grid(row=1, column=0, sticky=tk.W)
        self.retailer_entry.grid(row=1, column=1)
        self.price_label.grid(row=1, column=2, sticky=tk.W)
        self.price_entry.grid(row=1, column=3)
        self.parts_list.grid(row=3, column=0, columnspan=4,
                             rowspan=6, pady=20, padx=20)
        self.scrollbar.grid(row=3, column=4, rowspan=6, sticky=tk.N+tk.S)
        self.add_btn.grid(row=2, column=0, pady=20)
        self.remove_btn.grid(row=2, column=1)
        self.update_btn.grid(row=2, column=2)
        self.clear_btn.grid(row=2, column=3)

    def bind_widgets(self):
        """Binding widgets when it needed"""
        # Set scroll to listbox
        self.scrollbar.configure(command=self.parts_list.yview)
        self.parts_list.configure(yscrollcommand=self.scrollbar.set)
        # Bind select
        self.parts_list.bind("<<ListboxSelect>>", self.select_item)

    def populate_list(self):
        """Delete items before update. So when you keep pressing
        it doesnt keep getting (pretending by calling this twice)"""
        self.parts_list.delete(0, tk.END)
        # Loop through records
        for row in db.fetch():
            self.parts_list.insert(tk.END, row)

    def select_item(self, event):
        """Runs when some item in the Listbox is selected"""
        try:
            # Get index
            index = self.parts_list.curselection()[0]
            # Get selected item
            self.selected_item = self.parts_list.get(index)
            # Add text to entries
            self.part_entry.delete(0, tk.END)
            self.part_entry.insert(tk.END, self.selected_item[1])
            self.customer_entry.delete(0, tk.END)
            self.customer_entry.insert(tk.END, self.selected_item[2])
            self.retailer_entry.delete(0, tk.END)
            self.retailer_entry.insert(tk.END, self.selected_item[3])
            self.price_entry.delete(0, tk.END)
            self.price_entry.insert(tk.END, self.selected_item[4])
        except IndexError:
            pass

    def add_item(self):
        """Add new item"""
        if self.part_text.get() == "" or self.customer_text.get() == "" or self.retailer_text.get() == "" or self.price_text.get() == "":
            messagebox.showerror(
                "Required Fields", "Please include all fields")
            return None
        # Insert into DB
        db.insert(self.part_text.get(), self.customer_text.get(),
                  self.retailer_text.get(), self.price_text.get())
        # Clear list
        self.parts_list.delete(0, tk.END)
        # Insert into list
        self.parts_list.insert(tk.END, (self.part_text.get(), self.customer_text.get(),
                                        self.retailer_text.get(), self.price_text.get()))
        self.clear_text()
        self.populate_list()

    def remove_item(self):
        """Remove selected item"""
        db.remove(self.selected_item[0])
        self.clear_text()
        self.populate_list()

    def update_item(self):
        """Update selected item"""
        db.update(self.selected_item[0], self.part_text.get(), self.customer_text.get(),
                  self.retailer_text.get(), self.price_text.get())
        self.populate_list()

    def clear_text(self):
        """Clear all text fields"""
        self.part_entry.delete(0, tk.END)
        self.customer_entry.delete(0, tk.END)
        self.retailer_entry.delete(0, tk.END)
        self.price_entry.delete(0, tk.END)
        self.parts_list.select_clear(0, tk.END)
Exemplo n.º 14
0
class PiScreen(tkinter.Frame):
    def __init__(self, master: 'tkinter.Tk'):
        global client, status, theme
        # host = '192.168.1.120'
        host = 'localhost'
        if sys.platform.startswith('linux'):
            host = 'localhost'
        client.connect(host, 6600)
        tkinter.Frame.__init__(self, master, padx=0, pady=0)
        self.pack()
        self.place(height=240, width=320, x=0, y=0)
        status = client.status()
        self.volume = int(status["volume"])

        self.screen_data = {
            "1": [
                "QUEUE", "PLAYLISTS", "LIBRARY", "SETUP", "CLEAR PLAYLIST",
                "RANDOM " + status['random'], "REPEAT " + status['repeat'],
                "SINGLE " + status['single'], "CONSUME " + status['consume']
            ],
            "1.1": {
                "ACTION": "QUEUE"
            },
            "1.2": {
                "ACTION": "PLAYLISTS"
            },
            "1.3": ["ARTISTS", "ALBUMS", "GENRES"],
            "1.3.1": {
                "ACTION": "ARTISTS"
            },
            "1.3.2": {
                "ACTION": "ALBUMS"
            },
            "1.3.3": {
                "ACTION": "GENRES"
            },
            "1.4": ["UPDATE LIBRARY", "THEMES"],
            "1.4.1": {
                "ACTION": "UPDATE_LIBRARY"
            },
            "1.4.2": {
                "ACTION": "THEMES"
            },
            "1.5": {
                "ACTION": "CLEAR"
            },
            "1.6": {
                "ACTION": "RANDOM"
            },
            "1.7": {
                "ACTION": "REPEAT"
            },
            "1.8": {
                "ACTION": "SINGLE"
            },
            "1.9": {
                "ACTION": "CONSUME"
            }
        }

        self.screen_format = {"1.Q": "SONG", "1.P": "PLAYLIST"}

        self.current_song_var = tkinter.StringVar()
        self.footer_text_var = tkinter.StringVar()

        # Screens
        self.playerScreen = Canvas(self,
                                   width=320,
                                   height=240,
                                   bg=theme['PLAYER']['background'],
                                   borderwidth=0,
                                   highlightthickness=0)

        self.menuScreen = Frame(self, width=320, height=240, bg="white")
        self.menuScreen.place(height=240, width=320, x=0, y=0)

        # Menu Screen items
        self.headerFrame = Frame(self.menuScreen,
                                 width=320,
                                 height=20,
                                 bg=theme['HEADER']['background'])
        self.headerFrame.pack(side=tkinter.TOP, fill=X)

        self.currentSongLabel = Label(self.headerFrame,
                                      font=(theme['HEADER']['font'], 12,
                                            'bold'),
                                      bg=theme['HEADER']['background'],
                                      foreground=theme['HEADER']['foreground'],
                                      textvariable=self.current_song_var,
                                      justify=tkinter.LEFT,
                                      anchor=tkinter.W)
        self.currentSongLabel.place(x=0,
                                    y=0,
                                    width=300,
                                    height=20,
                                    anchor=tkinter.NW)

        self.volumeLabel = Label(self.headerFrame,
                                 font=(theme['HEADER']['font'], 10, 'bold'),
                                 bg=theme['HEADER']['background'],
                                 foreground=theme['HEADER']['foreground'],
                                 text='')
        self.volumeLabel.place(x=300, y=0, anchor=tkinter.NW)

        self.mainFrame = Frame(self.menuScreen, width=320, height=200)
        self.mainFrame.pack(side=tkinter.TOP, fill=Y)

        self.listbox = Listbox(self.mainFrame,
                               selectmode=tkinter.SINGLE,
                               font=(theme['MAIN']['font'], 11),
                               bg=theme['MAIN']['background'],
                               fg=theme['MAIN']['foreground'],
                               height=10,
                               activestyle="none",
                               borderwidth=0,
                               highlightthickness=0,
                               selectbackground=theme['MAIN']['selected'],
                               selectforeground=theme['MAIN']['foreground'])
        self.listbox.bind("<Key>", self.handle_keys)
        self.listbox.configure(width=320, height=11)
        self.listbox.pack(side=tkinter.TOP,
                          expand=1,
                          ipadx=0,
                          ipady=0,
                          padx=0,
                          pady=0)
        self.listbox.focus_set()

        self.footer = Label(self.menuScreen,
                            textvariable=self.footer_text_var,
                            font=(theme['FOOTER']['font'], 10, 'bold'),
                            bg=theme['FOOTER']['background'],
                            foreground=theme['FOOTER']['foreground'],
                            justify=tkinter.LEFT,
                            anchor=tkinter.W)
        self.footer.configure(width=320, height=1)
        self.footer.pack(side=tkinter.BOTTOM)

        self.focus_set()
        self.bind("<Key>", self.handle_keys)
        self.screen = "1"
        self.show_screen()
        self.tick()

    def tick(self):
        global awayCount, keyMode, footerMessage, footerMessageCount
        self.update_header()
        if keyMode != 'PLAYER':
            awayCount += 1
            if awayCount > 120:
                awayCount = 0
                self.screen = ''
                self.show_screen()
        else:
            awayCount = 0

        if footerMessage == self.footer_text_var.get():
            footerMessageCount += 1
            if footerMessageCount > 8:
                footerMessageCount = 0
                self.footer_text_var.set("")
        else:
            footerMessage = self.footer_text_var.get()
            footerMessageCount = 0

        self.after(800, self.tick)

    def update_header(self):
        global status, keyMode, songChanged, currentSong, songName, songTicker, minTickerLength, songTickerCount
        status = client.status()
        self.volume = int(status["volume"])
        self.volumeLabel.configure(text=status["volume"])
        if status["state"] == "play":
            currentSong = client.currentsong()
            song = currentSong["artist"] + " - " + currentSong["title"]
            if songName != song:
                songChanged = True
                songName = song
                if keyMode != 'PLAYER':  # song changed, refresh ui
                    if len(songName) >= minTickerLength:
                        songTicker = True
                        songTickerCount = -1
                    else:
                        songTicker = False
                        songTickerCount = 0
            if keyMode != 'PLAYER':
                if songTicker:
                    songTickerCount += 1
                    if songTickerCount == len(songName) + 5:
                        songTickerCount = 0
                song = songName + "     "
                new_song = song[songTickerCount:] + song[:songTickerCount]
                self.current_song_var.set(new_song)
            elif keyMode == 'PLAYER':
                self.show_player()
        else:
            if songName != '':
                self.current_song_var.set('')
                songName = ''
                songChanged = True
                if keyMode == 'PLAYER':
                    self.show_player()

    def show_screen(self):
        global keyMode
        if self.screen == '':
            keyMode = 'PLAYER'
            self.menuScreen.place_forget()
            self.playerScreen.place(height=240, width=320, x=0, y=0)
            self.show_player()
            self.update()
            self.screen = '1'
            return
        self.listbox.delete(0, self.listbox.size() - 1)
        format_name = "string"
        if self.screen in self.screen_format:
            format_name = self.screen_format[self.screen]
        if isinstance(self.screen_data[self.screen], list):
            for item in self.screen_data[self.screen]:
                if format_name == "string":
                    if not item:
                        self.listbox.insert(tkinter.END, "")
                    else:
                        self.listbox.insert(tkinter.END, item[:36])
                if format_name == "SONG":
                    songname = ''
                    if 'artist' in item:
                        songname = item['artist'][:18]
                    songname += " - "
                    if 'title' in item:
                        max = 36 - len(songname)
                        songname += item['title'][:max]
                    self.listbox.insert(tkinter.END, songname)
                if format_name == "PLAYLIST":
                    playlist_name = ''
                    if isinstance(item, str):
                        playlist_name = item
                    else:
                        playlist_name = item['playlist']
                    self.listbox.insert(tkinter.END, playlist_name)

        self.listbox.select_set(0)  # This only sets focus on the first item.
        self.listbox.event_generate("<<ListboxSelect>>")
        self.update()
        return

    def show_player(self):
        global image, bg, songChanged, volumeChanged
        if songChanged or image is None:
            if sys.platform.startswith('linux'):
                process = subprocess.Popen(
                    "./coverart.sh", shell=True,
                    stdout=subprocess.PIPE).stdout.read()
            else:
                process = "./icons/ic_album_white_48dp.png"
            image = ImageTk.PhotoImage(
                Image.open(process).resize((136, 136), Image.ANTIALIAS))
        if bg is None:
            process = "./icons/bg.png"
            if 'img_background' in theme['PLAYER']:
                process = theme['PLAYER']['img_background']
            bg = ImageTk.PhotoImage(
                Image.open(process).resize((320, 240), Image.ANTIALIAS))
        if icon_random is None:
            self.load_icons()

        if status["state"] == "play":
            if songChanged:
                self.playerScreen.delete(tkinter.ALL)
                self.playerScreen.create_image(160, 120, image=bg)

                self.playerScreen.create_rectangle(
                    10, 10, 150, 150, fill=theme['PLAYER']['foreground'])
                self.playerScreen.create_image(80, 80, image=image)

                self.playerScreen.create_image(178, 132, image=icon_random)
                self.playerScreen.create_image(224, 132, image=icon_repeat)
                self.playerScreen.create_image(270, 132, image=icon_single)
                self.playerScreen.create_rectangle(
                    298,
                    146,
                    308,
                    92,
                    fill=theme['PLAYER']['background'],
                    outline=theme['PLAYER']['foreground'],
                    width=1)
                self.playerScreen.create_line(
                    303,
                    144,
                    303,
                    144 - int(self.volume / 2),
                    fill=theme['PLAYER']['foreground'],
                    width=7)

                self.playerScreen.create_text(
                    10,
                    160,
                    text=currentSong['artist'],
                    anchor=tkinter.NW,
                    fill=theme['PLAYER']['foreground'],
                    font=(theme['PLAYER']['font'], 14, 'bold'))
                self.playerScreen.create_text(
                    10,
                    185,
                    text=currentSong['title'],
                    anchor=tkinter.NW,
                    fill=theme['PLAYER']['foreground'],
                    font=(theme['PLAYER']['font'], 12, 'bold'))
                self.playerScreen.create_text(
                    10,
                    210,
                    text=currentSong['album'],
                    anchor=tkinter.NW,
                    fill=theme['PLAYER']['foreground'],
                    font=(theme['PLAYER']['font'], 10, 'bold'))
            else:
                time = str(status['time']).split(":")
                played = int((float(time[0]) / float(time[1])) * 320)
                if played < 3:  # bug
                    self.playerScreen.create_rectangle(
                        0, 236, 320, 240, fill=theme['PLAYER']['background'])
                self.playerScreen.create_rectangle(
                    0, 236, played, 240, fill=theme['PLAYER']['foreground'])
            if volumeChanged:
                volumeChanged = False
                self.playerScreen.create_rectangle(
                    298,
                    146,
                    308,
                    92,
                    fill=theme['PLAYER']['background'],
                    outline=theme['PLAYER']['foreground'],
                    width=1)
                self.playerScreen.create_line(
                    303,
                    144,
                    303,
                    144 - int(self.volume / 2),
                    fill=theme['PLAYER']['foreground'],
                    width=7)
        else:  # Blank Screen
            self.playerScreen.delete(tkinter.ALL)
            self.playerScreen.create_image(160, 120, image=bg)
            self.playerScreen.create_text(
                20,
                20,
                text=theme['PLAYER']['default_message'],
                anchor=tkinter.NW,
                fill=theme['PLAYER']['foreground'],
                font=(theme['PLAYER']['font'], 20, 'bold'))
        songChanged = False
        return

    def handle_keys(self, event):
        global config, client, selectedAlbum, selectedArtist, selectedGenre
        global keyMode, textEntry, textBackAction, textSaveAction, awayCount, theme_name
        global albums, artists, queue, songs, playlists, status, genres, songChanged, volumeChanged

        awayCount = 0
        keycode = str(event.keycode)
        # self.footer_text_var.set(str("Key Pressed : "+keycode))
        if keyMode == 'PLAYER' and keycode != config["PISCREEN_KEYS"]["vol_up"] \
                and keycode != config["PISCREEN_KEYS"]["vol_down"] \
                and keycode != config["PISCREEN_KEYS"]["play"] \
                and keycode != config["PISCREEN_KEYS"]["next"] \
                and keycode != config["PISCREEN_KEYS"]["prev"] \
                and keycode != config["PISCREEN_KEYS"]["power"] \
                and keycode != config["PISCREEN_KEYS"]["left"]:
            keyMode = 'MENU'
            self.playerScreen.place_forget()
            self.menuScreen.place(height=240, width=320, x=0, y=0)
            self.show_screen()
            self.update()
            return
        if keyMode == 'TEXT':
            if keycode == config["PISCREEN_KEYS"]["back"]:  # back
                keyMode = 'MENU'
                self.run_command(textBackAction)
            if keycode == config["PISCREEN_KEYS"]["ok"]:  # ok
                keyMode = 'MENU'
                self.run_command(textSaveAction)
            if event.keysym in '0123456789-abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ':
                textEntry += event.keysym
                self.footer_text_var.set(str("Entry : " + textEntry))
            return
        # self.footer.configure(text=str('Key Pressed ' + str(event.keycode)))
        if keycode == config["PISCREEN_KEYS"]["menu"]:
            if self.screen == "1.P":
                selection = int(self.listbox.curselection()[0]) + 1
                if selection > 1:
                    self.footer_text_var.set(
                        str("Press 1 + OK to Delete Playlist"))
                    keyMode = 'TEXT'
                    textBackAction = "PLAYLISTS"
                    textSaveAction = "DELETE_PLAYLIST"
            if self.screen == "1.Q":
                self.footer_text_var.set(str("Press OK to remove Song"))
                keyMode = 'TEXT'
                textBackAction = "QUEUE"
                textSaveAction = "DELETE_SONG"
            return
        if keycode == config["PISCREEN_KEYS"]["down"]:  # down
            if self.listbox.size() > 0:
                selection = int(self.listbox.curselection()[0])
                count = self.listbox.size()
                if selection < (count - 1):
                    self.listbox.select_clear(selection)
                    self.listbox.selection_set(selection + 1)
                    self.listbox.event_generate("<<ListboxSelect>>")
            return
        if keycode == config["PISCREEN_KEYS"]["up"]:  # up
            if self.listbox.size() > 0:
                selection = int(self.listbox.curselection()[0])
                if selection > 0:
                    self.listbox.select_clear(selection)
                    self.listbox.selection_set(selection - 1)
                    self.listbox.event_generate("<<ListboxSelect>>")
            return
        if keycode == config["PISCREEN_KEYS"]["left"] or keycode == config[
                "PISCREEN_KEYS"]["back"]:  # left or escape
            if self.screen != "1":
                menu = self.screen.rsplit(".", maxsplit=1)
                new_screen = menu[0]
                self.screen = new_screen
                self.show_screen()
            else:
                self.screen = ''
                songChanged = True
                self.show_screen()
            return
        if keycode == config["PISCREEN_KEYS"]["right"] or keycode == config[
                "PISCREEN_KEYS"]["ok"]:  # right or return
            if self.listbox.size() > 0:
                selection = int(self.listbox.curselection()[0]) + 1
                new_screen = self.screen + "." + str(selection)
                if new_screen in self.screen_data:
                    if type(self.screen_data[new_screen]) is list:
                        self.screen = new_screen
                        self.show_screen()
                    else:
                        self.run_command(
                            self.screen_data[new_screen]["ACTION"])
                else:
                    if str(new_screen).startswith("1.Q."):
                        menu = new_screen.rsplit(".", maxsplit=1)
                        client.playid(int(queue[int(menu[1]) - 1]["id"]))
                        return
                    if str(new_screen).startswith("1.P."):
                        menu = new_screen.rsplit(".", maxsplit=1)
                        if menu[1] == "1":
                            keyMode = 'TEXT'
                            textBackAction = 'PLAYLISTS'
                            textSaveAction = 'SAVE_PLAYLIST'
                            textEntry = ''
                            self.footer_text_var.set(
                                'Back to Cancel, Ok to Save')
                        else:
                            playlist = playlists[int(menu[1]) - 1]['playlist']
                            client.clear()
                            client.load(playlist)
                            client.play()
                        return
                    if str(new_screen).startswith("1.3.A"):
                        if new_screen.count(".") == 3:
                            menu = new_screen.rsplit(".", maxsplit=1)
                            selectedArtist = artists[int(menu[1]) - 1]
                            albums = []
                            albums = client.list("album", selectedArtist)
                            albums[:0] = ["Add All"]
                            self.footer_text_var.set("SELECTED Artist " +
                                                     selectedArtist)
                            self.screen = new_screen
                            self.screen_data[new_screen] = albums
                            self.show_screen()
                            return
                        elif new_screen.count(".") == 4:
                            menu = new_screen.rsplit(".", maxsplit=1)
                            if menu[1] == "1":  # add all
                                client.findadd("artist", selectedArtist)
                                self.footer_text_var.set("Added All for " +
                                                         selectedArtist)
                                self.screen = menu[0].rsplit(".",
                                                             maxsplit=1)[0]
                                self.show_screen()
                            else:
                                selectedAlbum = albums[int(menu[1]) - 1]
                                songs = client.list("title", "album",
                                                    selectedAlbum, "artist",
                                                    selectedArtist)
                                songs[:0] = ["Add All"]
                                self.screen = new_screen
                                self.screen_data[new_screen] = songs
                                self.show_screen()
                                self.footer_text_var.set("Album Selected " +
                                                         selectedAlbum)
                            return
                        elif new_screen.count(".") == 5:
                            menu = new_screen.rsplit(".", maxsplit=1)
                            if menu[1] == "1":  # add all
                                client.findadd("album", selectedAlbum,
                                               "artist", selectedArtist)
                                self.footer_text_var.set("Added All for " +
                                                         selectedAlbum + "/" +
                                                         selectedArtist)
                                self.screen = menu[0].rsplit(".",
                                                             maxsplit=1)[0]
                                self.show_screen()
                            else:
                                selected_song = songs[int(menu[1]) - 1]
                                client.findadd("title", selected_song, "album",
                                               selectedAlbum, "artist",
                                               selectedArtist)
                                self.footer_text_var.set("Added " +
                                                         selected_song + "/" +
                                                         selectedAlbum + "/" +
                                                         selectedArtist)
                            return
                    if str(new_screen).startswith("1.3.B"):
                        menu = new_screen.rsplit(".", maxsplit=1)
                        if new_screen.count(".") == 3:
                            selectedAlbum = albums[int(menu[1]) - 1]
                            songs = client.list("title", "album",
                                                selectedAlbum)
                            songs[:0] = ["Add All"]
                            self.screen = new_screen
                            self.screen_data[new_screen] = songs
                            self.show_screen()
                            self.footer_text_var.set("Album Selected " +
                                                     selectedAlbum)
                        if new_screen.count(".") == 4:
                            if menu[1] == "1":  # add all
                                client.findadd("album", selectedAlbum)
                                self.footer_text_var.set(
                                    "Added All for album " + selectedAlbum)
                                self.screen = menu[0].rsplit(".",
                                                             maxsplit=1)[0]
                                self.show_screen()
                            else:
                                selected_song = songs[int(menu[1]) - 1]
                                client.findadd("title", selected_song, "album",
                                               selectedAlbum)
                                self.footer_text_var.set("Added " +
                                                         selected_song + "/" +
                                                         selectedAlbum)
                        return
                    if str(new_screen).startswith("1.3.C"):
                        menu = new_screen.rsplit(".", maxsplit=1)
                        if new_screen.count(".") == 3:
                            selectedGenre = genres[int(menu[1]) - 1]
                            songs = client.list("title", "genre",
                                                selectedGenre)
                            self.screen = new_screen
                            self.screen_data[new_screen] = songs
                            self.show_screen()
                            self.footer_text_var.set("Genre Selected " +
                                                     selectedAlbum)
                        if new_screen.count(".") == 4:
                            selected_song = songs[int(menu[1]) - 1]
                            client.findadd("title", selected_song, "genre",
                                           selectedGenre)
                            self.footer_text_var.set("Added " + selected_song +
                                                     selectedGenre)
                        return
                    if str(new_screen).startswith("1.4.T"):
                        menu = new_screen.rsplit(".", maxsplit=1)
                        theme_name = themes[int(menu[1]) - 1]
                        self.footer_text_var.set("Applying Theme " +
                                                 theme_name)
                        self.apply_theme()
            return
        if keycode == config["PISCREEN_KEYS"]["vol_up"]:
            if self.volume < 100:
                self.volume += 1
                client.setvol(self.volume)
                volumeChanged = True
                self.footer_text_var.set("Volume Up")
            else:
                self.footer_text_var.set("Volume Max!!")
            return
        if keycode == config["PISCREEN_KEYS"]["vol_down"]:
            if self.volume > 0:
                self.volume -= 1
                client.setvol(self.volume)
                volumeChanged = True
                self.footer_text_var.set("Volume Down")
            else:
                self.footer_text_var.set("Volume Zero!!")
            return
        if keycode == config["PISCREEN_KEYS"]["play"]:
            if status["state"] == "play":
                client.pause()
                self.footer_text_var.set("Paused")
            else:
                client.play()
                self.footer_text_var.set("Playing")
            return
        if keycode == config["PISCREEN_KEYS"]["next"]:
            client.next()
            self.footer_text_var.set("Next Song")
            return
        if keycode == config["PISCREEN_KEYS"]["prev"]:
            client.previous()
            self.footer_text_var.set("Previous Song")
            return
        if keycode == config["PISCREEN_KEYS"]["home"]:
            self.screen = ''
            self.show_screen()
            return
        if keycode == config["PISCREEN_KEYS"]["power"]:
            if sys.platform.startswith('linux'):
                call("sudo nohup shutdown -h now", shell=True)
            else:
                self.footer_text_var.set("Can't PowerOff from remote")
            return
        self.footer_text_var.set("UNKNOWN " + keycode)

    def run_command(self, action):
        global client, keyMode, textEntry, status
        global albums, artists, queue, songs, playlists, genres, themes
        if action == "QUEUE":
            local_queue = client.playlistinfo()
            queue.clear()
            for item in local_queue:
                queue.append(item)
            self.screen = "1.Q"
            self.screen_data["1.Q"] = queue
            self.footer_text_var.set("Right to play Song, Menu to delete")
            self.show_screen()
        elif action == "PLAYLISTS":
            playlists = client.listplaylists()
            playlists[:0] = ["SAVE PLAYLIST"]
            self.screen = "1.P"
            self.screen_data["1.P"] = playlists
            self.footer_text_var.set("Right to play Playlist, Menu to delete")
            self.show_screen()
        elif action == "ARTISTS":
            artists = client.list("artist")
            self.screen = "1.3.A"
            self.screen_data["1.3.A"] = artists
            self.show_screen()
        elif action == "ALBUMS":
            albums = client.list("album")
            self.screen = "1.3.B"
            self.screen_data["1.3.B"] = albums
            self.show_screen()
        elif action == "GENRES":
            genres = client.list("genre")
            self.screen = "1.3.C"
            self.screen_data["1.3.C"] = genres
            self.show_screen()
        elif action == "UPDATE_LIBRARY":
            self.footer_text_var.set("Updating library")
            client.update()
        elif action == "THEMES":
            self.footer_text_var.set("Select Theme")
            themes = ["default", "foofighters", "light"]
            self.screen = "1.4.T"
            self.screen_data["1.4.T"] = themes
            self.show_screen()
        elif action == "SAVE_PLAYLIST":
            keyMode = 'MENU'
            found = False
            if textEntry == '':
                self.footer_text_var.set("Name Empty!!")
                return
            for playlist in playlists:
                if isinstance(
                        playlist,
                        str) is False and textEntry == playlist['playlist']:
                    found = True
            if found:
                client.rm(textEntry)
                client.save(textEntry)
            else:
                client.save(textEntry)
            self.footer_text_var.set("Saved Playlist " + textEntry)
            textEntry = ''
            self.run_command("PLAYLISTS")
        elif action == "DELETE_PLAYLIST":
            keyMode = 'MENU'
            if textEntry == '1':
                selection = int(self.listbox.curselection()[0])
                client.rm(playlists[selection]['playlist'])
            textEntry = ''
            self.run_command("PLAYLISTS")
        elif action == "DELETE_SONG":
            keyMode = 'MENU'
            client.delete(int(self.listbox.curselection()[0]))
            textEntry = ''
            self.run_command("QUEUE")
        elif action == "CLEAR":
            self.footer_text_var.set("Clearing Queue")
            client.clear()
        elif action == "RANDOM":
            if status['random'] == '0':
                client.random('1')
            else:
                client.random('0')
            status = client.status()
            self.screen_data['1'][5] = "RANDOM " + status['random']
            self.update_random()
            self.show_screen()
        elif action == "REPEAT":
            if status['repeat'] == '0':
                client.repeat('1')
            else:
                client.repeat('0')
            status = client.status()
            self.screen_data['1'][6] = "REPEAT " + status['repeat']
            self.update_repeat()
            self.show_screen()
        elif action == "SINGLE":
            if status['single'] == '0':
                client.single('1')
            else:
                client.single('0')
            status = client.status()
            self.screen_data['1'][7] = "SINGLE " + status['single']
            self.update_single()
            self.show_screen()
        elif action == "CONSUME":
            if status['consume'] == '0':
                client.consume('1')
            else:
                client.consume('0')
            status = client.status()
            self.screen_data['1'][8] = "CONSUME " + status['consume']
            self.show_screen()
        self.update()
        return

    def load_icons(self):
        self.update_random()
        self.update_repeat()
        self.update_single()

    def update_random(self):
        global status, theme, icon_random
        fgcolor = ImageColor.getrgb(theme['PLAYER']['foreground'])
        bgcolor = ImageColor.getrgb(theme['PLAYER']['background'])
        fgcolor += (255, )
        bgcolor += (255, )
        icon_random = Image.open('./icons/ic_shuffle_white_36dp.png')
        if icon_random.mode != 'RGBA':
            icon_random = icon_random.convert('RGBA')
        data = list(icon_random.getdata())
        newData = list()
        for pixel in data:
            if pixel[3] != 0:
                if status['random'] == '1':
                    newData.append(fgcolor)
                else:
                    newData.append(bgcolor)
            else:
                newData.append(pixel)
        icon_random.putdata(newData)
        icon_random = ImageTk.PhotoImage(
            icon_random.resize((36, 36), Image.ANTIALIAS))

    def update_single(self):
        global status, theme, icon_single
        fgcolor = ImageColor.getrgb(theme['PLAYER']['foreground'])
        bgcolor = ImageColor.getrgb(theme['PLAYER']['background'])
        fgcolor += (255, )
        bgcolor += (255, )
        icon_single = Image.open('./icons/ic_repeat_one_white_36dp.png')
        if icon_single.mode != 'RGBA':
            icon_single = icon_single.convert('RGBA')
        data = list(icon_single.getdata())
        newData = list()
        for pixel in data:
            if pixel[3] != 0:
                if status['single'] == '1':
                    newData.append(fgcolor)
                else:
                    newData.append(bgcolor)
            else:
                newData.append(pixel)
        icon_single.putdata(newData)
        icon_single = ImageTk.PhotoImage(
            icon_single.resize((36, 36), Image.ANTIALIAS))

    def update_repeat(self):
        global status, theme, icon_repeat
        fgcolor = ImageColor.getrgb(theme['PLAYER']['foreground'])
        bgcolor = ImageColor.getrgb(theme['PLAYER']['background'])
        fgcolor += (255, )
        bgcolor += (255, )
        icon_repeat = Image.open('./icons/ic_repeat_white_36dp.png')
        if icon_repeat.mode != 'RGBA':
            icon_repeat = icon_repeat.convert('RGBA')
        data = list(icon_repeat.getdata())
        newData = list()
        for pixel in data:
            if pixel[3] != 0:
                if status['repeat'] == '1':
                    newData.append(fgcolor)
                else:
                    newData.append(bgcolor)
            else:
                newData.append(pixel)
        icon_repeat.putdata(newData)
        icon_repeat = ImageTk.PhotoImage(
            icon_repeat.resize((36, 36), Image.ANTIALIAS))

    def apply_theme(self):
        global theme_name, theme, config, bg
        my_file = Path('./theme/' + theme_name + '/theme.ini')
        if my_file.is_file():
            theme = configparser.ConfigParser()
            theme.read('./theme/' + theme_name + '/theme.ini')
            # player related settings
            bg = None
            self.playerScreen.configure(bg=theme['PLAYER']['background'])
            self.load_icons()
            # menu related settings
            self.headerFrame.configure(bg=theme['HEADER']['background'])
            self.currentSongLabel.configure(
                font=(theme['HEADER']['font'], 12, 'bold'),
                bg=theme['HEADER']['background'],
                foreground=theme['HEADER']['foreground'])
            self.volumeLabel.configure(
                font=(theme['HEADER']['font'], 10, 'bold'),
                bg=theme['HEADER']['background'],
                foreground=theme['HEADER']['foreground'])
            self.listbox.configure(
                font=(theme['MAIN']['font'], 11),
                bg=theme['MAIN']['background'],
                fg=theme['MAIN']['foreground'],
                selectbackground=theme['MAIN']['selected'],
                selectforeground=theme['MAIN']['foreground'])
            self.footer.configure(font=(theme['FOOTER']['font'], 10, 'bold'),
                                  bg=theme['FOOTER']['background'],
                                  foreground=theme['FOOTER']['foreground'])

            # write theme to config.ini
            config["THEME"]["theme"] = theme_name
            with open('config.ini', 'w') as configfile:
                config.write(configfile)
        else:
            self.footer_text_var.set("Theme Not Found")
            theme_name = config["THEME"]["theme"]
Exemplo n.º 15
0
class MessageMakerListFrame:
    def __init__(self, messageMakerPartFrame):
        self.frame = Frame(messageMakerPartFrame.frame)
        self.scrollbar = Scrollbar(self.frame, orient=VERTICAL)
        self.listBox = Listbox(self.frame,
                               activestyle="none",
                               width=40,
                               height=12,
                               yscrollcommand=self.scrollbar.set)
        self.scrollbar.config(command=self.listBox.yview)
        self.scrollbar.grid(row=0, column=1, sticky=NS)
        self.populateListbox(messageMakerPartFrame.parent.message.parts)
        self.window = messageMakerPartFrame.parent
        self.messageMakerPartFrame = messageMakerPartFrame

        self.listBox.grid(row=0, column=0)

    def moveSelectedUp(self):
        current = self.listBox.curselection()
        if current and current[0] != 0:
            index = current[0]
            text = self.listBox.get(index)
            self.listBox.delete(index)
            self.listBox.insert(index - 1, text)
            self.listBox.selection_set(index - 1)
            self.listBox.see(index - 2)
            self.window.message.parts[index], self.window.message.parts[
                index - 1] = self.window.message.parts[
                    index - 1], self.window.message.parts[index]

    def moveSelectedDown(self):
        current = self.listBox.curselection()
        if current and current[0] != self.listBox.size() - 1:
            index = current[0]
            text = self.listBox.get(index)
            self.listBox.delete(index)
            self.listBox.insert(index + 1, text)
            self.listBox.selection_set(index + 1)
            self.listBox.see(index + 2)
            self.window.message.parts[index], self.window.message.parts[
                index + 1] = self.window.message.parts[
                    index + 1], self.window.message.parts[index]

    def deleteSelected(self):
        current = self.listBox.curselection()
        if current:
            index = current[0]
            self.listBox.delete(index)
            self.listBox.selection_set(index)
            self.listBox.see(index)
            del self.window.message.parts[index]
            for part in self.window.message.parts:
                part.sortOrder = self.window.message.parts.index(part) + 1

    def copySelected(self):
        current = self.listBox.curselection()
        if current:
            index = current[0]
            copiedPart = deepcopy(self.window.message.parts[index])
            copiedPart.sortOrder = len(self.window.message.parts)
            self.window.message.parts.append(copiedPart)
            self.listBox.select_clear(0, END)
            self.listBox.insert(END,
                                copiedPart.partType + ": " + copiedPart.value)
            self.listBox.selection_set(END)
            self.listBox.see(END)

    def populateListbox(self, parts):
        self.listBox.delete(0, END)
        index = 1
        for part in parts:
            self.listBox.insert(index, part.partType + ": " + part.value)
            index += 1

    def getMessageComponentWindow(self, isEditButton):
        if isEditButton:
            current = self.listBox.curselection()
            if current:
                index = current[0]
                MessageComponentWindow(self, self.window.message.parts[index],
                                       index)
            else:
                return
        else:
            MessageComponentWindow(self, None,
                                   len(self.window.message.parts) + 1)