示例#1
0
 def update_style(self):
     bg = CONFIG.get(self.name, 'background', fallback='grey10')
     fg = CONFIG.get(self.name, 'foreground', fallback='white')
     active_bg = active_color(*self.winfo_rgb(bg))
     self.attributes('-alpha', CONFIG.get(self.name, 'alpha',
                                          fallback=0.85))
     self.configure(bg=bg)
     self._calendar.menu.configure(bg=bg,
                                   fg=fg,
                                   selectcolor=fg,
                                   activeforeground=fg,
                                   activebackground=active_bg)
     self.menu.configure(bg=bg,
                         fg=fg,
                         selectcolor=fg,
                         activeforeground=fg,
                         activebackground=active_bg)
     self.menu_pos.configure(bg=bg,
                             fg=fg,
                             selectcolor=fg,
                             activeforeground=fg,
                             activebackground=active_bg)
     keys = self._calendar.keys()
     opts = {
         opt: CONFIG.get('Calendar', opt)
         for opt in CONFIG.options('Calendar') if opt in keys
     }
     self._calendar.configure(**opts)
     self._calendar['font'] = CONFIG.get('Calendar', 'font')
     self._calendar.update_style()
示例#2
0
 def ting():
     """ joue le son marquant le changement de période """
     if not CONFIG.getboolean("Pomodoro", "mute", fallback=False):
         Popen([
             CONFIG.get("General", "soundplayer"),
             CONFIG.get("Pomodoro", "beep")
         ])
示例#3
0
    def _setup_style(self):
        # scrollbars
        for widget in ['Events', 'Tasks']:
            bg = CONFIG.get(widget, 'background', fallback='gray10')
            fg = CONFIG.get(widget, 'foreground', fallback='white')

            widget_bg = self.winfo_rgb(bg)
            widget_fg = tuple(
                round(c * 255 / 65535) for c in self.winfo_rgb(fg))
            active_bg = active_color(*widget_bg)
            active_bg2 = active_color(*active_color(*widget_bg, 'RGB'))

            slider_vert = Image.new('RGBA', (13, 28), active_bg)
            slider_vert.putalpha(self._slider_alpha)
            slider_vert_active = Image.new('RGBA', (13, 28), widget_fg)
            slider_vert_active.putalpha(self._slider_alpha)
            slider_vert_prelight = Image.new('RGBA', (13, 28), active_bg2)
            slider_vert_prelight.putalpha(self._slider_alpha)

            self._im_trough[widget].put(" ".join(
                ["{" + " ".join([bg] * 15) + "}"] * 15))
            self._im_slider_vert_active[widget].paste(slider_vert_active)
            self._im_slider_vert[widget].paste(slider_vert)
            self._im_slider_vert_prelight[widget].paste(slider_vert_prelight)

        for widget in self.widgets.values():
            widget.update_style()
示例#4
0
 def settings(self):
     splash_supp = CONFIG.get('General', 'splash_supported', fallback=True)
     dialog = Settings(self)
     self.wait_window(dialog)
     self._setup_style()
     if splash_supp != CONFIG.get('General', 'splash_supported'):
         for widget in self.widgets.values():
             widget.update_position()
示例#5
0
 def display_tasks(self, force=False):
     tasks = self.master.get_tasks()
     tasks.sort(key=lambda ev: ev['End'])
     self.display.configure(state='normal')
     self.display.delete('1.0', 'end')
     for ev in tasks:
         if not self.hide_completed or ev['Task'] != 'Completed':
             if ev["WholeDay"]:
                 end = format_date(ev['End'], locale=CONFIG.get("General", "locale"))
             else:
                 end = format_datetime(ev['End'], locale=CONFIG.get("General", "locale"))
             picto = TASK_STATE.get(ev['Task'], ev['Task'])
             txt = "\t%s\t%s [%s]\n" % (picto, ev['Summary'], end)
             self.display.insert('end', txt)
     self.display.configure(state='disabled')
示例#6
0
 def get_next_week_events(self):
     """Return events scheduled for the next 7 days """
     locale = CONFIG.get("General", "locale")
     next_ev = {}
     today = datetime.now().date()
     for d in range(7):
         day = today + timedelta(days=d)
         evts = self.widgets['Calendar'].get_events(day)
         if evts:
             evts = [self.events[iid] for iid in evts]
             evts.sort(key=lambda ev: ev.get_start_time())
             desc = []
             for ev in evts:
                 if ev["WholeDay"]:
                     date = ""
                 else:
                     date = "%s - %s " % (
                         format_time(ev['Start'], locale=locale),
                         format_time(ev['End'], locale=locale))
                 place = "(%s)" % ev['Place']
                 if place == "()":
                     place = ""
                 desc.append(("%s%s %s\n" % (date, ev['Summary'], place),
                              ev['Description']))
             next_ev[day.strftime('%A')] = desc
     return next_ev
示例#7
0
    def __init__(self, name, master=None, **kw):
        """
        Create a  desktop widget that sticks on the desktop.
        """
        Toplevel.__init__(self, master)
        self.name = name
        if CONFIG.getboolean('General', 'splash_supported', fallback=True):
            self.attributes('-type', 'splash')
        else:
            self.attributes('-type', 'toolbar')

        self.style = Style(self)

        self._position = StringVar(self, CONFIG.get(self.name, 'position'))
        self._position.trace_add(
            'write',
            lambda *x: CONFIG.set(self.name, 'position', self._position.get()))

        self.ewmh = EWMH()
        self.title('scheduler.{}'.format(self.name.lower()))

        self.withdraw()

        # control main menu checkbutton
        self.variable = BooleanVar(self, False)

        # --- menu
        self.menu = Menu(self, relief='sunken', activeborderwidth=0)
        self._populate_menu()

        self.create_content(**kw)

        self.x = None
        self.y = None

        # --- geometry
        geometry = CONFIG.get(self.name, 'geometry')
        self.update_idletasks()
        if geometry:
            self.geometry(geometry)
        self.update_idletasks()

        if CONFIG.getboolean(self.name, 'visible', fallback=True):
            self.show()

        # --- bindings
        self.bind('<Configure>', self._on_configure)
示例#8
0
 def update_style(self):
     bg = CONFIG.get(self.name, 'background', fallback='grey10')
     fg = CONFIG.get(self.name, 'foreground', fallback='white')
     active_bg = active_color(*self.winfo_rgb(bg))
     self.attributes('-alpha', CONFIG.get(self.name, 'alpha',
                                          fallback=0.85))
     self.configure(bg=bg)
     self.menu.configure(bg=bg,
                         fg=fg,
                         selectcolor=fg,
                         activeforeground=fg,
                         activebackground=active_bg)
     self.menu_pos.configure(bg=bg,
                             fg=fg,
                             selectcolor=fg,
                             activeforeground=fg,
                             activebackground=active_bg)
示例#9
0
 def values(self):
     """ return the values (Summary, Place, Start, End)
         to put in the main window treeview """
     locale = CONFIG.get("General", "locale")
     if self['WholeDay']:
         start = format_date(self['Start'], locale=locale)
         end = format_date(self['End'], locale=locale)
     else:
         start = format_datetime(self['Start'], locale=locale)
         end = format_datetime(self['End'], locale=locale)
     return self['Summary'], self['Place'], start, end, self['Category']
示例#10
0
 def update_style(self):
     self.attributes('-alpha', CONFIG.get(self.name, 'alpha', fallback=0.85))
     bg = CONFIG.get('Timer', 'background')
     fg = CONFIG.get('Timer', 'foreground')
     active_bg = active_color(*self.winfo_rgb(bg))
     self.configure(bg=bg)
     self.menu.configure(bg=bg, fg=fg, selectcolor=fg, activeforeground=fg,
                         activebackground=active_bg)
     self.menu_pos.configure(bg=bg, fg=fg, selectcolor=fg, activeforeground=fg,
                             activebackground=active_bg)
     self.display.configure(font=CONFIG.get('Timer', 'font_time'))
     self.intervals.configure(bg=bg, fg=fg,
                              font=CONFIG.get('Timer', 'font_intervals'))
     self.style.configure('timer.TButton', background=bg, relief='flat',
                          foreground=fg, borderwidth=0)
     self.style.configure('timer.TLabel', background=bg,
                          foreground=fg)
     self.style.configure('timer.TSizegrip', background=bg)
     self.style.map('timer.TSizegrip', background=[('active', active_bg)])
     self.style.map('timer.TButton', background=[('disabled', bg),
                                                 ('!disabled', 'active', active_bg)])
示例#11
0
 def update_style(self):
     bg = CONFIG.get('Events', 'background')
     fg = CONFIG.get('Events', 'foreground')
     active_bg = active_color(*self.winfo_rgb(bg))
     self.attributes('-alpha', CONFIG.get(self.name, 'alpha',
                                          fallback=0.85))
     self.style.configure('Events.TFrame', background=bg)
     self.style.configure('Events.TSizegrip', background=bg)
     self.style.configure('Events.TSeparator', background=bg)
     self.style.configure('Events.TLabel',
                          background=bg,
                          foreground=fg,
                          font=CONFIG.get('Events', 'font'))
     self.style.configure('title.Events.TLabel',
                          font=CONFIG.get('Events', 'font_title'))
     self.style.configure('day.Events.TLabel',
                          font=CONFIG.get('Events', 'font_day'))
     self.style.configure('Toggle', background=bg)
     self.configure(bg=bg)
     self.menu_pos.configure(bg=bg,
                             fg=fg,
                             selectcolor=fg,
                             activeforeground=fg,
                             activebackground=active_bg)
     self.menu.configure(bg=bg,
                         fg=fg,
                         selectcolor=fg,
                         activeforeground=fg,
                         activebackground=active_bg)
     self.canvas.configure(bg=bg)
