Example #1
0
class Config(Toplevel):
    def __init__(self, master):
        Toplevel.__init__(self, master, class_=APP_NAME)
        self.title(_("Settings"))
        self.grab_set()
        self.columnconfigure(0, weight=1)
        self.columnconfigure(1, weight=1)
        self.rowconfigure(0, weight=1)
        self.resizable(True, True)
        self.minsize(470, 574)

        style = Style(self)
        self._bg = style.lookup('TFrame', 'background')

        self.notebook = Notebook(self)
        self._validate = self.register(self._validate_entry_nb)

        self.img_color = PhotoImage(master=self, file=IM_COLOR)

        self.lang = StringVar(self,
                              LANGUAGES[CONFIG.get("General", "language")])
        self.gui = StringVar(self,
                             CONFIG.get("General", "trayicon").capitalize())

        self._init_general()
        self._init_widget()

        self.notebook.grid(sticky='ewsn', row=0, column=0, columnspan=2)
        Button(self, text=_('Ok'), command=self.ok).grid(row=1,
                                                         column=0,
                                                         sticky='e',
                                                         padx=4,
                                                         pady=10)
        Button(self, text=_('Cancel'), command=self.destroy).grid(row=1,
                                                                  column=1,
                                                                  sticky='w',
                                                                  padx=4,
                                                                  pady=10)

    def _init_general(self):
        frame_general = Frame(self)
        self.notebook.add(frame_general, text=_("General"))
        # --- Language
        Label(frame_general, text=_("Language")).grid(row=0,
                                                      column=0,
                                                      padx=8,
                                                      pady=4,
                                                      sticky="e")

        menu_lang = Menu(frame_general, tearoff=False, background=self._bg)
        mb = Menubutton(frame_general, menu=menu_lang, textvariable=self.lang)
        mb.grid(row=0, column=1, padx=8, pady=4, sticky="w")
        for lang in LANGUAGES:
            language = LANGUAGES[lang]
            menu_lang.add_radiobutton(label=language,
                                      value=language,
                                      variable=self.lang,
                                      command=self.translate)

        # --- gui toolkit
        Label(frame_general,
              text=_("GUI Toolkit for the system tray icon")).grid(row=2,
                                                                   column=0,
                                                                   padx=8,
                                                                   pady=4,
                                                                   sticky="e")

        menu_gui = Menu(frame_general, tearoff=False, background=self._bg)
        Menubutton(frame_general,
                   menu=menu_gui,
                   width=9,
                   textvariable=self.gui).grid(row=2,
                                               column=1,
                                               padx=8,
                                               pady=4,
                                               sticky="w")
        for toolkit, b in TOOLKITS.items():
            if b:
                menu_gui.add_radiobutton(label=toolkit.capitalize(),
                                         value=toolkit.capitalize(),
                                         variable=self.gui,
                                         command=self.change_gui)
        # --- Update delay
        Label(frame_general,
              text=_("Feed update delay (min)")).grid(row=4,
                                                      column=0,
                                                      padx=8,
                                                      pady=4,
                                                      sticky="e")
        self.entry_delay = Entry(frame_general,
                                 width=10,
                                 justify='center',
                                 validate='key',
                                 validatecommand=(self._validate, '%P'))
        self.entry_delay.grid(row=4, column=1, padx=8, pady=4, sticky='w')
        self.entry_delay.insert(
            0,
            CONFIG.getint('General', 'update_delay') // 60000)
        # --- image loading timeout
        Label(frame_general,
              text=_("Image loading timeout (s)")).grid(row=5,
                                                        column=0,
                                                        padx=8,
                                                        pady=4,
                                                        sticky="e")
        self.entry_timeout = Entry(frame_general,
                                   width=10,
                                   justify='center',
                                   validate='key',
                                   validatecommand=(self._validate, '%P'))
        self.entry_timeout.grid(row=5, column=1, padx=8, pady=4, sticky='w')
        self.entry_timeout.insert(
            0, CONFIG.getint('General', 'img_timeout', fallback=10))
        # --- Notifications
        self.notifications = Checkbutton(frame_general,
                                         text=_("Activate notifications"))
        self.notifications.grid(row=6,
                                column=0,
                                padx=8,
                                pady=4,
                                columnspan=2,
                                sticky='w')
        if CONFIG.getboolean('General', 'notifications', fallback=True):
            self.notifications.state(('selected', '!alternate'))
        else:
            self.notifications.state(('!selected', '!alternate'))

        # --- Confirm remove feed
        self.confirm_feed_rem = Checkbutton(
            frame_general,
            text=_("Show confirmation dialog before removing feed"))
        self.confirm_feed_rem.grid(row=7,
                                   column=0,
                                   padx=8,
                                   pady=4,
                                   columnspan=2,
                                   sticky='w')
        if CONFIG.getboolean('General', 'confirm_feed_remove', fallback=True):
            self.confirm_feed_rem.state(('selected', '!alternate'))
        else:
            self.confirm_feed_rem.state(('!selected', '!alternate'))
        # --- Confirm remove cat
        self.confirm_cat_rem = Checkbutton(
            frame_general,
            text=_("Show confirmation dialog before removing category"))
        self.confirm_cat_rem.grid(row=8,
                                  column=0,
                                  padx=8,
                                  pady=4,
                                  columnspan=2,
                                  sticky='w')
        if CONFIG.getboolean('General', 'confirm_cat_remove', fallback=True):
            self.confirm_cat_rem.state(('selected', '!alternate'))
        else:
            self.confirm_cat_rem.state(('!selected', '!alternate'))
        # --- Confirm update
        self.confirm_update = Checkbutton(
            frame_general, text=_("Check for updates on start-up"))
        self.confirm_update.grid(row=9,
                                 column=0,
                                 padx=8,
                                 pady=4,
                                 columnspan=2,
                                 sticky='w')
        if CONFIG.getboolean('General', 'check_update', fallback=True):
            self.confirm_update.state(('selected', '!alternate'))
        else:
            self.confirm_update.state(('!selected', '!alternate'))

        # --- Splash supported
        self.splash_support = Checkbutton(
            frame_general,
            text=_("Check this box if the widgets disappear when you click"))
        self.splash_support.grid(row=10,
                                 column=0,
                                 padx=8,
                                 pady=4,
                                 columnspan=2,
                                 sticky='w')
        if not CONFIG.getboolean('General', 'splash_supported', fallback=True):
            self.splash_support.state(('selected', '!alternate'))
        else:
            self.splash_support.state(('!selected', '!alternate'))

    def _init_widget(self):
        frame_widget = Frame(self)
        self.notebook.add(frame_widget, text=_('Widget'))

        # --- font
        frame_font = Frame(frame_widget)
        self.title_font = FontFrame(frame_font,
                                    CONFIG.get("Widget", "font_title"), True)
        self.text_font = FontFrame(frame_font, CONFIG.get("Widget", "font"))
        frame_font.columnconfigure(1, weight=1)
        Label(frame_font, text=_('Title')).grid(row=0,
                                                column=0,
                                                sticky='nw',
                                                padx=4,
                                                pady=4)
        self.title_font.grid(row=0, column=1)
        Separator(frame_font, orient='horizontal').grid(row=1,
                                                        columnspan=2,
                                                        sticky='ew',
                                                        padx=4,
                                                        pady=4)
        Label(frame_font, text=_('Text')).grid(row=2,
                                               column=0,
                                               sticky='nw',
                                               padx=4,
                                               pady=4)
        self.text_font.grid(row=2, column=1)

        # --- opacity
        self.opacity_frame = OpacityFrame(frame_widget,
                                          CONFIG.get("Widget", "alpha"))

        # --- colors
        frame_color = Frame(frame_widget)
        frame_color.columnconfigure(1, weight=1)
        frame_color.columnconfigure(3, weight=1)
        self.color_bg = ColorFrame(frame_color,
                                   CONFIG.get("Widget", "background"),
                                   _('Background color'))
        self.color_fg = ColorFrame(frame_color,
                                   CONFIG.get("Widget", "foreground"),
                                   _('Foreground color'))
        self.color_feed_bg = ColorFrame(
            frame_color, CONFIG.get("Widget", "feed_background"),
            _('Background color'))
        self.color_feed_fg = ColorFrame(
            frame_color, CONFIG.get("Widget", "feed_foreground"),
            _('Foreground color'))
        self.color_link = ColorFrame(frame_color,
                                     CONFIG.get("Widget", "link_color"),
                                     _('Link color'))
        Label(frame_color, text=_('General')).grid(row=0,
                                                   column=0,
                                                   sticky='w',
                                                   padx=4,
                                                   pady=2)
        self.color_bg.grid(row=0, column=1, sticky='e', padx=4, pady=2)
        self.color_fg.grid(row=1, column=1, sticky='e', padx=4, pady=2)

        Separator(frame_color, orient='horizontal').grid(row=2,
                                                         columnspan=4,
                                                         sticky='ew',
                                                         padx=4,
                                                         pady=4)
        Label(frame_color, text=_('Feed entry')).grid(row=3,
                                                      column=0,
                                                      sticky='w',
                                                      padx=4,
                                                      pady=2)
        self.color_feed_bg.grid(row=3, column=1, sticky='e', padx=4, pady=2)
        self.color_feed_fg.grid(row=4, column=1, sticky='e', padx=4, pady=2)
        self.color_link.grid(row=5, column=1, sticky='e', padx=4, pady=2)

        # --- pack
        Label(frame_widget,
              text=_('Font'),
              font='TkDefaultFont 9 bold',
              anchor='w').pack(padx=4, fill='x')
        frame_font.pack(fill='x', padx=14)
        Separator(frame_widget, orient='horizontal').pack(fill='x', pady=6)
        self.opacity_frame.pack(padx=(4, 10), fill='x')
        Separator(frame_widget, orient='horizontal').pack(fill='x', pady=6)
        Label(frame_widget,
              text=_('Colors'),
              font='TkDefaultFont 9 bold',
              anchor='w').pack(padx=4, fill='x')
        frame_color.pack(fill='x', padx=14)

    def display_label(self, value):
        self.opacity_label.configure(text=" {val} %".format(
            val=int(float(value))))

    def translate(self):
        showinfo(
            "Information",
            _("The language setting will take effect after restarting the application"
              ),
            parent=self)

    @staticmethod
    def _config_size(variable, font):
        size = variable.get()
        if size:
            font.configure(size=size)

    @staticmethod
    def _validate_entry_nb(P):
        """ Allow only to enter numbers"""
        parts = P.split(".")
        b = len(parts) < 3 and P != "."
        for p in parts:
            b = b and (p == "" or p.isdigit())
        return b

    def change_gui(self):
        showinfo(
            "Information",
            _("The GUI Toolkit setting will take effect after restarting the application"
              ),
            parent=self)

    def ok(self):
        # --- general
        CONFIG.set("General", "language", REV_LANGUAGES[self.lang.get()])
        CONFIG.set("General", "trayicon", self.gui.get().lower())
        CONFIG.set("General", "update_delay",
                   "%i" % (int(self.entry_delay.get()) * 60000))
        CONFIG.set("General", "img_timeout",
                   "%i" % (int(self.entry_timeout.get())))
        CONFIG.set('General', 'confirm_feed_remove',
                   str(self.confirm_feed_rem.instate(('selected', ))))
        CONFIG.set('General', 'confirm_cat_remove',
                   str(self.confirm_cat_rem.instate(('selected', ))))
        CONFIG.set('General', 'check_update',
                   str(self.confirm_update.instate(('selected', ))))
        CONFIG.set('General', 'splash_supported',
                   str(not self.splash_support.instate(('selected', ))))
        CONFIG.set('General', 'notifications',
                   str(self.notifications.instate(('selected', ))))
        # --- widget
        CONFIG.set("Widget", "alpha", "%i" % self.opacity_frame.get_opacity())

        font_title_dic = self.title_font.get_font()
        font_title_dic[
            'underline'] = 'underline' if font_title_dic['underline'] else ''
        font_title_dic['family'] = font_title_dic['family'].replace(' ', '\ ')
        CONFIG.set(
            "Widget", "font_title",
            "{family} {size} {weight} {slant} {underline}".format(
                **font_title_dic))
        font_text_dic = self.text_font.get_font()
        font_text_dic['family'] = font_text_dic['family'].replace(' ', '\ ')
        CONFIG.set("Widget", "font", "{family} {size}".format(**font_text_dic))
        CONFIG.set("Widget", "foreground", self.color_fg.get_color())
        CONFIG.set("Widget", "background", self.color_bg.get_color())
        CONFIG.set("Widget", "feed_foreground", self.color_feed_fg.get_color())
        CONFIG.set("Widget", "feed_background", self.color_feed_bg.get_color())
        CONFIG.set("Widget", "link_color", self.color_link.get_color())
        self.destroy()
Example #2
0
class StringEntry(LabelFrame):  # changed
    """String class for entry
        rationalised with integer and float classes
        super

    Parameters
    ----------
    parent : str
        parent handle
    lf_text : str
        text on LabelFrame
    def_inp : str
        default text
    colour : str
        frame colour
    mod : boolean
        enable or disable state switch

    Returns
    -------
    string
    """
    def __init__(self, parent, lf_text, def_inp="", colour='brown', mod=False):
        self.lf_text = lf_text

        super().__init__(parent, text=lf_text)  # added

        self.mod = mod

        self.ent0 = None  # for entry
        self.cb_opt = None  # for check option

        self.out_var = StringVar()
        self.out_var.set(def_inp)

        self.construct(colour)

    def construct(self, colour):
        """construct of colour style

        Parameters
        ----------
        colour : str
            frame colour

        Returns
        -------
        None
        """
        self.farbe = farbe = {
            'blue': 'light blue',
            'brown': 'brown1',
            'green': 'light green',
            'pink': '#EAAFBF'
        }

        colour = colour if colour in farbe else 'brown'

        self.colour = colour

        st1 = Style()
        st1.theme_use('default')

        st1.configure(colour + '.TLabelframe', background='#C9B99B')
        st1.configure(colour + '.TLabelframe.Label', background=farbe[colour])
        st1.configure(colour + '.TCheckbutton', background=farbe[colour])
        st1.configure('brown.TLabel', background='#EDEF77')
        st1.configure('lowr.TLabel', background='lightblue')
        st1.configure('upr.TLabel', background='red')

        #       self.lf1 = Labelframe(self.fr, text=self.lf_text,
        #                           style=self.colour+'.TLabelframe')
        #       self.lf1.grid(column=0,row=0,padx=10, pady=10)
        self['style'] = self.colour + '.TLabelframe'
        self.messlbl = Label(self, style='brown.TLabel')  # self.lf1
        self.messlbl.grid(row=2, column=0, pady=10, padx=10)

        self.make_entry()

    def make_entry(self):
        """construct of Entry

        Parameters
        ----------
        None

        Returns
        -------
        None
        """
        vcmd = self.register(self.is_okay)

        self.ent0 = ent0 = Entry(
            self,
            validate='key',
            validatecommand=(vcmd, '%P', '%S', '%i'),  # self.lf1
            textvariable=self.out_var)
        ent0.bind("<Return>", self.end_input)
        ent0.grid(row=1, column=0, padx=10)
        ent0.focus()

        if self.mod in (True, False):
            self.modify()

    def modify(self):
        """construct of state switch

        Parameters
        ----------
        None

        Returns
        -------
        None
        """
        # entry disabled until checkbox is ticked
        self.cb_opt = Checkbutton(
            self,
            command=self.toggle_opt,  # self.lf1
            style=self.colour + '.TCheckbutton')
        self['labelwidget'] = self.cb_opt  # self.lf1[
        if self.mod:
            self.ent0.state(['!disabled'])
            self.cb_opt.state(['!selected'])
            self.cb_opt['text'] = self.lf_text
            self.ent0.focus()
        else:
            self.ent0.state(['disabled'])
            self.cb_opt.state(['selected'])
            self.cb_opt['text'] = self.lf_text

    def toggle_opt(self):
        """state switch logic

        Parameters
        ----------
        None

        Returns
        -------
        None
        """
        # state of entry controlled
        # by the state of the check button in Option frame label widget
        if self.cb_opt.instate(['selected']):
            self.ent0.state(['disabled'])
            self.cb_opt['text'] = self.lf_text
        else:
            self.ent0.state(['!disabled'])
            self.cb_opt['text'] = self.lf_text
            self.ent0.focus()

    def end_input(self, _evt):
        """limit on string

        Parameters
        ----------
        evt : str
            bind handle

        Returns
        -------
        None
        """
        if len(self.out_var.get()) > 5:
            self.messlbl['text'] = "That's OK"
        else:
            self.messlbl['text'] = "Need at least 6 characters"

    def is_okay(self, text, inp, ind):
        """ validation function

        Parameters
        ----------
        text : str
            text if allowed
        inp : str
            current input

        Returns
        -------
        boolean
        """
        ind = int(ind)
        if (inp.isalnum() or inp in (",", ".", "'", " ")) and ind > 0:
            return True
        else:
            return bool((text.isupper() or text == "") and ind == 0)
Example #3
0
class StringEntry:
    """String class for entry
        added colour, change state

    Parameters
    ----------
    parent : str
        parent handle
    lf_text : str
        text on LabelFrame
    mess_text : str
        message
    def_text : str
        default text
    colour : str
        frame colour
    mod : str
        enable or disable state switch

    Returns
    -------
    string
    """
    def __init__(self,
                 parent,
                 lf_text,
                 mess_text,
                 def_text="",
                 colour='brown',
                 mod=False):
        self.parent = parent
        self.lf_text = lf_text
        self.mess_text = mess_text
        self.mod = mod

        self.out_var = StringVar()
        self.out_var.set(def_text)

        self.farbe = farbe = {
            'blue': 'light blue',
            'brown': '#EDEF77',
            'green': 'light green',
            'pink': '#EAAFBF'
        }

        colour = colour if colour in farbe else 'brown'

        self.colour = colour

        st1 = Style()
        st1.theme_use('default')

        st1.configure(colour + '.TLabelframe', background='#C9B99B')
        st1.configure(colour + '.TLabelframe.Label', background=farbe[colour])
        st1.configure(colour + '.TCheckbutton', background=farbe[colour])
        st1.configure('brown.TLabel', background='#EDEF77')

        self.construct()

    def construct(self):
        """construct of LabelFrame and message

        Parameters
        ----------
        None

        Returns
        -------
        None
        """
        self.lf1 = Labelframe(self.parent,
                              text=self.lf_text,
                              style=self.colour + '.TLabelframe')
        self.lf1.grid(column=0, row=0, padx=10, pady=10)
        self.messlbl = Label(self.lf1,
                             text=self.mess_text,
                             style='brown.TLabel')
        self.messlbl.grid(row=2, column=0, pady=10, padx=10)

        self.make_entry()

    def make_entry(self):
        """construct of Entry

        Parameters
        ----------
        None

        Returns
        -------
        None
        """
        vcmd = self.lf1.register(self.is_okay)

        self.ent1 = ent1 = Entry(self.lf1,
                                 validate='key',
                                 validatecommand=(vcmd, '%P', '%S', '%i'),
                                 textvariable=self.out_var)
        ent1.bind("<Return>", self.end_input)
        ent1.grid(row=1, column=0, padx=10)
        ent1.focus()

        if self.mod in (True, False):
            self.modify()

    def modify(self):
        """construct of state switch

        Parameters
        ----------
        None

        Returns
        -------
        None
        """
        lf_text = self.lf_text
        # entry disabled until checkbox is ticked
        self.cb_opt = Checkbutton(self.lf1,
                                  command=self.toggle_opt,
                                  style=self.colour + '.TCheckbutton')
        self.lf1['labelwidget'] = self.cb_opt
        if self.mod:
            self.ent1.state(['!disabled'])
            self.cb_opt.state(['!selected'])
            self.cb_opt['text'] = lf_text + ' Check to prevent editing '
            self.ent1.focus()
        else:
            self.ent1.state(['disabled'])
            self.cb_opt.state(['selected'])
            self.cb_opt['text'] = lf_text + ' Check to modify '

    def toggle_opt(self):
        """state switch logic

        Parameters
        ----------
        None

        Returns
        -------
        None
        """
        lf_text = self.lf_text
        #       state of entry controlled
        #       by the state of the check button in Option frame label widget
        if self.cb_opt.instate(['selected']):
            print('selected state')
            self.ent1.state(['disabled'])
            self.cb_opt['text'] = lf_text + ' Check to modify '
        else:
            print('unselected state')
            self.ent1.state(['!disabled'])  # enable option
            self.cb_opt['text'] = lf_text + ' Check to prevent editing '
            self.ent1.focus()

    def end_input(self, _evt):
        """limit on string

        Parameters
        ----------
        evt : str
            bind handle

        Returns
        -------
        None
        """
        if len(self.out_var.get()) > 5:
            self.messlbl['text'] = "That's OK"
        else:
            self.messlbl['text'] = "Should be at least 6 characters long"

    def is_okay(self, text, inp, ind):
        """ validation function

        Parameters
        ----------
        text : str
            text if allowed
        inp : str
            current input

        Returns
        -------
        boolean
        """
        ind = int(ind)
        print(ind)
        if (inp.isalnum() or inp in (",", ".", "'", " ")) and ind > 0:
            return True
        else:
            return bool((text.isupper() or text == "") and ind == 0)
Example #4
0
class NotebookDemo:
    def __init__(self, fr):

        self.fr = fr
        self.style = Style()  # ts.ThemedStyle() # Style()
        self._create_demo_panel()  # run this before allBtns
        self.allBtns = self.ttkbut + self.cbs[1:] + self.rb
        try:
            piratz_theme.install('piratz')
        except Exception:
            import warnings
            warnings.warn("piratz theme being used without images")

    def _create_demo_panel(self):
        demoPanel = Frame(self.fr, name="demo")
        demoPanel.pack(side='top', fill='both', expand='y')

        # create the notebook
        self.nb = nb = Notebook(demoPanel, name="nb")
        nb.bind("<<NotebookTabChanged>>", self._on_tab_changed)

        # extend bindings to top level window allowing
        #   CTRL+TAB - cycles thru tabs
        #   SHIFT+CTRL+TAB - previous tab
        #   ALT+K - select tab using mnemonic (K = underlined letter)
        nb.enable_traversal()

        nb.pack(fill='both', expand='y', padx=2, pady=3)
        self._create_descrip_tab(nb)
        self._create_treeview_tab(nb)
        self._create_text_tab(nb)

    def _create_descrip_tab(self, nb):
        # frame to hold contents
        frame = Frame(nb, name='descrip')

        # widgets to be displayed on 'Description' tab
        # position and set resize behaviour

        frame.rowconfigure(1, weight=1)
        frame.columnconfigure((0, 1), weight=1, uniform=1)
        lf = LabelFrame(frame, text='Animals')
        lf.pack(pady=5, padx=5, side='left', fill='y')
        themes = ['horse', 'elephant', 'crocodile', 'bat', 'grouse']
        self.ttkbut = []
        for t in themes:
            b = Button(lf, text=t)
            b.pack(pady=2)
            self.ttkbut.append(b)

        lF2 = LabelFrame(frame, text="Theme Combobox")
        lF2.pack(pady=5, padx=5)
        themes = list(sorted(
            self.style.theme_names()))  # get_themes # used in ttkthemes
        themes.insert(0, "Pick a theme")
        self.cb = cb = Combobox(lF2,
                                values=themes,
                                state="readonly",
                                height=10)
        cb.set(themes[0])
        #cb.bind('<<ComboboxSelected>>', self.change_style)
        cb.grid(row=0, column=0, sticky='nw', pady=5)

        lf1 = LabelFrame(frame, text='Checkbuttons')
        lf1.pack(pady=5, padx=5, side='left', fill='y')

        # control variables
        self.enabled = IntVar()
        self.cheese = IntVar()
        self.tomato = IntVar()
        self.basil = IntVar()
        self.oregano = IntVar()
        # checkbuttons
        self.cbOpt = Checkbutton(lf1,
                                 text='Enabled',
                                 variable=self.enabled,
                                 command=self._toggle_opt)
        cbCheese = Checkbutton(text='Cheese',
                               variable=self.cheese,
                               command=self._show_vars)
        cbTomato = Checkbutton(text='Tomato',
                               variable=self.tomato,
                               command=self._show_vars)
        sep1 = Separator(orient='h')
        cbBasil = Checkbutton(text='Basil',
                              variable=self.basil,
                              command=self._show_vars)
        cbOregano = Checkbutton(text='Oregano',
                                variable=self.oregano,
                                command=self._show_vars)
        sep2 = Separator(orient='h')

        self.cbs = [
            self.cbOpt, sep1, cbCheese, cbTomato, sep2, cbBasil, cbOregano
        ]
        for opt in self.cbs:
            if opt.winfo_class() == 'TCheckbutton':
                opt.configure(onvalue=1, offvalue=0)
                opt.setvar(opt.cget('variable'), 0)

            opt.pack(in_=lf1,
                     side='top',
                     fill='x',
                     pady=2,
                     padx=5,
                     anchor='nw')

        lf2 = LabelFrame(frame, text='Radiobuttons', labelanchor='n')
        lf2.pack(pady=5, padx=5, side='left', fill='y')

        self.rb = []
        self.happiness = StringVar()
        for s in ['Great', 'Good', 'OK', 'Poor', 'Awful']:
            b = Radiobutton(lf2,
                            text=s,
                            value=s,
                            variable=self.happiness,
                            command=lambda s=s: self._show_vars())
            b.pack(anchor='nw', side='top', fill='x', pady=5, padx=5)
            self.rb.append(b)

        right = LabelFrame(frame, text='Control Variables')
        right.pack(pady=5, padx=5, side='left', fill='y')

        self.vb0 = Label(right, font=('Courier', 10))
        self.vb1 = Label(right, font=('Courier', 10))
        self.vb2 = Label(right, font=('Courier', 10))
        self.vb3 = Label(right, font=('Courier', 10))
        self.vb4 = Label(right, font=('Courier', 10))
        self.vb5 = Label(right, font=('Courier', 10))

        self.vb0.pack(anchor='nw', pady=5, padx=5)
        self.vb1.pack(anchor='nw', pady=5, padx=5)
        self.vb2.pack(anchor='nw', pady=5, padx=5)
        self.vb3.pack(anchor='nw', pady=5, padx=5)
        self.vb4.pack(anchor='nw', pady=5, padx=5)
        self.vb5.pack(anchor='nw', pady=5, padx=5)

        self._show_vars()
        # add to notebook (underline = index for short-cut character)
        nb.add(frame, text='Description', underline=0, padding=2)

    # =============================================================================
    def _create_treeview_tab(self, nb):
        # Populate the second pane. Note that the content doesn't really matter
        tree = None
        self.backg = ["white", '#f0f0ff']
        tree_columns = ("country", "capital", "currency")
        tree_data = [("Argentina", "Buenos Aires", "ARS"),
                     ("Australia", "Canberra", "AUD"),
                     ("Brazil", "Brazilia", "BRL"),
                     ("Canada", "Ottawa", "CAD"), ("China", "Beijing", "CNY"),
                     ("France", "Paris", "EUR"), ("Germany", "Berlin", "EUR"),
                     ("India", "New Delhi", "INR"), ("Italy", "Rome", "EUR"),
                     ("Japan", "Tokyo", "JPY"),
                     ("Mexico", "Mexico City", "MXN"),
                     ("Russia", "Moscow", "RUB"),
                     ("South Africa", "Pretoria", "ZAR"),
                     ("United Kingdom", "London", "GBP"),
                     ("United States", "Washington, D.C.", "USD")]

        container = Frame(nb)
        container.pack(fill='both', expand=False)
        self.tree = Treeview(container, columns=tree_columns, show="headings")
        vsb = Scrollbar(container, orient="vertical", command=self.tree.yview)
        hsb = Scrollbar(container,
                        orient="horizontal",
                        command=self.tree.xview)
        self.tree.configure(yscrollcommand=vsb.set, xscrollcommand=hsb.set)
        self.tree.grid(column=0, row=0, sticky='ns', in_=container)
        vsb.grid(column=1, row=0, sticky='ns', in_=container)
        hsb.grid(column=0, row=1, sticky='ew', in_=container)

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

        for col in tree_columns:
            self.tree.heading(
                col,
                text=col.title(),
                command=lambda c=col: self.sortby(self.tree, c, 0))
            # XXX tkFont.Font().measure expected args are incorrect according
            #     to the Tk docs
            self.tree.column(col,
                             width=Font().measure(col.title()),
                             stretch=False)

        for ix, item in enumerate(tree_data):
            itemID = self.tree.insert('', 'end', values=item)
            self.tree.item(itemID, tags=itemID)
            self.tree.tag_configure(itemID, background=self.backg[ix % 2])

            # adjust columns lengths if necessary
            for indx, val in enumerate(item):
                ilen = Font().measure(val)
                if self.tree.column(tree_columns[indx], width=None) < ilen:
                    self.tree.column(tree_columns[indx], width=ilen)

        sg = Sizegrip(container)
        sg.grid(sticky='e')

        nb.add(container, text='Treeview', underline=0, padding=2)

    # =============================================================================
    def _create_text_tab(self, nb):
        self.dir0 = 1
        self.dir1 = 1
        # populate the third frame with other widgets
        fr = Frame(nb, name='fr')

        lF = LabelFrame(fr, text="Slider")
        fr1 = Frame(lF)
        fr1.grid(row=0, column=0, sticky='nsew')
        from_ = 100
        to = 0
        value = 0
        step = 10
        fontSize = 9
        self.scvar = IntVar()
        scRange = self.any_number_range(from_, to, step)
        scLen = len(scRange[1]) * (fontSize + 10)
        self.sc = Scale(fr1,
                        from_=from_,
                        to=to,
                        variable=self.scvar,
                        orient='vertical',
                        length=scLen,
                        command=self.v_scale)
        self.sc.set(value)
        l1 = Label(fr1, textvariable=self.scvar, width=5)
        l1.grid(row=0, column=0, padx=5, pady=5)
        self.sc.grid(row=0, column=1, padx=5, pady=5)
        fr4 = Frame(fr1)
        fr4.grid(row=0, column=2)
        sc_split = '\n'.join(scRange[0].split())
        lb = Label(fr1, text=sc_split, font=('Courier New', str(fontSize)))
        lb.grid(row=0, column=2, padx=5, pady=5)

        fr2 = Frame(lF, name='fr2')
        fr2.grid(row=0, column=1, sticky='nsew')
        self.schvar = IntVar()
        a = 0
        b = 100
        schRange = self.any_number_range(a, b, s=10)
        schLen = Font().measure(schRange[0])
        self.sch = Scale(fr2,
                         from_=a,
                         to=b,
                         length=schLen,
                         variable=self.schvar,
                         orient='horizontal',
                         command=self.h_scale)

        self.sch.set(0)
        l2 = Label(fr2, textvariable=self.schvar)
        l2.grid(row=1, column=1, pady=2)
        self.sch.grid(row=2, column=1, padx=5, pady=5, sticky='nsew')
        l3 = Label(fr2, text=schRange[0], font=('Courier New', str(fontSize)))
        l3.grid(row=3, column=1, padx=5, pady=5)
        lF.grid(row=0, column=0, sticky='nesw', pady=5, padx=5)

        lF1 = LabelFrame(fr, text="Progress", name='lf')
        pb1var = IntVar()
        pb2var = IntVar()
        self.pbar = Progressbar(lF1,
                                variable=pb1var,
                                length=150,
                                mode="indeterminate",
                                name='pb1',
                                orient='horizontal')
        self.pb2 = Progressbar(lF1,
                               variable=pb2var,
                               length=150,
                               mode='indeterminate',
                               name='pb2',
                               orient='vertical')
        self.pbar["value"] = 25
        self.h_progress()
        self.v_progress()
        self.pbar.grid(row=1, column=0, padx=5, pady=5, sticky='nw')
        self.pb2.grid(row=1, column=1, padx=5, pady=5, sticky='nw')
        l3 = Label(lF1, textvariable=pb1var)
        l3.grid(row=0, column=0, pady=2, sticky='nw')
        l4 = Label(lF1, textvariable=pb2var)
        l4.grid(row=0, column=1, pady=2, sticky='nw')

        sg1 = Sizegrip(fr)
        sg1.grid(row=2, column=2, sticky='e')

        lF1.grid(row=1, column=0, sticky='nesw', pady=5, padx=5)

        # add to notebook (underline = index for short-cut character)
        nb.add(fr, text='Sliders & Others', underline=0)

    #=========================================================================
    def _toggle_opt(self):
        # state of the option buttons controlled
        # by the state of the Option frame label widget

        for opt in self.allBtns:
            if opt.winfo_class() != 'TSeparator':
                if self.cbOpt.instate(('selected', )):
                    opt['state'] = '!disabled'  # enable option
                    self.nb.tab(1, state='normal')
                else:
                    opt['state'] = 'disabled'
                    self.nb.tab(1, state='disabled')
        self._show_vars()

    def _show_vars(self):
        # set text for labels in var_panel to include the control
        # variable name and current variable value
        self.vb0['text'] = '{:<11} {:<8}'.format('enabled:',
                                                 self.enabled.get())
        self.vb1['text'] = '{:<11} {:<8}'.format('cheese:', self.cheese.get())
        self.vb2['text'] = '{:<11} {:<8}'.format('tomato:', self.tomato.get())
        self.vb3['text'] = '{:<11} {:<8}'.format('basil:', self.basil.get())
        self.vb4['text'] = '{:<11} {:<8}'.format('oregano:',
                                                 self.oregano.get())
        self.vb5['text'] = '{:<11} {:<8}'.format('happiness:',
                                                 self.happiness.get())

    def sortby(self, tree, col, descending):
        """Sort tree contents when a column is clicked on."""
        # grab values to sort
        data = [(tree.set(child, col), child)
                for child in tree.get_children('')]

        # reorder data
        data.sort(reverse=descending)
        for indx, item in enumerate(data):
            tree.move(item[1], '', indx)

        # switch the heading so that it will sort in the opposite direction
        tree.heading(col,
                     command=lambda col=col: self.sortby(
                         tree, col, int(not descending)))
        # reconfigure tags after ordering
        list_of_items = tree.get_children('')
        for i in range(len(list_of_items)):
            tree.tag_configure(list_of_items[i], background=self.backg[i % 2])

    def any_number_range(self, a, b, s=1):
        """ Generate consecutive values list between two numbers with optional step (default=1)."""
        if (a == b):
            return a
        else:
            mx = max(a, b)
            mn = min(a, b)
            result = []
            output = ''
            # inclusive upper limit. If not needed, delete '+1' in the line below
            while (mn < mx + 1):
                # if step is positive we go from min to max
                if s > 0:
                    result.append(mn)
                    mn += s
                # if step is negative we go from max to min
                if s < 0:
                    result.append(mx)
                    mx += s
                # val
            maxLen = 0
            output = ""
            for ix, res in enumerate(result[:-1]):  # last value ignored
                if len(str(res)) > maxLen:
                    maxLen = len(str(res))
            if maxLen == 1:
                output = ' '.join(str(i)
                                  for i in result)  # converts list to string
            else:
                for ix, res in enumerate(result):
                    if maxLen == 2:
                        if len(str(res)) == 1:
                            output = output + str(res) + " " * maxLen
                        elif len(str(res)) == 2:
                            output = output + str(res) + " "
                        else:
                            output = output + str(res)
            #print(output)
            return output, result

    def change_style(self, event=None):
        """set the Style to the content of the Combobox"""
        content = self.cb.get()
        try:
            self.style.theme_use(content)
        except TclError as err:
            messagebox.showerror('Error', err)
        else:
            root.title(content)

    def change_theme(self, theme):
        window = ttktheme.ThemedTk()
        window.set_theme(theme)
        root.title(theme)

    def _on_tab_changed(self, event):
        event.widget.update_idletasks()
        tab = event.widget.nametowidget(event.widget.select())
        event.widget.configure(height=tab.winfo_reqheight(),
                               width=tab.winfo_reqwidth())

    def h_progress(self):
        widg = self.pbar
        widg['value'] += 1 * self.dir0
        if widg['value'] == 100:
            widg.state(['background', '!active'])
            self.dir0 = -1
            widg.after(50, self.h_progress)
        elif widg['value'] == 0:
            widg.state(['active', '!background'])
            self.dir0 = 1
            widg.after(50, self.h_progress)
        else:
            widg.after(50, self.h_progress)

    def v_progress(self):
        widg1 = self.pb2
        widg1['value'] += 1 * self.dir1
        if widg1['value'] == 0:  # (dir1-1)*100+16
            widg1.state(['active', '!invalid', '!background'])
            self.dir1 = 1
            widg1.after(40, self.v_progress)
        elif widg1['value'] == 16:  # (dir1-1)*100+16
            widg1.state(['background', '!invalid', '!active'])
            widg1.after(40, self.v_progress)
        elif widg1['value'] == 33:
            widg1.state(['invalid', '!background', '!active'])
            widg1.after(40, self.v_progress)
        elif widg1['value'] == 50:
            widg1.state(['active', '!invalid', '!background'])
            widg1.after(40, self.v_progress)
        elif widg1['value'] == 66:
            widg1.state(['background', '!invalid', '!active'])
            widg1.after(40, self.v_progress)
        elif widg1['value'] == 83:
            widg1.state(['invalid', '!background', '!active'])
            widg1.after(40, self.v_progress)
        elif widg1['value'] == 100:
            widg1.state(['active', '!invalid', '!background'])
            self.dir1 = -1
            widg1.after(40, self.v_progress)
        else:
            widg1.after(40, self.v_progress)

    def h_scale(self, schvar):
        v = int(float(schvar))
        widg = self.sch
        imgw = {
            0: ['readonly', '!selected', '!background', '!focus', '!active'],
            1: ['selected', '!readonly', '!background', '!focus', '!active']
        }
        if v >= 0 and v < 10:
            widg.state(['active', '!readonly', '!selected'])
        elif v > 80 and v < 91:
            widg.state(['focus', '!background', '!readonly', '!selected'])
        elif v > 90 and v < 100:
            widg.state(['background', '!invalid', '!focus'])
        elif v == 100:
            widg.state(['invalid', '!background'])
        else:
            widg.state(imgw[v % 2])

    def v_scale(self, scvar):
        v = int(float(scvar))
        widg1 = self.sc
        imgw = {
            0: ['background', '!selected', '!invalid', '!active'],
            1: ['selected', '!invalid', '!background', '!active']
        }
        if v >= 0 and v < 5:
            widg1.state(['active', '!background', '!selected'])
        elif v > 90:
            widg1.state(['invalid', '!selected', '!background'])
        else:
            widg1.state(imgw[v % 2])
Example #5
0
class Config(Toplevel):
    """Config dialog."""
    def __init__(self, master):
        """Create Config dialog."""
        Toplevel.__init__(self, master, class_='MyNotes')
        self.title(_("Preferences"))
        self.grab_set()
        self.protocol("WM_DELETE_WINDOW", self.quit)
        self.changes = {}, {}, False, False
        self.minsize(width=430, height=450)

        # --- style
        style = Style(self)
        style.theme_use("clam")
        style.configure("TScale", sliderlength=20)
        style.map("TCombobox",
                  fieldbackground=[('readonly', 'white')],
                  selectbackground=[('readonly', 'white')],
                  selectforeground=[('readonly', 'black')])
        style.configure("prev.TLabel", background="white")
        style.map("prev.TLabel", background=[("active", "white")])
        color = CONFIG.get("Categories",
                           CONFIG.get("General", "default_category"))
        style.configure("titlebar.TFrame", background=color)
        style.configure("titlebar.TLabel", background=color)
        style.configure("text.TFrame", background="white")

        # --- body
        self.notebook = Notebook(self)
        okcancel_frame = Frame(self)
        okcancel_frame.columnconfigure(0, weight=1)
        okcancel_frame.columnconfigure(1, weight=1)
        okcancel_frame.pack(fill="x", side='bottom')
        self.notebook.pack(expand=True, fill="both")

        # --- * General settings
        self._init_general()

        # --- * Font settings
        self._init_font()

        # --- * Categories
        self.category_settings = CategoryManager(self.notebook, master)
        self.notebook.add(self.category_settings,
                          text=_("Categories"),
                          sticky="ewsn",
                          padding=4)
        # --- * Symbols
        size = CONFIG.get("Font", "text_size")
        family = CONFIG.get("Font", "text_family")
        symbols_settings = Frame(self.notebook, padding=4)
        self.notebook.add(symbols_settings,
                          text=_("Symbols"),
                          sticky="ewsn",
                          padding=4)
        txt_frame = Frame(symbols_settings,
                          relief="sunken",
                          borderwidth=1,
                          style="text.TFrame")
        txt_frame.rowconfigure(0, weight=1)
        txt_frame.columnconfigure(0, weight=1)
        self.symbols = Text(txt_frame,
                            width=1,
                            height=1,
                            highlightthickness=0,
                            spacing2=5,
                            spacing1=5,
                            relief="flat",
                            padx=4,
                            pady=4,
                            font="%s %s" % (family.replace(" ", "\ "), size))
        scroll_y = AutoScrollbar(txt_frame,
                                 orient='vertical',
                                 command=self.symbols.yview)
        self.symbols.configure(yscrollcommand=scroll_y.set)

        self.symbols.insert("1.0", CONFIG.get("General", "symbols"))
        Label(symbols_settings, text=_("Available symbols")).pack(padx=4,
                                                                  pady=4)
        txt_frame.pack(fill="both", expand=True, padx=4, pady=4)
        self.symbols.grid(sticky='ewns')
        scroll_y.grid(row=0, column=1, sticky='ns')
        Button(symbols_settings, text=_('Reset'),
               command=self.reset_symbols).pack(padx=4, pady=4)

        # --- * AutoCorrect
        self.autocorrect_settings = AutoCorrectConfig(self.notebook, master)
        self.notebook.add(self.autocorrect_settings,
                          text=_("AutoCorrect"),
                          sticky="ewsn",
                          padding=4)

        # --- Ok/Cancel buttons
        Button(okcancel_frame, text="Ok", command=self.ok).grid(row=1,
                                                                column=0,
                                                                padx=4,
                                                                pady=10,
                                                                sticky="e")
        Button(okcancel_frame, text=_("Cancel"),
               command=self.destroy).grid(row=1,
                                          column=1,
                                          padx=4,
                                          pady=10,
                                          sticky="w")

    def _init_general(self):
        general_settings = Frame(self.notebook, padding=4)
        general_settings.columnconfigure(0, weight=1)
        self.notebook.add(general_settings,
                          text=_("General"),
                          sticky="ewsn",
                          padding=4)

        # ---- language

        self.lang = StringVar(self,
                              LANGUAGES[CONFIG.get("General", "language")])
        lang_frame = Frame(general_settings)
        Label(lang_frame, text=_("Language")).grid(row=0,
                                                   sticky="w",
                                                   padx=4,
                                                   pady=4)
        menu_lang = Menu(lang_frame, tearoff=False)
        Menubutton(lang_frame, menu=menu_lang, width=9,
                   textvariable=self.lang).grid(row=0,
                                                column=1,
                                                padx=8,
                                                pady=4)
        for lang in LANGUAGES.values():
            menu_lang.add_radiobutton(variable=self.lang,
                                      label=lang,
                                      value=lang,
                                      command=self.translate)
        # ---- gui toolkit
        self.gui = StringVar(self,
                             CONFIG.get("General", "trayicon").capitalize())
        gui_frame = Frame(general_settings)
        Label(gui_frame,
              text=_("GUI Toolkit for the system tray icon")).grid(row=0,
                                                                   column=0,
                                                                   padx=4,
                                                                   pady=4,
                                                                   sticky="w")
        menu_gui = Menu(gui_frame, tearoff=False)
        Menubutton(gui_frame, menu=menu_gui, width=9,
                   textvariable=self.gui).grid(row=0,
                                               column=1,
                                               padx=4,
                                               pady=4,
                                               sticky="w")
        for toolkit, b in TOOLKITS.items():
            if b:
                menu_gui.add_radiobutton(label=toolkit.capitalize(),
                                         value=toolkit.capitalize(),
                                         variable=self.gui,
                                         command=self.change_gui)
        # ---- opacity
        self.opacity = OpacityFrame(general_settings,
                                    CONFIG.getint("General", "opacity"))
        # ---- position
        frame_position = Frame(general_settings)
        self.position = StringVar(self, CONFIG.get("General", "position"))
        Label(frame_position,
              text=_("Default position of the notes")).grid(row=0,
                                                            columnspan=3,
                                                            sticky="w",
                                                            padx=4,
                                                            pady=4)
        Radiobutton(frame_position,
                    text=_("Always above"),
                    value="above",
                    variable=self.position).grid(row=1, column=0, padx=4)
        Radiobutton(frame_position,
                    text=_("Always below"),
                    value="below",
                    variable=self.position).grid(row=1, column=1, padx=4)
        Radiobutton(frame_position,
                    text=_("Normal"),
                    value="normal",
                    variable=self.position).grid(row=1, column=2, padx=4)
        # ---- titlebar
        self.titlebar_disposition = StringVar(
            self, CONFIG.get("General", "buttons_position"))
        self.title_var = StringVar(
            self)  # to add date if date_in_title is true
        font_title = "%s %s" % (CONFIG.get("Font", "title_family").replace(
            " ", "\ "), CONFIG.get("Font", "title_size"))
        style = CONFIG.get("Font", "title_style").split(",")
        if style:
            font_title += " "
            font_title += " ".join(style)

        frame_titlebar = Frame(general_settings)
        frame_titlebar.columnconfigure(1, weight=1)
        frame_titlebar.columnconfigure(3, weight=1)
        Label(frame_titlebar,
              text=_("Title bar disposition")).grid(row=0,
                                                    columnspan=4,
                                                    sticky="w",
                                                    padx=4,
                                                    pady=4)
        Radiobutton(frame_titlebar,
                    value="right",
                    variable=self.titlebar_disposition).grid(row=1,
                                                             column=0,
                                                             padx=4)
        right = Frame(frame_titlebar, style="titlebar.TFrame")
        right.grid(row=1, column=1, sticky="ew", padx=4)

        def select_right(event):
            self.titlebar_disposition.set("right")

        Label(right,
              textvariable=self.title_var,
              style="titlebar.TLabel",
              anchor="center",
              font=font_title).pack(side="left", fill="x", expand=True)
        Label(right, image="img_close",
              style="titlebar.TLabel").pack(side="right")
        Label(right, image="img_roll",
              style="titlebar.TLabel").pack(side="right")
        for ch in right.children.values():
            ch.bind("<Button-1>", select_right)
        Radiobutton(frame_titlebar,
                    value="left",
                    variable=self.titlebar_disposition).grid(row=1, column=2)
        left = Frame(frame_titlebar, style="titlebar.TFrame")
        left.grid(row=1, column=3, sticky="ew")

        def select_left(event):
            self.titlebar_disposition.set("left")

        Label(left, image="img_close",
              style="titlebar.TLabel").pack(side="left")
        Label(left, image="img_roll",
              style="titlebar.TLabel").pack(side="left")
        Label(left,
              textvariable=self.title_var,
              style="titlebar.TLabel",
              anchor="center",
              font=font_title).pack(side="right", fill="x", expand=True)
        for ch in left.children.values():
            ch.bind("<Button-1>", select_left)

        self.date_in_title = BooleanVar(
            self, CONFIG.getboolean('General', 'date_in_title', fallback=True))
        date_in_title = Checkbutton(frame_titlebar,
                                    variable=self.date_in_title,
                                    text=_('Display creation date in title'),
                                    command=self.toggle_date)
        date_in_title.grid(row=2, columnspan=4, sticky='w', pady=4, padx=4)
        self.toggle_date()
        # ---- placement
        lang_frame.grid(sticky="w")
        Separator(general_settings, orient="horizontal").grid(sticky="ew",
                                                              pady=10)
        gui_frame.grid(sticky="w")
        Separator(general_settings, orient="horizontal").grid(sticky="ew",
                                                              pady=10)
        # opacity_frame.grid(sticky='w')
        self.opacity.grid(sticky='w', padx=4)
        Separator(general_settings, orient="horizontal").grid(sticky="ew",
                                                              pady=10)
        frame_position.grid(sticky="ew")
        Separator(general_settings, orient="horizontal").grid(sticky="ew",
                                                              pady=10)
        frame_titlebar.grid(sticky="ew", pady=4)

        # ---- clean local data
        Separator(general_settings, orient="horizontal").grid(sticky="ew",
                                                              pady=10)
        Button(general_settings,
               text=_('Delete unused local data'),
               command=self.cleanup).grid(padx=4, pady=4, sticky='w')

        # ---- splash supported
        Separator(general_settings, orient="horizontal").grid(sticky="ew",
                                                              pady=10)
        self.splash_support = Checkbutton(
            general_settings,
            text=_("Check this box if the notes disappear when you click"))
        self.splash_support.grid(padx=4, pady=4, sticky='w')
        if not CONFIG.getboolean('General', 'splash_supported', fallback=True):
            self.splash_support.state(('selected', '!alternate'))
        else:
            self.splash_support.state(('!selected', '!alternate'))

    def _init_font(self):
        font_settings = Frame(self.notebook, padding=4)
        font_settings.columnconfigure(1, weight=1)
        self.notebook.add(font_settings,
                          text=_("Font"),
                          sticky="ewsn",
                          padding=4)

        # ---- title
        title_size = CONFIG.get("Font", "title_size")
        title_family = CONFIG.get("Font", "title_family").replace(" ", "\ ")
        font_title = '{} {}'.format(title_family, title_size)
        style = CONFIG.get("Font", "title_style").split(",")
        if style:
            font_title = font_title + " " + " ".join(style)

        self.title_font = FontFrame(font_settings, font_title, style=True)
        # ---- text
        size = CONFIG.get("Font", "text_size")
        family = CONFIG.get("Font", "text_family").replace(" ", "\ ")

        self.text_font = FontFrame(font_settings, '{} {}'.format(family, size))

        # ---- mono
        mono_fonts = [f for f in set(font.families()) if 'Mono' in f]
        mono_family = CONFIG.get("Font", "mono").replace(" ", "\ ")

        self.mono_font = FontFrame(font_settings,
                                   '{} {}'.format(mono_family, size),
                                   size=False,
                                   font_list=mono_fonts)
        add_trace(
            self.text_font.font_size,
            'write', lambda *args: self.mono_font._config_size(
                self.text_font.font_size, self.mono_font.font))

        # ---- placement
        Label(font_settings, text=_("Title")).grid(row=0,
                                                   column=0,
                                                   padx=4,
                                                   pady=4,
                                                   sticky="nw")
        self.title_font.grid(row=0, column=1, sticky="w", padx=20)
        Separator(font_settings, orient="horizontal").grid(row=1,
                                                           columnspan=2,
                                                           sticky="ew",
                                                           pady=10)
        Label(font_settings, text=_("Text")).grid(row=2,
                                                  column=0,
                                                  padx=4,
                                                  pady=4,
                                                  sticky="nw")
        self.text_font.grid(row=2, column=1, sticky="w", padx=20)
        Separator(font_settings, orient="horizontal").grid(row=3,
                                                           columnspan=2,
                                                           sticky="ew",
                                                           pady=10)
        Label(font_settings, text=_("Mono")).grid(row=4,
                                                  column=0,
                                                  padx=4,
                                                  pady=4,
                                                  sticky="nw")
        self.mono_font.grid(row=4, column=1, sticky="w", padx=20)

    def reset_symbols(self):
        self.symbols.delete('1.0', 'end')
        self.symbols.insert('1.0', SYMBOLS)

    def toggle_date(self):
        if self.date_in_title.get():
            self.title_var.set('{} - {}'.format(_('Title'), strftime('%x')))
        else:
            self.title_var.set(_('Title'))

    def cleanup(self):
        """Remove unused local data and latex images."""
        self.master.cleanup()
        showinfo(_('Information'),
                 _('Unused local data have been cleaned up.'))

    def ok(self):
        """Validate configuration."""
        # --- splash supported
        splash_supp = not self.splash_support.instate(('selected', ))
        splash_change = splash_supp != CONFIG.getboolean(
            "General", "splash_supported", fallback=True)
        # --- font
        mono_font = self.mono_font.get_font()['family']
        text_font = self.text_font.get_font()
        title_font = self.title_font.get_font()
        style = "{weight},{slant}".format(**title_font)
        style = style + ',underline' * title_font['underline']

        # --- language
        language = REV_LANGUAGES[self.lang.get()]

        # --- symbols
        symbols = [
            l.strip() for l in self.symbols.get("1.0", "end").splitlines()
        ]

        # --- autocorrect
        self.autocorrect_settings.ok()
        autocorrect = "\t".join(
            ["%s %s" % (key, val) for key, val in AUTOCORRECT.items()])

        # --- update CONFIG
        CONFIG.set("General", "default_category",
                   self.category_settings.default_category.get().lower())
        CONFIG.set("General", "language", language)
        CONFIG.set("General", "opacity", str(self.opacity.get()))
        CONFIG.set("General", "position", self.position.get())
        CONFIG.set("General", "buttons_position",
                   self.titlebar_disposition.get())
        CONFIG.set("General", "date_in_title", str(self.date_in_title.get()))
        CONFIG.set("General", "symbols", "".join(symbols))
        CONFIG.set("General", "trayicon", self.gui.get().lower())
        CONFIG.set("General", "autocorrect", autocorrect)
        CONFIG.set('General', 'splash_supported', str(splash_supp))

        CONFIG.set("Font", "text_size", str(text_font['size']))
        CONFIG.set("Font", "text_family", text_font['family'])
        CONFIG.set("Font", "title_family", title_font['family'])
        CONFIG.set("Font", "title_size", str(title_font['size']))
        CONFIG.set("Font", "title_style", style)
        CONFIG.set("Font", "mono", mono_font)

        # --- notes config
        col_changes = {}
        name_changes = {}
        new_cat = False
        for cat in self.category_settings.categories:
            new_name = self.category_settings.get_name(cat)
            if cat in CONFIG.options("Categories"):
                old_color = CONFIG.get("Categories", cat)
                new_color = COLORS[self.category_settings.get_color(cat)]
                if new_name != cat:
                    name_changes[cat] = new_name
                    CONFIG.remove_option("Categories", cat)
                    CONFIG.set("Categories", new_name, new_color)
                if old_color != new_color:
                    col_changes[new_name] = (old_color, new_color)
                    CONFIG.set("Categories", new_name, new_color)

            else:
                new_cat = True
                CONFIG.set("Categories", new_name,
                           COLORS[self.category_settings.get_color(cat)])
        save_config()
        self.changes = col_changes, name_changes, new_cat, splash_change
        self.destroy()

    def get_changes(self):
        return self.changes

    def translate(self):
        """Show information dialog about language change."""
        showinfo(
            _("Information"),
            _("The language setting will take effect after restarting the application"
              ),
            parent=self)

    def change_gui(self):
        """Show information dialog about gui toolkit change."""
        showinfo(
            "Information",
            _("The GUI Toolkit setting will take effect after restarting the application"
              ),
            parent=self)

    def display_label(self, value):
        self.opacity_label.configure(text=" {val} %".format(
            val=int(float(value))))

    def quit(self):
        self.destroy()
Example #6
0
class Config(Toplevel):
    def __init__(self, master):
        Toplevel.__init__(self, master)
        self.title(_("Preferences"))
        self.grab_set()
        self.resizable(False, False)
        self.protocol("WM_DELETE_WINDOW", self.quit)
        self.changes = {}, {}

        # --- style
        style = Style(self)
        style.theme_use("clam")
        style.configure("TScale", sliderlength=20)
        style.map("TCombobox",
                  fieldbackground=[('readonly', 'white')],
                  selectbackground=[('readonly', 'white')],
                  selectforeground=[('readonly', 'black')])
        style.configure("prev.TLabel", background="white")
        style.map("prev.TLabel", background=[("active", "white")])
        color = CONFIG.get("Categories",
                           CONFIG.get("General", "default_category"))
        style.configure("titlebar.TFrame", background=color)
        style.configure("titlebar.TLabel", background=color)
        style.configure("text.TFrame", background="white")

        # --- body
        self.notebook = Notebook(self)
        okcancel_frame = Frame(self)
        okcancel_frame.columnconfigure(0, weight=1)
        okcancel_frame.columnconfigure(1, weight=1)
        self.notebook.pack(expand=True, fill="both")
        okcancel_frame.pack(fill="x", expand=True)

        # --- * General settings
        general_settings = Frame(self.notebook)
        general_settings.columnconfigure(0, weight=1)
        self.notebook.add(general_settings,
                          text=_("General"),
                          sticky="ewsn",
                          padding=4)

        # --- *-- language
        lang = {"fr": "Français", "en": "English"}
        self.lang = StringVar(self, lang[CONFIG.get("General", "language")])
        lang_frame = Frame(general_settings)
        Label(lang_frame, text=_("Language")).grid(row=0,
                                                   sticky="w",
                                                   padx=4,
                                                   pady=4)
        menu_lang = Menu(lang_frame, tearoff=False)
        Menubutton(lang_frame, menu=menu_lang, width=9,
                   textvariable=self.lang).grid(row=0,
                                                column=1,
                                                padx=8,
                                                pady=4)
        menu_lang.add_radiobutton(label="English",
                                  value="English",
                                  variable=self.lang,
                                  command=self.translate)
        menu_lang.add_radiobutton(label="Français",
                                  value="Français",
                                  variable=self.lang,
                                  command=self.translate)
        # --- *-- opacity
        self.opacity_scale = Scale(general_settings,
                                   orient="horizontal",
                                   length=200,
                                   from_=0,
                                   to=100,
                                   value=CONFIG.get("General", "opacity"),
                                   command=self.display_label)
        self.opacity_label = Label(
            general_settings,
            text="{val}%".format(val=self.opacity_scale.get()))
        # --- *-- position
        frame_position = Frame(general_settings)
        self.position = StringVar(self, CONFIG.get("General", "position"))
        Label(frame_position,
              text=_("Default position of the notes")).grid(row=0,
                                                            columnspan=3,
                                                            sticky="w",
                                                            padx=4,
                                                            pady=4)
        Radiobutton(frame_position,
                    text=_("Always above"),
                    value="above",
                    variable=self.position).grid(row=1, column=0)
        Radiobutton(frame_position,
                    text=_("Always below"),
                    value="below",
                    variable=self.position).grid(row=1, column=1)
        Radiobutton(frame_position,
                    text=_("Normal"),
                    value="normal",
                    variable=self.position).grid(row=1, column=2)
        # --- *-- titlebar
        self.titlebar_disposition = StringVar(
            self, CONFIG.get("General", "buttons_position"))
        font_title = "%s %s" % (CONFIG.get("Font", "title_family").replace(
            " ", "\ "), CONFIG.get("Font", "title_size"))
        style = CONFIG.get("Font", "title_style").split(",")
        if style:
            font_title += " "
            font_title += " ".join(style)

        frame_titlebar = Frame(general_settings)
        frame_titlebar.columnconfigure(1, weight=1)
        frame_titlebar.columnconfigure(3, weight=1)
        Label(frame_titlebar,
              text=_("Title bar disposition")).grid(row=0,
                                                    columnspan=4,
                                                    sticky="w",
                                                    padx=4,
                                                    pady=4)
        Radiobutton(frame_titlebar,
                    value="right",
                    variable=self.titlebar_disposition).grid(row=1, column=0)
        right = Frame(frame_titlebar, style="titlebar.TFrame")
        right.grid(row=1, column=1, sticky="ew")

        def select_right(event):
            self.titlebar_disposition.set("right")

        Label(right,
              text=_("Title"),
              style="titlebar.TLabel",
              anchor="center",
              font=font_title).pack(side="left", fill="x", expand=True)
        Label(right, image="img_close",
              style="titlebar.TLabel").pack(side="right")
        Label(right, image="img_roll",
              style="titlebar.TLabel").pack(side="right")
        for ch in right.children.values():
            ch.bind("<Button-1>", select_right)
        Radiobutton(frame_titlebar,
                    value="left",
                    variable=self.titlebar_disposition).grid(row=1, column=2)
        left = Frame(frame_titlebar, style="titlebar.TFrame")
        left.grid(row=1, column=3, sticky="ew")

        def select_left(event):
            self.titlebar_disposition.set("left")

        Label(left, image="img_close",
              style="titlebar.TLabel").pack(side="left")
        Label(left, image="img_roll",
              style="titlebar.TLabel").pack(side="left")
        Label(left,
              text=_("Title"),
              style="titlebar.TLabel",
              anchor="center",
              font=font_title).pack(side="right", fill="x", expand=True)
        for ch in left.children.values():
            ch.bind("<Button-1>", select_left)
        # --- *-- placement
        lang_frame.grid(sticky="w")
        Separator(general_settings, orient="horizontal").grid(sticky="ew",
                                                              pady=10)
        Label(general_settings, text=_("Opacity")).grid(sticky="w",
                                                        padx=4,
                                                        pady=4)
        self.opacity_scale.grid(padx=4, pady=(4, 10))
        self.opacity_label.place(in_=self.opacity_scale,
                                 relx=1,
                                 rely=0.5,
                                 anchor="w",
                                 bordermode="outside")
        Separator(general_settings, orient="horizontal").grid(sticky="ew",
                                                              pady=10)
        frame_position.grid(sticky="ew")
        Separator(general_settings, orient="horizontal").grid(sticky="ew",
                                                              pady=10)
        frame_titlebar.grid(sticky="ew", pady=4)
        if LATEX:
            Separator(general_settings, orient="horizontal").grid(sticky="ew",
                                                                  pady=10)
            Button(general_settings,
                   text=_('Delete unused LaTex data'),
                   command=self.cleanup).grid(padx=4, pady=4, sticky='w')

        # --- * Font settings
        font_settings = Frame(self.notebook)
        font_settings.columnconfigure(0, weight=1)
        self.notebook.add(font_settings,
                          text=_("Font"),
                          sticky="ewsn",
                          padding=4)

        # --- *-- title
        fonttitle_frame = Frame(font_settings)

        title_size = CONFIG.get("Font", "title_size")
        title_family = CONFIG.get("Font", "title_family")

        self.sampletitle = Label(fonttitle_frame,
                                 text=_("Sample text"),
                                 anchor="center",
                                 style="prev.TLabel",
                                 relief="groove")

        self.sampletitle.grid(row=2,
                              columnspan=2,
                              padx=4,
                              pady=6,
                              ipadx=4,
                              ipady=4,
                              sticky="eswn")
        self.fonts = list(set(font.families()))
        self.fonts.append("TkDefaultFont")
        self.fonts.sort()
        w = max([len(f) for f in self.fonts])
        self.sizes = [
            "%i" % i for i in (list(range(6, 17)) + list(range(18, 32, 2)))
        ]

        self.fonttitle_family = Combobox(fonttitle_frame,
                                         values=self.fonts,
                                         width=(w * 2) // 3,
                                         exportselection=False,
                                         validate="key")
        self._validate_title_size = self.register(
            lambda *args: self.validate_font_size(self.fonttitle_size, *args))
        self._validate_title_family = self.register(
            lambda *args: self.validate_font_family(self.fonttitle_family, *
                                                    args))
        self.fonttitle_family.configure(
            validatecommand=(self._validate_title_family, "%d", "%S", "%i",
                             "%s", "%V"))
        self.fonttitle_family.current(self.fonts.index(title_family))
        self.fonttitle_family.grid(row=0, column=0, padx=4, pady=4)
        self.fonttitle_size = Combobox(
            fonttitle_frame,
            values=self.sizes,
            width=5,
            exportselection=False,
            validate="key",
            validatecommand=(self._validate_title_size, "%d", "%P", "%V"))
        self.fonttitle_size.current(self.sizes.index(title_size))
        self.fonttitle_size.grid(row=0, column=1, padx=4, pady=4)

        frame_title_style = Frame(fonttitle_frame)
        frame_title_style.grid(row=1, columnspan=2, padx=4, pady=6)
        self.is_bold = Checkbutton(frame_title_style,
                                   text=_("Bold"),
                                   command=self.update_preview_title)
        self.is_italic = Checkbutton(frame_title_style,
                                     text=_("Italic"),
                                     command=self.update_preview_title)
        self.is_underlined = Checkbutton(frame_title_style,
                                         text=_("Underline"),
                                         command=self.update_preview_title)
        style = CONFIG.get("Font", "title_style")
        if "bold" in style:
            self.is_bold.state(("selected", ))
        if "italic" in style:
            self.is_italic.state(("selected", ))
        if "underline" in style:
            self.is_underlined.state(("selected", ))
        self.is_bold.pack(side="left")
        self.is_italic.pack(side="left")
        self.is_underlined.pack(side="left")

        self.update_preview_title()
        # --- *-- text
        size = CONFIG.get("Font", "text_size")
        family = CONFIG.get("Font", "text_family")

        font_frame = Frame(font_settings)
        self.sample = Label(font_frame,
                            text=_("Sample text"),
                            anchor="center",
                            style="prev.TLabel",
                            relief="groove")
        self.sample.grid(row=1,
                         columnspan=2,
                         padx=4,
                         pady=6,
                         ipadx=4,
                         ipady=4,
                         sticky="eswn")

        self.font_family = Combobox(font_frame,
                                    values=self.fonts,
                                    width=(w * 2) // 3,
                                    exportselection=False,
                                    validate="key")
        self._validate_family = self.register(
            lambda *args: self.validate_font_family(self.font_family, *args))
        self._validate_size = self.register(
            lambda *args: self.validate_font_size(self.font_size, *args))
        self.font_family.configure(validatecommand=(self._validate_family,
                                                    "%d", "%S", "%i", "%s",
                                                    "%V"))
        self.font_family.current(self.fonts.index(family))
        self.font_family.grid(row=0, column=0, padx=4, pady=4)
        self.font_size = Combobox(font_frame,
                                  values=self.sizes,
                                  width=5,
                                  exportselection=False,
                                  validate="key",
                                  validatecommand=(self._validate_size, "%d",
                                                   "%P", "%V"))
        self.font_size.current(self.sizes.index(size))
        self.font_size.grid(row=0, column=1, padx=4, pady=4)

        self.update_preview()

        # --- *-- placement
        Label(font_settings, text=_("Title")).grid(row=0,
                                                   padx=4,
                                                   pady=4,
                                                   sticky="w")
        fonttitle_frame.grid(row=1)
        Separator(font_settings, orient="horizontal").grid(row=2,
                                                           sticky="ew",
                                                           pady=10)
        Label(font_settings, text=_("Text")).grid(row=3,
                                                  padx=4,
                                                  pady=4,
                                                  sticky="w")
        font_frame.grid(row=4)

        # --- * Categories
        self.category_settings = CategoryManager(self.notebook, master)
        self.notebook.add(self.category_settings,
                          text=_("Categories"),
                          sticky="ewsn",
                          padding=4)
        # --- * Symbols
        symbols_settings = Frame(self.notebook)
        self.notebook.add(symbols_settings,
                          text=_("Symbols"),
                          sticky="ewsn",
                          padding=4)
        txt_frame = Frame(symbols_settings,
                          relief="sunken",
                          borderwidth=1,
                          style="text.TFrame")
        self.symbols = Text(txt_frame,
                            width=1,
                            height=1,
                            highlightthickness=0,
                            spacing2=5,
                            spacing1=5,
                            relief="flat",
                            padx=4,
                            pady=4,
                            font="%s %s" % (family.replace(" ", "\ "), size))
        self.symbols.insert("1.0", CONFIG.get("General", "symbols"))
        Label(symbols_settings, text=_("Available symbols")).pack(padx=4,
                                                                  pady=4)
        txt_frame.pack(fill="both", expand=True, padx=4, pady=4)
        self.symbols.pack(fill="both", expand=True)
        Button(symbols_settings, text=_('Reset'),
               command=self.reset_symbols).pack(padx=4, pady=4)

        # --- Ok/Cancel buttons
        Button(okcancel_frame, text="Ok", command=self.ok).grid(row=1,
                                                                column=0,
                                                                padx=4,
                                                                pady=10,
                                                                sticky="e")
        Button(okcancel_frame, text=_("Cancel"),
               command=self.destroy).grid(row=1,
                                          column=1,
                                          padx=4,
                                          pady=10,
                                          sticky="w")
        # --- bindings
        self.font_family.bind('<<ComboboxSelected>>', self.update_preview)
        self.font_family.bind('<Return>', self.update_preview)
        self.font_size.bind('<<ComboboxSelected>>',
                            self.update_preview,
                            add=True)
        self.font_size.bind('<Return>', self.update_preview, add=True)
        self.fonttitle_family.bind('<<ComboboxSelected>>',
                                   self.update_preview_title)
        self.fonttitle_size.bind('<<ComboboxSelected>>',
                                 self.update_preview_title,
                                 add=True)
        self.fonttitle_family.bind('<Return>', self.update_preview_title)
        self.fonttitle_size.bind('<Return>',
                                 self.update_preview_title,
                                 add=True)

    def reset_symbols(self):
        self.symbols.delete('1.0', 'end')
        self.symbols.insert('1.0', SYMBOLS)

    def cleanup(self):
        ''' Remove unused latex images '''
        self.master.cleanup()

    def validate_font_size(self, combo, d, ch, V):
        ''' Validation of the size entry content '''
        if d == '1':
            l = [i for i in self.sizes if i[:len(ch)] == ch]
            if l:
                i = self.sizes.index(l[0])
                combo.current(i)
                index = combo.index("insert")
                combo.selection_range(index + 1, "end")
                combo.icursor(index + 1)
            return ch.isdigit()
        else:
            return True

    def validate_font_family(self, combo, action, modif, pos, prev_txt, V):
        """ completion of the text in the path entry with existing
            folder/file names """
        try:
            sel = combo.selection_get()
            txt = prev_txt.replace(sel, '')
        except TclError:
            txt = prev_txt
        if action == "0":
            txt = txt[:int(pos)] + txt[int(pos) + 1:]
            return True
        else:
            txt = txt[:int(pos)] + modif + txt[int(pos):]
            l = [i for i in self.fonts if i[:len(txt)] == txt]
            if l:
                i = self.fonts.index(l[0])
                combo.current(i)
                index = combo.index("insert")
                combo.delete(0, "end")
                combo.insert(0, l[0].replace("\ ", " "))
                combo.selection_range(index + 1, "end")
                combo.icursor(index + 1)
                return True
            else:
                return False

    def ok(self):
        family = self.font_family.get()
        if family not in self.fonts:
            l = [i for i in self.fonts if i[:len(family)] == family]
            if l:
                family = l[0]
            else:
                family = 'TkDefaultFont'
        size = self.font_size.get()
        familytitle = self.fonttitle_family.get()
        if familytitle not in self.fonts:
            l = [i for i in self.fonts if i[:len(familytitle)] == familytitle]
            if l:
                familytitle = l[0]
            else:
                familytitle = 'TkDefaultFont'
        sizetitle = self.fonttitle_size.get()
        opacity = "%i" % float(self.opacity_scale.get())
        language = self.lang.get().lower()[:2]
        style = ""
        if self.is_bold.instate(("selected", )):
            style += "bold,"
        if self.is_italic.instate(("selected", )):
            style += "italic,"
        if self.is_underlined.instate(("selected", )):
            style += "underline,"
        if style:
            style = style[:-1]

        symbols = [
            l.strip() for l in self.symbols.get("1.0", "end").splitlines()
        ]

        CONFIG.set("General", "default_category",
                   self.category_settings.default_category.get().lower())
        CONFIG.set("General", "language", language)
        CONFIG.set("General", "opacity", opacity)
        CONFIG.set("General", "position", self.position.get())
        CONFIG.set("General", "buttons_position",
                   self.titlebar_disposition.get())
        CONFIG.set("General", "symbols", "".join(symbols))
        CONFIG.set("Font", "text_size", size)
        CONFIG.set("Font", "text_family", family)
        CONFIG.set("Font", "title_family", familytitle)
        CONFIG.set("Font", "title_size", sizetitle)
        CONFIG.set("Font", "title_style", style)

        col_changes = {}
        name_changes = {}
        for cat in self.category_settings.categories:
            new_name = self.category_settings.get_name(cat)
            if cat in CONFIG.options("Categories"):
                old_color = CONFIG.get("Categories", cat)
                new_color = COLORS[self.category_settings.get_color(cat)]
                if new_name != cat:
                    name_changes[cat] = new_name
                    CONFIG.remove_option("Categories", cat)
                    CONFIG.set("Categories", new_name, new_color)
                if old_color != new_color:
                    col_changes[new_name] = (old_color, new_color)
                    CONFIG.set("Categories", new_name, new_color)

            else:
                CONFIG.set("Categories", new_name,
                           COLORS[self.category_settings.get_color(cat)])
        save_config()
        self.changes = col_changes, name_changes
        self.destroy()

    def get_changes(self):
        return self.changes

    def translate(self):
        showinfo(
            "Information",
            _("The language setting will take effect after restarting the application"
              ),
            parent=self)

    def update_preview(self, event=None):
        family = self.font_family.get()
        size = self.font_size.get()
        self.sample.configure(font="%s %s" % (family.replace(" ", "\ "), size))

    def update_preview_title(self, event=None):
        family = self.fonttitle_family.get()
        size = self.fonttitle_size.get()
        config = "%s %s" % (family.replace(" ", "\ "), size)
        if self.is_bold.instate(("selected", )):
            config += " bold"
        if self.is_italic.instate(("selected", )):
            config += " italic"
        if self.is_underlined.instate(("selected", )):
            config += " underline"
        self.sampletitle.configure(font=config)

    def display_label(self, value):
        self.opacity_label.configure(text=" {val} %".format(
            val=int(float(value))))

    def quit(self):
        self.destroy()
Example #7
0
        if ram_display:
            ram.set_value(round(bytes_to_gb(virtual_memory().used), 1))
        else:
            ram.set_value(int(virtual_memory().percent))
        if hasattr(sensors_battery(), 'percent'):
            battery.set(int(sensors_battery().percent))
            if sensors_battery().power_plugged:
                if battery.get() == 100:
                    p_label.config(text=' Fully charged  ')
                else:
                    p_label.config(text='Charging ' +
                                   ('  ' * (3 - len(str(int(battery.get())))) +
                                    str(int(battery.get())) + '%'))
            else:
                p_label.config(text=f'  Battery ' +
                               ('  ' * (3 - len(str(int(battery.get())))) +
                                str(int(battery.get())) + '%  '))
        else:
            p_label.config(text='No batt present')
            battery.set('0')
        disk.set_value(int(disk_usage('/').percent))
        d = datetime.now()
        clock_hours.set_value(d.strftime('%I').lstrip('0'))
        clock_minutes.set_value(d.strftime('%M'))

        root.attributes('-topmost', top.instate(['selected']))
        root.update()
        sleep(0.01)
    except Exception:
        break