示例#12
0
    def _init_events(self):
        self.frames[_('Events')].columnconfigure(0, weight=1)
        # --- Fonts
        frame_font = ttk.Frame(self.frames[_('Events')])
        frame_font.columnconfigure(2, weight=1)
        ttk.Label(frame_font, text=_('Font'),
                  style='title.TLabel').grid(row=0,
                                             column=0,
                                             sticky='w',
                                             padx=4,
                                             pady=4)
        # --- --- title
        ttk.Label(frame_font, style='subtitle.TLabel',
                  text=_('Title')).grid(row=1,
                                        column=0,
                                        sticky='ne',
                                        padx=4,
                                        pady=8)
        self.events_font_title = FontFrame(frame_font,
                                           CONFIG.get('Events', 'font_title'),
                                           True)
        self.events_font_title.grid(row=1, column=1, padx=4, pady=4)
        ttk.Separator(frame_font, orient='horizontal').grid(row=2,
                                                            columnspan=3,
                                                            padx=10,
                                                            pady=4,
                                                            sticky='ew')
        # --- --- day
        ttk.Label(frame_font, style='subtitle.TLabel',
                  text=_('Day')).grid(row=3,
                                      column=0,
                                      sticky='ne',
                                      padx=4,
                                      pady=8)
        self.events_font_day = FontFrame(frame_font,
                                         CONFIG.get('Events', 'font_day'),
                                         True)
        self.events_font_day.grid(row=3, column=1, padx=4, pady=4)
        ttk.Separator(frame_font, orient='horizontal').grid(row=4,
                                                            columnspan=3,
                                                            padx=10,
                                                            pady=4,
                                                            sticky='ew')
        # --- --- text
        ttk.Label(frame_font, style='subtitle.TLabel',
                  text=_('Text')).grid(row=5,
                                       column=0,
                                       sticky='ne',
                                       padx=4,
                                       pady=8)
        self.events_font = FontFrame(frame_font, CONFIG.get('Events', 'font'))
        self.events_font.grid(row=5, column=1, padx=4, pady=4)

        # --- opacity
        self.events_opacity = OpacityFrame(
            self.frames[_('Events')],
            CONFIG.getfloat("Events", "alpha", fallback=0.85))

        # --- colors
        frame_color = ttk.Frame(self.frames[_('Events')])
        ttk.Label(frame_color, text=_('Colors'),
                  style='title.TLabel').grid(row=0,
                                             column=0,
                                             sticky='w',
                                             padx=8,
                                             pady=4)
        self.events_bg = ColorFrame(frame_color,
                                    CONFIG.get('Events', 'background'),
                                    _('Background'))
        self.events_bg.grid(row=0, column=1, sticky='e', padx=8, pady=4)
        self.events_fg = ColorFrame(frame_color,
                                    CONFIG.get('Events', 'foreground'),
                                    _('Foreground'))
        self.events_fg.grid(row=0, column=2, sticky='e', padx=8, pady=4)

        # --- placement
        frame_font.grid(sticky='ew')
        ttk.Separator(self.frames[_('Events')],
                      orient='horizontal').grid(sticky='ew', pady=8)
        self.events_opacity.grid(sticky='w', padx=4)
        ttk.Separator(self.frames[_('Events')],
                      orient='horizontal').grid(sticky='ew', pady=8)
        frame_color.grid(sticky='w')
示例#13
0
    def _init_calendar(self):
        # --- general config
        general = ttk.Frame(self.frames[_('Calendar')], padding=4)
        general.columnconfigure(1, weight=1)
        self.frames[_('Calendar')].add(general, text=_('General'))
        # --- --- opacity
        self.cal_opacity = OpacityFrame(
            general, CONFIG.getfloat('Calendar', 'alpha', fallback=0.85))
        self.cal_opacity.grid(row=0, columnspan=2, sticky='w', padx=4)

        ttk.Separator(general, orient='horizontal').grid(row=1,
                                                         columnspan=2,
                                                         pady=10,
                                                         sticky='ew')
        # --- --- font
        ttk.Label(general, text=_('Font'),
                  style='title.TLabel').grid(row=2,
                                             sticky='nw',
                                             padx=4,
                                             pady=4)
        self.cal_font = FontFrame(general, CONFIG.get('Calendar', 'font'))
        self.cal_font.grid(row=2, column=1, sticky='w', padx=4, pady=4)

        # --- Colors
        frame_color = ttk.Frame(self.frames[_('Calendar')], padding=4)
        frame_color.columnconfigure(3, weight=1)
        self.frames[_('Calendar')].add(frame_color, text=_('Colors'))
        self.cal_colors = {}

        ttk.Label(frame_color, style='subtitle.TLabel',
                  text=_('General')).grid(row=0, column=0, sticky='w')
        self.cal_bg = ColorFrame(frame_color,
                                 CONFIG.get('Calendar', 'background'),
                                 _('Background'))
        self.cal_fg = ColorFrame(frame_color,
                                 CONFIG.get('Calendar', 'foreground'),
                                 _('Foreground'))
        self.cal_bd = ColorFrame(frame_color,
                                 CONFIG.get('Calendar', 'bordercolor'),
                                 _('Border'))
        self.cal_bg.grid(row=0, column=1, sticky='e', padx=8, pady=4)
        self.cal_fg.grid(row=0, column=2, sticky='e', padx=8, pady=4)
        self.cal_bd.grid(row=1, column=1, sticky='e', padx=8, pady=4)

        cal_colors = {
            'normal': _('Normal day'),
            'weekend': _('Weekend'),
            'othermonth': _('Other month day'),
            'othermonthwe': _('Other month weekend'),
            'select': _('Selected day'),
            'headers': _('Headers'),
            'tooltip': _('Tooltip')
        }

        for i, (name, label) in enumerate(cal_colors.items()):
            bg = ColorFrame(frame_color,
                            CONFIG.get('Calendar', name + 'background'),
                            _('Background'))
            fg = ColorFrame(frame_color,
                            CONFIG.get('Calendar', name + 'foreground'),
                            _('Foreground'))
            self.cal_colors[name + 'background'] = bg
            self.cal_colors[name + 'foreground'] = fg

            ttk.Separator(frame_color, orient='horizontal').grid(row=2 + 2 * i,
                                                                 columnspan=4,
                                                                 pady=10,
                                                                 sticky='ew')
            ttk.Label(frame_color,
                      style='subtitle.TLabel',
                      wraplength=110,
                      text=label).grid(row=3 + 2 * i, column=0, sticky='w')
            bg.grid(row=3 + 2 * i, column=1, sticky='e', padx=8, pady=4)
            fg.grid(row=3 + 2 * i, column=2, sticky='e', padx=8, pady=4)

        # --- Categories
        categories = ttk.Frame(self.frames[_('Calendar')], padding=4)
        categories.columnconfigure(0, weight=1)
        categories.rowconfigure(0, weight=1)
        self.frames[_('Calendar')].add(categories, text=_('Event categories'))

        can = tk.Canvas(categories,
                        bg=self['bg'],
                        highlightthickness=0,
                        width=1,
                        relief='flat')
        scroll = AutoScrollbar(categories,
                               orient='vertical',
                               command=can.yview)
        can.configure(yscrollcommand=scroll.set)
        can.grid(row=0, column=0, sticky='ewns')
        scroll.grid(row=0, column=1, sticky='ns')

        ttk.Button(categories, image=self._im_plus,
                   command=self.add_cat).grid(row=1,
                                              column=0,
                                              sticky='w',
                                              pady=4)

        self.cat_frame = ttk.Frame(can)
        can.create_window(0, 0, anchor='nw', window=self.cat_frame)

        self.cats = {}
        for i, cat in enumerate(CONFIG.options("Categories")):
            l = ttk.Label(self.cat_frame, text=cat, style='subtitle.TLabel')
            col = CONFIG.get('Categories', cat).split(', ')
            bg = ColorFrame(self.cat_frame, col[1].strip(), _('Background'))
            fg = ColorFrame(self.cat_frame, col[0].strip(), _('Foreground'))
            b = ttk.Button(self.cat_frame,
                           image=self._im_moins,
                           padding=2,
                           command=lambda c=cat: self.del_cat(c))
            self.cats[cat] = [l, bg, fg, b]
            l.grid(row=i, column=0, sticky='e', padx=4, pady=4)
            bg.grid(row=i, column=1, sticky='e', padx=4, pady=4)
            fg.grid(row=i, column=2, sticky='e', padx=4, pady=4)
            b.grid(row=i, column=3, sticky='e', padx=4, pady=4)
        self.update_idletasks()
        can.configure(width=self.cat_frame.winfo_reqwidth())
        can.configure(scrollregion=can.bbox('all'))
        can.bind('<4>', lambda e: self._scroll(e, -1))
        can.bind('<5>', lambda e: self._scroll(e, 1))
        self.cat_frame.bind(
            '<Configure>',
            lambda e: can.configure(scrollregion=can.bbox('all')))
示例#14
0
    def _init_reminders(self):
        # --- window

        def toggle_window():
            b = 'selected' in self.reminders_window.state()
            state = [b * '!' + 'disabled']
            label.state(state)
            self.reminders_timeout.state(state)
            self.reminders_blink.state(state)
            self.reminders_sound.state(state)

        frame_window = ttk.Frame(self.frames[_('Reminders')])
        frame_window.columnconfigure(0, weight=1)
        self.reminders_window = ttk.Checkbutton(frame_window,
                                                text=_('Banner'),
                                                style='title.TCheckbutton',
                                                command=toggle_window)
        self.reminders_window.grid(sticky='w',
                                   row=0,
                                   columnspan=2,
                                   column=0,
                                   pady=4)
        self.reminders_window.state(
            ('!alternate', '!' *
             (not CONFIG.getboolean('Reminders', 'window')) + 'selected'))
        # --- --- timeout
        frame_timeout = ttk.Frame(frame_window)
        frame_timeout.grid(sticky='w', padx=(16, 4), pady=4)
        label = ttk.Label(frame_timeout, text=_('Timeout (min)'))
        label.pack(side='left')
        self.reminders_timeout = ttk.Entry(frame_timeout,
                                           width=5,
                                           justify='center',
                                           validate='key',
                                           validatecommand=(self._only_nb,
                                                            '%P'))
        self.reminders_timeout.insert(0, CONFIG.get('Reminders', 'timeout'))
        self.reminders_timeout.pack(side='left', padx=4)
        # --- --- colors
        frame_color = ttk.Frame(frame_window)
        frame_color.grid(sticky='w', padx=(16, 4), pady=4)
        self.reminders_window_bg = ColorFrame(
            frame_color, CONFIG.get('Reminders', 'window_bg'), _('Background'))
        self.reminders_window_bg.pack(side='left', padx=(0, 4))
        self.reminders_window_fg = ColorFrame(
            frame_color, CONFIG.get('Reminders', 'window_fg'), _('Foreground'))
        self.reminders_window_fg.pack(side='left', padx=(4, 0))
        # --- --- opacity
        self.reminders_opacity = OpacityFrame(frame_window,
                                              CONFIG.getfloat('Reminders',
                                                              'window_alpha',
                                                              fallback=0.75),
                                              style='TLabel')
        self.reminders_opacity.grid(sticky='w', padx=(16, 4), pady=4)

        ttk.Separator(frame_window, orient='horizontal').grid(sticky='ew',
                                                              padx=(16, 10),
                                                              pady=10)

        # --- --- blink
        frame_blink = ttk.Frame(frame_window)
        frame_blink.grid(sticky='w', padx=(16, 4), pady=4)

        def toggle_blink():
            b = 'selected' in self.reminders_blink.state()
            state = [b * '!' + 'disabled']
            self.reminders_window_bg_alt.state(state)
            self.reminders_window_fg_alt.state(state)

        self.reminders_blink = ttk.Checkbutton(frame_blink,
                                               text=_('Blink'),
                                               command=toggle_blink)
        self.reminders_blink.pack(anchor='nw')
        self.reminders_blink.state(
            ('!alternate',
             '!' * (not CONFIG.getboolean('Reminders', 'blink')) + 'selected'))
        self.reminders_window_bg_alt = ColorFrame(
            frame_blink, CONFIG.get('Reminders', 'window_bg_alternate'),
            _('Alternate Background'))
        self.reminders_window_bg_alt.pack(side='left', padx=(16, 4))
        self.reminders_window_fg_alt = ColorFrame(
            frame_blink, CONFIG.get('Reminders', 'window_fg_alternate'),
            _('Alternate Foreground'))
        self.reminders_window_fg_alt.pack(side='left', padx=10)
        toggle_blink()

        ttk.Separator(frame_window, orient='horizontal').grid(sticky='ew',
                                                              padx=(16, 10),
                                                              pady=10)
        # --- --- alarm

        self.reminders_sound = SoundFrame(frame_window,
                                          CONFIG.get('Reminders', 'alarm'),
                                          CONFIG.get('Reminders', 'mute'),
                                          _('Alarm'))
        self.reminders_sound.grid(sticky='ew', padx=(16, 10), pady=4)

        # --- notif
        frame_notif = ttk.Frame(self.frames[_('Reminders')])
        self.reminders_notif = ttk.Checkbutton(frame_notif,
                                               text=_('Notification'),
                                               style='title.TCheckbutton')
        self.reminders_notif.grid(sticky='w', pady=4)
        self.reminders_notif.state(
            ('!alternate',
             '!' * (not CONFIG.getboolean('Reminders', 'notification')) +
             'selected'))

        # --- placement
        frame_window.pack(anchor='nw', fill='x')
        ttk.Separator(self.frames[_('Reminders')],
                      orient='horizontal').pack(fill='x', pady=10)
        frame_notif.pack(anchor='nw')
示例#15
0
    def _init_general(self):
        self.frames[_('General')].columnconfigure(0, weight=1)
        # --- variables
        self.gui = tk.StringVar(self,
                                CONFIG.get("General", "trayicon").capitalize())
        self.lang = tk.StringVar(self,
                                 LANGUAGES[CONFIG.get("General", "language")])

        # --- Langue
        lang_frame = ttk.Frame(self.frames[_('General')])

        ttk.Label(lang_frame, text=_("Language")).pack(side="left")
        languages = list(REV_LANGUAGES)
        self.cb_lang = ttk.Combobox(lang_frame,
                                    textvariable=self.lang,
                                    state='readonly',
                                    style='menu.TCombobox',
                                    exportselection=False,
                                    width=len(max(languages, key=len)) + 1,
                                    values=languages)
        self.cb_lang.pack(side="left", padx=4)
        self.cb_lang.bind('<<ComboboxSelected>>', self.change_langue)
        # --- gui toolkit
        frame_gui = ttk.Frame(self.frames[_('General')])
        ttk.Label(
            frame_gui,
            text=_("GUI Toolkit for the system tray icon")).pack(side="left")
        self.cb_gui = ttk.Combobox(
            frame_gui,
            textvariable=self.gui,
            state='readonly',
            style='menu.TCombobox',
            exportselection=False,
            width=4,
            values=[t.capitalize() for (t, b) in TOOLKITS.items() if b])
        self.cb_gui.pack(side="left", padx=4)
        self.cb_gui.bind('<<ComboboxSelected>>', self.change_gui)
        # --- Update checks
        # self.confirm_update = ttk.Checkbutton(self.frames[_('General')],
        # text=_("Check for updates on start-up"))
        # if CONFIG.getboolean('General', 'check_update', fallback=True):
        # self.confirm_update.state(('selected', '!alternate'))
        # else:
        # self.confirm_update.state(('!selected', '!alternate'))

        # --- eyes
        frame_eyes = ttk.Frame(self.frames[_('General')])
        ttk.Label(frame_eyes, text=_("Eyes' rest"),
                  style='title.TLabel').grid(sticky='w', padx=4, pady=4)
        ttk.Label(frame_eyes,
                  text=_("Interval between two eyes' rest (min)")).grid(
                      row=1, column=0, sticky='w', padx=4, pady=4)
        self.eyes_interval = ttk.Entry(frame_eyes,
                                       width=4,
                                       justify='center',
                                       validate='key',
                                       validatecommand=(self._only_nb, '%P'))
        self.eyes_interval.insert(
            0, CONFIG.get("General", "eyes_interval", fallback='20'))
        self.eyes_interval.grid(row=1, column=1, sticky='w', padx=4, pady=4)

        # --- Splash supported
        self.splash_support = ttk.Checkbutton(
            self.frames[_('General')],
            text=_("Check this box if the widgets disappear when you click"))
        if not CONFIG.getboolean('General', 'splash_supported', fallback=True):
            self.splash_support.state(('selected', '!alternate'))
        else:
            self.splash_support.state(('!selected', '!alternate'))

        # --- Maintenance
        frame_maintenance = ttk.Frame(self.frames[_('General')])
        ttk.Label(frame_maintenance,
                  text=_("Maintenance"),
                  style='title.TLabel').grid(sticky='w', padx=4, pady=4)
        ttk.Label(frame_maintenance,
                  text=_("Delete all outdated events")).grid(row=1,
                                                             column=0,
                                                             sticky='w',
                                                             padx=4,
                                                             pady=4)
        ttk.Button(frame_maintenance,
                   image=self._im_cleanup,
                   padding=1,
                   command=self.cleanup).grid(row=1,
                                              column=1,
                                              sticky='w',
                                              padx=4,
                                              pady=4)
        ttk.Label(
            frame_maintenance,
            text=
            _("Refresh scheduled reminders\n(needed after APScheduler's updates)"
              )).grid(row=2, column=0, sticky='w', padx=4, pady=4)
        ttk.Button(frame_maintenance,
                   image=self._im_refresh,
                   padding=1,
                   command=self.refresh).grid(row=2,
                                              column=1,
                                              sticky='w',
                                              padx=4,
                                              pady=4)

        # --- placement
        ttk.Label(self.frames[_('General')],
                  text=_("Interface"),
                  style='title.TLabel').grid(sticky='w', pady=4)
        lang_frame.grid(pady=4, sticky="ew")
        frame_gui.grid(pady=4, sticky="ew")
        # self.confirm_update.grid(pady=4, sticky='w')
        self.splash_support.grid(pady=4, sticky='w')
        ttk.Separator(self.frames[_('General')],
                      orient='horizontal').grid(sticky='ew', pady=10)
        frame_eyes.grid(pady=4, sticky="ew")
        ttk.Separator(self.frames[_('General')],
                      orient='horizontal').grid(sticky='ew', pady=10)
        frame_maintenance.grid(pady=4, sticky="ew")
示例#16
0
 def to_datetime(date):
     date_format = get_date_format("short", CONFIG.get("General",
                                                       "locale")).pattern
     dayfirst = date_format.startswith("d")
     yearfirst = date_format.startswith("y")
     return parse(date, dayfirst=dayfirst, yearfirst=yearfirst)
示例#17
0
    def valide(self):
        """Update config and return whether the pomodor timer should be stopped."""
        old_tpsw = CONFIG.getint("Pomodoro", "work_time")
        old_tpsp = CONFIG.getint("Pomodoro", "break_time")
        old_tpsr = CONFIG.getint("Pomodoro", "rest_time")
        try:
            tpsw = int(self.travail.get())
        except ValueError:  # empty entry
            tpsw = 0
        if tpsw == 0:
            tpsw = old_tpsw
        try:
            tpsp = int(self.pause.get())
        except ValueError:
            tpsp = 0
        if tpsp == 0:
            tpsp = old_tpsp
        try:
            tpsr = int(self.rest.get())
        except ValueError:
            tpsr = 0
        if tpsr == 0:
            tpsr = old_tpsr

        sound, mute = self.sound.get()
        font_prop = self.font.get_font()
        font = "{} {}".format(font_prop['family'].replace(' ', '\ '),
                              font_prop['size'])
        try:
            legend_rows = int(self.legend_row_nb.get())
        except ValueError:
            legend_rows = 0
        if legend_rows == 0:
            legend_rows = CONFIG.getint("Pomodoro", "legend_max_height")

        if not os.path.exists(sound):
            showerror(
                _("Error"),
                _("The file {filepath} does not exists, the old file will be used."
                  ).format(filepath=sound))
            sound = CONFIG.get("Pomodoro", "beep")

        CONFIG.set("Pomodoro", "alpha", str(self.opacity.get_opacity()))
        CONFIG.set("Pomodoro", "font", font)
        CONFIG.set("Pomodoro", "background", self.bg.get_color())
        CONFIG.set("Pomodoro", "foreground", self.fg.get_color())
        CONFIG.set("Pomodoro", "work_time", str(tpsw))
        CONFIG.set("Pomodoro", "work_bg", self.work_bg.get_color())
        CONFIG.set("Pomodoro", "work_fg", self.work_fg.get_color())
        CONFIG.set("Pomodoro", "break_time", str(tpsp))
        CONFIG.set("Pomodoro", "break_bg", self.break_bg.get_color())
        CONFIG.set("Pomodoro", "break_fg", self.break_fg.get_color())
        CONFIG.set("Pomodoro", "rest_time", str(tpsr))
        CONFIG.set("Pomodoro", "rest_bg", self.rest_bg.get_color())
        CONFIG.set("Pomodoro", "rest_fg", self.rest_fg.get_color())
        CONFIG.set("Pomodoro", "beep", sound)
        CONFIG.set("Pomodoro", "mute", str(mute))
        CONFIG.set("Pomodoro", "legend_max_height", str(legend_rows))
        for task, widget in self.tasks.items():
            CONFIG.set("PomodoroTasks", task, widget.get_color())

        return old_tpsw != tpsw or old_tpsp != tpsp or old_tpsr != old_tpsr
示例#18
0
    def plot_stats(self):
        tasks = [t.capitalize() for t in CONFIG.options("PomodoroTasks")]
        tasks.sort()
        coul = [CONFIG.get("PomodoroTasks", task) for task in tasks]
        stats_x = []
        stats_y = []
        demain = dt.date.today().toordinal() + 1
        min_x = demain

        # récupération des données
        no_data = True
        db = sqlite3.connect(PATH_STATS)
        cursor = db.cursor()
        for i, task in enumerate(tasks):
            name = task.lower().replace(' ', '_')
            try:
                cursor.execute('SELECT date, work FROM {}'.format(scrub(name)))
                data = cursor.fetchall()
            except sqlite3.OperationalError:
                # task was never worked
                stats_x.append([demain - 1])
                stats_y.append(np.array([0]))
            else:
                no_data = False
                x = []
                y = []
                for date, work in data:
                    x.append(date)
                    y.append(work / 60)
                min_x = min(x[0], min_x)
                stats_x.append(x)
                stats_y.append(y)
        db.close()

        # plots
        xx = np.arange(min_x, demain, dtype=float)
        yy0 = np.zeros_like(xx)  # pour empiler les stats
        if not no_data:
            for (i, task), x, y in zip(enumerate(tasks), stats_x, stats_y):
                yy = np.array([], dtype=int)
                # comble les trous par des 0
                # ainsi, les jours où une tâche n'a pas été travaillée correspondent
                # à des 0 sur le graph
                xxx = np.arange(min_x, x[0])
                yy = np.concatenate((yy, np.zeros_like(xxx, dtype=int)))
                for j in range(len(x) - 1):
                    xxx = np.arange(x[j], x[j + 1])
                    yy = np.concatenate(
                        (yy, [y[j]], np.zeros(len(xxx) - 1, dtype=int)))
                xxx = np.arange(x[-1], demain)
                yy = np.concatenate(
                    (yy, [y[-1]], np.zeros(len(xxx) - 1, dtype=int)))
                self.ax.bar(xx,
                            yy,
                            bottom=yy0,
                            width=0.8,
                            label=task,
                            color=coul[i])
                yy0 += yy
            self.ax.xaxis.set_major_formatter(DateFormatter('%x'))
            self.ax.set_xlim(min_x - 0.5, demain - 0.5)
            self.ax.set_ylabel(_("time (h)"))
            self.ax.set_xlabel(_("date"))
            self.ax.xaxis_date()
            rows = CONFIG.getint("Pomodoro", "legend_max_height", fallback=6)
            ncol = int(np.ceil(len(tasks) / rows))

            lgd = self.ax.legend(fontsize=10,
                                 ncol=ncol,
                                 columnspacing=0.7,
                                 handlelength=0.9,
                                 handletextpad=0.5)
            try:
                lgd.set_draggable(True)
            except AttributeError:
                lgd.draggable(True)
            max_y = yy0.max()
            self.ax.set_ylim(0, max_y + 0.1 * max_y)
            self.ax.tick_params('x', rotation=70)
            self.update_idletasks()
            self.fig.tight_layout()
        self.figAgg.draw()
        self.toolbar.push_current()
        self.ax.set_xlim(max(demain - 30, min_x) - 0.5, demain - 0.5)
        self.toolbar.push_current()
        self.figAgg.draw()
示例#19
0
    def __init__(self):
        Tk.__init__(self, className='Scheduler')
        logging.info('Start')
        self.protocol("WM_DELETE_WINDOW", self.hide)
        self._visible = BooleanVar(self, False)
        self.withdraw()

        self.icon_img = PhotoImage(master=self, file=ICON48)
        self.iconphoto(True, self.icon_img)

        # --- systray icon
        self.icon = TrayIcon(ICON, fallback_icon_path=ICON_FALLBACK)

        # --- menu
        self.menu_widgets = SubMenu(parent=self.icon.menu)
        self.menu_eyes = Eyes(self.icon.menu, self)
        self.icon.menu.add_checkbutton(label=_('Manager'),
                                       command=self.display_hide)
        self.icon.menu.add_cascade(label=_('Widgets'), menu=self.menu_widgets)
        self.icon.menu.add_cascade(label=_("Eyes' rest"), menu=self.menu_eyes)
        self.icon.menu.add_command(label=_('Settings'), command=self.settings)
        self.icon.menu.add_separator()
        self.icon.menu.add_command(label=_('About'),
                                   command=lambda: About(self))
        self.icon.menu.add_command(label=_('Quit'), command=self.exit)
        self.icon.bind_left_click(lambda: self.display_hide(toggle=True))

        add_trace(self._visible, 'write', self._visibility_trace)

        self.menu = Menu(self, tearoff=False)
        self.menu.add_command(label=_('Edit'), command=self._edit_menu)
        self.menu.add_command(label=_('Delete'), command=self._delete_menu)
        self.right_click_iid = None

        self.menu_task = Menu(self.menu, tearoff=False)
        self._task_var = StringVar(self)
        menu_in_progress = Menu(self.menu_task, tearoff=False)
        for i in range(0, 110, 10):
            prog = '{}%'.format(i)
            menu_in_progress.add_radiobutton(label=prog,
                                             value=prog,
                                             variable=self._task_var,
                                             command=self._set_progress)
        for state in ['Pending', 'Completed', 'Cancelled']:
            self.menu_task.add_radiobutton(label=_(state),
                                           value=state,
                                           variable=self._task_var,
                                           command=self._set_progress)
        self._img_dot = tkPhotoImage(master=self)
        self.menu_task.insert_cascade(1,
                                      menu=menu_in_progress,
                                      compound='left',
                                      label=_('In Progress'),
                                      image=self._img_dot)
        self.title('Scheduler')
        self.rowconfigure(1, weight=1)
        self.columnconfigure(0, weight=1)

        self.scheduler = BackgroundScheduler(coalesce=False,
                                             misfire_grace_time=86400)
        self.scheduler.add_jobstore('sqlalchemy',
                                    url='sqlite:///%s' % JOBSTORE)
        self.scheduler.add_jobstore('memory', alias='memo')
        # --- style
        self.style = Style(self)
        self.style.theme_use("clam")
        self.style.configure('title.TLabel', font='TkdefaultFont 10 bold')
        self.style.configure('title.TCheckbutton',
                             font='TkdefaultFont 10 bold')
        self.style.configure('subtitle.TLabel', font='TkdefaultFont 9 bold')
        self.style.configure('white.TLabel', background='white')
        self.style.configure('border.TFrame',
                             background='white',
                             border=1,
                             relief='sunken')
        self.style.configure("Treeview.Heading", font="TkDefaultFont")
        bgc = self.style.lookup("TButton", "background")
        fgc = self.style.lookup("TButton", "foreground")
        bga = self.style.lookup("TButton", "background", ("active", ))
        self.style.map('TCombobox',
                       fieldbackground=[('readonly', 'white'),
                                        ('readonly', 'focus', 'white')],
                       background=[("disabled", "active", "readonly", bgc),
                                   ("!disabled", "active", "readonly", bga)],
                       foreground=[('readonly', '!disabled', fgc),
                                   ('readonly', '!disabled', 'focus', fgc),
                                   ('readonly', 'disabled', 'gray40'),
                                   ('readonly', 'disabled', 'focus', 'gray40')
                                   ],
                       arrowcolor=[("disabled", "gray40")])
        self.style.configure('menu.TCombobox',
                             foreground=fgc,
                             background=bgc,
                             fieldbackground=bgc)
        self.style.map('menu.TCombobox',
                       fieldbackground=[('readonly', bgc),
                                        ('readonly', 'focus', bgc)],
                       background=[("disabled", "active", "readonly", bgc),
                                   ("!disabled", "active", "readonly", bga)],
                       foreground=[('readonly', '!disabled', fgc),
                                   ('readonly', '!disabled', 'focus', fgc),
                                   ('readonly', 'disabled', 'gray40'),
                                   ('readonly', 'disabled', 'focus', 'gray40')
                                   ],
                       arrowcolor=[("disabled", "gray40")])
        self.style.map('DateEntry', arrowcolor=[("disabled", "gray40")])
        self.style.configure('cal.TFrame', background='#424242')
        self.style.configure('month.TLabel',
                             background='#424242',
                             foreground='white')
        self.style.configure('R.TButton',
                             background='#424242',
                             arrowcolor='white',
                             bordercolor='#424242',
                             lightcolor='#424242',
                             darkcolor='#424242')
        self.style.configure('L.TButton',
                             background='#424242',
                             arrowcolor='white',
                             bordercolor='#424242',
                             lightcolor='#424242',
                             darkcolor='#424242')
        active_bg = self.style.lookup('TEntry', 'selectbackground',
                                      ('focus', ))
        self.style.map('R.TButton',
                       background=[('active', active_bg)],
                       bordercolor=[('active', active_bg)],
                       darkcolor=[('active', active_bg)],
                       lightcolor=[('active', active_bg)])
        self.style.map('L.TButton',
                       background=[('active', active_bg)],
                       bordercolor=[('active', active_bg)],
                       darkcolor=[('active', active_bg)],
                       lightcolor=[('active', active_bg)])
        self.style.configure('txt.TFrame', background='white')
        self.style.layout('down.TButton', [('down.TButton.downarrow', {
            'side': 'right',
            'sticky': 'ns'
        })])
        self.style.map('TRadiobutton',
                       indicatorforeground=[('disabled', 'gray40')])
        self.style.map('TCheckbutton',
                       indicatorforeground=[('disabled', 'gray40')],
                       indicatorbackground=[
                           ('pressed', '#dcdad5'),
                           ('!disabled', 'alternate', 'white'),
                           ('disabled', 'alternate', '#a0a0a0'),
                           ('disabled', '#dcdad5')
                       ])
        self.style.map('down.TButton', arrowcolor=[("disabled", "gray40")])

        self.style.map('TMenubutton',
                       arrowcolor=[('disabled',
                                    self.style.lookup('TMenubutton',
                                                      'foreground',
                                                      ['disabled']))])
        bg = self.style.lookup('TFrame', 'background', default='#ececec')
        self.configure(bg=bg)
        self.option_add('*Toplevel.background', bg)
        self.option_add('*Menu.background', bg)
        self.option_add('*Menu.tearOff', False)
        # toggle text
        self._open_image = PhotoImage(name='img_opened',
                                      file=IM_OPENED,
                                      master=self)
        self._closed_image = PhotoImage(name='img_closed',
                                        file=IM_CLOSED,
                                        master=self)
        self._open_image_sel = PhotoImage(name='img_opened_sel',
                                          file=IM_OPENED_SEL,
                                          master=self)
        self._closed_image_sel = PhotoImage(name='img_closed_sel',
                                            file=IM_CLOSED_SEL,
                                            master=self)
        self.style.element_create(
            "toggle",
            "image",
            "img_closed", ("selected", "!disabled", "img_opened"),
            ("active", "!selected", "!disabled", "img_closed_sel"),
            ("active", "selected", "!disabled", "img_opened_sel"),
            border=2,
            sticky='')
        self.style.map('Toggle', background=[])
        self.style.layout('Toggle', [('Toggle.border', {
            'children': [('Toggle.padding', {
                'children': [('Toggle.toggle', {
                    'sticky': 'nswe'
                })],
                'sticky': 'nswe'
            })],
            'sticky':
            'nswe'
        })])
        # toggle sound
        self._im_sound = PhotoImage(master=self, file=IM_SOUND)
        self._im_mute = PhotoImage(master=self, file=IM_MUTE)
        self._im_sound_dis = PhotoImage(master=self, file=IM_SOUND_DIS)
        self._im_mute_dis = PhotoImage(master=self, file=IM_MUTE_DIS)
        self.style.element_create(
            'mute',
            'image',
            self._im_sound, ('selected', '!disabled', self._im_mute),
            ('selected', 'disabled', self._im_mute_dis),
            ('!selected', 'disabled', self._im_sound_dis),
            border=2,
            sticky='')
        self.style.layout('Mute', [('Mute.border', {
            'children': [('Mute.padding', {
                'children': [('Mute.mute', {
                    'sticky': 'nswe'
                })],
                'sticky': 'nswe'
            })],
            'sticky':
            'nswe'
        })])
        self.style.configure('Mute', relief='raised')
        # widget scrollbar
        self._im_trough = {}
        self._im_slider_vert = {}
        self._im_slider_vert_prelight = {}
        self._im_slider_vert_active = {}
        self._slider_alpha = Image.open(IM_SCROLL_ALPHA)
        for widget in ['Events', 'Tasks']:
            bg = CONFIG.get(widget, 'background', fallback='gray10')
            fg = CONFIG.get(widget, 'foreground')

            widget_bg = self.winfo_rgb(bg)
            widget_fg = tuple(
                round(c * 255 / 65535) for c in self.winfo_rgb(fg))
            active_bg = active_color(*widget_bg)
            active_bg2 = active_color(*active_color(*widget_bg, 'RGB'))

            slider_vert = Image.new('RGBA', (13, 28), active_bg)
            slider_vert_active = Image.new('RGBA', (13, 28), widget_fg)
            slider_vert_prelight = Image.new('RGBA', (13, 28), active_bg2)

            self._im_trough[widget] = tkPhotoImage(width=15,
                                                   height=15,
                                                   master=self)
            self._im_trough[widget].put(" ".join(
                ["{" + " ".join([bg] * 15) + "}"] * 15))
            self._im_slider_vert_active[widget] = PhotoImage(
                slider_vert_active, master=self)
            self._im_slider_vert[widget] = PhotoImage(slider_vert, master=self)
            self._im_slider_vert_prelight[widget] = PhotoImage(
                slider_vert_prelight, master=self)
            self.style.element_create('%s.Vertical.Scrollbar.trough' % widget,
                                      'image', self._im_trough[widget])
            self.style.element_create(
                '%s.Vertical.Scrollbar.thumb' % widget,
                'image',
                self._im_slider_vert[widget],
                ('pressed', '!disabled', self._im_slider_vert_active[widget]),
                ('active', '!disabled', self._im_slider_vert_prelight[widget]),
                border=6,
                sticky='ns')
            self.style.layout(
                '%s.Vertical.TScrollbar' % widget,
                [('%s.Vertical.Scrollbar.trough' % widget, {
                    'children': [('%s.Vertical.Scrollbar.thumb' % widget, {
                        'expand': '1'
                    })],
                    'sticky':
                    'ns'
                })])
        # --- tree
        columns = {
            _('Summary'): ({
                'stretch': True,
                'width': 300
            }, lambda: self._sort_by_desc(_('Summary'), False)),
            _('Place'): ({
                'stretch': True,
                'width': 200
            }, lambda: self._sort_by_desc(_('Place'), False)),
            _('Start'): ({
                'stretch': False,
                'width': 150
            }, lambda: self._sort_by_date(_('Start'), False)),
            _('End'): ({
                'stretch': False,
                'width': 150
            }, lambda: self._sort_by_date(_("End"), False)),
            _('Category'): ({
                'stretch': False,
                'width': 100
            }, lambda: self._sort_by_desc(_('Category'), False))
        }
        self.tree = Treeview(self, show="headings", columns=list(columns))
        for label, (col_prop, cmd) in columns.items():
            self.tree.column(label, **col_prop)
            self.tree.heading(label, text=label, anchor="w", command=cmd)
        self.tree.tag_configure('0', background='#ececec')
        self.tree.tag_configure('1', background='white')
        self.tree.tag_configure('outdated', foreground='red')

        scroll = AutoScrollbar(self,
                               orient='vertical',
                               command=self.tree.yview)
        self.tree.configure(yscrollcommand=scroll.set)

        # --- toolbar
        toolbar = Frame(self)
        self.img_plus = PhotoImage(master=self, file=IM_ADD)
        Button(toolbar, image=self.img_plus, padding=1,
               command=self.add).pack(side="left", padx=4)
        Label(toolbar, text=_("Filter by")).pack(side="left", padx=4)
        # --- TODO: add filter by start date (after date)
        self.filter_col = Combobox(
            toolbar,
            state="readonly",
            # values=("",) + self.tree.cget('columns')[1:],
            values=("", _("Category")),
            exportselection=False)
        self.filter_col.pack(side="left", padx=4)
        self.filter_val = Combobox(toolbar,
                                   state="readonly",
                                   exportselection=False)
        self.filter_val.pack(side="left", padx=4)
        Button(toolbar,
               text=_('Delete All Outdated'),
               padding=1,
               command=self.delete_outdated_events).pack(side="right", padx=4)

        # --- grid
        toolbar.grid(row=0, columnspan=2, sticky='we', pady=4)
        self.tree.grid(row=1, column=0, sticky='eswn')
        scroll.grid(row=1, column=1, sticky='ns')

        # --- restore data
        data = {}
        self.events = {}
        self.nb = 0
        try:
            with open(DATA_PATH, 'rb') as file:
                dp = Unpickler(file)
                data = dp.load()
        except Exception:
            l = [
                f for f in os.listdir(os.path.dirname(BACKUP_PATH))
                if f.startswith('data.backup')
            ]
            if l:
                l.sort(key=lambda x: int(x[11:]))
                shutil.copy(os.path.join(os.path.dirname(BACKUP_PATH), l[-1]),
                            DATA_PATH)
                with open(DATA_PATH, 'rb') as file:
                    dp = Unpickler(file)
                    data = dp.load()
        self.nb = len(data)
        backup()
        now = datetime.now()
        for i, prop in enumerate(data):
            iid = str(i)
            self.events[iid] = Event(self.scheduler, iid=iid, **prop)
            self.tree.insert('',
                             'end',
                             iid,
                             values=self.events[str(i)].values())
            tags = [str(self.tree.index(iid) % 2)]
            self.tree.item(iid, tags=tags)
            if not prop['Repeat']:
                for rid, d in list(prop['Reminders'].items()):
                    if d < now:
                        del self.events[iid]['Reminders'][rid]
        self.after_id = self.after(15 * 60 * 1000, self.check_outdated)

        # --- bindings
        self.bind_class("TCombobox",
                        "<<ComboboxSelected>>",
                        self.clear_selection,
                        add=True)
        self.bind_class("TCombobox", "<Control-a>", self.select_all)
        self.bind_class("TEntry", "<Control-a>", self.select_all)
        self.tree.bind('<3>', self._post_menu)
        self.tree.bind('<1>', self._select)
        self.tree.bind('<Double-1>', self._edit_on_click)
        self.menu.bind('<FocusOut>', lambda e: self.menu.unpost())
        self.filter_col.bind("<<ComboboxSelected>>", self.update_filter_val)
        self.filter_val.bind("<<ComboboxSelected>>", self.apply_filter)

        # --- widgets
        self.widgets = {}
        prop = {
            op: CONFIG.get('Calendar', op)
            for op in CONFIG.options('Calendar')
        }
        self.widgets['Calendar'] = CalendarWidget(self,
                                                  locale=CONFIG.get(
                                                      'General', 'locale'),
                                                  **prop)
        self.widgets['Events'] = EventWidget(self)
        self.widgets['Tasks'] = TaskWidget(self)
        self.widgets['Timer'] = Timer(self)
        self.widgets['Pomodoro'] = Pomodoro(self)

        self._setup_style()

        for item, widget in self.widgets.items():
            self.menu_widgets.add_checkbutton(
                label=_(item),
                command=lambda i=item: self.display_hide_widget(i))
            self.menu_widgets.set_item_value(_(item), widget.variable.get())
            add_trace(widget.variable,
                      'write',
                      lambda *args, i=item: self._menu_widgets_trace(i))

        self.icon.loop(self)
        self.tk.eval("""
apply {name {
    set newmap {}
    foreach {opt lst} [ttk::style map $name] {
        if {($opt eq "-foreground") || ($opt eq "-background")} {
            set newlst {}
            foreach {st val} $lst {
                if {($st eq "disabled") || ($st eq "selected")} {
                    lappend newlst $st $val
                }
            }
            if {$newlst ne {}} {
                lappend newmap $opt $newlst
            }
        } else {
            lappend newmap $opt $lst
        }
    }
    ttk::style map $name {*}$newmap
}} Treeview
        """)

        # react to scheduler --update-date in command line
        signal.signal(signal.SIGUSR1, self.update_date)

        # update selected date in calendar and event list every day
        self.scheduler.add_job(self.update_date,
                               CronTrigger(hour=0, minute=0, second=1),
                               jobstore='memo')

        self.scheduler.start()
示例#20
0
 def update_style(self):
     cats = {cat: CONFIG.get('Categories', cat).split(', ') for cat in CONFIG.options('Categories')}
     for cat, (fg, bg) in cats.items():
         style = 'ev_%s.%s.TLabel' % (cat, self._style_prefixe)
         self.style.configure(style, background=bg, foreground=fg)
示例#21
0
    def __init__(self, master, event, new=False):
        Toplevel.__init__(self, master)
        self.minsize(410, 402)
        if master.winfo_ismapped():
            self.transient(master)
        self.protocol('WM_DELETE_WINDOW', self.cancel)

        self._only_nb = self.register(only_nb)

        self.event = event
        if new:
            self.title(_('New Event'))
        else:
            self.title(_('Edit Event'))
        self._new = new
        self._task = BooleanVar(self, bool(event['Task']))
        self._whole_day = BooleanVar(self, event['WholeDay'])

        # --- style
        style = Style(self)
        active_bg = style.lookup('TEntry', 'selectbackground', ('focus', ))

        self.alarms = []

        notebook = Notebook(self)
        notebook.pack(fill='both', expand=True)
        Button(self, text=_('Ok'), command=self.ok).pack(pady=(10, 6), padx=4)

        # --- event settings
        frame_event = Frame(notebook)
        notebook.add(frame_event, text=_('Event'), sticky='eswn', padding=4)
        frame_event.columnconfigure(1, weight=1)
        frame_event.rowconfigure(5, weight=1)

        self.img_moins = PhotoImage(master=self, file=IM_DEL)
        self.img_bell = PhotoImage(master=self, file=IM_BELL)
        Label(frame_event, text=_('Summary')).grid(row=0,
                                                   column=0,
                                                   padx=4,
                                                   pady=6,
                                                   sticky='e')
        Label(frame_event, text=_('Place')).grid(row=1,
                                                 column=0,
                                                 padx=4,
                                                 pady=6,
                                                 sticky='e')
        Label(frame_event, text=_('Start')).grid(row=2,
                                                 column=0,
                                                 padx=4,
                                                 pady=6,
                                                 sticky='e')
        self._end_label = Label(frame_event, text=_('End'))
        self._end_label.grid(row=3, column=0, padx=4, pady=6, sticky='e')
        frame_task = Frame(frame_event)
        frame_task.grid(row=4, column=1, padx=4, pady=6, sticky='w')
        Label(frame_event, text=_('Description')).grid(row=5,
                                                       column=0,
                                                       padx=4,
                                                       pady=6,
                                                       sticky='e')
        Label(frame_event, text=_('Category')).grid(row=6,
                                                    column=0,
                                                    padx=4,
                                                    pady=6,
                                                    sticky='e')
        Button(frame_event,
               image=self.img_bell,
               command=self.add_reminder,
               padding=0).grid(row=7, column=0, padx=4, pady=6, sticky='en')

        self.summary = Entry(frame_event, width=35)
        self.summary.insert(0, self.event['Summary'])
        self.summary.grid(row=0, column=1, padx=4, pady=6, sticky='ew')
        self.place = Entry(frame_event, width=35)
        self.place.insert(0, self.event['Place'])
        self.place.grid(row=1, column=1, padx=4, pady=6, sticky='ew')
        frame_start = Frame(frame_event)
        frame_start.grid(row=2, column=1, padx=4, pady=6, sticky='w')
        frame_end = Frame(frame_event)
        frame_end.grid(row=3, column=1, padx=4, pady=6, sticky='w')
        txt_frame = Frame(frame_event,
                          style='txt.TFrame',
                          border=1,
                          relief='sunken')
        self.desc = Text(txt_frame,
                         width=35,
                         height=4,
                         highlightthickness=0,
                         relief='flat',
                         selectbackground=active_bg)
        self.desc.insert('1.0', self.event['Description'])
        self.desc.pack(fill='both', expand=True)
        txt_frame.grid(row=5, column=1, padx=4, pady=6, sticky='ewsn')
        cats = list(CONFIG.options('Categories'))
        width = max([len(cat) for cat in cats])
        self.category = Combobox(frame_event,
                                 width=width + 2,
                                 values=cats,
                                 state='readonly')
        self.category.set(event['Category'])
        self.category.grid(row=6, column=1, padx=4, pady=6, sticky='w')
        self.frame_alarms = Frame(frame_event)
        self.frame_alarms.grid(row=7, column=1, sticky='w')

        # --- *--- task
        Checkbutton(frame_task,
                    text=_('Task'),
                    command=self._change_label,
                    variable=self._task).pack(side='left')

        self.task_progress = Combobox(frame_task,
                                      state='readonly',
                                      width=9,
                                      values=(_('Pending'), _('In Progress'),
                                              _('Completed'), _('Cancelled')))
        self.task_progress.pack(side='left', padx=(8, 4))
        self.in_progress = Combobox(
            frame_task,
            state='readonly',
            width=5,
            values=['{}%'.format(i) for i in range(0, 110, 10)])
        self.in_progress.pack(side='left', padx=4)
        if not event['Task']:
            self.task_progress.set(_('Pending'))
            self.in_progress.set('0%')
        elif '%' in event['Task']:
            self.task_progress.set(_('In Progress'))
            self.in_progress.set(event['Task'])
        else:
            self.task_progress.set(_(event['Task']))
            self.in_progress.set('0%')

        # calendar settings
        prop = {
            op: CONFIG.get('Calendar', op)
            for op in CONFIG.options('Calendar')
        }
        prop['font'] = "Liberation\ Sans 9"
        prop.update(selectforeground='white', selectbackground=active_bg)
        locale = CONFIG.get('General', 'locale')

        # --- *--- start date
        self.start_date = self.event['Start']
        self.start_entry = DateEntry(frame_start,
                                     locale=locale,
                                     width=10,
                                     justify='center',
                                     year=self.start_date.year,
                                     month=self.start_date.month,
                                     day=self.start_date.day,
                                     **prop)

        self.start_hour = Combobox(frame_start,
                                   width=3,
                                   justify='center',
                                   state='readonly',
                                   exportselection=False,
                                   values=['%02d' % i for i in range(24)])
        self.start_hour.set('%02d' % self.start_date.hour)
        self.start_min = Combobox(frame_start,
                                  width=3,
                                  justify='center',
                                  state='readonly',
                                  exportselection=False,
                                  values=['%02d' % i for i in range(0, 60, 5)])
        self.start_min.set('%02d' % self.start_date.minute)
        self.start_entry.pack(side='left', padx=(0, 18))
        self.start_hour.pack(side='left', padx=(4, 0))
        self.start_date = self.start_date.date()
        Label(frame_start, text=':').pack(side='left')
        self.start_min.pack(side='left', padx=(0, 4))
        Checkbutton(frame_start,
                    text=_("whole day"),
                    variable=self._whole_day,
                    command=self._toggle_whole_day).pack(side='left', padx=4)

        # --- *--- end date
        self.end_date = self.event['End']
        self.end_entry = DateEntry(frame_end,
                                   justify='center',
                                   locale=locale,
                                   width=10,
                                   year=self.end_date.year,
                                   month=self.end_date.month,
                                   day=self.end_date.day,
                                   **prop)

        self.end_hour = Combobox(frame_end,
                                 width=3,
                                 justify='center',
                                 state='readonly',
                                 exportselection=False,
                                 values=['%02d' % i for i in range(24)])
        self.end_hour.set('%02d' % self.end_date.hour)
        self.end_min = Combobox(frame_end,
                                width=3,
                                justify='center',
                                state='readonly',
                                exportselection=False,
                                values=['%02d' % i for i in range(0, 60, 5)])
        self.end_min.set('%02d' % self.end_date.minute)
        self.end_entry.pack(side='left', padx=(0, 18))

        self.end_hour.pack(side='left', padx=(4, 0))
        Label(frame_end, text=':').pack(side='left')
        self.end_min.pack(side='left', padx=(0, 4))
        self.end_date = self.end_date.date()

        for date in self.event['Reminders'].values():
            self.add_reminder(date)

        self._toggle_whole_day()

        # --- repetition settings
        frame_rep = Frame(notebook)
        notebook.add(frame_rep, text=_('Repetition'), padding=4, sticky='eswn')
        frame_rep.columnconfigure(0, weight=1)
        frame_rep.columnconfigure(1, weight=1)
        frame_rep.rowconfigure(1, weight=1)
        self._repeat = BooleanVar(self, bool(self.event['Repeat']))
        repeat = {
            'Frequency': 'year',
            'Limit': 'always',
            'NbTimes': 1,
            'EndDate': (datetime.now() + timedelta(days=1)).date(),
            'WeekDays': [self.start_date.isocalendar()[2] - 1]
        }
        repeat.update(self.event['Repeat'])

        self._repeat_freq = StringVar(self, repeat['Frequency'])
        Checkbutton(frame_rep,
                    text=_('Repeat event'),
                    variable=self._repeat,
                    command=self._toggle_rep).grid(row=0,
                                                   column=0,
                                                   columnspan=2,
                                                   padx=4,
                                                   pady=6,
                                                   sticky='w')
        # --- *--- Frequency
        frame_freq = LabelFrame(frame_rep, text=_('Frequency'))
        frame_freq.grid(row=1, column=0, sticky='eswn', padx=(0, 3))
        self._lfreq = Label(frame_freq, text=_('Every:'))
        self._lfreq.grid(row=0, column=0, padx=4, pady=2, sticky='e')

        self._freqs = []
        for i, val in enumerate(['Year', 'Month', 'Week']):
            r = Radiobutton(frame_freq,
                            text=_(val),
                            variable=self._repeat_freq,
                            value=val.lower(),
                            command=self._toggle_wd)
            r.grid(row=i, column=1, padx=4, pady=2, sticky='nw')
            self._freqs.append(r)

        frame_days = Frame(frame_freq)
        frame_days.grid(row=2, column=2, padx=4, pady=2, sticky='nw')
        self._week_days = []
        days = get_day_names("wide", locale=locale)
        days = [days[i] for i in range(7)]
        for day in days:
            ch = Checkbutton(frame_days, text=day)
            ch.pack(anchor='w')
            self._week_days.append(ch)

        for d in repeat['WeekDays']:
            self._week_days[int(d)].state(('selected', ))

        # --- *--- Limit
        frame_lim = LabelFrame(frame_rep, text=_('Limit'))
        frame_lim.grid(row=1, column=1, sticky='eswn', padx=(3, 0))
        frame_lim.grid(row=1, column=1, sticky='eswn', padx=(3, 0))
        self._repeat_lim = StringVar(self, repeat['Limit'])

        # always
        r1 = Radiobutton(frame_lim,
                         text=_('Always'),
                         value='always',
                         variable=self._repeat_lim,
                         command=self._toggle_lim)
        r1.grid(row=0, column=0, sticky='w')
        # until
        r2 = Radiobutton(frame_lim,
                         text=_('Until'),
                         value='until',
                         variable=self._repeat_lim,
                         command=self._toggle_lim)
        r2.grid(row=1, column=0, sticky='w')
        until_date = repeat['EndDate']
        self.until_entry = DateEntry(frame_lim,
                                     width=10,
                                     justify='center',
                                     locale=locale,
                                     year=until_date.year,
                                     month=until_date.month,
                                     day=until_date.day,
                                     **prop)

        self.until_entry.grid(row=1,
                              column=1,
                              columnspan=2,
                              sticky='w',
                              padx=(4, 10),
                              pady=2)

        # after
        r3 = Radiobutton(frame_lim,
                         text=_('After'),
                         value='after',
                         variable=self._repeat_lim,
                         command=self._toggle_lim)
        r3.grid(row=2, column=0, sticky='w')
        frame_after = Frame(frame_lim,
                            style='txt.TFrame',
                            relief='sunken',
                            border=1)
        self.s_after = Spinbox(frame_after,
                               from_=0,
                               to=100,
                               width=3,
                               justify='center',
                               relief='flat',
                               highlightthickness=0,
                               validate='key',
                               validatecommand=(self._only_nb, '%P'),
                               disabledbackground='white')
        self.s_after.pack()
        self.s_after.delete(0, 'end')
        self.s_after.insert(0, str(repeat['NbTimes']))
        frame_after.grid(row=2, column=1, padx=4, pady=2, sticky='w')
        self._llim = Label(frame_lim, text=_('times'))
        self._llim.grid(row=2, column=2, padx=0, pady=2, sticky='w')

        self._rb_lim = [r1, r2, r3]

        self._toggle_rep()
        self._change_label()

        # --- bindings
        self.bind('<Configure>')
        self.task_progress.bind('<<ComboboxSelected>>',
                                self._toggle_in_progress)
        self.start_entry.bind('<<DateEntrySelected>>', self._select_start)
        self.end_entry.bind('<<DateEntrySelected>>', self._select_end)
        self.start_hour.bind("<<ComboboxSelected>>", self._select_start_hour)
        self.start_min.bind("<<ComboboxSelected>>", self._select_start_min)
        self.end_min.bind("<<ComboboxSelected>>", self._select_end_time)
        self.end_hour.bind("<<ComboboxSelected>>", self._select_end_time)
        self.bind_class("TCombobox",
                        "<<ComboboxSelected>>",
                        self.__clear_selection,
                        add=True)

        # self.wait_visibility(self)
        # self.grab_set()
        self.summary.focus_set()
示例#22
0
    def create_content(self, **kw):
        self.minsize(190, 190)

        self.on = False  # is the timer on?

        if not CONFIG.options("Tasks"):
            CONFIG.set("Tasks", _("Work"), CMAP[0])

        self._stats = None

        # --- colors
        self.background = {
            _("Work"): CONFIG.get("Pomodoro", "work_bg"),
            _("Break"): CONFIG.get("Pomodoro", "break_bg"),
            _("Rest"): CONFIG.get("Pomodoro", "rest_bg")
        }
        self.foreground = {
            _("Work"): CONFIG.get("Pomodoro", "work_fg"),
            _("Break"): CONFIG.get("Pomodoro", "break_fg"),
            _("Rest"): CONFIG.get("Pomodoro", "rest_fg")
        }

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

        # nombre de séquence de travail effectuées d'affilée (pour
        # faire des pauses plus longues tous les 4 cycles)
        self.nb_cycles = 0
        self.pomodori = IntVar(self, 0)

        # --- images
        self.im_go = PhotoImage(master=self, file=IM_START)
        self.im_stop = PhotoImage(master=self, file=IM_STOP)
        self.im_tomate = PhotoImage(master=self, file=IM_POMODORO)
        self.im_graph = PhotoImage(master=self, file=IM_GRAPH)

        # --- tasks list
        tasks_frame = Frame(self, style='pomodoro.TFrame')
        tasks_frame.grid(row=3, column=0, columnspan=3, sticky="wnse")
        tasks = [t.capitalize() for t in CONFIG.options("PomodoroTasks")]
        tasks.sort()
        self.task = StringVar(self, tasks[0])
        self.menu_tasks = Menu(tasks_frame,
                               relief='sunken',
                               activeborderwidth=0)
        self.choose_task = Menubutton(tasks_frame,
                                      textvariable=self.task,
                                      menu=self.menu_tasks,
                                      style='pomodoro.TMenubutton')
        Label(tasks_frame,
              text=_("Task: "),
              style='pomodoro.TLabel',
              font="TkDefaultFont 12",
              width=6,
              anchor="e").pack(side="left", padx=4)
        self.choose_task.pack(side="right", fill="x", pady=4)

        # --- display
        self.tps = [CONFIG.getint("Pomodoro", "work_time"),
                    0]  # time: min, sec
        self.activite = StringVar(self, _("Work"))
        self.titre = Label(self,
                           textvariable=self.activite,
                           font='TkDefaultFont 14',
                           style='timer.pomodoro.TLabel',
                           anchor="center")
        self.titre.grid(row=0,
                        column=0,
                        columnspan=2,
                        sticky="we",
                        pady=(4, 0),
                        padx=4)
        self.temps = Label(self,
                           text="{0:02}:{1:02}".format(self.tps[0],
                                                       self.tps[1]),
                           style='timer.pomodoro.TLabel',
                           anchor="center")
        self.temps.grid(row=1, column=0, columnspan=2, sticky="nswe", padx=4)
        self.aff_pomodori = Label(self,
                                  textvariable=self.pomodori,
                                  anchor='e',
                                  padding=(20, 4, 20, 4),
                                  image=self.im_tomate,
                                  compound="left",
                                  style='timer.pomodoro.TLabel',
                                  font='TkDefaultFont 14')
        self.aff_pomodori.grid(row=2, columnspan=2, sticky="ew", padx=4)

        # --- buttons
        self.b_go = Button(self,
                           image=self.im_go,
                           command=self.go,
                           style='pomodoro.TButton')
        self.b_go.grid(row=4, column=0, sticky="ew")
        self.b_stats = Button(self,
                              image=self.im_graph,
                              command=self.display_stats,
                              style='pomodoro.TButton')
        self.b_stats.grid(row=4, column=1, sticky="ew")

        self._corner = Sizegrip(self, style="pomodoro.TSizegrip")
        self._corner.place(relx=1, rely=1, anchor='se')

        # --- bindings
        self.bind('<3>', lambda e: self.menu.tk_popup(e.x_root, e.y_root))
        tasks_frame.bind('<ButtonPress-1>', self._start_move)
        tasks_frame.bind('<ButtonRelease-1>', self._stop_move)
        tasks_frame.bind('<B1-Motion>', self._move)
        self.titre.bind('<ButtonPress-1>', self._start_move)
        self.titre.bind('<ButtonRelease-1>', self._stop_move)
        self.titre.bind('<B1-Motion>', self._move)
        self.temps.bind('<ButtonPress-1>', self._start_move)
        self.temps.bind('<ButtonRelease-1>', self._stop_move)
        self.temps.bind('<B1-Motion>', self._move)
        self.b_stats.bind('<Enter>', self._on_enter)
        self.b_stats.bind('<Leave>', self._on_leave)
示例#23
0
    def _init_tasks(self):
        self.frames[_('Tasks')].columnconfigure(0, weight=1)
        self.tasks_hide_comp = tk.BooleanVar(
            self, CONFIG.getboolean('Tasks', 'hide_completed'))
        # --- Fonts
        frame_font = ttk.Frame(self.frames[_('Tasks')])
        frame_font.columnconfigure(2, weight=1)
        ttk.Label(frame_font, text=_('Font'),
                  style='title.TLabel').grid(row=0,
                                             column=0,
                                             sticky='w',
                                             padx=4,
                                             pady=4)
        # --- --- title
        ttk.Label(frame_font, style='subtitle.TLabel',
                  text=_('Title')).grid(row=1,
                                        column=0,
                                        sticky='nw',
                                        padx=4,
                                        pady=8)
        self.tasks_font_title = FontFrame(frame_font,
                                          CONFIG.get('Tasks', 'font_title'),
                                          True)
        self.tasks_font_title.grid(row=1, column=1, padx=4, pady=4)
        ttk.Separator(frame_font, orient='horizontal').grid(row=2,
                                                            columnspan=3,
                                                            padx=10,
                                                            pady=4,
                                                            sticky='ew')
        # --- --- text
        ttk.Label(frame_font, style='subtitle.TLabel',
                  text=_('Text')).grid(row=5,
                                       column=0,
                                       sticky='nw',
                                       padx=4,
                                       pady=8)
        self.tasks_font = FontFrame(frame_font, CONFIG.get('Tasks', 'font'))
        self.tasks_font.grid(row=5, column=1, padx=4, pady=4)

        # --- opacity
        self.tasks_opacity = OpacityFrame(
            self.frames[_('Tasks')],
            CONFIG.getfloat("Tasks", "alpha", fallback=0.85))

        # --- colors
        frame_color = ttk.Frame(self.frames[_('Tasks')])
        ttk.Label(frame_color, text=_('Colors'),
                  style='title.TLabel').grid(row=0,
                                             column=0,
                                             sticky='w',
                                             padx=8,
                                             pady=4)
        self.tasks_bg = ColorFrame(frame_color,
                                   CONFIG.get('Tasks', 'background'),
                                   _('Background'))
        self.tasks_bg.grid(row=0, column=1, sticky='e', padx=8, pady=4)
        self.tasks_fg = ColorFrame(frame_color,
                                   CONFIG.get('Tasks', 'foreground'),
                                   _('Foreground'))
        self.tasks_fg.grid(row=0, column=2, sticky='e', padx=8, pady=4)

        # --- placement
        frame_font.grid(sticky='ew')
        ttk.Separator(self.frames[_('Tasks')],
                      orient='horizontal').grid(sticky='ew', pady=8)
        self.tasks_opacity.grid(sticky='w', padx=4)
        ttk.Separator(self.frames[_('Tasks')],
                      orient='horizontal').grid(sticky='ew', pady=8)
        frame_color.grid(sticky='w')
        ttk.Separator(self.frames[_('Tasks')],
                      orient='horizontal').grid(sticky='ew', pady=8)
        ttk.Checkbutton(self.frames[_('Tasks')],
                        text=_('Hide completed tasks'),
                        variable=self.tasks_hide_comp).grid(sticky='w',
                                                            padx=4,
                                                            pady=4)
示例#24
0
    def __init__(self, parent, **options):
        """ créer le Toplevel permettant de modifier les paramètres """
        Frame.__init__(self, parent, **options)

        self.onglets = Notebook(self)
        self.onglets.pack(fill='both', expand=True)
        self.im_color = PhotoImage(master=self, file=IM_COLOR)
        self.im_plus = PhotoImage(master=self, file=IM_ADD)
        self.im_moins = PhotoImage(master=self, file=IM_DEL)

        self.okfct = self.register(only_nb)

        self.style = Style(self)

        self.nb_task = len(CONFIG.options("PomodoroTasks"))

        # --- Général (temps, police et langue)
        self.general = Frame(self.onglets, padding=10)
        self.general.columnconfigure(1, weight=1)
        self.onglets.add(self.general, text=_("General"))

        # --- --- Temps
        Label(self.general, text=_("Times (min)"),
              style='title.TLabel').grid(row=0,
                                         pady=4,
                                         padx=(2, 10),
                                         sticky="w")
        self.time_frame = Frame(self.general)
        self.time_frame.grid(row=0, column=1, sticky="w", padx=4)
        Label(self.time_frame, text=_("Work")).grid(row=0, padx=4, column=0)
        self.travail = Entry(self.time_frame,
                             width=4,
                             justify='center',
                             validatecommand=(self.okfct, '%P'),
                             validate='key')
        self.travail.insert(0, CONFIG.get("Pomodoro", "work_time"))
        self.travail.grid(row=0, column=1, padx=(0, 10))
        Label(self.time_frame, text=_("Break")).grid(row=0, column=2, padx=4)
        self.pause = Entry(self.time_frame,
                           width=4,
                           justify='center',
                           validatecommand=(self.okfct, '%P'),
                           validate='key')
        self.pause.insert(0, CONFIG.get("Pomodoro", "break_time"))
        self.pause.grid(row=0, column=3, padx=(0, 10))
        Label(self.time_frame, text=_("Rest")).grid(row=0, column=4, padx=4)
        self.rest = Entry(self.time_frame,
                          width=4,
                          justify='center',
                          validatecommand=(self.okfct, '%P'),
                          validate='key')
        self.rest.insert(0, CONFIG.get("Pomodoro", "rest_time"))
        self.rest.grid(row=0, column=5)

        Separator(self.general, orient='horizontal').grid(row=1,
                                                          columnspan=2,
                                                          sticky="ew",
                                                          pady=10)

        # --- --- Police
        Label(self.general, text=_("Font"),
              style='title.TLabel').grid(row=2, sticky='nw', padx=(2, 10))
        self.font = FontFrame(self.general,
                              font=CONFIG.get('Pomodoro', 'font'),
                              sample_text="02:17")
        self.font.grid(row=2, column=1, padx=4, sticky='w')

        Separator(self.general, orient='horizontal').grid(row=3,
                                                          columnspan=2,
                                                          sticky="ew",
                                                          pady=10)

        # --- --- Opacity
        self.opacity = OpacityFrame(self.general)
        self.opacity.grid(row=5, columnspan=2, sticky='w', padx=(2, 4), pady=4)

        Separator(self.general, orient='horizontal').grid(row=6,
                                                          columnspan=2,
                                                          sticky="ew",
                                                          pady=10)

        # --- --- Son
        self.sound = SoundFrame(self.general,
                                CONFIG.get("Pomodoro", "beep"),
                                mute=CONFIG.getboolean("Pomodoro", "mute"),
                                label=_("Sound"),
                                style='title.TLabel')
        self.sound.grid(row=7, columnspan=2, sticky='ew', pady=4)

        # --- Couleurs
        self.couleurs = Frame(self.onglets, padding=10)
        self.couleurs.columnconfigure(3, weight=1)
        self.onglets.add(self.couleurs, text=_("Colors"))

        self.bg = ColorFrame(self.couleurs, CONFIG.get("Pomodoro",
                                                       "background"),
                             _("Background"))
        self.work_bg = ColorFrame(self.couleurs,
                                  CONFIG.get("Pomodoro", "work_bg"),
                                  _("Background"))
        self.break_bg = ColorFrame(self.couleurs,
                                   CONFIG.get("Pomodoro", "break_bg"),
                                   _("Background"))
        self.rest_bg = ColorFrame(self.couleurs,
                                  CONFIG.get("Pomodoro", "rest_bg"),
                                  _("Background"))
        self.fg = ColorFrame(self.couleurs, CONFIG.get("Pomodoro",
                                                       "foreground"),
                             _("Foreground"))
        self.work_fg = ColorFrame(self.couleurs,
                                  CONFIG.get("Pomodoro", "work_fg"),
                                  _("Foreground"))
        self.break_fg = ColorFrame(self.couleurs,
                                   CONFIG.get("Pomodoro", "break_fg"),
                                   _("Foreground"))
        self.rest_fg = ColorFrame(self.couleurs,
                                  CONFIG.get("Pomodoro", "rest_fg"),
                                  _("Foreground"))

        Label(self.couleurs, text=_("General"),
              style='title.TLabel').grid(row=0,
                                         column=0,
                                         pady=4,
                                         padx=(2, 10),
                                         sticky="w")
        self.bg.grid(row=0, column=1, sticky='e', padx=8, pady=4)
        self.fg.grid(row=0, column=2, sticky='e', padx=8, pady=4)
        Separator(self.couleurs, orient='horizontal').grid(row=1,
                                                           sticky="ew",
                                                           pady=10,
                                                           columnspan=4)
        Label(self.couleurs, text=_("Work"),
              style='title.TLabel').grid(row=2,
                                         column=0,
                                         pady=4,
                                         padx=(2, 10),
                                         sticky="w")
        self.work_bg.grid(row=2, column=1, sticky='e', padx=8, pady=4)
        self.work_fg.grid(row=2, column=2, sticky='e', padx=8, pady=4)
        Separator(self.couleurs, orient='horizontal').grid(row=3,
                                                           sticky="ew",
                                                           pady=10,
                                                           columnspan=4)
        Label(self.couleurs, text=_("Break"),
              style='title.TLabel').grid(row=4,
                                         column=0,
                                         pady=4,
                                         padx=(2, 10),
                                         sticky="w")
        self.break_bg.grid(row=4, column=1, sticky='e', padx=8, pady=4)
        self.break_fg.grid(row=4, column=2, sticky='e', padx=8, pady=4)
        Separator(self.couleurs, orient='horizontal').grid(row=5,
                                                           sticky="ew",
                                                           pady=10,
                                                           columnspan=4)
        Label(self.couleurs, text=_("Rest"),
              style='title.TLabel').grid(row=6,
                                         column=0,
                                         pady=4,
                                         padx=(2, 10),
                                         sticky="w")
        self.rest_bg.grid(row=6, column=1, sticky='e', padx=8, pady=4)
        self.rest_fg.grid(row=6, column=2, sticky='e', padx=8, pady=4)

        # --- Tasks
        self.stats = Frame(self.onglets, padding=10)
        self.stats.columnconfigure(0, weight=1)
        self.stats.rowconfigure(2, weight=1)
        self.onglets.add(self.stats, text=_("Tasks"))
        # graph legend
        legend_frame = Frame(self.stats)
        Label(legend_frame,
              style='title.TLabel',
              text=_('Maximum number of rows in the legend')).pack(side='left')
        self.legend_row_nb = Entry(legend_frame,
                                   width=4,
                                   justify='center',
                                   validatecommand=(self.okfct, '%P'),
                                   validate='key')
        self.legend_row_nb.insert(
            0, CONFIG.get('Pomodoro', 'legend_max_height', fallback='6'))
        self.legend_row_nb.pack(side='left', padx=4)

        # task colors
        can = Canvas(self.stats,
                     bg=self.style.lookup('TFrame', 'background'),
                     highlightthickness=0,
                     width=1,
                     relief='flat')
        scroll = AutoScrollbar(self.stats,
                               orient='vertical',
                               command=can.yview)
        can.configure(yscrollcommand=scroll.set)
        self.task_frame = Frame(can)
        can.create_window(0, 0, anchor='nw', window=self.task_frame)

        tasks = CONFIG.options("PomodoroTasks")
        tasks.sort()
        cmap = [CONFIG.get("PomodoroTasks", task) for task in tasks]
        self.tasks = {}
        self._tasks_btns = {}
        for i, (coul, task) in enumerate(zip(cmap, tasks)):
            self.tasks[task] = ColorFrame(self.task_frame, coul,
                                          task.capitalize())
            self.tasks[task].grid(row=i, column=0, sticky='e', padx=4, pady=4)
            b = Button(self.task_frame,
                       image=self.im_moins,
                       padding=2,
                       command=lambda t=task: self.del_task(t))
            b.grid(row=i, column=1, sticky='w', padx=4, pady=4)
            self._tasks_btns[task] = b
        if len(tasks) == 1:
            self._tasks_btns[tasks[0]].state(['disabled'])

        legend_frame.grid(row=0, columnspan=2, sticky='w', pady=4)
        Label(self.stats,
              text=_('Colors in the statistic graph'),
              style='title.TLabel').grid(row=1, column=0, sticky='w', pady=4)
        can.grid(row=2, column=0, sticky='ewns')
        scroll.grid(row=2, column=1, sticky='ns')
        Button(self.stats, image=self.im_plus,
               command=self.add_task).grid(row=3, column=0, sticky='w')

        self.update_idletasks()
        can.configure(width=self.task_frame.winfo_reqwidth())
        can.configure(scrollregion=can.bbox('all'))
        can.bind('<4>', lambda e: self._scroll(e, -1))
        can.bind('<5>', lambda e: self._scroll(e, 1))
        self.task_frame.bind(
            '<Configure>',
            lambda e: can.configure(scrollregion=can.bbox('all')))
示例#25
0
    def _init_timer(self):
        self.frames[_('Timer')].columnconfigure(0, weight=1)
        # --- Fonts
        frame_font = ttk.Frame(self.frames[_('Timer')])
        frame_font.columnconfigure(2, weight=1)
        ttk.Label(frame_font, text=_('Font'),
                  style='title.TLabel').grid(row=0,
                                             column=0,
                                             sticky='w',
                                             padx=4,
                                             pady=4)
        # --- --- time
        ttk.Label(frame_font, style='subtitle.TLabel',
                  text=_('Time')).grid(row=1,
                                       column=0,
                                       sticky='nw',
                                       padx=4,
                                       pady=8)
        self.timer_font_time = FontFrame(frame_font,
                                         CONFIG.get('Timer', 'font_time'),
                                         sample_text="02:17")
        self.timer_font_time.grid(row=1, column=1, padx=4, pady=4)
        ttk.Separator(frame_font, orient='horizontal').grid(row=2,
                                                            columnspan=3,
                                                            padx=10,
                                                            pady=4,
                                                            sticky='ew')
        # --- --- intervals
        ttk.Label(frame_font, style='subtitle.TLabel',
                  text=_('Intervals')).grid(row=5,
                                            column=0,
                                            sticky='nw',
                                            padx=4,
                                            pady=8)
        self.timer_font_intervals = FontFrame(frame_font,
                                              CONFIG.get(
                                                  'Timer', 'font_intervals'),
                                              sample_text="02:17")
        self.timer_font_intervals.grid(row=5, column=1, padx=4, pady=4)

        # --- opacity
        self.timer_opacity = OpacityFrame(
            self.frames[_('Timer')],
            CONFIG.getfloat("Timer", "alpha", fallback=0.85))

        # --- colors
        frame_color = ttk.Frame(self.frames[_('Timer')])
        ttk.Label(frame_color, text=_('Colors'),
                  style='title.TLabel').grid(row=0,
                                             column=0,
                                             sticky='w',
                                             padx=8,
                                             pady=4)
        self.timer_bg = ColorFrame(frame_color,
                                   CONFIG.get('Timer', 'background'),
                                   _('Background'))
        self.timer_bg.grid(row=0, column=1, sticky='e', padx=8, pady=4)
        self.timer_fg = ColorFrame(frame_color,
                                   CONFIG.get('Timer', 'foreground'),
                                   _('Foreground'))
        self.timer_fg.grid(row=0, column=2, sticky='e', padx=8, pady=4)

        # --- placement
        frame_font.grid(sticky='ew')
        ttk.Separator(self.frames[_('Timer')],
                      orient='horizontal').grid(sticky='ew', pady=8)
        self.timer_opacity.grid(sticky='w', padx=4)
        ttk.Separator(self.frames[_('Timer')],
                      orient='horizontal').grid(sticky='ew', pady=8)
        frame_color.grid(sticky='w')
示例#26
0
    def update_style(self):
        self.menu_tasks.delete(0, 'end')
        tasks = [t.capitalize() for t in CONFIG.options('PomodoroTasks')]
        tasks.sort()
        for task in tasks:
            self.menu_tasks.add_radiobutton(label=task,
                                            value=task,
                                            variable=self.task)
        if self.task.get() not in tasks:
            self.stop(False)
            self.task.set(tasks[0])

        self.attributes('-alpha', CONFIG.get(self.name, 'alpha',
                                             fallback=0.85))
        bg = CONFIG.get('Pomodoro', 'background')
        fg = CONFIG.get('Pomodoro', 'foreground')
        active_bg = active_color(*self.winfo_rgb(bg))
        self.style.configure('pomodoro.TMenubutton',
                             background=bg,
                             relief='flat',
                             foreground=fg,
                             borderwidth=0,
                             arrowcolor=fg)
        self.style.configure('pomodoro.TButton',
                             background=bg,
                             relief='flat',
                             foreground=fg,
                             borderwidth=0)
        self.style.configure('pomodoro.TLabel', background=bg, foreground=fg)
        self.style.configure('pomodoro.TFrame', background=bg)
        self.style.configure('pomodoro.TSizegrip', background=bg)
        self.style.map('pomodoro.TSizegrip',
                       background=[('active', active_bg)])
        self.style.map('pomodoro.TButton',
                       background=[('disabled', bg),
                                   ('!disabled', 'active', active_bg)])
        self.style.map('pomodoro.TMenubutton',
                       background=[('disabled', bg),
                                   ('!disabled', 'active', active_bg)])
        self.configure(bg=bg)
        self.menu.configure(bg=bg,
                            fg=fg,
                            selectcolor=fg,
                            activeforeground=fg,
                            activebackground=active_bg)
        self.menu_pos.configure(bg=bg,
                                fg=fg,
                                selectcolor=fg,
                                activeforeground=fg,
                                activebackground=active_bg)
        self.menu_tasks.configure(bg=bg,
                                  activebackground=active_bg,
                                  fg=fg,
                                  selectcolor=fg,
                                  activeforeground=fg)
        self.background = {
            _("Work"): CONFIG.get("Pomodoro", "work_bg"),
            _("Break"): CONFIG.get("Pomodoro", "break_bg"),
            _("Rest"): CONFIG.get("Pomodoro", "rest_bg")
        }
        self.foreground = {
            _("Work"): CONFIG.get("Pomodoro", "work_fg"),
            _("Break"): CONFIG.get("Pomodoro", "break_fg"),
            _("Rest"): CONFIG.get("Pomodoro", "rest_fg")
        }
        act = self.activite.get()
        self.style.configure('timer.pomodoro.TLabel',
                             font=CONFIG.get("Pomodoro", "font"),
                             foreground=self.foreground[act],
                             background=self.background[act])