Example #1
0
class _EditorFrame(tk.Frame):
    """
    A widget for creating, editing, and saving Settings objects for the
    pyTRSplat module. (Not for direct use. SettingsEditor object embeds
    / controls this object.)
    """

    MW_PADX = 4
    MW_PADY = 1

    FIRST_WRITE_CHKBTN_ROW = 5

    SM_ENTRYBOX_WIDTH = 3
    MID_ENTRYBOX_WIDTH = 6
    ENTRYBOX_PADX = 4
    INNER_LBL_PADX = 4

    DIM_ROW = 1
    GRID_MARG_FIRST_ROW = 2
    LINE_CONFIG_FIRST_ROW = 30

    # For pulling typeface keys by value
    TYPEFACES_BY_FP = {}
    for k, v in Settings.TYPEFACES.items():
        TYPEFACES_BY_FP[v] = k
    DEFAULT_FONT_KEY = 'Sans-Serif'

    def __init__(self, master=None, load_settings=None):
        tk.Frame.__init__(self, master=master)
        self.master = master

        if load_settings is None:
            load_settings = Settings(preset=None)
        ls = load_settings

        # TODO: Toggle displaying px or inches
        # TODO: Configure ppi (when displaying inches)

        #################################
        # DIMENSIONS / MARGINS
        #################################
        dim_frame = tk.Frame(self)
        dim_frame.grid(row=self.DIM_ROW, column=1, sticky='w')
        self.page_width = self.IntVarSetter(dim_frame,
                                            var_name='RAW_width',
                                            display_name='Page Width',
                                            start_val=ls.dim[0])
        self.page_width.grid(row=0,
                             column=1,
                             padx=self.MW_PADX,
                             pady=self.MW_PADY,
                             sticky='w')
        self.page_height = self.IntVarSetter(dim_frame,
                                             var_name='RAW_width',
                                             display_name='Page Height',
                                             start_val=ls.dim[1])
        self.page_height.grid(row=0,
                              column=2,
                              padx=self.MW_PADX,
                              pady=self.MW_PADY,
                              sticky='w')

        # Main margins
        next_avail_row = self.GRID_MARG_FIRST_ROW
        self.y_top_marg = self.IntVarSetter(self,
                                            var_name='y_top_marg',
                                            display_name='Upper Margin (Grid)',
                                            start_val=ls.y_top_marg)
        self.y_top_marg.grid(row=next_avail_row,
                             column=1,
                             padx=self.MW_PADX,
                             pady=self.MW_PADY,
                             sticky='w')
        next_avail_row += 1

        self.y_bottom_marg = self.IntVarSetter(
            self,
            var_name='y_bottom_marg',
            start_val=ls.y_bottom_marg,
            display_name='Bottom Margin (Entire Page)')
        self.y_bottom_marg.grid(row=next_avail_row,
                                column=1,
                                padx=self.MW_PADX,
                                pady=self.MW_PADY,
                                sticky='w')
        next_avail_row += 1

        self.qq_side = self.QQSideSetter(
            self,
            var_name='qq_side',
            display_name='Side length of each QQ square',
            start_val=ls.qq_side)
        self.qq_side.grid(row=next_avail_row,
                          column=1,
                          padx=self.MW_PADX,
                          pady=self.MW_PADY,
                          sticky='w')
        # TODO: Display left/right margins that are left after this setting
        # TODO: Optional set-by-LR-margin.
        next_avail_row += 1

        cb_text = ('Size of area to clear at center of each '
                   'section for writing section number')
        self.centerbox_wh = self.IntVarSetter(self,
                                              var_name='centerbox_wh',
                                              display_name=cb_text,
                                              start_val=ls.centerbox_wh)
        self.centerbox_wh.grid(row=next_avail_row,
                               column=1,
                               sticky='w',
                               padx=self.MW_PADX,
                               pady=self.MW_PADY)
        next_avail_row += 1

        #################################
        # CONFIGURE LINES / FILL
        #################################

        self.qq_fill_RGBA = self.QQColorSetter(self, RGBA=ls.qq_fill_RGBA)
        self.qq_fill_RGBA.grid(row=next_avail_row,
                               column=1,
                               sticky='w',
                               padx=self.MW_PADX,
                               pady=self.MW_PADY)
        next_avail_row += 1

        next_avail_row = self.LINE_CONFIG_FIRST_ROW
        self.sec_line = self.LineSetter(self,
                                        var_name='sec_line',
                                        display_name='Section Line',
                                        stroke=ls.sec_line_stroke,
                                        RGBA=ls.sec_line_RGBA)
        self.sec_line.grid(row=next_avail_row, column=1, sticky='w')
        next_avail_row += 1

        self.ql_line = self.LineSetter(self,
                                       var_name='ql',
                                       display_name='Half-Dividing Line',
                                       stroke=ls.ql_stroke,
                                       RGBA=ls.ql_RGBA)
        self.ql_line.grid(row=next_avail_row, column=1, sticky='w')
        next_avail_row += 1

        self.qql_line = self.LineSetter(self,
                                        var_name='qql',
                                        display_name='Quarter-Dividing Line',
                                        stroke=ls.qql_stroke,
                                        RGBA=ls.qql_RGBA)
        self.qql_line.grid(row=next_avail_row, column=1, sticky='w')
        next_avail_row += 1

        #################################
        # WHAT TO WRITE / FONTS / TEXT CONFIGURE
        #################################
        self.write_header = tk.BooleanVar(self,
                                          value=ls.write_header,
                                          name='write_header')
        self.write_header_chkbtn = Checkbutton(
            self,
            text='Write Header in Top Margin',
            onvalue=True,
            offvalue=False,
            variable=self.write_header)
        self.write_header_chkbtn.grid(row=next_avail_row,
                                      column=1,
                                      sticky='w',
                                      padx=self.MW_PADX,
                                      pady=self.MW_PADY)
        next_avail_row += 1

        tf = _EditorFrame.TYPEFACES_BY_FP.get(ls.headerfont_typeface,
                                              _EditorFrame.DEFAULT_FONT_KEY)
        self.header_font = self.FontSetter(self,
                                           font_size=ls.headerfont_size,
                                           display_name='Header Font',
                                           var_name='headerfont',
                                           typeface=tf,
                                           RGBA=ls.headerfont_RGBA)
        self.header_font.grid(row=next_avail_row, column=1, sticky='w')
        next_avail_row += 1

        self.y_header_marg = self.IntVarSetter(
            self,
            var_name='y_header_marg',
            start_val=ls.y_header_marg,
            display_name=
            'How far above grid to write header (within top margin)')
        self.y_header_marg.grid(row=next_avail_row,
                                column=1,
                                padx=self.MW_PADX,
                                pady=self.MW_PADY,
                                sticky='w')
        next_avail_row += 1

        self.write_section_numbers = tk.BooleanVar(
            self, value=ls.write_section_numbers, name='write_section_numbers')
        self.write_section_numbers_chkbtn = Checkbutton(
            self,
            text='Write Section Numbers',
            onvalue=True,
            offvalue=False,
            variable=self.write_section_numbers)
        self.write_section_numbers_chkbtn.grid(row=next_avail_row,
                                               column=1,
                                               sticky='w',
                                               padx=self.MW_PADX,
                                               pady=self.MW_PADY)
        next_avail_row += 1

        tf = _EditorFrame.TYPEFACES_BY_FP.get(ls.secfont_typeface,
                                              _EditorFrame.DEFAULT_FONT_KEY)
        self.section_numbers_font = self.FontSetter(
            self,
            font_size=ls.secfont_size,
            display_name='Section Number Font',
            var_name='secfont',
            typeface=tf,
            RGBA=ls.secfont_RGBA)
        self.section_numbers_font.grid(row=next_avail_row,
                                       column=1,
                                       sticky='w')
        next_avail_row += 1

        self.write_lot_numbers = tk.BooleanVar(self,
                                               value=ls.write_lot_numbers,
                                               name='write_lot_numbers')
        self.write_lot_numbers_chkbtn = Checkbutton(
            self,
            text='Write lot numbers within the appropriate QQ(s)',
            onvalue=True,
            offvalue=False,
            variable=self.write_lot_numbers)
        self.write_lot_numbers_chkbtn.grid(row=next_avail_row,
                                           column=1,
                                           sticky='w',
                                           padx=self.MW_PADX,
                                           pady=self.MW_PADY)
        next_avail_row += 1

        tf = _EditorFrame.TYPEFACES_BY_FP.get(ls.lotfont_typeface,
                                              _EditorFrame.DEFAULT_FONT_KEY)
        self.lot_font = self.FontSetter(self,
                                        font_size=ls.lotfont_size,
                                        display_name='Lot Number Font',
                                        var_name='lotfont',
                                        typeface=tf,
                                        RGBA=ls.lotfont_RGBA)
        self.lot_font.grid(row=next_avail_row, column=1, sticky='w')
        next_avail_row += 1

        self.lot_num_offset_px = self.IntVarSetter(
            self,
            var_name='lot_num_offset_px',
            start_val=ls.lot_num_offset_px,
            display_name=
            'Lot number distance from top-left corner of QQ (in px)')
        self.lot_num_offset_px.grid(row=next_avail_row,
                                    column=1,
                                    padx=self.MW_PADX,
                                    pady=self.MW_PADY,
                                    sticky='w')
        next_avail_row += 1

        self.write_tracts = tk.BooleanVar(self,
                                          value=ls.write_tracts,
                                          name='write_tracts')
        self.write_tracts_chkbtn = Checkbutton(
            self,
            text='Write all tracts at the bottom',
            onvalue=True,
            offvalue=False,
            variable=self.write_tracts)
        self.write_tracts_chkbtn.grid(row=next_avail_row,
                                      column=1,
                                      sticky='w',
                                      padx=self.MW_PADX,
                                      pady=self.MW_PADY)
        next_avail_row += 1

        tf = _EditorFrame.TYPEFACES_BY_FP.get(ls.tractfont_typeface,
                                              _EditorFrame.DEFAULT_FONT_KEY)
        self.tract_font = self.FontSetter(self,
                                          font_size=ls.tractfont_size,
                                          display_name='Tract Font',
                                          var_name='tractfont',
                                          typeface=tf,
                                          RGBA=ls.tractfont_RGBA)
        self.tract_font.grid(row=next_avail_row, column=1, sticky='w')
        next_avail_row += 1

        # A customized RGBASetter for warningfont_RGBA, since we don't
        # need to set typeface or size:
        wfont_txt = 'Font color for writing errors/warnings'
        self.warning_font_RGBA = _EditorFrame.RGBASetter(
            self,
            display_name=wfont_txt,
            show_opacity=False,
            var_name='warningfont_RGBA',
            RGBA=ls.warningfont_RGBA)
        self.warning_font_RGBA.rgba_frame.grid(row=0, column=1)
        lbl = tk.Label(self.warning_font_RGBA, text=wfont_txt)
        lbl.grid(row=0, column=0)
        self.warning_font_RGBA.grid(row=next_avail_row, column=1, sticky='w')
        next_avail_row += 1

        #################################
        # TractTextBox margins and other tract-writing configurables
        #################################
        self.y_px_before_tracts = self.IntVarSetter(
            self,
            var_name='y_px_before_tracts',
            start_val=ls.y_px_before_tracts,
            display_name=
            'Distance between bottom of the grid and the first written tract')
        self.y_px_before_tracts.grid(row=next_avail_row,
                                     column=1,
                                     padx=self.MW_PADX,
                                     pady=self.MW_PADY,
                                     sticky='w')
        next_avail_row += 1

        self.x_text_left_marg = self.IntVarSetter(
            self,
            var_name='x_text_left_marg',
            start_val=ls.x_text_left_marg,
            display_name='Left Margin (for tract text below grid)')
        self.x_text_left_marg.grid(row=next_avail_row,
                                   column=1,
                                   padx=self.MW_PADX,
                                   pady=self.MW_PADY,
                                   sticky='w')
        next_avail_row += 1

        self.x_text_right_marg = self.IntVarSetter(
            self,
            var_name='x_text_right_marg',
            start_val=ls.x_text_right_marg,
            display_name='Right Margin (for tract text below grid)')
        self.x_text_right_marg.grid(row=next_avail_row,
                                    column=1,
                                    padx=self.MW_PADX,
                                    pady=self.MW_PADY,
                                    sticky='w')
        next_avail_row += 1

        self.y_px_between_tracts = self.IntVarSetter(
            self,
            var_name='y_px_between_tracts',
            start_val=ls.y_px_between_tracts,
            display_name='Space between lines of text')
        self.y_px_between_tracts.grid(row=next_avail_row,
                                      column=1,
                                      padx=self.MW_PADX,
                                      pady=self.MW_PADY,
                                      sticky='w')
        next_avail_row += 1

        self.paragraph_indent = self.IntVarSetter(
            self,
            var_name='paragraph_indent',
            start_val=ls.paragraph_indent,
            display_name='Paragraph indent (in spaces, not pixels or inches)')
        self.paragraph_indent.grid(row=next_avail_row,
                                   column=1,
                                   padx=self.MW_PADX,
                                   pady=self.MW_PADY,
                                   sticky='w')
        next_avail_row += 1

        self.new_line_indent = self.IntVarSetter(
            self,
            var_name='new_line_indent',
            start_val=ls.new_line_indent,
            display_name='Linebreak indent (in spaces, not pixels or inches)')
        self.new_line_indent.grid(row=next_avail_row,
                                  column=1,
                                  padx=self.MW_PADX,
                                  pady=self.MW_PADY,
                                  sticky='w')
        next_avail_row += 1

        self.justify_tract_text = tk.BooleanVar(self,
                                                value=ls.justify_tract_text,
                                                name='justify_tract_text')
        self.justify_tract_text_chkbtn = Checkbutton(
            self,
            text='Justify tract text',
            onvalue=True,
            offvalue=False,
            variable=self.justify_tract_text)
        self.justify_tract_text_chkbtn.grid(row=next_avail_row,
                                            column=1,
                                            sticky='w',
                                            padx=self.MW_PADX,
                                            pady=self.MW_PADY)
        next_avail_row += 1

        # Set the bool variables, according to the attributes in `ls`
        # (i.e. enact the settings in the `load_settings` object).
        # Note: This is not optimal design, but it seems to solve a
        # weird bug. Back when these values were set at the time that
        # the variables/checkbuttons themselves were created, the
        # _EditorFrame would fail to actually set them (to either True
        # or False), maybe 5% of the time. When clicking "Load Preset"
        # button repeatedly, with nothing different, would sometimes get
        # different results, and I could not reliably recreate the bug.
        # This is ineligant, but seems(?) to fix it...
        for var_name in [
                'write_header', 'write_section_numbers', 'write_lot_numbers',
                'write_tracts', 'justify_tract_text'
        ]:
            getattr(self, var_name).set(getattr(ls, var_name))

    def compile_settings(self):
        """
        Compile all of the configured parameters into a Settings object,
        and return that object.
        IMPORTANT: Returns `False` if any fields contained invalid values.
        """

        #TODO: Error-check any impossible parameters (margins too big, etc.)

        settings = []
        w = self.page_width.compile()
        h = self.page_height.compile()
        dim = f"dim={w},{h}"
        settings.append(dim)
        settings.append(self.qq_side.compile())
        settings.append(self.y_bottom_marg.compile())
        settings.append(self.header_font.compile())
        settings.append(self.y_header_marg.compile())
        settings.append(self.tract_font.compile())
        settings.append(self.section_numbers_font.compile())
        settings.append(self.lot_font.compile())
        warning_RGBA = self.warning_font_RGBA.compile_RGBA()
        if warning_RGBA is False:
            settings.append(warning_RGBA)
        else:
            settings.append(f"warningfont_RGBA={warning_RGBA}")
        settings.append(self.compile_checkbuttons())
        settings.append(self.y_top_marg.compile())
        settings.append(self.lot_num_offset_px.compile())
        settings.append(self.y_px_before_tracts.compile())
        settings.append(self.sec_line.compile())
        settings.append(self.ql_line.compile())
        settings.append(self.qql_line.compile())
        settings.append(self.qq_fill_RGBA.compile())
        settings.append(self.centerbox_wh.compile())
        settings.append(self.x_text_left_marg.compile())
        settings.append(self.x_text_right_marg.compile())
        settings.append(self.y_px_between_tracts.compile())
        settings.append(self.paragraph_indent.compile())
        settings.append(self.new_line_indent.compile())
        settings.append(self.qq_fill_RGBA.compile())

        # Check for any errors:
        for setting in settings:
            if setting is False:
                return False
        settings_text = '\n'.join(settings)
        set_obj = Settings()
        set_obj._parse_text_to_settings(settings_text)
        return set_obj

    def warning(self, title, message):
        """
        Show a warning, then reset focus on the window.
        """
        tk.messagebox.showwarning(title, message)
        self.focus()

    def compile_checkbuttons(self) -> str:
        """
        Compile parameters that are configured in Checkbuttons within
        the main window. Return as string.
        """
        txt = ''
        # For each of these var_names, check the state of the checkbutton
        # and set the val accordingly.
        #
        # Note: This is not optimal design, but it seems to solve a
        # weird bug. Checking the BooleanVar values with .get() seemed
        # to set the state of the checkboxes to 'alternate' maybe 5% of
        # the time, and I couldn't recreate it reliably to debug it.
        # This is ineligant, but seems(?) to fix it...
        for var_name in [
                'write_header', 'write_section_numbers', 'write_lot_numbers',
                'write_tracts', 'justify_tract_text'
        ]:
            chkbtn = getattr(self, var_name + '_chkbtn')
            val = False
            if 'selected' in chkbtn.state():
                val = True
                chkbtn.state(['selected'])
            else:
                chkbtn.state(['!selected'])
            chkbtn.state(['!alternate'])

            txt = f"{txt}{var_name}={val}\n"

        return txt

    class RGBASetter(tk.Frame):
        """
        The skeleton of a class that uses RGBAWidget. Not used directly,
        but allows child classes to inherit `.compile_RGBA()` method.

        IMPORTANT:
        Creates `self.rgba_frame` but does NOT place it on the grid;
        must call `rgba_frame.grid(...)` for every subclass!
        """
        def __init__(self,
                     master=None,
                     display_name='',
                     var_name='',
                     RGBA=(0, 0, 0, 255),
                     show_opacity=True):
            """
            :param display_name: The public display name of the variable
            (for warning message purposes).
            :param var_name: The name of the variable (corresponding to
            the attribute name of a Settings object).
            :param RGBA: The starting RGBA values.
            :param show_opacity: Whether to give the option to set
            opacity.
            """

            tk.Frame.__init__(self, master=master)
            self.master = master
            self.display_name = display_name
            self.var_name = var_name
            self.show_opacity = show_opacity

            # RGBA
            self.R, self.G, self.B, self.A = None, None, None, None
            self.rgba_frame = self.RGBAWidget(self, RGBA=RGBA)
            self.rgba_frame.grid(row=0, column=0)

        def compile_RGBA(self) -> str:
            """
            Compile the entered RGBA values into a string, formatted
            '(0,0,0,0)'. If invalid values have been entered, will
            instead show a popup error message and return `False`.
            """
            try:
                r = int(self.R.get())
                g = int(self.G.get())
                b = int(self.B.get())
                a = int(self.A.get())
                for i in [r, g, b, a]:
                    if i < 0 or i > 255:
                        raise ValueError
            except ValueError:
                opacity_txt = ''
                if self.show_opacity:
                    opacity_txt = ' and Opacity'
                self.master.warning(
                    'Invalid RGBA',
                    "Error: Enter numerical values (0 to 255) for "
                    f"RGB{opacity_txt} for <{self.display_name}>.")
                return False
            return f"{r},{g},{b},{a}"

        def rgb_to_hex(self) -> str:
            """
            Convert the current RGB values to a hex string.
            """
            try:
                r = int(self.R.get())
                g = int(self.G.get())
                b = int(self.B.get())
                rgb_as_hex = '#'
                for i in [r, g, b]:
                    if i < 0 or i > 255:
                        raise ValueError
                    h = hex(i).split('x')[-1]
                    h = h.rjust(2, '0')
                    rgb_as_hex = rgb_as_hex + h
                return rgb_as_hex
            except:
                return False

        class RGBAWidget(tk.Frame):
            """
            A frame for setting RGBA values.  (Note: `.R`, `.G`, `.B`,
            and `A.` are set for `master`, not for `self`.)
            """
            DISPLAY_COLOR_PREVIEW = True

            def __init__(self, master=None, RGBA=(0, 0, 0, 255)):
                tk.Frame.__init__(self, master)
                self.master = master
                lbl = tk.Label(self, text='RGB color values (0-255):')
                lbl.grid(row=0,
                         column=0,
                         sticky='w',
                         padx=_EditorFrame.INNER_LBL_PADX)
                self.show_opacity = master.show_opacity

                self.master.R = tk.Entry(self,
                                         width=_EditorFrame.SM_ENTRYBOX_WIDTH)
                self.master.R.grid(row=0,
                                   column=1,
                                   sticky='w',
                                   padx=_EditorFrame.ENTRYBOX_PADX)
                self.master.R.insert(tk.END, str(RGBA[0]))

                self.master.G = tk.Entry(self,
                                         width=_EditorFrame.SM_ENTRYBOX_WIDTH)
                self.master.G.grid(row=0,
                                   column=2,
                                   sticky='w',
                                   padx=_EditorFrame.ENTRYBOX_PADX)
                self.master.G.insert(tk.END, str(RGBA[1]))

                self.master.B = tk.Entry(self,
                                         width=_EditorFrame.SM_ENTRYBOX_WIDTH)
                self.master.B.grid(row=0,
                                   column=3,
                                   sticky='w',
                                   padx=_EditorFrame.ENTRYBOX_PADX)
                self.master.B.insert(tk.END, str(RGBA[2]))

                if self.DISPLAY_COLOR_PREVIEW:
                    preview_btn = tk.Button(self,
                                            text='Preview:',
                                            command=self.update_preview)
                    preview_btn.grid(row=0, column=4, padx=1)

                    self.preview_label = tk.Label(self,
                                                  bg=master.rgb_to_hex(),
                                                  width=2)
                    self.preview_label.grid(row=0, column=5, sticky='w')

                lbl = tk.Label(self, text='Opacity (0-255):')
                self.master.A = tk.Entry(self,
                                         width=_EditorFrame.SM_ENTRYBOX_WIDTH)
                self.master.A.insert(tk.END, str(RGBA[3]))
                if self.show_opacity:
                    lbl.grid(row=0,
                             column=6,
                             sticky='w',
                             padx=_EditorFrame.INNER_LBL_PADX)
                    self.master.A.grid(row=0,
                                       column=7,
                                       sticky='w',
                                       padx=_EditorFrame.ENTRYBOX_PADX)

            def update_preview(self):
                rgb_as_hex = self.master.rgb_to_hex()
                if rgb_as_hex is False:
                    return
                self.preview_label.config(bg=rgb_as_hex)

    class IntVarSetter(tk.Frame):
        """
        A frame for setting a single-integer type variable.
        """
        def __init__(self,
                     master=None,
                     var_name='',
                     display_name='',
                     start_val=0):
            tk.Frame.__init__(self, master=master)
            self.editor = master
            self.var_name = var_name
            self.display_name = display_name
            self.v = tk.Entry(master=self,
                              width=_EditorFrame.MID_ENTRYBOX_WIDTH)
            self.v.grid(row=0,
                        column=0,
                        sticky='w',
                        padx=_EditorFrame.ENTRYBOX_PADX)
            self.v.insert(tk.END, str(start_val))
            lbl = tk.Label(self, text=display_name)
            lbl.grid(row=0,
                     column=1,
                     sticky='w',
                     padx=_EditorFrame.INNER_LBL_PADX)

        def compile(self):
            try:
                if self.var_name.startswith('RAW'):
                    return int(self.v.get())
                return f"{self.var_name}={int(self.v.get())}\n"
            except:
                self.master.warning(
                    'Invalid Number', "Error: Enter a numerical value for "
                    f"<{self.display_name}>")
                return False

    class QQSideSetter(IntVarSetter):
        """
        A frame for setting qq_side variable, while also showing the
        resulting margins.
        """
        def __init__(self,
                     master=None,
                     var_name='',
                     display_name='',
                     start_val=0):
            _EditorFrame.IntVarSetter.__init__(self, master, var_name,
                                               display_name, start_val)

            marg_per_qq_btn = tk.Button(
                self,
                text="Calculate Left/Right Page Margins:",
                padx=3,
                command=self.marg_per_qq)
            marg_per_qq_btn.grid(row=0, column=3, sticky='e')
            self.lr_marg = tk.Entry(self,
                                    width=_EditorFrame.MID_ENTRYBOX_WIDTH)
            self.marg_per_qq()
            self.lr_marg.grid(row=0, column=4, sticky='w')

            qq_per_margin_btn = tk.Button(
                self,
                text="Calculate QQ side length per specified L/R margins",
                padx=3,
                command=self.qq_per_margin)
            qq_per_margin_btn.grid(row=0, column=5, sticky='e')

        def qq_per_margin(self):
            """Calculate the qq_side, per lr_marg."""
            try:
                w = int(self.master.page_width.v.get())
                lr_marg = int(self.lr_marg.get())
            except ValueError:
                return False
            qq_side = (w - (lr_marg * 2)) // 24
            if qq_side <= 0:
                return False
            self.v.delete(0, 'end')
            self.v.insert(tk.END, qq_side)

        def marg_per_qq(self):
            """Calculate the lr_marg, per qq_side and width."""
            try:
                w = int(self.master.page_width.v.get())
                qq_side = int(self.v.get())
            except ValueError:
                return False
            lr_marg = (w - (qq_side * 4 * 6)) // 2
            if lr_marg <= 0:
                return False
            self.lr_marg.delete(0, 'end')
            self.lr_marg.insert(tk.END, lr_marg)

    class QQColorSetter(RGBASetter):
        """
        A frame for setting QQ fill color.
        """
        def __init__(self,
                     master=None,
                     display_name='QQ Fill',
                     var_name='qq_fill_RGBA',
                     RGBA=Settings.RGBA_BLUE_OVERLAY):
            _EditorFrame.RGBASetter.__init__(self,
                                             master,
                                             display_name,
                                             var_name,
                                             RGBA,
                                             show_opacity=True)
            lbl = tk.Label(self, text=display_name, anchor='e')
            lbl.grid(row=0, column=0)

            # This frame is created by the parent class. Only needs to be
            # placed on grid here.
            self.rgba_frame.grid(row=0, column=1, sticky='w')

        def compile(self) -> str:
            """
            Compile the RGBA into the appropriate string.

            :return: A string with the appropriate text.
            """

            # get RGBA
            rgba = self.compile_RGBA()
            if rgba is False:
                return False

            return f"{self.var_name}={rgba}\n"

    class FontSetter(RGBASetter):
        """
        A frame for setting font size, color, and typeface.
        """

        AVAIL_FONTS = list(Settings.TYPEFACES.keys())

        def __init__(self,
                     master=None,
                     font_size=12,
                     display_name='',
                     var_name='',
                     typeface='Sans-Serif',
                     RGBA=(0, 0, 0, 255)):
            _EditorFrame.RGBASetter.__init__(self,
                                             master,
                                             display_name,
                                             var_name,
                                             RGBA,
                                             show_opacity=False)

            # Font size
            lbl = tk.Label(self, text='Font size:', anchor='e')
            lbl.grid(row=0, column=0)
            self.font_size = tk.Entry(self,
                                      width=_EditorFrame.SM_ENTRYBOX_WIDTH)
            self.font_size.grid(row=0,
                                column=1,
                                sticky='w',
                                padx=_EditorFrame.ENTRYBOX_PADX)
            self.font_size.insert(tk.END, font_size)

            # Typeface
            lbl = tk.Label(self, text="'Liberation' Font:", anchor='e')
            lbl.grid(row=0, column=2)
            self.typeface = Combobox(self, width=18)
            self.typeface.grid(row=0,
                               column=3,
                               sticky='w',
                               padx=_EditorFrame.ENTRYBOX_PADX)

            self.typeface['values'] = self.AVAIL_FONTS
            try:
                typeface_index = self.AVAIL_FONTS.index(typeface)
            except:
                typeface_index = 0
            self.typeface.current(typeface_index)

            # RGBA
            # This frame is created by the parent class. Only needs to be
            # placed on grid here.
            # TODO: Bugfix: why isn't rgba_frame showing up in grid?
            self.rgba_frame.grid(row=0, column=4, sticky='w')

        def compile(self) -> str:
            """
            Compile the size, typeface, and RGBA into the appropriate
            string.

            :return: A string with the appropriate text.
            """

            # Get font size
            try:
                font_size = int(self.font_size.get())
                if font_size < 1:
                    raise ValueError
            except (ValueError, TypeError):
                self.master.warning(
                    'Invalid Stroke',
                    "Error: Enter a positive numerical value for 'size' for "
                    f"<{self.display_name}>")
                return False
            txt = f"{self.var_name}_size={font_size}\n"

            # Get typeface
            typeface_fp = Settings.TYPEFACES.get(self.typeface.get())
            if typeface_fp is False:
                self.master.warning(
                    'Invalid Font',
                    "Error: Choose one of the available fonts for "
                    f"<{self.display_name}>")
                return False
            txt = (f"{txt}{self.var_name}_typeface="
                   f"{Settings.TYPEFACES[self.typeface.get()]}\n")

            # get RGBA
            rgba = self.compile_RGBA()
            if rgba is False:
                return False

            return f"{txt}{self.var_name}_RGBA={rgba}\n"

    class LineSetter(RGBASetter):
        """
        A frame for setting a line (Section, Half, Quarter).
        Possible `var_name` options: 'sec_line', 'ql', 'qql'
        """
        MAIN_LBL_WID = 18

        def __init__(self,
                     master=None,
                     var_name='',
                     display_name='',
                     stroke=1,
                     RGBA=(0, 0, 0, 255)):
            _EditorFrame.RGBASetter.__init__(self,
                                             master,
                                             display_name,
                                             var_name,
                                             RGBA,
                                             show_opacity=False)
            self.master = master
            lbl = tk.Label(self,
                           text=display_name + ':',
                           width=self.MAIN_LBL_WID,
                           anchor='w')
            lbl.grid(row=0,
                     column=0,
                     sticky='w',
                     padx=_EditorFrame.INNER_LBL_PADX)

            # Stroke
            lbl = tk.Label(self, text='stroke (px):')
            lbl.grid(row=0,
                     column=1,
                     sticky='w',
                     padx=_EditorFrame.INNER_LBL_PADX)
            self.stroke = tk.Entry(self, width=_EditorFrame.SM_ENTRYBOX_WIDTH)
            self.stroke.grid(row=0,
                             column=2,
                             sticky='w',
                             padx=_EditorFrame.ENTRYBOX_PADX)
            self.stroke.insert(tk.END, str(stroke))

            # RGBA
            # This frame is created by the parent class. Only needs to be
            # placed on grid here.
            self.rgba_frame.grid(row=0, column=3)

        def compile(self):
            """
            Compile stroke and RGBA into the appropriate string. Returns
            `False` if either contained invalid values.
            """

            try:
                strk = int(self.stroke.get())
                if strk < 1:
                    raise ValueError
            except (ValueError, TypeError):
                self.master.warning(
                    'Invalid Stroke',
                    "Error: Enter a positive numerical value for 'stroke' for "
                    f"<{self.display_name}>")
                return False
            txt = f"{self.var_name}_stroke={strk}\n"
            rgba = self.compile_RGBA()
            if rgba is False:
                return False
            return f"{txt}{self.var_name}_RGBA={rgba}\n"
Example #2
0
File: grep.py Project: iflat/idlecn
 def create_other_buttons(self):
     btn = Checkbutton(self.make_frame()[0],
                       variable=self.recvar,
                       text="是否包含子目录")
     btn.pack(side="top", fill="both")
Example #3
0
 def add_check_button(self):
     self.v1 = IntVar()
     self.v2 = IntVar()
     self.v3 = IntVar()
     self.v4 = IntVar()
     self.v5 = IntVar()
     self.v6 = IntVar()
     self.v7 = IntVar()
     self.v1.set("T")
     self.Check_total = Checkbutton(self.win,
                                    text="全部车次",
                                    variable=self.v1,
                                    onvalue='T')
     self.Check_total.place(x=168, y=7, width=80, height=30)
     self.Check_total = Checkbutton(self.win,
                                    text="G-高铁",
                                    variable=self.v2,
                                    onvalue='T')
     self.Check_total.place(x=258, y=7, width=70, height=30)
     self.Check_total = Checkbutton(self.win,
                                    text="D-动车",
                                    variable=self.v3,
                                    onvalue='T')
     self.Check_total.place(x=348, y=7, width=60, height=30)
     self.Check_total = Checkbutton(self.win,
                                    text="Z-直达",
                                    variable=self.v4,
                                    onvalue='T')
     self.Check_total.place(x=418, y=7, width=60, height=30)
     self.Check_total = Checkbutton(self.win,
                                    text="T-特快",
                                    variable=self.v5,
                                    onvalue='T')
     self.Check_total.place(x=488, y=7, width=60, height=30)
     self.Check_total = Checkbutton(self.win,
                                    text="K-快速",
                                    variable=self.v6,
                                    onvalue='T')
     self.Check_total.place(x=568, y=7, width=60, height=30)
     self.Check_total = Checkbutton(self.win,
                                    text="其他",
                                    variable=self.v7,
                                    onvalue='T')
     self.Check_total.place(x=648, y=7, width=60, height=30)
Example #4
0
 def create_other_buttons(self):
     "Add check button to recurse down subdirectories."
     btn = Checkbutton(
             self.make_frame()[0], variable=self.recvar,
             text="Recurse down subdirectories")
     btn.pack(side="top", fill="both")
class HighlightCode():
	"""
	Created by yogesh singh and please follow my instagram page @dynamiccoding for more projects 
	Plese install pygments and pyperclip .
	.
	make sure to follow me on github as well .

	and give feedback and suggestions also .........
	"""
	def __init__(self,root):
		self.root = root

		self.check_line_on = BooleanVar()   

		self.code_text = ScrolledText(self.root,bd=4,relief=GROOVE)
		self.code_text.place(x=0,y=0,height=300,width=300)


		self.output_code = ScrolledText(self.root,bd=4,relief=GROOVE)
		self.output_code.place(x=300,y=0,height=300,width=300) 

		self.control_frame = Frame(self.root,bd=2,relief=GROOVE)
		self.control_frame.place(x=25,y=310,height=130,width=550)

		# ................ controls in control frames ...................

		self.languages = ['python','C','C++','java','php','C#']

		self.borders = ['dotted','dashed','solid','double','groove','ridge','inset','none','hidden']

		#self.border_width = ['2px','4px','6px','8px','10px','medium','thick']

		self.border_clrs = ['red','black','gray','white','green','yellow','pink','cyan','sky blue']

		self.styles = ['default', 'emacs', 'friendly', 'colorful', 'autumn', 'murphy', 
		 'monokai', 'perldoc', 'pastie', 'borland', 'trac', 'native', 'fruity', 'bw', 
		'vim', 'vs', 'tango', 'rrt', 'xcode', 'igor', 'paraiso-light', 'paraiso-dark', 'lovelace', 
		'algol', 'algol_nu', 'arduino', 'rainbow_dash', 'abap',
		 'solarized-dark', 'solarized-light', 'sas', 'stata', 'stata-light', 'stata-dark', 'inkpot']

		self.style_combo = Combobox(self.control_frame,width=20,values=self.styles,justify=CENTER)
		self.style_combo.set('Select Style')
		self.style_combo.place(x=10,y=5)

		self.border_combo = Combobox(self.control_frame,width=20,values=self.borders,justify=CENTER)
		self.border_combo.set('Select Border')
		self.border_combo.place(x=10,y=45)

		
		self.border_color_combo = Combobox(self.control_frame,width=20,values=self.border_clrs,justify=CENTER)
		self.border_color_combo.set('Border Color')
		self.border_color_combo.place(x=10,y=85)

		self.language_combo = Combobox(self.control_frame,width=15,values=self.languages,justify=CENTER)
		self.language_combo.set('python')
		self.language_combo.place(x=180,y=40)

		self.Line_no_check = Checkbutton(self.control_frame,text='Enable Line No.',onvalue=True,offvalue=False,
			variable=self.check_line_on)
		self.Line_no_check.place(x=180,y=9)

		


		highlight_btn = ttk.Button(self.control_frame,text='Highlight',command=self.highlight_code)
		highlight_btn.place(x=300,y=10)

		copy_edit_code = ttk.Button(self.control_frame,text='Copy Code',command=self.copy_code)
		copy_edit_code.place(x=300,y=50)

		clear_input_text = ttk.Button(self.control_frame,text='Clear Input Box',
			width=20,command=lambda:self.code_text.delete(0.0,END))
		clear_input_text.place(x=400,y=10)

		clear_output_text = ttk.Button(self.control_frame,text='Clear Output Box',
			width=20,command=lambda:self.output_code.delete(0.0,END))
		clear_output_text.place(x=400,y=50)


# ............... Functions  .....................

	def highlight_code(self):
		self.output_code.delete(0.0,END)
		lexer = self.language_combo.get()
		linenos = self.check_line_on.get()
		defstyles = 'overflow:auto;width:auto;'
		divstyles = self.get_default_style()
		style = self.style_combo.get()
		if style == 'Select Style':
			style ='default'

		code = self.code_text.get(0.0,END)

		formatter = HtmlFormatter(style=style,
                              linenos=False,
                              noclasses=True,
                              cssclass='',
                              cssstyles=defstyles + divstyles,
                              prestyles='margin: 0')
		html = highlight(code, get_lexer_by_name(lexer, stripall=True), formatter)
		if linenos:
			html = self.insert_line_numbers(html)
		html = "<!-- Syntax Highlighter by Dynamic Coding Code Highlighter -->" + html
		self.output_code.insert(0.0,html)

	def get_default_style(self):
		if self.border_color_combo.get() != 'Border Color'  or self.border_combo.get() != 'Select Border':
			if self.border_color_combo.get() == 'Border Color':
				self.border_color_combo.set('solid')
			if self.border_combo.get() == 'Select Border':
				self.border_combo.set('gray')

			return 'border:'+str(self.border_combo.get())+' '+str(self.border_color_combo.get())+';border-width:.1em .1em .1em .8em;padding:.2em .6em;'
		else:
			return 'border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;'

	def insert_line_numbers(self,html):
	    match = re.search('(<pre[^>]*>)(.*)(</pre>)', html, re.DOTALL)
	    if not match: return html

	    pre_open = match.group(1)
	    pre = match.group(2)
	    pre_close = match.group(3)

	    html = html.replace(pre_close, '</pre></td></tr></table>')
	    numbers = range(1, pre.count('\n') + 1)
	    format = '%' + str(len(str(numbers[-1]))) + 'i'
	    lines = '\n'.join(format % i for i in numbers)
	    html = html.replace(pre_open, '<table><tr><td>' + pre_open + lines + '</pre></td><td>' + pre_open)
	    return html

	def copy_code(self):
		pc.copy(self.output_code.get(0.0,END))
		messagebox.showinfo("Highlighter says"," Code is copied to Clipboard")
Example #6
0
    def __init__(self, master, **kwargs):
        Checkbutton.__init__(self, master, **kwargs)

        self.configure(style="TButton", command=self._stateChanged)
Example #7
0
    def __init__(self,
                 parent,
                 txt: dict = dict(),
                 path_browser=None,
                 path_var: str = ""):
        """Instanciating the output workbook."""
        self.p = parent
        self.txt = txt
        Frame.__init__(self)

        # -- VARIABLES -------------------------------------------------------
        self.target_path = StringVar()
        # formats / type: vectors
        self.li_vectors_formats = (
            ".shp",
            ".tab",
            ".kml",
            ".gml",
            ".geojson",
        )  # vectors handled
        self.li_shp = []  # list for shapefiles path
        self.li_tab = []  # list for MapInfo tables path
        self.li_kml = []  # list for KML path
        self.li_gml = []  # list for GML path
        self.li_geoj = []  # list for GeoJSON paths
        self.li_gxt = []  # list for GXT paths
        self.li_vectors = []  # list for all vectors
        # formats / type: rasters
        self.li_raster = []  # list for rasters paths
        self.li_raster_formats = (".ecw", ".tif", ".jp2")  # raster handled
        # formats / type: file databases
        self.li_fdb = []  # list for all files databases
        self.li_egdb = []  # list for Esri File Geodatabases
        self.li_spadb = []  # list for Spatialite Geodatabases
        # formats / type: CAO/DAO
        self.li_cdao = []  # list for all CAO/DAO files
        self.li_dxf = []  # list for AutoCAD DXF paths
        self.li_dwg = []  # list for AutoCAD DWG paths
        self.li_dgn = []  # list for MicroStation DGN paths
        # formats / type: maps documents
        self.li_mapdocs = []  # list for all map & documents
        self.li_qgs = []  # list for QGS path

        # -- Source path -----------------------------------------------------
        self.FrPath = Labelframe(self,
                                 name="files",
                                 text=txt.get("gui_fr1", "Path"))

        # target folder
        self.lb_target = Label(self.FrPath, text=txt.get("gui_path"))
        self.ent_target = Entry(master=self.FrPath,
                                width=35,
                                textvariable=self.target_path)
        self.btn_browse = Button(
            self.FrPath,
            text="\U0001F3AF " + txt.get("gui_choix", "Browse"),
            command=lambda: self.get_target_path(r"."),
            takefocus=True,
        )
        self.btn_browse.focus_force()

        # widgets placement
        self.lb_target.grid(row=1,
                            column=1,
                            columnspan=1,
                            sticky="NSWE",
                            padx=2,
                            pady=2)
        self.ent_target.grid(row=1,
                             column=2,
                             columnspan=1,
                             sticky="NSWE",
                             padx=2,
                             pady=2)
        self.btn_browse.grid(row=1, column=3, sticky="NSE", padx=2, pady=2)

        # -- Format filters --------------------------------------------------
        self.FrFilters = Labelframe(self,
                                    name="filters",
                                    text=txt.get("gui_fr3", "Filters"))
        # formats options
        self.opt_shp = IntVar(self.FrFilters)  # able/disable shapefiles
        self.opt_tab = IntVar(self.FrFilters)  # able/disable MapInfo tables
        self.opt_kml = IntVar(self.FrFilters)  # able/disable KML
        self.opt_gml = IntVar(self.FrFilters)  # able/disable GML
        self.opt_geoj = IntVar(self.FrFilters)  # able/disable GeoJSON
        self.opt_gxt = IntVar(self.FrFilters)  # able/disable GXT
        self.opt_egdb = IntVar(self.FrFilters)  # able/disable Esri FileGDB
        self.opt_spadb = IntVar(self.FrFilters)  # able/disable Spatalite DB
        self.opt_rast = IntVar(self.FrFilters)  # able/disable rasters
        self.opt_cdao = IntVar(self.FrFilters)  # able/disable CAO/DAO files
        self.opt_qgs = IntVar(self.FrFilters)  # able/disable Geospatial QGS

        # format choosen: check buttons
        caz_shp = Checkbutton(self.FrFilters,
                              text=".shp",
                              variable=self.opt_shp)
        caz_tab = Checkbutton(self.FrFilters,
                              text=".tab",
                              variable=self.opt_tab)
        caz_kml = Checkbutton(self.FrFilters,
                              text=".kml",
                              variable=self.opt_kml)
        caz_gml = Checkbutton(self.FrFilters,
                              text=".gml",
                              variable=self.opt_gml)
        caz_geoj = Checkbutton(self.FrFilters,
                               text=".geojson",
                               variable=self.opt_geoj)
        caz_gxt = Checkbutton(self.FrFilters,
                              text=".gxt",
                              variable=self.opt_gxt)
        caz_egdb = Checkbutton(self.FrFilters,
                               text="Esri FileGDB",
                               variable=self.opt_egdb)
        caz_spadb = Checkbutton(self.FrFilters,
                                text="Spatialite",
                                variable=self.opt_spadb)
        caz_rast = Checkbutton(
            self.FrFilters,
            text="rasters ({0})".format(", ".join(self.li_raster_formats)),
            variable=self.opt_rast,
        )
        caz_cdao = Checkbutton(self.FrFilters,
                               text="CAO/DAO",
                               variable=self.opt_cdao)
        # widgets placement
        caz_shp.grid(row=1, column=0, sticky="NSWE", padx=2, pady=2)
        caz_tab.grid(row=1, column=1, sticky="NSWE", padx=2, pady=2)
        caz_kml.grid(row=1, column=2, sticky="NSWE", padx=2, pady=2)
        caz_gml.grid(row=1, column=3, sticky="NSWE", padx=2, pady=2)
        caz_geoj.grid(row=1, column=4, sticky="NSWE", padx=2, pady=2)
        caz_gxt.grid(row=1, column=5, sticky="NSWE", padx=2, pady=2)
        caz_rast.grid(row=2,
                      column=0,
                      columnspan=2,
                      sticky="NSWE",
                      padx=2,
                      pady=2)
        caz_egdb.grid(row=2,
                      column=2,
                      columnspan=2,
                      sticky="NSWE",
                      padx=2,
                      pady=2)
        caz_cdao.grid(row=2,
                      column=4,
                      columnspan=1,
                      sticky="NSWE",
                      padx=2,
                      pady=2)
        caz_spadb.grid(row=2,
                       column=5,
                       columnspan=2,
                       sticky="NSWE",
                       padx=2,
                       pady=2)

        # frames placement
        self.FrPath.grid(row=3, column=1, padx=2, pady=2, sticky="NSWE")
        self.FrFilters.grid(row=4, column=1, padx=2, pady=2, sticky="NSWE")
Example #8
0
lbl3 = Label(window, text="Макс. итерации", font=("Arial", 14))
lbl3.grid(column=1, row=1, sticky='W')
txt3 = Entry(window, width=15)
txt3.configure(background='LightSteelBlue4')
txt3.insert(0, '500')
txt3.grid(column=1, row=1)

lbl4 = Label(window, text="Начальная точка", font=("Arial", 14))
lbl4.grid(column=1, row=2, sticky='W')
txt4 = Entry(window, width=15)
txt4.configure(background='LightSteelBlue4')
txt4.insert(0, '0 0 0 0 0 0')
txt4.grid(column=1, row=2)
chk4_state = IntVar()
chk4_state.set(1)
chk4 = Checkbutton(window, text="Задать автоматически", var=chk4_state)
chk4.grid(column=1, row=2, sticky='E')

scroll_txt = scrolledtext.ScrolledText(window,
                                       width=100,
                                       height=27,
                                       pady=5,
                                       padx=5)
scroll_txt.configure(background='LightSteelBlue4')
scroll_txt.grid(column=0, row=3)

fig = Figure()
ax = fig.add_subplot(111)
ax.set_xlabel("X axis")
ax.set_ylabel("Y axis")
ax.grid()
Example #9
0
#class checkbox:
#  def _init_(self, name, state):
# self.name = name
# self.state = BooleanVar()
#  self.state.set(False) # задайте проверку состояния чекбокса

#def set_state(state):
# name = BooleanVar()
#name.set(False)

window = Tk()
window.title("Выберите параметры анализа текста")
window.geometry('400x400')
chk_state1 = BooleanVar()
chk_state1.set(False)  # задайте проверку состояния чекбокса
chk1 = Checkbutton(window, text='Выравнивание абзаца', var=chk_state1)
chk1.grid(column=0, row=0)
chk_state2 = BooleanVar()
chk_state2.set(False)
chk2 = Checkbutton(window, text='Отступ перед абзацем(см)', var=chk_state2)
chk2.grid(column=0, row=1)
chk_state3 = BooleanVar()
chk_state3.set(False)
chk3 = Checkbutton(window, text='Отступ после абзаца(см)', var=chk_state3)
chk3.grid(column=0, row=2)
chk_state4 = BooleanVar()
chk_state4.set(False)
chk4 = Checkbutton(window, text='Отступ слева(см)', var=chk_state4)
chk4.grid(column=0, row=3)
chk_state5 = BooleanVar()
chk_state5.set(False)
Example #10
0
    def new_frame(self, schema, frame, data, sch):
        max_cols = 0
        max_rows = 0
        is_grid = False
        for key, value in schema.items():
            type_ = value.pop("type", "")
            if type_ == "frame" or type_ == "group":
                is_grid = True
                children = value.pop("children", {})
                pos = value.pop("pos", {})
                new_frame = Frame(master=frame, borderwidth=1, relief="raised")
                new_frame.grid(sticky="nsew", **pos)

                max_cols = max(max_cols,
                               pos.get("column", 0) + pos.get("columnspan", 1))
                max_rows = max(max_rows,
                               pos.get("row", 0) + pos.get("rowspan", 1))

                Label(master=new_frame,
                      text=value.pop("label", key),
                      font=("Helvetica", 11, "bold")).pack(fill="x", pady=4)

                if type_ == "group":
                    new_frame = Frame(master=new_frame)
                    new_frame.pack(fill="both", expand=True)

                sch[key] = {"__frame__": new_frame}
                data[key] = {}
                self.new_frame(children, new_frame, data[key], sch[key])
                continue

            default = value.pop("default", None)
            data[key] = None
            if type_ == "str":
                self.insert_label(frame, value, key)

                sch[key] = Entry(master=frame, validate="all",
                    validatecommand=(self.register(
                        lambda v, d=data, k=key: \
                            self.validate_entry(v, d, k)), "%P"
                    )
                )

                if value.get("password", False):
                    sch[key].config(show="*")

                sch[key].pack(fill="x", padx=10)

                if isinstance(default, str):
                    sch[key].insert(0, default)
                    data[key] = default

            elif type_ == "int":
                self.insert_label(frame, value, key)
                kind = value.pop("kind", "regular")
                sch[key] = Entry(master=frame, validate="all",
                    validatecommand=(self.register(
                        lambda v, d=data, k=key: \
                            self.validate_entry(v, d, k, int)), "%P"
                    )
                )

                sch[key].pack(fill="x", padx=10)

                if isinstance(default, int):
                    sch[key].insert(0, str(default))
                    data[key] = default

            elif type_ == "float":
                self.insert_label(frame, value, key)
                sch[key] = Entry(master=frame, validate="all",
                    validatecommand=(self.register(
                        lambda v, d=data, k=key: \
                            self.validate_entry(v, d, k, float)), "%P"
                    )
                )

                sch[key].pack(fill="x", padx=10)

                if isinstance(default, float):
                    sch[key].insert(0, str(default))
                    data[key] = default

            elif type_ == "bool":
                data[key] = False

                frm = Frame(master=frame)
                frm.pack(fill="x", padx=10)

                Label(master=frm,
                      text=value.pop("label", key),
                      font=("Helvetica", 9, "bold")).pack(side="left")

                sch[key] = Checkbutton(
                    master=frm,
                    text="",
                    command=lambda d=data, k=key: self.change_bool(d, k))
                sch[key].pack(side="left")

                Label(master=frm, text="").pack(fill="x",
                                                side="left",
                                                expand=True)

                if isinstance(default, bool):
                    data[key] = default
                    if default:
                        sch[key]  # .select()

            elif type_ == "choice":
                self.insert_label(frame, value, key)
                values = value.pop("values", [])

                sch[key] = Combobox(master=frame, values=values)
                sch[key].pack(fill="x", padx=10)
                sch[key].bind("<<ComboboxSelected>>",
                    lambda e, s=sch[key], d=data, k=key: \
                        self.change_choice(s,d,k)
                )
                sch[key].current()
                if isinstance(default, str):
                    sch[key].current(values.index(default))
                    data[key] = default

            elif type_ == "file" or type_ == "folder":
                self.insert_label(frame, value, key)
                frm = Frame(master=frame)
                frm.pack(fill="x", padx=10)

                sch[key] = Label(master=frm,
                                 relief="sunken",
                                 borderwidth=1,
                                 anchor="w")
                sch[key].pack(fill="both", side="left", expand=True)

                Button(
                    master=frm,
                    text="...",
                    command=lambda s=sch[key], d=data, k=key, t=type_: \
                        self.select_folder(s, d, k, t),
                    # padx=0,
                    # pady=0
                ).pack(side=LEFT)

                if isinstance(default, str):
                    sch[key]["text"] = default
                    data[key] = default

            elif type_ == "button":
                sch[key] = Button(master=frame, text=value.pop("text", key))
                sch[key].pack(fill="x", padx=10)
                del data[key]

        if is_grid:
            frame.columnconfigure(list(range(max_cols)), weight=1)
            frame.rowconfigure(list(range(max_rows)), weight=1)
        else:
            try:
                Label(master=frame, text=" ").pack()
            except:
                pass
    def build(self):
        self.rbs = []
        self.rbs1 = []
        self.lF0 = lF0 = LabelFrame(self.fr, text='Widget and Themes')
        lF0.grid(row=0, column=0, sticky='nw')
        self.fr1 = fr1 = Frame(lF0)
        fr1.grid(row=0, column=0, sticky='nw')
        # create check box to select reverse selection order
        self.lF12 = lF12 = LabelFrame(fr1, text='Select Widget before Theme')
        lF12.grid(row=0, column=0, sticky='nw')
        self.ord = ord = IntVar()
        ord.set(0)
        cbut3 = Checkbutton(lF12,
                            text='Reverse selection order',
                            variable=ord,
                            command=self.selord)
        cbut3.grid(row=0, column=0, padx=5, pady=5)
        cbut3.state(['!selected'])

        # create a Combobox to choose widgets
        widget_sel = [
            'Button', 'Checkbutton', 'Combobox', 'Entry', 'Frame', 'Label',
            'LabelFrame', 'Menubutton', 'Notebook', 'PanedWindow',
            'Progressbar', 'Radiobutton', 'Scale', 'Scrollbar', 'Separator',
            'Sizegrip', 'Treeview'
        ]
        ord = self.ord

        self.lf6 = LabelFrame(self.fr1,
                              text='Select Widget',
                              style="RoundedFrame",
                              padding=(10, 1, 10, 10))
        self.lf6.grid(row=1, column=0, sticky='nw')

        self.lf6.state([("focus" if self.ord.get() == 0 else "!focus")])
        self.widget_value = StringVar()
        self.cb = Combobox(
            self.lf6,
            values=widget_sel,
            textvariable=self.widget_value,
            state=('disabled' if self.ord.get() == 1 else 'active'))
        self.cb.grid(row=0, column=0, padx=5, pady=5, sticky='nw')
        self.cb.bind('<<ComboboxSelected>>', self.enabled)

        # create a Radio Buttons to choose orientation
        fr2 = Frame(self.lF0)
        fr2.grid(row=0, column=1, sticky='nw')
        self.lF5 = lF5 = LabelFrame(
            fr2,
            style="RoundedFrame",
            padding=(10, 1, 10, 10),
            text='Orientation of \nProgressbar \nScale \nScrollbar')
        lF5.grid(row=0, column=0, padx=5, pady=5, sticky='nw')
        self.orient = StringVar()
        orientT = ['Horizontal', 'Vertical']
        for ix, val in enumerate(orientT):
            rb = Radiobutton(lF5,
                             text=val,
                             value=val,
                             command=self.orient_command,
                             variable=self.orient,
                             state='disabled')
            rb.grid(row=ix, column=0, sticky='w')
            self.rbs.append(rb)

        # create Radio Buttons to choose themes
        themes = {
            "alt": "alt - standard",
            "clam": "clam - standard",
            "classic": "classic - standard",
            "default": "default - standard"
        }

        self.lF1 = LabelFrame(self.fr1,
                              text='Select Theme',
                              style="RoundedFrame",
                              padding=(10, 1, 10, 10))
        self.lF1.grid(row=2, column=0, sticky='n')
        self.theme_value = StringVar()
        for ix, val in enumerate(themes):
            rb1 = Radiobutton(self.lF1,
                              text=themes[val],
                              value=val,
                              state='disabled',
                              variable=self.theme_value,
                              command=self.theme_command)
            rb1.grid(row=ix, column=0, padx=10, sticky='nw')
            self.rbs1.append(rb1)
Example #12
0
class MSControls(Frame):
    #TODO: select parameters for small Multiples when len(cluster_params)>6
    def __init__(self, parent,plot, params, k=1):
        super(MSControls, self).__init__(parent)#,text="Scatterplot-Options")
        self.params=params
        self.plot=plot #type:SimpleScatter
        self.k=k
        self.clusel=Label(self)


        apply_changes=self.plot.apply_settings


        #background
        self.wbvar = StringVar(value="0")
        self.whibla = Checkbutton(self, text='Black Background', command=apply_changes,
                                         variable=self.wbvar)
        self.whibla.grid(column=0, row=4, sticky=(W, N), columnspan=2)

        #Dot settings
        frm = Frame(self)
        frm.grid(column=0, row=5, sticky=(W, N, E), columnspan=2)
        frm.columnconfigure(2,weight=1)
        Label(frm,text="alpha:").grid(column=0, row=0, sticky=(N, E))
        Label(frm,text="dotsize:").grid(column=3, row=0, sticky=(N, E))

        self.alpha=StringVar(self,value="0.2")
        self.s=StringVar(self,value="4")

        Spinbox(frm,from_=0.05, to=1, increment=0.05, command=apply_changes, textvariable=self.alpha,width=4)\
            .grid(column=1, row=0, sticky=(W, E))
        Spinbox(frm,from_=0.5, to=20, increment=0.5 , command=apply_changes, textvariable=self.s,width=4)\
            .grid(column=4, row=0, sticky=(W, E))




        Button(frm,text="Apply", command=apply_changes)\
            .grid(column=0, row=1, sticky=(N, E,W), columnspan=5)

    def set_new_cols(self, newcols):
        self.params=newcols

    def set_new_cluster(self, k):
        if self.k == k or (self.k<=1 and k<=1):
            return
        self.clusel.destroy()
        self.clusel=ClusterSelect(self,self.plot,k)
        self.clusel.grid(column=0, row=6, sticky=(N, E,W), columnspan=2)

    def do_white_on_black(self):
        return self.wbvar.get() is not "0"

    def get_alpha(self):
        return float(self.alpha.get())

    def get_s(self):
        return float(self.s.get())

    def get_cols(self):
        pass
def set_config():
    sys_para = sys.argv
    file_path = os.path.split(sys_para[0])[0]
    gui = False
    if platform.uname()[0] == 'Windows':  # Win默认打开
        gui = True
    if platform.uname()[0] == 'Linux':  # Linux 默认关闭
        gui = False
    if '--gui' in sys.argv:  # 指定 gui 模式
        gui = True
    if '--nogui' in sys.argv:  # 带 nogui 就覆盖前面Win打开要求
        gui = False

    config_file = os.path.join(file_path, 's3_download_config.ini')
    # If no config file, read the default config
    if not os.path.exists(config_file):
        config_file += '.default'
        print("No customized config, use the default config")
    cfg = ConfigParser()
    print(f'Reading config file: {config_file}')

    try:
        global SrcBucket, S3Prefix, SrcFileIndex, SrcProfileName, DesDir, MaxRetry, MaxThread, MaxParallelFile, LoggingLevel
        cfg.read(config_file, encoding='utf-8-sig')
        SrcBucket = cfg.get('Basic', 'SrcBucket')
        S3Prefix = cfg.get('Basic', 'S3Prefix')
        SrcFileIndex = cfg.get('Basic', 'SrcFileIndex')
        SrcProfileName = cfg.get('Basic', 'SrcProfileName')
        DesDir = cfg.get('Basic', 'DesDir')
        Megabytes = 1024 * 1024
        ChunkSize = cfg.getint('Advanced', 'ChunkSize') * Megabytes
        MaxRetry = cfg.getint('Advanced', 'MaxRetry')
        MaxThread = cfg.getint('Advanced', 'MaxThread')
        MaxParallelFile = cfg.getint('Advanced', 'MaxParallelFile')
        LoggingLevel = cfg.get('Advanced', 'LoggingLevel')
    except Exception as e:
        print("ERR loading s3_download_config.ini", str(e))
        input('PRESS ENTER TO QUIT')
        sys.exit(0)

    if gui:
        # For GUI
        from tkinter import Tk, filedialog, END, StringVar, BooleanVar, messagebox
        from tkinter.ttk import Combobox, Label, Button, Entry, Spinbox, Checkbutton
        # get profile name list in ./aws/credentials
        pro_conf = RawConfigParser()
        pro_path = os.path.join(os.path.expanduser("~"), ".aws")
        cre_path = os.path.join(pro_path, "credentials")
        if os.path.exists(cre_path):
            pro_conf.read(cre_path)
            profile_list = pro_conf.sections()
        else:
            print(
                f"There is no aws_access_key in {cre_path}, please input for S3 Bucket: "
            )
            os.mkdir(pro_path)
            aws_access_key_id = input('aws_access_key_id: ')
            aws_secret_access_key = input('aws_secret_access_key: ')
            region = input('region: ')
            pro_conf.add_section('default')
            pro_conf['default']['aws_access_key_id'] = aws_access_key_id
            pro_conf['default'][
                'aws_secret_access_key'] = aws_secret_access_key
            pro_conf['default']['region'] = region
            profile_list = ['default']
            with open(cre_path, 'w') as f:
                print(f"Saving credentials to {cre_path}")
                pro_conf.write(f)

        # Click Select Folder
        def browse_folder():
            local_dir = filedialog.askdirectory(
                initialdir=os.path.dirname(__file__))
            url_txt.delete(0, END)
            url_txt.insert(0, local_dir)
            file_txt.delete(0, END)
            file_txt.insert(0, "*")
            # Finsih browse folder

        # Click List Buckets
        def ListBuckets(*args):
            SrcProfileName = SrcProfileName_txt.get()
            client = Session(profile_name=SrcProfileName).client('s3')
            bucket_list = []
            try:
                response = client.list_buckets()
                if 'Buckets' in response:
                    bucket_list = [b['Name'] for b in response['Buckets']]
            except Exception as e:
                messagebox.showerror(
                    'Error', f'Failt to List buckets. \n'
                    f'Please verify your aws_access_key of profile: [{SrcProfileName}]\n'
                    f'{str(e)}')
                bucket_list = ['CAN_NOT_GET_BUCKET_LIST']
            SrcBucket_txt['values'] = bucket_list
            SrcBucket_txt.current(0)
            # Finish ListBuckets

        # Click List Prefix
        def ListPrefix(*args):
            SrcProfileName = SrcProfileName_txt.get()
            client = Session(profile_name=SrcProfileName).client('s3')
            prefix_list = []
            this_bucket = SrcBucket_txt.get()
            max_get = 100
            try:
                response = client.list_objects_v2(
                    Bucket=this_bucket, Delimiter='/'
                )  # Only get the max 1000 prefix for simply list
                if 'CommonPrefixes' in response:
                    prefix_list = [
                        c['Prefix'] for c in response['CommonPrefixes']
                    ]
                if not prefix_list:
                    messagebox.showinfo(
                        'Message', f'There is no "/" Prefix in: {this_bucket}')
                if response['IsTruncated']:
                    messagebox.showinfo(
                        'Message',
                        f'More than {max_get} Prefix, cannot fully list here.')
            except Exception as e:
                messagebox.showinfo(
                    'Error',
                    f'Cannot get prefix list from bucket: {this_bucket}, {str(e)}'
                )
            S3Prefix_txt['values'] = prefix_list
            S3Prefix_txt.current(0)
            # Finish list prefix

        def browse_file(*args):
            SrcProfileName = SrcProfileName_txt.get()
            S3Prefix = S3Prefix_txt.get()
            client = Session(profile_name=SrcProfileName).client('s3')
            file_list = []
            this_bucket = SrcBucket_txt.get()
            max_get = 100
            try:
                response = client.list_objects_v2(
                    Bucket=this_bucket,
                    Prefix=str(PurePosixPath(S3Prefix)) + '/',
                    Delimiter='/'
                )  # Only get the max 1000 files for simply list

                # For delete prefix in des_prefix
                if S3Prefix == '' or S3Prefix == '/':
                    # 目的bucket没有设置 Prefix
                    dp_len = 0
                else:
                    # 目的bucket的 "prefix/"长度
                    dp_len = len(str(PurePosixPath(S3Prefix))) + 1

                if 'Contents' in response:
                    file_list = [
                        c['Key'][dp_len:] for c in response['Contents']
                    ]  # 去掉Prefix
                if not file_list:
                    messagebox.showinfo(
                        'Message',
                        f'There is no files in s3://{this_bucket}/{S3Prefix}')
                if response['IsTruncated']:
                    messagebox.showinfo(
                        'Message',
                        f'More than {max_get} files, cannot fully list here.')
            except Exception as e:
                messagebox.showinfo(
                    'Error',
                    f'Cannot get file list from bucket s3://{this_bucket}/{S3Prefix}, {str(e)}'
                )
            file_txt['values'] = file_list
            file_txt.current(0)
            # Finish list files

        # Click START button
        def close():
            window.withdraw()
            ok = messagebox.askokcancel(
                'Start downloading job',
                f'DOWNLOAD FROM s3://{SrcBucket_txt.get()}/{S3Prefix_txt.get()}\n'
                f'TO LOCAL {url_txt.get()}\n'
                f'Click OK to START')
            if not ok:
                window.deiconify()
                return
            window.quit()
            return
            # Finish close()

        # Start GUI
        window = Tk()
        window.title(
            "LONGBOW - AMAZON S3 DOWNLOAD TOOL WITH BREAK-POINT RESUMING")
        window.geometry('705x350')
        window.configure(background='#ECECEC')
        window.protocol("WM_DELETE_WINDOW", sys.exit)

        Label(window, text="S3 Bucket").grid(column=0,
                                             row=1,
                                             sticky='w',
                                             padx=2,
                                             pady=2)
        SrcBucket_txt = Combobox(window, width=48)
        SrcBucket_txt.grid(column=1, row=1, sticky='w', padx=2, pady=2)
        SrcBucket_txt['values'] = SrcBucket
        SrcBucket_txt.current(0)
        Button(window, text="List Buckets", width=10, command=ListBuckets) \
            .grid(column=2, row=1, sticky='w', padx=2, pady=2)

        Label(window, text="S3 Prefix").grid(column=0,
                                             row=2,
                                             sticky='w',
                                             padx=2,
                                             pady=2)
        S3Prefix_txt = Combobox(window, width=48)
        S3Prefix_txt.grid(column=1, row=2, sticky='w', padx=2, pady=2)
        S3Prefix_txt['values'] = S3Prefix
        if S3Prefix != '':
            S3Prefix_txt.current(0)
        Button(window, text="List Prefix", width=10, command=ListPrefix) \
            .grid(column=2, row=2, sticky='w', padx=2, pady=2)

        Label(window, text="Filename or *").grid(column=0,
                                                 row=3,
                                                 sticky='w',
                                                 padx=2,
                                                 pady=2)
        file_txt = Combobox(window, width=48)
        file_txt.grid(column=1, row=3, sticky='w', padx=2, pady=2)
        file_txt['values'] = SrcFileIndex
        if SrcFileIndex != '':
            file_txt.current(0)
        Button(window, text="Select File", width=10, command=browse_file) \
            .grid(column=2, row=3, sticky='w', padx=2, pady=2)

        Label(window, text="AWS Profile").grid(column=0,
                                               row=4,
                                               sticky='w',
                                               padx=2,
                                               pady=2)
        SrcProfileName_txt = Combobox(window, width=15, state="readonly")
        SrcProfileName_txt['values'] = tuple(profile_list)
        SrcProfileName_txt.grid(column=1, row=4, sticky='w', padx=2, pady=2)
        if SrcProfileName in profile_list:
            position = profile_list.index(SrcProfileName)
            SrcProfileName_txt.current(position)
        else:
            SrcProfileName_txt.current(0)
        SrcProfileName = SrcProfileName_txt.get()
        SrcProfileName_txt.bind("<<ComboboxSelected>>", ListBuckets)

        Label(window, text="Folder").grid(column=0,
                                          row=5,
                                          sticky='w',
                                          padx=2,
                                          pady=2)
        url_txt = Entry(window, width=50)
        url_txt.grid(column=1, row=5, sticky='w', padx=2, pady=2)
        url_btn = Button(window,
                         text="Select Folder",
                         width=10,
                         command=browse_folder)
        url_btn.grid(column=2, row=5, sticky='w', padx=2, pady=2)
        url_txt.insert(0, DesDir)

        Label(window, text="MaxThread/File").grid(column=0,
                                                  row=6,
                                                  sticky='w',
                                                  padx=2,
                                                  pady=2)
        if MaxThread < 1 or MaxThread > 100:
            MaxThread = 5
        var_t = StringVar()
        var_t.set(str(MaxThread))
        MaxThread_txt = Spinbox(window,
                                from_=1,
                                to=100,
                                width=15,
                                textvariable=var_t)
        MaxThread_txt.grid(column=1, row=6, sticky='w', padx=2, pady=2)

        Label(window, text="MaxParallelFile").grid(column=0,
                                                   row=7,
                                                   sticky='w',
                                                   padx=2,
                                                   pady=2)
        if MaxParallelFile < 1 or MaxParallelFile > 100:
            MaxParallelFile = 5
        var_f = StringVar()
        var_f.set(str(MaxParallelFile))
        MaxParallelFile_txt = Spinbox(window,
                                      from_=1,
                                      to=100,
                                      width=15,
                                      textvariable=var_f)
        MaxParallelFile_txt.grid(column=1, row=7, sticky='w', padx=2, pady=2)

        save_config = BooleanVar()
        save_config.set(True)
        save_config_txt = Checkbutton(window,
                                      text="Save to s3_download_config.ini",
                                      var=save_config)
        save_config_txt.grid(column=1, row=9, padx=2, pady=2)

        Button(window, text="Start Download", width=15,
               command=close).grid(column=1, row=10, padx=5, pady=5)
        window.mainloop()

        DesDir = url_txt.get()
        SrcFileIndex = file_txt.get()
        SrcBucket = SrcBucket_txt.get()
        S3Prefix = S3Prefix_txt.get()
        SrcProfileName = SrcProfileName_txt.get()
        MaxThread = int(MaxThread_txt.get())
        MaxParallelFile = int(MaxParallelFile_txt.get())

        if save_config:
            cfg['Basic']['SrcBucket'] = SrcBucket
            cfg['Basic']['S3Prefix'] = S3Prefix
            cfg['Basic']['SrcFileIndex'] = SrcFileIndex
            cfg['Basic']['SrcProfileName'] = SrcProfileName
            cfg['Basic']['DesDir'] = DesDir
            cfg['Advanced']['MaxThread'] = str(MaxThread)
            cfg['Advanced']['MaxParallelFile'] = str(MaxParallelFile)

            config_file = os.path.join(file_path, 's3_download_config.ini')
            with codecs.open(config_file, 'w', 'utf-8') as f:
                cfg.write(f)
                print(f"Save config to {config_file}")
        # GUI window finish

    if S3Prefix == '/':
        S3Prefix = ''
    # Finish set_config()
    return ChunkSize
Example #14
0
    def __init__(self, master=None, load_settings=None):
        tk.Frame.__init__(self, master=master)
        self.master = master

        if load_settings is None:
            load_settings = Settings(preset=None)
        ls = load_settings

        # TODO: Toggle displaying px or inches
        # TODO: Configure ppi (when displaying inches)

        #################################
        # DIMENSIONS / MARGINS
        #################################
        dim_frame = tk.Frame(self)
        dim_frame.grid(row=self.DIM_ROW, column=1, sticky='w')
        self.page_width = self.IntVarSetter(dim_frame,
                                            var_name='RAW_width',
                                            display_name='Page Width',
                                            start_val=ls.dim[0])
        self.page_width.grid(row=0,
                             column=1,
                             padx=self.MW_PADX,
                             pady=self.MW_PADY,
                             sticky='w')
        self.page_height = self.IntVarSetter(dim_frame,
                                             var_name='RAW_width',
                                             display_name='Page Height',
                                             start_val=ls.dim[1])
        self.page_height.grid(row=0,
                              column=2,
                              padx=self.MW_PADX,
                              pady=self.MW_PADY,
                              sticky='w')

        # Main margins
        next_avail_row = self.GRID_MARG_FIRST_ROW
        self.y_top_marg = self.IntVarSetter(self,
                                            var_name='y_top_marg',
                                            display_name='Upper Margin (Grid)',
                                            start_val=ls.y_top_marg)
        self.y_top_marg.grid(row=next_avail_row,
                             column=1,
                             padx=self.MW_PADX,
                             pady=self.MW_PADY,
                             sticky='w')
        next_avail_row += 1

        self.y_bottom_marg = self.IntVarSetter(
            self,
            var_name='y_bottom_marg',
            start_val=ls.y_bottom_marg,
            display_name='Bottom Margin (Entire Page)')
        self.y_bottom_marg.grid(row=next_avail_row,
                                column=1,
                                padx=self.MW_PADX,
                                pady=self.MW_PADY,
                                sticky='w')
        next_avail_row += 1

        self.qq_side = self.QQSideSetter(
            self,
            var_name='qq_side',
            display_name='Side length of each QQ square',
            start_val=ls.qq_side)
        self.qq_side.grid(row=next_avail_row,
                          column=1,
                          padx=self.MW_PADX,
                          pady=self.MW_PADY,
                          sticky='w')
        # TODO: Display left/right margins that are left after this setting
        # TODO: Optional set-by-LR-margin.
        next_avail_row += 1

        cb_text = ('Size of area to clear at center of each '
                   'section for writing section number')
        self.centerbox_wh = self.IntVarSetter(self,
                                              var_name='centerbox_wh',
                                              display_name=cb_text,
                                              start_val=ls.centerbox_wh)
        self.centerbox_wh.grid(row=next_avail_row,
                               column=1,
                               sticky='w',
                               padx=self.MW_PADX,
                               pady=self.MW_PADY)
        next_avail_row += 1

        #################################
        # CONFIGURE LINES / FILL
        #################################

        self.qq_fill_RGBA = self.QQColorSetter(self, RGBA=ls.qq_fill_RGBA)
        self.qq_fill_RGBA.grid(row=next_avail_row,
                               column=1,
                               sticky='w',
                               padx=self.MW_PADX,
                               pady=self.MW_PADY)
        next_avail_row += 1

        next_avail_row = self.LINE_CONFIG_FIRST_ROW
        self.sec_line = self.LineSetter(self,
                                        var_name='sec_line',
                                        display_name='Section Line',
                                        stroke=ls.sec_line_stroke,
                                        RGBA=ls.sec_line_RGBA)
        self.sec_line.grid(row=next_avail_row, column=1, sticky='w')
        next_avail_row += 1

        self.ql_line = self.LineSetter(self,
                                       var_name='ql',
                                       display_name='Half-Dividing Line',
                                       stroke=ls.ql_stroke,
                                       RGBA=ls.ql_RGBA)
        self.ql_line.grid(row=next_avail_row, column=1, sticky='w')
        next_avail_row += 1

        self.qql_line = self.LineSetter(self,
                                        var_name='qql',
                                        display_name='Quarter-Dividing Line',
                                        stroke=ls.qql_stroke,
                                        RGBA=ls.qql_RGBA)
        self.qql_line.grid(row=next_avail_row, column=1, sticky='w')
        next_avail_row += 1

        #################################
        # WHAT TO WRITE / FONTS / TEXT CONFIGURE
        #################################
        self.write_header = tk.BooleanVar(self,
                                          value=ls.write_header,
                                          name='write_header')
        self.write_header_chkbtn = Checkbutton(
            self,
            text='Write Header in Top Margin',
            onvalue=True,
            offvalue=False,
            variable=self.write_header)
        self.write_header_chkbtn.grid(row=next_avail_row,
                                      column=1,
                                      sticky='w',
                                      padx=self.MW_PADX,
                                      pady=self.MW_PADY)
        next_avail_row += 1

        tf = _EditorFrame.TYPEFACES_BY_FP.get(ls.headerfont_typeface,
                                              _EditorFrame.DEFAULT_FONT_KEY)
        self.header_font = self.FontSetter(self,
                                           font_size=ls.headerfont_size,
                                           display_name='Header Font',
                                           var_name='headerfont',
                                           typeface=tf,
                                           RGBA=ls.headerfont_RGBA)
        self.header_font.grid(row=next_avail_row, column=1, sticky='w')
        next_avail_row += 1

        self.y_header_marg = self.IntVarSetter(
            self,
            var_name='y_header_marg',
            start_val=ls.y_header_marg,
            display_name=
            'How far above grid to write header (within top margin)')
        self.y_header_marg.grid(row=next_avail_row,
                                column=1,
                                padx=self.MW_PADX,
                                pady=self.MW_PADY,
                                sticky='w')
        next_avail_row += 1

        self.write_section_numbers = tk.BooleanVar(
            self, value=ls.write_section_numbers, name='write_section_numbers')
        self.write_section_numbers_chkbtn = Checkbutton(
            self,
            text='Write Section Numbers',
            onvalue=True,
            offvalue=False,
            variable=self.write_section_numbers)
        self.write_section_numbers_chkbtn.grid(row=next_avail_row,
                                               column=1,
                                               sticky='w',
                                               padx=self.MW_PADX,
                                               pady=self.MW_PADY)
        next_avail_row += 1

        tf = _EditorFrame.TYPEFACES_BY_FP.get(ls.secfont_typeface,
                                              _EditorFrame.DEFAULT_FONT_KEY)
        self.section_numbers_font = self.FontSetter(
            self,
            font_size=ls.secfont_size,
            display_name='Section Number Font',
            var_name='secfont',
            typeface=tf,
            RGBA=ls.secfont_RGBA)
        self.section_numbers_font.grid(row=next_avail_row,
                                       column=1,
                                       sticky='w')
        next_avail_row += 1

        self.write_lot_numbers = tk.BooleanVar(self,
                                               value=ls.write_lot_numbers,
                                               name='write_lot_numbers')
        self.write_lot_numbers_chkbtn = Checkbutton(
            self,
            text='Write lot numbers within the appropriate QQ(s)',
            onvalue=True,
            offvalue=False,
            variable=self.write_lot_numbers)
        self.write_lot_numbers_chkbtn.grid(row=next_avail_row,
                                           column=1,
                                           sticky='w',
                                           padx=self.MW_PADX,
                                           pady=self.MW_PADY)
        next_avail_row += 1

        tf = _EditorFrame.TYPEFACES_BY_FP.get(ls.lotfont_typeface,
                                              _EditorFrame.DEFAULT_FONT_KEY)
        self.lot_font = self.FontSetter(self,
                                        font_size=ls.lotfont_size,
                                        display_name='Lot Number Font',
                                        var_name='lotfont',
                                        typeface=tf,
                                        RGBA=ls.lotfont_RGBA)
        self.lot_font.grid(row=next_avail_row, column=1, sticky='w')
        next_avail_row += 1

        self.lot_num_offset_px = self.IntVarSetter(
            self,
            var_name='lot_num_offset_px',
            start_val=ls.lot_num_offset_px,
            display_name=
            'Lot number distance from top-left corner of QQ (in px)')
        self.lot_num_offset_px.grid(row=next_avail_row,
                                    column=1,
                                    padx=self.MW_PADX,
                                    pady=self.MW_PADY,
                                    sticky='w')
        next_avail_row += 1

        self.write_tracts = tk.BooleanVar(self,
                                          value=ls.write_tracts,
                                          name='write_tracts')
        self.write_tracts_chkbtn = Checkbutton(
            self,
            text='Write all tracts at the bottom',
            onvalue=True,
            offvalue=False,
            variable=self.write_tracts)
        self.write_tracts_chkbtn.grid(row=next_avail_row,
                                      column=1,
                                      sticky='w',
                                      padx=self.MW_PADX,
                                      pady=self.MW_PADY)
        next_avail_row += 1

        tf = _EditorFrame.TYPEFACES_BY_FP.get(ls.tractfont_typeface,
                                              _EditorFrame.DEFAULT_FONT_KEY)
        self.tract_font = self.FontSetter(self,
                                          font_size=ls.tractfont_size,
                                          display_name='Tract Font',
                                          var_name='tractfont',
                                          typeface=tf,
                                          RGBA=ls.tractfont_RGBA)
        self.tract_font.grid(row=next_avail_row, column=1, sticky='w')
        next_avail_row += 1

        # A customized RGBASetter for warningfont_RGBA, since we don't
        # need to set typeface or size:
        wfont_txt = 'Font color for writing errors/warnings'
        self.warning_font_RGBA = _EditorFrame.RGBASetter(
            self,
            display_name=wfont_txt,
            show_opacity=False,
            var_name='warningfont_RGBA',
            RGBA=ls.warningfont_RGBA)
        self.warning_font_RGBA.rgba_frame.grid(row=0, column=1)
        lbl = tk.Label(self.warning_font_RGBA, text=wfont_txt)
        lbl.grid(row=0, column=0)
        self.warning_font_RGBA.grid(row=next_avail_row, column=1, sticky='w')
        next_avail_row += 1

        #################################
        # TractTextBox margins and other tract-writing configurables
        #################################
        self.y_px_before_tracts = self.IntVarSetter(
            self,
            var_name='y_px_before_tracts',
            start_val=ls.y_px_before_tracts,
            display_name=
            'Distance between bottom of the grid and the first written tract')
        self.y_px_before_tracts.grid(row=next_avail_row,
                                     column=1,
                                     padx=self.MW_PADX,
                                     pady=self.MW_PADY,
                                     sticky='w')
        next_avail_row += 1

        self.x_text_left_marg = self.IntVarSetter(
            self,
            var_name='x_text_left_marg',
            start_val=ls.x_text_left_marg,
            display_name='Left Margin (for tract text below grid)')
        self.x_text_left_marg.grid(row=next_avail_row,
                                   column=1,
                                   padx=self.MW_PADX,
                                   pady=self.MW_PADY,
                                   sticky='w')
        next_avail_row += 1

        self.x_text_right_marg = self.IntVarSetter(
            self,
            var_name='x_text_right_marg',
            start_val=ls.x_text_right_marg,
            display_name='Right Margin (for tract text below grid)')
        self.x_text_right_marg.grid(row=next_avail_row,
                                    column=1,
                                    padx=self.MW_PADX,
                                    pady=self.MW_PADY,
                                    sticky='w')
        next_avail_row += 1

        self.y_px_between_tracts = self.IntVarSetter(
            self,
            var_name='y_px_between_tracts',
            start_val=ls.y_px_between_tracts,
            display_name='Space between lines of text')
        self.y_px_between_tracts.grid(row=next_avail_row,
                                      column=1,
                                      padx=self.MW_PADX,
                                      pady=self.MW_PADY,
                                      sticky='w')
        next_avail_row += 1

        self.paragraph_indent = self.IntVarSetter(
            self,
            var_name='paragraph_indent',
            start_val=ls.paragraph_indent,
            display_name='Paragraph indent (in spaces, not pixels or inches)')
        self.paragraph_indent.grid(row=next_avail_row,
                                   column=1,
                                   padx=self.MW_PADX,
                                   pady=self.MW_PADY,
                                   sticky='w')
        next_avail_row += 1

        self.new_line_indent = self.IntVarSetter(
            self,
            var_name='new_line_indent',
            start_val=ls.new_line_indent,
            display_name='Linebreak indent (in spaces, not pixels or inches)')
        self.new_line_indent.grid(row=next_avail_row,
                                  column=1,
                                  padx=self.MW_PADX,
                                  pady=self.MW_PADY,
                                  sticky='w')
        next_avail_row += 1

        self.justify_tract_text = tk.BooleanVar(self,
                                                value=ls.justify_tract_text,
                                                name='justify_tract_text')
        self.justify_tract_text_chkbtn = Checkbutton(
            self,
            text='Justify tract text',
            onvalue=True,
            offvalue=False,
            variable=self.justify_tract_text)
        self.justify_tract_text_chkbtn.grid(row=next_avail_row,
                                            column=1,
                                            sticky='w',
                                            padx=self.MW_PADX,
                                            pady=self.MW_PADY)
        next_avail_row += 1

        # Set the bool variables, according to the attributes in `ls`
        # (i.e. enact the settings in the `load_settings` object).
        # Note: This is not optimal design, but it seems to solve a
        # weird bug. Back when these values were set at the time that
        # the variables/checkbuttons themselves were created, the
        # _EditorFrame would fail to actually set them (to either True
        # or False), maybe 5% of the time. When clicking "Load Preset"
        # button repeatedly, with nothing different, would sometimes get
        # different results, and I could not reliably recreate the bug.
        # This is ineligant, but seems(?) to fix it...
        for var_name in [
                'write_header', 'write_section_numbers', 'write_lot_numbers',
                'write_tracts', 'justify_tract_text'
        ]:
            getattr(self, var_name).set(getattr(ls, var_name))
Example #15
0
class MainWindow:
    def __init__(self) -> None:
        self.Root = Tk()
        self.App = Frame(self.Root, padding=(5, 2))
        self.UpdatesFrame = LabelFrame(self.App,
                                       text=L.UpdatesFrame,
                                       borderwidth=2,
                                       relief='sunken',
                                       padding=(5, 2))
        self.upd_enabled = BooleanVar()  # Флаг обновлений
        self.upd_unit = StringVar()  # Единица измерения времени
        self.time_units = {
            Minutes: L.Minutes,
            Hours: L.Hours,
            Days: L.Days,
            Weeks: L.Weeks,
            Months: L.Months
        }
        self.size_units = {
            Bytes: L.Bytes,
            KBytes: L.KBytes,
            MBytes: L.MBytes,
            GBytes: L.GBytes,
            TBytes: L.TBytes
        }  # Список единиц измерения времени
        self.maxfsize = StringVar()  # Максимальный размер файла
        self.size_unit = StringVar()  # Единица измерения информации
        self.units_amount1 = StringVar()  # Количество единиц
        self.quar = BooleanVar()  # False - удалять, True - карантин
        self.quar_path = StringVar()  # Расположение карантина
        self.rpt_enabled = BooleanVar()  # Флаг отправки отчета
        self.email = StringVar()  # Адрес отправки
        self.passwd = StringVar()  # Пароль исходящего ящика
        self.rpt_unit = StringVar()  # Единица измерения времени
        self.units_amount2 = StringVar()  # Количество единиц

        self.Upd_Label1 = Label(self.UpdatesFrame, text=L.Upd_Label1)
        self.Upd_Checkbutton1 = Checkbutton(self.UpdatesFrame,
                                            variable=self.upd_enabled)
        self.Upd_Label2 = Label(self.UpdatesFrame, text=L.Upd_Label2)
        self.Upd_Spinbox1 = Spinbox(self.UpdatesFrame,
                                    textvariable=self.units_amount1,
                                    from_=1,
                                    to=999999999,
                                    width=4)
        self.Upd_OptionMenu1 = OptionMenu(self.UpdatesFrame, self.upd_unit,
                                          *self.time_units.values())
        self.Upd_Button1 = Button(
            self.UpdatesFrame,
            text=L.Upd_Button1,
            command=lambda: EntryOptionsWindow('AV_SOURCES', self.Root))

        self.ScanFrame = LabelFrame(self.App,
                                    text=L.ScanFrame,
                                    borderwidth=2,
                                    relief='sunken',
                                    padding=(5, 2))
        self.Scn_Label1 = Label(self.ScanFrame, text=L.Scn_Label1)
        self.Scn_Spinbox1 = Spinbox(self.ScanFrame,
                                    textvariable=self.maxfsize,
                                    from_=0,
                                    to=999999999,
                                    width=8)

        self.Quar_Label = Label(self.ScanFrame, text=L.Quar_Label)
        self.Quar_RadButton1 = Radiobutton(self.ScanFrame,
                                           text=L.Quar_RadButton1,
                                           variable=self.quar,
                                           value=False)
        self.Quar_RadButton2 = Radiobutton(self.ScanFrame,
                                           text=L.Quar_RadButton2,
                                           variable=self.quar,
                                           value=True)

        self.Scn_OptionMenu1 = OptionMenu(self.ScanFrame, self.size_unit,
                                          *self.size_units.values())
        self.Scn_Edit_Targets = Button(
            self.ScanFrame,
            text=L.Scn_Edit_Targets,
            command=lambda: EntryOptionsWindow(
                'SCAN_TARGETS', self.Root, select_path=True))
        self.Scn_Edit_Exceptions = Button(
            self.ScanFrame,
            text=L.Scn_Edit_Exceptions,
            command=lambda: EntryOptionsWindow('SCAN_EXCLUDE', self.Root))
        self.Quar_Button1 = Button(
            self.ScanFrame,
            text=L.Quar_Button1,
            command=lambda: self.quar_path.set(filedialog.askdirectory()))

        self.ReportFrame = LabelFrame(self.App,
                                      text=L.ReportFrame,
                                      borderwidth=2,
                                      relief='sunken',
                                      padding=(5, 2))

        self.Rpt_Label1 = Label(self.ReportFrame, text=L.Rpt_Label1)
        self.Rpt_Checkbutton1 = Checkbutton(self.ReportFrame,
                                            variable=self.rpt_enabled)
        self.Rpt_Label2 = Label(self.ReportFrame, text=L.Rpt_Label2)
        self.Rpt_Entry1 = Entry(self.ReportFrame,
                                textvariable=self.email,
                                width=32)
        self.Rpt_Label3 = Label(self.ReportFrame, text=L.Rpt_Label3)
        self.Rpt_Entry2 = Entry(self.ReportFrame,
                                textvariable=self.passwd,
                                width=32,
                                show='*')
        self.Rpt_Label4 = Label(self.ReportFrame, text=L.Rpt_Label4)
        self.Rpt_Spinbox1 = Spinbox(self.ReportFrame,
                                    textvariable=self.units_amount2,
                                    from_=1,
                                    to=999999999,
                                    width=4)
        self.Rpt_OptionMenu1 = OptionMenu(self.ReportFrame, self.rpt_unit,
                                          *self.time_units.values())
        self.Rpt_Button1 = Button(
            self.ReportFrame,
            text=L.Rpt_Button1,
            command=lambda: EntryOptionsWindow('SEND_TO', self.Root))

        self.Buttons = Frame(self.App, padding=(5, 2))
        self.Button1 = Button(self.Buttons,
                              text=L.Done,
                              command=self.save_conf)
        self.Button2 = Button(self.Buttons,
                              text=L.Cancel,
                              command=self.Root.destroy)

    def main(self) -> None:
        self.upd_unit.set(self.time_units[type(UPDATE_FREQ)])
        self.units_amount1.set(UPDATE_FREQ.value)
        self.upd_enabled.set(CHECK_FOR_UPDATES)
        self.Upd_Checkbutton1.configure(command=(lambda: self.__change_state(
            self.upd_enabled, self.Upd_Label2, self.Upd_Spinbox1, self.
            Upd_OptionMenu1, self.Upd_Button1) and self.upd_enabled.set(
                not self.upd_enabled.get())))
        self.Rpt_Checkbutton1.configure(command=(lambda: self.__change_state(
            self.rpt_enabled, self.Rpt_Label2, self.Rpt_Entry1, self.
            Rpt_Label3, self.Rpt_Entry2, self.Rpt_Label4, self.Rpt_Spinbox1,
            self.Rpt_OptionMenu1, self.Rpt_Button1) and self.rpt_enabled.set(
                not self.rpt_enabled.get())))
        self.maxfsize.set(MAX_FILE_SIZE.value)
        self.size_unit.set(self.size_units[type(MAX_FILE_SIZE)])
        self.quar.set(REMOVE_THREATS)
        self.quar_path.set(QUARANTINE_PATH)
        self.rpt_enabled.set(SEND_SCAN_REPORTS)
        self.email.set(SEND_FROM)
        try:
            with open('/root/.cobpwd', 'r') as f:
                self.passwd.set(f.read())
        except FileNotFoundError:
            pass
        self.rpt_unit.set(self.time_units[type(SEND_FREQ)])
        self.units_amount2.set(SEND_FREQ.value)

        self.App.pack(fill='both', expand=True)
        center_win(self.Root, '500x500')
        self.Root.resizable(False, False)
        self.Root.title('CobraAV Configuration')

        self.UpdatesFrame.place(y=0, height=150, width=490)
        self.__change_state(self.upd_enabled, self.Upd_Label2,
                            self.Upd_Spinbox1, self.Upd_OptionMenu1)

        self.__change_state(self.rpt_enabled, self.Rpt_Label2, self.Rpt_Entry1,
                            self.Rpt_Label3, self.Rpt_Entry2, self.Rpt_Label4,
                            self.Rpt_Spinbox1, self.Rpt_OptionMenu1,
                            self.Rpt_Button1)

        self.Upd_Label1.place(relx=.01, rely=.05)  # Проверять обновления ?
        self.Upd_Checkbutton1.place(relx=.8, rely=.05)  # Да/Нет

        self.Upd_Label2.place(relx=.01, rely=.3)  # Частота проверки
        self.Upd_Spinbox1.place(relx=.55, rely=.3, width=60)  # Количество
        self.Upd_OptionMenu1.place(relx=.72, rely=.28)  # Единицы измерения
        self.Upd_Button1.place(relx=.01, rely=.65)  # Источники сигнатур

        self.ScanFrame.place(y=150, height=150, width=490)

        self.Scn_Label1.place(relx=.01, rely=.05)  # Максимальный размер файла
        self.Scn_Spinbox1.place(relx=.55, rely=.05, width=60)  # Количество

        self.Quar_Label.place(relx=.01, rely=.35)
        self.Quar_RadButton1.place(
            relx=.52, rely=.35)  # Переключатель на удаление угрозы
        self.Quar_RadButton2.place(
            relx=.72,
            rely=.35)  # Переключатель на добавление вкарантина угрозы
        self.Quar_Button1.place(relx=.56, rely=.65)  # Расположение карантина

        self.Scn_OptionMenu1.place(relx=.72, rely=.014)  # Единицы измерения
        self.Scn_Edit_Targets.place(relx=.01, rely=.65)  # Цели сканирования
        self.Scn_Edit_Exceptions.place(relx=.33, rely=.65)  # Исключения

        self.Rpt_Label1.place(relx=.01, rely=.05)  # Отправлять отчеты ?
        self.Rpt_Checkbutton1.place(relx=.8, rely=.05)  # Да/Нет

        self.ReportFrame.place(y=300, height=150, width=490)
        self.Rpt_Label2.place(relx=.01, rely=.35)  # Адрес отправки отчетов:
        self.Rpt_Entry1.place(relx=.35,
                              rely=.35)  # Ввод адреса отправки отчетов
        self.Rpt_Label3.place(relx=.01, rely=.50)  # Пароль:
        self.Rpt_Entry2.place(relx=.35, rely=.50)  # Ввод пароля:
        self.Rpt_Label4.place(relx=.01, rely=.75)  # Частота отправки
        self.Rpt_Spinbox1.place(relx=.35, rely=.75, width=60)  # Количество
        self.Rpt_OptionMenu1.place(relx=.52, rely=.72)  # Единицы измерения
        self.Rpt_Button1.place(relx=.72, rely=.74)  # Получатели

        self.Buttons.place(y=450, height=50, width=490)
        self.Button1.place(relx=.62, rely=.2)  # Кнопка "Готово"
        self.Button2.place(relx=.82, rely=.2)  # Кнопка "Отмена"

        self.Root.mainloop()

    @staticmethod
    def __change_state(state: BooleanVar, *args: Widget) -> None:
        for i in args:
            i.configure(state=('disabled', 'normal')[state.get()])

    def save_conf(self) -> None:
        size_units = {v: k for k, v in self.size_units.items()}
        time_units = {v: k for k, v in self.time_units.items()}

        def wrap_list(a: 'list[str]') -> str:
            return '[' + ', \n'.join(f"r'{i}'" for i in a) + ']'

        def wrap_cls(_unit: Variable, amount: Variable) -> str:
            unit = _unit.get()
            if unit in size_units:
                return size_units[unit].__name__ + f'({amount.get()})'
            elif unit in time_units:
                return time_units[unit].__name__ + f'({amount.get()})'
            else:
                raise NotImplementedError

        if self.upd_enabled.get() and not CHECK_FOR_UPDATES:
            system('systemctl enable cobra-update.service')
            system('systemctl restart cobra-update.service')
        else:
            system('systemctl stop cobra-update.service')
            system('systemctl disable cobra-update.service')

        if self.rpt_enabled.get() and not SEND_SCAN_REPORTS:
            system('systemctl enable cobra-notify.service')
            system('systemctl restart cobra-notify.service')
        else:
            system('systemctl stop cobra-notify.service')
            system('systemctl disable cobra-notify.service')

        with open('/root/.cobpwd', 'w') as f:
            f.write(self.passwd.get())

        with open(CONF_PATH, 'w') as f:
            f.write(f"""from libunits import *

CHECK_FOR_UPDATES = {int(self.upd_enabled.get())}  # Check for updates
UPDATE_FREQ = {wrap_cls(self.upd_unit, self.units_amount1)}  # Check interval
MAX_FILE_SIZE = {wrap_cls(self.size_unit, self.maxfsize)}  # Max file size

# Antivirus database sources
AV_SOURCES = {wrap_list(AV_SOURCES)}

# Antivirus database path
DB_PATH = r'{DB_PATH}'

# On threat:
# 0 - quarantine
# 1 - remove
REMOVE_THREATS = {int(self.quar.get())}

# Directories to scan
SCAN_TARGETS = {wrap_list(SCAN_TARGETS)}

# Exclude from scanning
SCAN_EXCLUDE = {wrap_list(SCAN_EXCLUDE)}

# quarantine location
QUARANTINE_PATH = r'{self.quar_path.get() or QUARANTINE_PATH}'

# Send scan reports
SEND_SCAN_REPORTS = {int(self.rpt_enabled.get())}

# Scan reports frequency
SEND_FREQ = {wrap_cls(self.rpt_unit, self.units_amount2)}

# Send from this email
SEND_FROM = r'{self.email.get()}'

# Send to these emails
SEND_TO = {wrap_list(SEND_TO)}

# SMTP settings (preset for gmail)
SMTP_HOST = 'smtp.gmail.com'
SMTP_PORT = 587

# GUI Language
LANG = '{LANG}'
""")
        self.Root.destroy()
Example #16
0
    def __init__(self, parent, sourceCmdGen, audioRec):
        Toplevel.__init__(self, parent)
        #self.transient(parent)
        self.cmdGen = sourceCmdGen
        self.audioRec = audioRec

        self.title(string="Screen Recorder - Settings")
        self.iconbitmap("icon.ico")
        self.resizable(width=False, height=False)
        self.minsize(400, 450)
        self.columnconfigure(0, weight=1)
        self.rowconfigure(0, weight=1)

        self.notebook = Notebook(self)
        self.notebook.grid(row=0,
                           column=0,
                           columnspan=4,
                           sticky="nesw",
                           padx=5,
                           pady=5)

        ########################################### VIDEO OPTIONS ##############################################
        self.videoOptions = Frame(self)
        self.videoOptions.columnconfigure(1, weight=1)

        Label(self.videoOptions,
              text="Suggested FPS (Not guaranteed): ").grid(row=0, column=0)

        self.FPSVar = StringVar()
        self.FPSspin = Spinbox(self.videoOptions,
                               from_=1,
                               to=120,
                               textvariable=self.FPSVar)
        self.FPSspin.grid(row=0, column=1, sticky="ew", pady=5)
        self.FPSVar.set(self.cmdGen.fps)

        self.hwaccVar = StringVar()

        Label(
            self.videoOptions,
            text=
            "Encoding (GPU encoding may improve perfomance, but also may result in corrupted files):"
        ).grid(row=1, column=0, columnspan=2, sticky="w")
        self.buttonCPU = Radiobutton(self.videoOptions,
                                     text="CPU-only encoder",
                                     variable=self.hwaccVar,
                                     value="CPU")
        self.buttonCPU.grid(row=2, column=0, columnspan=2, sticky="w")
        self.buttonNVENC = Radiobutton(
            self.videoOptions,
            text="Nvidia NVENC GPU encoder (experimental)",
            variable=self.hwaccVar,
            value="NVENC")
        self.buttonNVENC.grid(row=3, column=0, columnspan=2, sticky="w")

        if self.cmdGen.encoder == "mpeg4":
            self.hwaccVar.set("CPU")
        elif self.cmdGen.encoder == "h264_nvenc":
            self.hwaccVar.set("NVENC")

        self.drawMouseVar = IntVar()
        self.drawMouseVar.set(self.cmdGen.drawMouse)
        self.drawMouseCheck = Checkbutton(self.videoOptions,
                                          text="Draw mouse",
                                          variable=self.drawMouseVar)
        self.drawMouseCheck.grid(row=5,
                                 column=0,
                                 columnspan=2,
                                 sticky='w',
                                 pady=10)

        self.notebook.add(self.videoOptions, text="Video Options")

        ######################################################################################################################
        ############################################### AUDIO OPTIONS #####################################################
        self.audioOptions = Frame(self)
        self.audioOptions.columnconfigure(0, weight=1)
        self.audioOptions.rowconfigure(2, weight=1)

        self.audInputVar = StringVar()

        self.defaultCheck = Radiobutton(
            self.audioOptions,
            text="Record from the default device only",
            value="default",
            variable=self.audInputVar)
        self.defaultCheck.grid(row=0, column=0, sticky="w")

        self.selectedCheck = Radiobutton(self.audioOptions,
                                         text="Record from these devices:",
                                         value="selected",
                                         variable=self.audInputVar)
        self.selectedCheck.grid(row=1, column=0, sticky="w")

        self.audioDevices = Listbox(self.audioOptions, selectmode="multiple")
        self.audioDevices.grid(row=2, column=0, sticky='news')

        self.deviceIDList = []
        for i in range(self.audioRec.getDeviceCount()):
            if self.audioRec.isInputDevice(i):
                self.deviceIDList.append(i)
                self.audioDevices.insert(
                    "end",
                    self.audioRec.getAPIName(i) + " || " +
                    self.audioRec.getDeviceName(i))
                if i in self.audioRec.devices:
                    self.audioDevices.selection_set('end')

        self.audInputVar.trace("w", self.audButtonChange)
        if self.audioRec.devices == [None]:
            self.audInputVar.set("default")
        else:
            self.audInputVar.set("selected")

        self.notebook.add(self.audioOptions, text="Audio Options")

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

        self.okButton = Button(self,
                               text="OK",
                               width=9,
                               command=self.applyQuit)
        self.okButton.grid(row=1, column=1, padx=4, pady=4)

        self.cancelButton = Button(self,
                                   text="Cancel",
                                   width=9,
                                   command=self.destroy)
        self.cancelButton.grid(row=1, column=2, padx=4, pady=4)

        self.applyButton = Button(self,
                                  text="Apply",
                                  width=9,
                                  command=self.apply)
        self.applyButton.grid(row=1, column=3, padx=4, pady=4)

        self.grab_set()
        self.focus()
Example #17
0
    def __init__(self) -> None:
        self.Root = Tk()
        self.App = Frame(self.Root, padding=(5, 2))
        self.UpdatesFrame = LabelFrame(self.App,
                                       text=L.UpdatesFrame,
                                       borderwidth=2,
                                       relief='sunken',
                                       padding=(5, 2))
        self.upd_enabled = BooleanVar()  # Флаг обновлений
        self.upd_unit = StringVar()  # Единица измерения времени
        self.time_units = {
            Minutes: L.Minutes,
            Hours: L.Hours,
            Days: L.Days,
            Weeks: L.Weeks,
            Months: L.Months
        }
        self.size_units = {
            Bytes: L.Bytes,
            KBytes: L.KBytes,
            MBytes: L.MBytes,
            GBytes: L.GBytes,
            TBytes: L.TBytes
        }  # Список единиц измерения времени
        self.maxfsize = StringVar()  # Максимальный размер файла
        self.size_unit = StringVar()  # Единица измерения информации
        self.units_amount1 = StringVar()  # Количество единиц
        self.quar = BooleanVar()  # False - удалять, True - карантин
        self.quar_path = StringVar()  # Расположение карантина
        self.rpt_enabled = BooleanVar()  # Флаг отправки отчета
        self.email = StringVar()  # Адрес отправки
        self.passwd = StringVar()  # Пароль исходящего ящика
        self.rpt_unit = StringVar()  # Единица измерения времени
        self.units_amount2 = StringVar()  # Количество единиц

        self.Upd_Label1 = Label(self.UpdatesFrame, text=L.Upd_Label1)
        self.Upd_Checkbutton1 = Checkbutton(self.UpdatesFrame,
                                            variable=self.upd_enabled)
        self.Upd_Label2 = Label(self.UpdatesFrame, text=L.Upd_Label2)
        self.Upd_Spinbox1 = Spinbox(self.UpdatesFrame,
                                    textvariable=self.units_amount1,
                                    from_=1,
                                    to=999999999,
                                    width=4)
        self.Upd_OptionMenu1 = OptionMenu(self.UpdatesFrame, self.upd_unit,
                                          *self.time_units.values())
        self.Upd_Button1 = Button(
            self.UpdatesFrame,
            text=L.Upd_Button1,
            command=lambda: EntryOptionsWindow('AV_SOURCES', self.Root))

        self.ScanFrame = LabelFrame(self.App,
                                    text=L.ScanFrame,
                                    borderwidth=2,
                                    relief='sunken',
                                    padding=(5, 2))
        self.Scn_Label1 = Label(self.ScanFrame, text=L.Scn_Label1)
        self.Scn_Spinbox1 = Spinbox(self.ScanFrame,
                                    textvariable=self.maxfsize,
                                    from_=0,
                                    to=999999999,
                                    width=8)

        self.Quar_Label = Label(self.ScanFrame, text=L.Quar_Label)
        self.Quar_RadButton1 = Radiobutton(self.ScanFrame,
                                           text=L.Quar_RadButton1,
                                           variable=self.quar,
                                           value=False)
        self.Quar_RadButton2 = Radiobutton(self.ScanFrame,
                                           text=L.Quar_RadButton2,
                                           variable=self.quar,
                                           value=True)

        self.Scn_OptionMenu1 = OptionMenu(self.ScanFrame, self.size_unit,
                                          *self.size_units.values())
        self.Scn_Edit_Targets = Button(
            self.ScanFrame,
            text=L.Scn_Edit_Targets,
            command=lambda: EntryOptionsWindow(
                'SCAN_TARGETS', self.Root, select_path=True))
        self.Scn_Edit_Exceptions = Button(
            self.ScanFrame,
            text=L.Scn_Edit_Exceptions,
            command=lambda: EntryOptionsWindow('SCAN_EXCLUDE', self.Root))
        self.Quar_Button1 = Button(
            self.ScanFrame,
            text=L.Quar_Button1,
            command=lambda: self.quar_path.set(filedialog.askdirectory()))

        self.ReportFrame = LabelFrame(self.App,
                                      text=L.ReportFrame,
                                      borderwidth=2,
                                      relief='sunken',
                                      padding=(5, 2))

        self.Rpt_Label1 = Label(self.ReportFrame, text=L.Rpt_Label1)
        self.Rpt_Checkbutton1 = Checkbutton(self.ReportFrame,
                                            variable=self.rpt_enabled)
        self.Rpt_Label2 = Label(self.ReportFrame, text=L.Rpt_Label2)
        self.Rpt_Entry1 = Entry(self.ReportFrame,
                                textvariable=self.email,
                                width=32)
        self.Rpt_Label3 = Label(self.ReportFrame, text=L.Rpt_Label3)
        self.Rpt_Entry2 = Entry(self.ReportFrame,
                                textvariable=self.passwd,
                                width=32,
                                show='*')
        self.Rpt_Label4 = Label(self.ReportFrame, text=L.Rpt_Label4)
        self.Rpt_Spinbox1 = Spinbox(self.ReportFrame,
                                    textvariable=self.units_amount2,
                                    from_=1,
                                    to=999999999,
                                    width=4)
        self.Rpt_OptionMenu1 = OptionMenu(self.ReportFrame, self.rpt_unit,
                                          *self.time_units.values())
        self.Rpt_Button1 = Button(
            self.ReportFrame,
            text=L.Rpt_Button1,
            command=lambda: EntryOptionsWindow('SEND_TO', self.Root))

        self.Buttons = Frame(self.App, padding=(5, 2))
        self.Button1 = Button(self.Buttons,
                              text=L.Done,
                              command=self.save_conf)
        self.Button2 = Button(self.Buttons,
                              text=L.Cancel,
                              command=self.Root.destroy)
class DownloadPopup(Toplevel):
    def __init__(self, master, info: dict, message_store: MessageStore, video_id: str = None):
        Toplevel.__init__(self, master)
        self.bind('<Escape>', lambda _: self.cancel())
        self.bind('<Return>', lambda _: self.ok())
        self.title('Get VOD')
        self.transient(master)
        self.grab_set()

        self.info: dict = info
        self.message_store: MessageStore = message_store
        self.chat_downloader: ChatDownloader = None

        self.updated_info: bool = False
        self.status_var = StringVar(value='...')
        self.content = Frame(self)
        self.content.pack(padx=20, pady=15)
        self.video_title_var = StringVar(value='')
        self.download_info_var = StringVar(value='')
        self.eta_var = StringVar(value='')
        Label(self.content, text='Enter a VOD URL or video ID:').pack(side=TOP, anchor=W, pady=(0, 5))
        self.entry = Entry(self.content, width=50)
        self.entry.pack(side=TOP, padx=2, pady=(0, 5))
        Label(self.content, textvariable=self.status_var).pack(side=TOP, anchor=W, pady=(0, 5))

        self.progress_var = IntVar(value=0)
        self.progress = Progressbar(self.content, variable=self.progress_var, maximum=1)
        self.progress.pack(side=TOP, fill=X, padx=2)

        Label(self.content, textvariable=self.video_title_var).pack(side=TOP, anchor=W, pady=(0, 5))
        Label(self.content, textvariable=self.download_info_var).pack(side=TOP, anchor=W, pady=(0, 5))
        Label(self.content, textvariable=self.eta_var).pack(side=TOP, anchor=W, pady=(0, 5))

        self.overwrite_cache_var = BooleanVar(value=False)
        self.overwrite_cache_check = Checkbutton(self.content, text='Overwrite cache',
                                                 variable=self.overwrite_cache_var)
        self.overwrite_cache_check.pack(side=TOP, anchor=W, pady=(0, 5))

        self.button = Button(self.content, text='OK', command=self.ok)
        self.button.pack(side=TOP)
        self.update()
        x_coord = self.master.winfo_x() + (self.master.winfo_width() // 2) - (self.winfo_width() // 2)
        y_coord = self.master.winfo_y() + (self.master.winfo_height() // 2) - (self.winfo_height() // 2)
        self.geometry(f'{self.winfo_width()}x{self.winfo_height()}+{x_coord}+{y_coord}')
        self.entry.focus_set()
        self.protocol('WM_DELETE_WINDOW', self.cancel)

        if video_id:
            self.entry.insert(0, video_id)
            self.overwrite_cache_check.focus_set()

            chat_filename: str = os.path.join(CACHE_FOLDER, f'chat-{video_id}.json')
            if not os.path.exists(chat_filename):
                self.ok()

    def cancel(self):
        if self.chat_downloader:
            self.chat_downloader.kill()
        self.info.clear()
        self.info.update({'title': 'Chat Player'})
        self.destroy()

    def ok(self):
        self.button.config(state=DISABLED)
        self.overwrite_cache_check.config(state=DISABLED)
        self.status_var.set('Validating...')
        self.after(1, self.validate)

    def validate(self):
        video_id: str = self.entry.get()
        if 'http' in video_id or 'twitch.tv' in video_id:
            video_id = parse_url(video_id)
        if len(video_id) > 0 and video_exists(video_id):
            self.chat_downloader = ChatDownloader(video_id, overwrite_cache=self.overwrite_cache_var.get())
            self.chat_downloader.start()
            self.after(1, self.download)
        else:
            self.status_var.set('Error: Invalid URL or video ID.')
            self.button.config(state=NORMAL)

    def download(self):
        if not self.chat_downloader.info:
            self.status_var.set('Getting info')
            self.after(100, self.download)
        elif not self.chat_downloader.messages:
            if not self.updated_info:
                self.status_var.set('Downloading chat')
                self.info.update(self.chat_downloader.info)
                self.video_title_var.set(self.info.get('title'))
                self.updated_info = True
            self.progress_var.set(self.chat_downloader.progress)
            self.download_info_var.set(
                f'{self.chat_downloader.num_messages} messages downloaded. '
                f'Duration {self.chat_downloader.duration_done_str}/{self.chat_downloader.duration_str}.')
            self.eta_var.set(f'ETA: {self.chat_downloader.eta_str}')
            self.after(100, self.download)
        else:
            self.message_store.set_messages(self.chat_downloader.messages)
            self.destroy()
Example #19
0
 def __init__(self, master, ordinances=False, **kwargs):
     super(Options, self).__init__(master, **kwargs)
     self.ancestors = IntVar()
     self.ancestors.set(4)
     self.descendants = IntVar()
     self.spouses = IntVar()
     self.ordinances = IntVar()
     self.contributors = IntVar()
     self.start_indis = StartIndis(self)
     self.fid = StringVar()
     btn = Frame(self)
     entry_fid = EntryWithMenu(btn, textvariable=self.fid, width=16)
     entry_fid.bind("<Key>", self.enter)
     label_ancestors = Label(self,
                             text=_("Number of generations to ascend"))
     entry_ancestors = EntryWithMenu(self,
                                     textvariable=self.ancestors,
                                     width=5)
     label_descendants = Label(self,
                               text=_("Number of generations to descend"))
     entry_descendants = EntryWithMenu(self,
                                       textvariable=self.descendants,
                                       width=5)
     btn_add_indi = Button(btn,
                           text=_("Add a FamilySearch ID"),
                           command=self.add_indi)
     btn_spouses = Checkbutton(self,
                               text="\t" +
                               _("Add spouses and couples information"),
                               variable=self.spouses)
     btn_ordinances = Checkbutton(self,
                                  text="\t" + _("Add Temple information"),
                                  variable=self.ordinances)
     btn_contributors = Checkbutton(self,
                                    text="\t" +
                                    _("Add list of contributors in notes"),
                                    variable=self.contributors)
     self.start_indis.grid(row=0, column=0, columnspan=3)
     entry_fid.grid(row=0, column=0, sticky="w")
     btn_add_indi.grid(row=0, column=1, sticky="w")
     btn.grid(row=1, column=0, columnspan=2, sticky="w")
     entry_ancestors.grid(row=2, column=0, sticky="w")
     label_ancestors.grid(row=2, column=1, sticky="w")
     entry_descendants.grid(row=3, column=0, sticky="w")
     label_descendants.grid(row=3, column=1, sticky="w")
     btn_spouses.grid(row=4, column=0, columnspan=2, sticky="w")
     if ordinances:
         btn_ordinances.grid(row=5, column=0, columnspan=3, sticky="w")
     btn_contributors.grid(row=6, column=0, columnspan=3, sticky="w")
     entry_ancestors.focus_set()
class NewSliderWindow(Toplevel):
    def __init__(self, master=None):
        super().__init__(master=master)
        self.set_basic()

        self.bind('<Configure>', lambda e: self.place_buttons())

    def set_basic(self):
        self.overrideredirect(1)
        self.set_geometry()
        self.set_scale()
        self.set_checkButton()
        self.set_save_closeButtons()

    def set_geometry(self):
        self.width = 60
        parentX = self.master.winfo_rootx()
        parentY = self.master.winfo_rooty()
        parentHeight = self.master.winfo_height()
        parentWidth = self.master.winfo_width()
        self.geometry(
            '%dx%d+%d+%d' %
            (self.width, parentHeight, parentX + parentWidth + 2, parentY))

    def set_save_closeButtons(self):
        self.saveButton = Button(self,
                                 image=saveIcon,
                                 command=self.update_image)
        self.cancelButton = Button(self, image=closeIcon, command=self.cancel)

        self.saveButton.place(relx=0.1, rely=0.8, relwidth=0.4)
        self.cancelButton.place(relx=0.55, rely=0.8, relwidth=0.4)

        self.saveButton.place(
            relx=0.1,
            rely=1 - ((0.4 * self.width) / self.master.winfo_height()),
            relwidth=0.4)
        self.cancelButton.place(
            relx=0.55,
            rely=1 - ((0.4 * self.width) / self.master.winfo_height()),
            relwidth=0.4)

    def place_buttons(self):
        self.saveButton.place(
            relx=0.03,
            rely=1 - ((0.45 * self.width) / self.master.winfo_height()),
            relwidth=0.45)
        self.cancelButton.place(
            relx=0.52,
            rely=1 - ((0.45 * self.width) / self.master.winfo_height()),
            relwidth=0.45)

    def set_scale(self):
        self.var = IntVar()
        self.scale = Scale(self,
                           length=256,
                           from_=0,
                           to=255,
                           orient=VERTICAL,
                           command=lambda e: self.update_preview(
                               int(self.var.get()), self.cbVal.get()),
                           variable=self.var,
                           digits=1,
                           resolution=1)
        self.scale.place(relx=0, rely=0.1, relwidth=0.9, relheight=0.7)
        self.scale.set(0)

    def set_checkButton(self):
        self.cbVal = IntVar()
        self.cb = Checkbutton(self,
                              width=0,
                              variable=self.cbVal,
                              command=lambda: self.update_preview(
                                  int(self.var.get()), self.cbVal.get()))
        self.cb.place(relx=0.4, rely=0.78)
        self.cb.invoke()

    #UPDATE IMAGE ON SLIDER CHANGE
    def update_preview(self, thresholdVal, checkBoxVal):
        self.master.image.threshold(thresholdVal, checkBoxVal)
        self.master.update_visible_image()

    #UPDATE IMAGE ON "SAVE" AND UPDATE HISTOGRAM
    def update_image(self):
        self.master.update_visible_image()
        self.master.image.copy = copy.deepcopy(self.master.image.cv2Image)
        self.master.image.fill_histogram()
        self.master.update_child_windows()
        self.master.thresholdScaleWindow = None
        self.master.manager.new_state(self.master.image.cv2Image)
        self.destroy()

    #GO BACK TO ORIGINAL ON "CANCEL"
    def cancel(self):
        self.master.image.cv2Image = copy.deepcopy(self.master.image.copy)
        self.master.update_visible_image()
        self.master.image.fill_histogram()
        self.master.update_child_windows()
        self.master.thresholdScaleWindow = None
        self.destroy()
Example #21
0
    def create_widgets(self):
        ''' Creates all widgets.
        '''
        rts_lbl = Label(self, text='Return to scale:')
        rts_lbl.grid(row=0, column=0, padx=XPAD_VALUE, pady=YPAD_VALUE,
                     sticky=W)
        self._create_frame_with_radio_btns(self, 'RETURN_TO_SCALE',
                                           ['VRS', 'CRS'],
                                           row_index=1, column_index=0)

        orientation_lbl = Label(self, text='Orientation:')
        orientation_lbl.grid(row=0, column=1, sticky=W, padx=XPAD_VALUE,
                             pady=YPAD_VALUE)
        self._create_frame_with_radio_btns(self, 'ORIENTATION',
                                           ['Input', 'Output'],
                                           row_index=1, column_index=1)

        model_lbl = Label(self, text='Model:')
        model_lbl.grid(row=0, column=2, padx=XPAD_VALUE, pady=YPAD_VALUE,
                       sticky=W)
        self._create_frame_with_radio_btns(self, 'DEA_FORM',
                                           ['Envelopment', 'Multiplier'],
                                           row_index=1, column_index=2,
                                           add_both=False)

        other_lbl = Label(self, text='Others:')
        other_lbl.grid(row=0, column=3, sticky=W, padx=XPAD_VALUE)

        max_slacks = IntVar()
        self.options['MAXIMIZE_SLACKS'] = max_slacks
        frame_other_options = Frame(self)
        self.max_slack_box = max_slacks_check_btn = Checkbutton(
            frame_other_options, text='Two phase', variable=max_slacks,
            command=(lambda: self.on_check_box_click(
                max_slacks, 'MAXIMIZE_SLACKS')))
        max_slacks_check_btn.grid(row=1, column=0, sticky=W)
        super_efficiency = IntVar()
        self.options['USE_SUPER_EFFICIENCY'] = super_efficiency
        super_efficiency_check_btn = Checkbutton(frame_other_options,
                                                 text='Super efficiency',
                                                 variable=super_efficiency,
                                                 command=(
                                                 lambda: self.on_check_box_click(
                                                 super_efficiency,
                                                 'USE_SUPER_EFFICIENCY')))
        super_efficiency_check_btn.grid(row=2, column=0, sticky=W)
        peel_the_onion = IntVar()
        self.options['PEEL_THE_ONION'] = peel_the_onion
        peel_the_onion_check_btn = Checkbutton(
            frame_other_options, text='Peel the onion', variable=peel_the_onion,
            command=(lambda: self.on_check_box_click(peel_the_onion,
                     'PEEL_THE_ONION')))
        peel_the_onion_check_btn.grid(row=3, column=0, sticky=W)
        frame_other_options.grid(row=1, column=3, padx=XPAD_VALUE,
                                 pady=YPAD_VALUE, sticky=W)

        frame_for_toleramce = Frame(self)
        tolerance_lbl = Label(frame_for_toleramce,
                              text='Multiplier model tolerance:')
        tolerance_lbl.grid(row=0, column=0, padx=XPAD_VALUE, pady=YPAD_VALUE,
                           sticky=W)
        tolerance_ent = Entry(frame_for_toleramce, width=5,
                              textvariable=self.multi_tol_strvar)
        tolerance_ent.insert(END, 0)
        tolerance_ent.grid(row=0, column=1, sticky=W, padx=XPAD_VALUE)
        categorical_lbl = Label(frame_for_toleramce, text='Categorical:')
        categorical_lbl.grid(row=1, column=0, padx=XPAD_VALUE,
                             pady=YPAD_VALUE, sticky=W)
        self.categorical_box = categorical_box = Combobox(
            frame_for_toleramce, textvariable=self.combobox_text_var,
            exportselection=0, state="readonly",
            width=20, values=(''),
            postcommand=self.change_categorical_box)
        categorical_box.grid(row=1, column=1, padx=XPAD_VALUE,
                             pady=YPAD_VALUE, sticky=W)
        frame_for_toleramce.grid(row=5, column=0, sticky=W, padx=XPAD_VALUE,
                                 pady=YPAD_VALUE, columnspan=4)
Example #22
0
hFinal.place(relx=0.82, rely=0.2, anchor=CENTER)
total = Entry(janela)
total.place(relx=0.65, rely=0.8, anchor=CENTER)
calculado = Entry(janela)
calculado.place(relx=0.65, rely=0.9, anchor=CENTER)

chuveiroEstado = BooleanVar()
chuveiroEstado.set(False)
lampadaEstado = BooleanVar()
lampadaEstado.set(False)
tomadaEstado = BooleanVar()
tomadaEstado.set(False)
arEstado = BooleanVar()
arEstado.set(False)

lampada = Checkbutton(janela, text='Lâmpadas', var=lampadaEstado)
lampada.place(relx=0.407, rely=0.55, anchor=CENTER)
chuveiro = Checkbutton(janela, text='Chuveiro', var=chuveiroEstado)
chuveiro.place(relx=0.4, rely=0.65, anchor=CENTER)
tomada = Checkbutton(janela, text='Tomadas', var=tomadaEstado)
tomada.place(relx=0.61, rely=0.55, anchor=CENTER)
ar = Checkbutton(janela, text='Ar Condicionado', var=arEstado)
ar.place(relx=0.655, rely=0.65, anchor=CENTER)

#FUNÇÕES


def aluno():
    mensagem = messagebox.showinfo(
        "Discente", "Nome: Milena Teixeira Correia\n\nR.A: 22.219.011-8")
Example #23
0
    def __init__(self,
                 master=None,
                 attributes='standard',
                 target_var=None,
                 header='Desired Tract Attributes',
                 show_ok=True,
                 show_cancel=True,
                 ok_button_text='Confirm Attributes',
                 cancel_button_text='Cancel',
                 confirm_cancel_prompt=None,
                 exit_after_ok=True,
                 prompt_after_ok=None,
                 external_var_dict=None,
                 **kw):
        """
        :param master: The tkinter master (same as for tkinter.Frame)
        :param target_var: A tk.StringVar to which the chosen
        attributes should be stored when the OK button is clicked.
        Stored as a single string, with attribute names separated by
        a comma and no spaces.
        :param attributes: Which attributes to allow the user to select
        from; may be passed as a list, or as a string with attributes
        separated by commas (defaults to 'standard')
        :param header: Text to be placed above the attribute options.
        :param show_ok: Include the OK button.
        :param ok_button_text: A string, for custom text for the OK
        button.
        :param prompt_after_ok: A string to display in a messagebox
        after the OK button has been clicked. Defaults to None.
        :param exit_after_ok: Whether to close the window after OK
        button is clicked. Defaults to False.
        :param cancel_button_text: A string, for custom text for the
        Cancel button.
        :param show_cancel: Include the Cancel button.
        IMPORTANT: If the Cancel button is clicked, it will set the
        `target_var` to the string 'CANCEL' and close the window.
        :param confirm_cancel_prompt: A string to display in a
        yes/no messagebox when the Cancel button is clicked. Defaults
        to None.
        :param external_var_dict: A dict with the key 'attrib_list',
        to which the chosen attributes should be set (as a list of
        strings). (Only used by `prompt_attrib()` -- probably ignore
        this parameter.)
        :param kw: Kwargs to pass through to tkinter.Frame at init.
        """

        default_master = False
        if not master:
            default_master = True
            master = tk.Tk()
            master.title('Select pyTRS Tract Attributes')

        tk.Frame.__init__(self, master, **kw)
        self.master = master
        if default_master:
            self.pack(padx=20, pady=20)

        if not target_var:
            target_var = tk.StringVar()
        self.target_var = target_var

        if not external_var_dict:
            external_var_dict = {'attrib_list': []}
        self.external_var_dict = external_var_dict

        self.show_ok = show_ok
        self.show_cancel = show_cancel
        self.prompt_after_ok = prompt_after_ok
        self.exit_after_ok = exit_after_ok
        self.confirm_cancel_prompt = confirm_cancel_prompt

        if isinstance(attributes, str):
            if attributes.lower() == 'standard':
                attributes = PromptAttrib.STANDARD_OPTIONS
            elif attributes.lower() == 'all':
                attributes = PromptAttrib.ALL_ATTRIBUTES.keys()
            else:
                attributes = [
                    at.lower().strip() for at in attributes.split(',')
                ]

        if header:
            hdr = tk.Label(self, text=str(header), font='"Arial Black"')
            hdr.grid(row=0, column=0, sticky='n')

        # Generate a new IntVar for each available attribute option, set
        # its value to the default value per STANDARD_ATTRIBUTES, store
        # it as an instance variable, and also set it to the attrib_dict.
        # Finally, create a checkbutton for that attribute.
        # So for attribute 'qqs':
        #   -> self.qqs_var --> a tk.IntVar with initial value 0
        #   -> self.attrib_dict['qqs'] --> self.qqs_var
        #   -> <create a checkbutton for qqs>
        self.attrib_dict = dict()
        cur_row = 5
        for att in attributes:
            new_var = tk.IntVar()
            new_var.set(PromptAttrib.ALL_ATTRIBUTES[att][1])
            setattr(self, f"{att}_var", new_var)
            self.attrib_dict[att] = new_var
            cb = Checkbutton(self,
                             text=PromptAttrib.ALL_ATTRIBUTES[att][0],
                             var=self.attrib_dict[att])
            cb.grid(row=cur_row, column=0, sticky='w', pady=2)
            cur_row += 1

        ctrl_frame = tk.Frame(self)
        ctrl_frame.grid(row=cur_row, column=0, padx=10, pady=10)

        if show_ok:
            ok_btn = tk.Button(ctrl_frame,
                               text=ok_button_text,
                               command=self.ok_clicked)
            ok_btn.grid(row=0, column=1, sticky='e', padx=20, pady=10)

        if show_cancel:
            cancel_btn = tk.Button(ctrl_frame,
                                   text=cancel_button_text,
                                   command=self.cancel_clicked)
            cancel_btn.grid(row=0, column=0, sticky='e', padx=20, pady=10)
    def makegridsquare(self, parent, imageobj, setguidata):
        frame = tk.Frame(parent,
                         width=self.thumbnailsize + 14,
                         height=self.thumbnailsize + 24)
        frame.obj = imageobj
        try:
            if setguidata:
                if not os.path.exists(imageobj.thumbnail):
                    self.fileManager.makethumb(imageobj)
                try:
                    buffer = pyvips.Image.new_from_file(imageobj.thumbnail)
                    img = ImageTk.PhotoImage(
                        Image.frombuffer("RGB", [buffer.width, buffer.height],
                                         buffer.write_to_memory()))
                except:  # Pillow fallback
                    img = ImageTk.PhotoImage(Image.open(imageobj.thumbnail))
            else:
                img = imageobj.guidata['img']

            canvas = tk.Canvas(frame,
                               width=self.thumbnailsize,
                               height=self.thumbnailsize)
            tooltiptext = tk.StringVar(frame, self.tooltiptext(imageobj))
            ToolTip(canvas, msg=tooltiptext.get, delay=1)
            canvas.create_image(self.thumbnailsize / 2,
                                self.thumbnailsize / 2,
                                anchor="center",
                                image=img)
            check = Checkbutton(frame,
                                textvariable=imageobj.name,
                                variable=imageobj.checked,
                                onvalue=True,
                                offvalue=False)
            canvas.grid(column=0, row=0, sticky="NSEW")
            check.grid(column=0, row=1, sticky="N")
            frame.rowconfigure(0, weight=4)
            frame.rowconfigure(1, weight=1)
            frame.config(height=self.thumbnailsize + 12)
            if (
                    setguidata
            ):  # save the data to the image obj to both store a reference and for later manipulation
                imageobj.setguidata({
                    "img": img,
                    "frame": frame,
                    "canvas": canvas,
                    "check": check,
                    "show": True,
                    "tooltip": tooltiptext
                })
            # anything other than rightclicking toggles the checkbox, as we want.
            canvas.bind("<Button-1>", partial(bindhandler, check, "invoke"))
            canvas.bind("<Button-3>", partial(self.displayimage, imageobj))
            check.bind("<Button-3>", partial(self.displayimage, imageobj))
            canvas.bind("<MouseWheel>", partial(bindhandler, parent, "scroll"))
            frame.bind("<MouseWheel>",
                       partial(bindhandler, self.imagegrid, "scroll"))
            check.bind("<MouseWheel>",
                       partial(bindhandler, self.imagegrid, "scroll"))
            if imageobj.moved:
                frame.configure(highlightbackground="green",
                                highlightthickness=2)
                if os.path.dirname(
                        imageobj.path) in self.fileManager.destinationsraw:
                    color = self.fileManager.destinations[indexOf(
                        self.fileManager.destinationsraw,
                        os.path.dirname(imageobj.path))]['color']
                    frame['background'] = color
                    canvas['background'] = color
            frame.configure(height=self.thumbnailsize + 10)
            if imageobj.dupename:
                frame.configure(highlightbackground="yellow",
                                highlightthickness=2)
        except Exception as e:
            logging.error(e)
        return frame
	def __init__(self,root):
		self.root = root

		self.check_line_on = BooleanVar()   

		self.code_text = ScrolledText(self.root,bd=4,relief=GROOVE)
		self.code_text.place(x=0,y=0,height=300,width=300)


		self.output_code = ScrolledText(self.root,bd=4,relief=GROOVE)
		self.output_code.place(x=300,y=0,height=300,width=300) 

		self.control_frame = Frame(self.root,bd=2,relief=GROOVE)
		self.control_frame.place(x=25,y=310,height=130,width=550)

		# ................ controls in control frames ...................

		self.languages = ['python','C','C++','java','php','C#']

		self.borders = ['dotted','dashed','solid','double','groove','ridge','inset','none','hidden']

		#self.border_width = ['2px','4px','6px','8px','10px','medium','thick']

		self.border_clrs = ['red','black','gray','white','green','yellow','pink','cyan','sky blue']

		self.styles = ['default', 'emacs', 'friendly', 'colorful', 'autumn', 'murphy', 
		 'monokai', 'perldoc', 'pastie', 'borland', 'trac', 'native', 'fruity', 'bw', 
		'vim', 'vs', 'tango', 'rrt', 'xcode', 'igor', 'paraiso-light', 'paraiso-dark', 'lovelace', 
		'algol', 'algol_nu', 'arduino', 'rainbow_dash', 'abap',
		 'solarized-dark', 'solarized-light', 'sas', 'stata', 'stata-light', 'stata-dark', 'inkpot']

		self.style_combo = Combobox(self.control_frame,width=20,values=self.styles,justify=CENTER)
		self.style_combo.set('Select Style')
		self.style_combo.place(x=10,y=5)

		self.border_combo = Combobox(self.control_frame,width=20,values=self.borders,justify=CENTER)
		self.border_combo.set('Select Border')
		self.border_combo.place(x=10,y=45)

		
		self.border_color_combo = Combobox(self.control_frame,width=20,values=self.border_clrs,justify=CENTER)
		self.border_color_combo.set('Border Color')
		self.border_color_combo.place(x=10,y=85)

		self.language_combo = Combobox(self.control_frame,width=15,values=self.languages,justify=CENTER)
		self.language_combo.set('python')
		self.language_combo.place(x=180,y=40)

		self.Line_no_check = Checkbutton(self.control_frame,text='Enable Line No.',onvalue=True,offvalue=False,
			variable=self.check_line_on)
		self.Line_no_check.place(x=180,y=9)

		


		highlight_btn = ttk.Button(self.control_frame,text='Highlight',command=self.highlight_code)
		highlight_btn.place(x=300,y=10)

		copy_edit_code = ttk.Button(self.control_frame,text='Copy Code',command=self.copy_code)
		copy_edit_code.place(x=300,y=50)

		clear_input_text = ttk.Button(self.control_frame,text='Clear Input Box',
			width=20,command=lambda:self.code_text.delete(0.0,END))
		clear_input_text.place(x=400,y=10)

		clear_output_text = ttk.Button(self.control_frame,text='Clear Output Box',
			width=20,command=lambda:self.output_code.delete(0.0,END))
		clear_output_text.place(x=400,y=50)
Example #26
0
class TkApp(Tk):
    """
    The main Tk class for the gui of simplebackup
    """
    def __init__(self, **kwargs):
        super().__init__()
        title = "Simple Backup | V" + __version__
        self.wm_title(title)
        self.protocol("WM_DELETE_WINDOW", self.on_closing)

        self.__thread = None
        self.__files_found = 0
        self.__files_copied = 0

        config_fn = kwargs.get("config_fn", user_config_filepath())
        self.__app_config = Config_Handler(config_fn)
        self.__curr_config = self.__app_config.default_config_i

        self.__menu = Menu(self)
        self.__menu_file = Menu(self.__menu, tearoff=0)
        self.__menu_file.add_command(label="Quit", command=self.quit)
        self.__menu_config = Menu(self.__menu, tearoff=0)
        self.__menu_config.add_command(label="New", command=self.new_config)
        self.__menu_config.add_command(label="Load",
                                       command=self.switch_config)
        self.__menu_config.add_command(label="Change Default",
                                       command=self.change_default_config)
        self.__menu_config.add_command(label="Rename Current",
                                       command=self.rename_curr_conf)
        self.__menu_config.add_separator()
        self.__menu_config.add_command(label="Delete Current",
                                       command=self.delete_current_config)
        self.__menu_config.add_command(label="Delete All",
                                       command=self.reset_config)
        self.__menu_help = Menu(self.__menu, tearoff=0)
        self.__menu_help.add_command(label="Check for Updates",
                                     command=self.show_update_popup)
        self.__menu_help.add_command(label="About",
                                     command=self.show_about_popup)
        self.__menu.add_cascade(label="File", menu=self.__menu_file)
        self.__menu.add_cascade(label="Config", menu=self.__menu_config)
        self.__menu.add_cascade(label="Help", menu=self.__menu_help)

        self.__title_l = Label(self, text=title, font=(16))
        self.__curr_config_name_l = Label(self)
        self.__last_backup_l = Label(self)
        self.__set_versions_to_keep = Button(
            self,
            text="Set Versions To Keep",
            command=self.update_versions_to_keep)
        self.__versions_to_keep_l = Label(self)
        self.__inc_folder_bnt = Button(self,
                                       text="Include Another Folder",
                                       command=self.add_included_folder)
        self.__included_folders_lb = Listbox(self, height=4)
        self.__included_folders_lb.bind("<<ListboxSelect>>",
                                        self.remove_selected_included_folder)
        self.__included_folders_lb.bind('<FocusOut>',
                                        self.deselect_included_folder)
        self.__excl_folder_bnt = Button(self,
                                        text="Exclude Another Folder",
                                        command=self.add_excluded_folder)
        self.__excluded_folders_lb = Listbox(self, height=4)
        self.__excluded_folders_lb.bind("<<ListboxSelect>>",
                                        self.remove_selected_excluded_folder)
        self.__excluded_folders_lb.bind('<FocusOut>',
                                        self.deselect_excluded_folder)
        self.__backup_to_bnt = Button(self,
                                      text="Backup Folder",
                                      command=self.set_backup_folder)
        self.__backup_folder_l = Label(self)
        self.__use_tar_l = Label(self, text="Use Tar")
        self.__use_tar_var = BooleanVar(self)
        self.__use_tar_var.trace_add("write", self.use_tar_changed)
        self.__use_tar = Checkbutton(self, variable=self.__use_tar_var)
        self.__backup_start_bnt = Button(self,
                                         text="Start Backup",
                                         command=self.start_backup)
        self.__progress = Progressbar(self)
        self.__statusbar = Label(self, text="ok", relief=SUNKEN, anchor=W)
        self._load_display()
        self._layout()

        if self.__app_config.show_help:
            self.show_help_popup()

    def on_closing(self):
        """
        called on window close
        """
        if self.__files_found != self.__files_copied:
            if messagebox.askyesno("Backup Running",
                                   "Do you want to stop the backup?"):
                self.destroy()
        else:
            self.destroy()

    def _load_display(self):
        """
        load the widgets with data from the current backup config,
        should be run after loading a config from file and at app launch
        """
        self.__versions_to_keep = self.__app_config.get_versions_to_keep(
            self.__curr_config)
        self.__included_folders = self.__app_config.get_included_folders(
            self.__curr_config)
        self.__excluded_folders = self.__app_config.get_excluded_folders(
            self.__curr_config)
        self.__backup_location = self.__app_config.get_backup_path(
            self.__curr_config)

        curr_conf_name = self.__app_config.get_config_name(self.__curr_config)
        self.__curr_config_name_l.config(text=f"Config Name: {curr_conf_name}")
        self.__last_backup_l.config(
            text=
            f"Last Known Backup: {self.__app_config.get_human_last_backup(self.__curr_config)}"
        )
        self.__versions_to_keep_l.config(text=self.__versions_to_keep)
        self.__included_folders_lb.delete(0, END)
        self.__included_folders_lb.insert(0, *self.__included_folders)
        self.__excluded_folders_lb.delete(0, END)
        self.__excluded_folders_lb.insert(0, *self.__excluded_folders)
        self.__backup_folder_l.config(text=str(self.__backup_location))
        self.__use_tar_var.set(
            self.__app_config.get_use_tar(self.__curr_config))

    def switch_config(self):
        """
        switches what config to use for backup,
        asks the user for a config to load,
        then loads the display
        """
        next_combo = ask_combobox("Load Config", "Config Name",
                                  self.__app_config.get_config_names())
        if next_combo != None:
            self.__curr_config = next_combo
            self._load_display()

    def change_default_config(self):
        """
        switches what config to use for the default backup,
        asks the user for a config to load
        """
        next_combo = ask_combobox("Default Config", "Config Name",
                                  self.__app_config.get_config_names())
        if next_combo != None:
            self.__app_config.default_config_i = next_combo

    def rename_curr_conf(self):
        """
        rename a existing config,
        will ask the user in a popup string input
        """
        new_name = simpledialog.askstring("Rename Config", "New Name")
        if new_name:
            self.__app_config.rename_config(self.__curr_config, new_name)
            self._load_display()

    def new_config(self):
        """
        creates a new empty backup config,
        asks the user for config name
        """
        name = simpledialog.askstring("New Config", "Config Name")
        if name:
            self.__app_config.create_config(name)

    def delete_current_config(self):
        """
        deletes the current selected config, asks the user to confirm
        """
        if messagebox.askyesno(
                "Confirm Delete",
                "Are you sure you want to delete the current config?"):
            self.__app_config.remove_config(self.__curr_config)
            self.__curr_config = self.__app_config.default_config_i
            self._load_display()

    def reset_config(self):
        """
        resets all the user configs, asks the user to confirm
        """
        if messagebox.askyesno(
                "Confirm Reset",
                "Are you sure you want to reset the all configurations?"):
            self.__app_config.reset_config()
            self.__curr_config = self.__app_config.default_config_i
            self._load_display()

    def use_tar_changed(self, *args):
        """
        called each time the __use_tar_var is called
        """
        self.__app_config.set_use_tar(self.__curr_config,
                                      self.__use_tar_var.get())

    def update_versions_to_keep(self):
        """
        update the number of versions to keep,
        asks the user for a integer
        """
        new_val = simpledialog.askinteger(
            "Versions To Keep",
            "How many backups do you want to keep",
            minvalue=0)
        if new_val != self.__versions_to_keep and new_val != None:
            self.__versions_to_keep = new_val
            self.__app_config.set_versions_to_keep(self.__curr_config,
                                                   self.__versions_to_keep)
            self.__versions_to_keep_l.config(text=self.__versions_to_keep)

    def deselect_included_folder(self, *args):
        """
        deselects the selected element in included folder
        """
        self.__included_folders_lb.selection_clear(0, END)

    def deselect_excluded_folder(self, *args):
        """
        deselects the selected element in excluded folder
        """
        self.__excluded_folders_lb.selection_clear(0, END)

    def add_included_folder(self):
        """
        add a folder to include in the backup,
        will ask user for a directory
        """
        folder = filedialog.askdirectory(initialdir="/",
                                         title="Select Folder To Backup")
        if folder:
            folder_path = Path(folder)
            if folder_path != self.__backup_location:
                self.__included_folders.append(folder_path)
                self.__included_folders_lb.insert(END, folder_path)
                self.__app_config.set_included_folders(self.__curr_config,
                                                       self.__included_folders)
            else:
                messagebox.showwarning(
                    title="Folder Same As Backup Path",
                    message=
                    "You selected a folder that was the same as the backup path!"
                )

    def remove_selected_included_folder(self, *args):
        """
        remove the currently selected
        item in the included folders ListBox,
        will ask the user to confirm
        """
        curr_selection = self.__included_folders_lb.curselection()
        # check if there is a selection
        if curr_selection:
            if messagebox.askyesno("Confirm Delete",
                                   "Are you want to delete this folder?"):
                index_to_del = curr_selection[0]
                self.__included_folders.pop(index_to_del)
                self.__app_config.set_included_folders(self.__curr_config,
                                                       self.__included_folders)
                self.__included_folders_lb.delete(index_to_del)
            self.deselect_included_folder()

    def add_excluded_folder(self):
        """
        add a folder to exclude in the backup,
        will ask user for a directory
        """
        folder = filedialog.askdirectory(initialdir="/",
                                         title="Select Folder To Exclude")
        if folder:
            folder_path = Path(folder)
            self.__excluded_folders.append(folder_path)
            self.__excluded_folders_lb.insert(END, folder_path)
            self.__app_config.set_excluded_folders(self.__curr_config,
                                                   self.__excluded_folders)

    def remove_selected_excluded_folder(self, *args):
        """
        remove the currently selected
        item in the excluded folders ListBox,
        will ask the user to confirm
        """

        curr_selection = self.__excluded_folders_lb.curselection()
        # check if there is a selection
        if curr_selection:
            if messagebox.askyesno("Confirm Delete",
                                   "Are you want to delete this folder?"):
                index_to_del = curr_selection[0]
                self.__excluded_folders.pop(index_to_del)
                self.__app_config.set_excluded_folders(self.__curr_config,
                                                       self.__excluded_folders)
                self.__excluded_folders_lb.delete(index_to_del)
            self.deselect_excluded_folder()

    def set_backup_folder(self):
        """
        sets the backup folder by asking the user for a base directory
        """
        folder = filedialog.askdirectory(initialdir="/",
                                         title="Select Where To Backup To")
        if folder:
            self.__backup_location = Path(folder)
            self.__backup_folder_l.config(text=folder)
            self.__app_config.set_backup_path(self.__curr_config,
                                              self.__backup_location)

    def enable_gui(self):
        """
        enable the gui buttons, run when a backup has completed
        """
        self.__set_versions_to_keep.config(state=NORMAL)
        self.__inc_folder_bnt.config(state=NORMAL)
        self.__included_folders_lb.config(state=NORMAL)
        self.__excl_folder_bnt.config(state=NORMAL)
        self.__excluded_folders_lb.config(state=NORMAL)
        self.__backup_to_bnt.config(state=NORMAL)
        self.__use_tar.config(state=NORMAL)
        self.__backup_start_bnt.config(state=NORMAL)

    def disable_gui(self):
        """
        disable the gui buttons, run when a backup is started
        """
        self.__set_versions_to_keep.config(state=DISABLED)
        self.__inc_folder_bnt.config(state=DISABLED)
        self.__included_folders_lb.config(state=DISABLED)
        self.__excl_folder_bnt.config(state=DISABLED)
        self.__excluded_folders_lb.config(state=DISABLED)
        self.__backup_to_bnt.config(state=DISABLED)
        self.__use_tar.config(state=DISABLED)
        self.__backup_start_bnt.config(state=DISABLED)

    def progress_find_incr(self, finished=False):
        """
        increment the progress bar for finding
        files by 1 or mark as finished

            :param finished: mark the progressbar as finished
        """
        if finished:
            self.__progress.config(mode="determinate")
            self.__progress.config(value=0, maximum=self.__files_found)
            self.__statusbar.config(text=f"Found {self.__files_found} Files")
        else:
            self.__files_found += 1
            self.__progress.config(value=self.__files_found)
            self.__statusbar.config(
                text=f"Searching For Files, Found {self.__files_found} Files")

    def progress_copy_incr(self):
        """
        increment the progress bar for copying
        files by 1 or mark as finished
        """
        self.__files_copied += 1
        self.__progress.config(value=self.__files_copied)
        self.__statusbar.config(
            text=f"Copying Files {self.__files_copied} of {self.__files_found}"
        )
        if self.__files_copied == self.__files_found:
            self.__app_config.set_last_backup(self.__curr_config,
                                              datetime.utcnow())
            self.__last_backup_l.config(
                text=
                f"Last Known Backup: {self.__app_config.get_human_last_backup(self.__curr_config)}"
            )
            self.__statusbar.config(text=f"Finished Copying Files")
            messagebox.showinfo(title="Finished Copying Files",
                                message="Finished copying all found files")
            # reset counters
            self.__files_found = 0
            self.__files_copied = 0
            self.__progress.config(value=0, maximum=100)
            self.enable_gui()

    def start_backup(self):
        """
        starts the backup
        """
        if not self.__backup_location:
            # no backup location was selected
            messagebox.showwarning(
                title="Backup Location Not Selected",
                message="You did not select a backup location!")
        elif not self.__included_folders:
            # no folders where found to backup
            messagebox.showwarning(
                title="No Folders To Backup",
                message="You did not add any folders to backup!")
        else:
            # basic checks passed
            self.disable_gui()
            # prep for search of files
            self.__progress.config(mode="indeterminate")
            self.__statusbar.config(text=f"Searching For Files")

            self.__thread = BackupThread(
                self.__included_folders, self.__excluded_folders,
                self.__backup_location, self.__versions_to_keep,
                self.progress_find_incr, self.progress_copy_incr,
                self.handle_error_message, self.__use_tar_var.get())
            # start the background backup thread so GUI wont appear frozen
            self.__thread.start()

    def show_about_popup(self):
        """
        show the about popup
        """
        messagebox.showinfo(
            "About", "simplebackup V" + __version__ +
            """ is cross-platform backup program written in python.
This app was made by enchant97/Leo Spratt.
It is licenced under GPL-3.0""")

    def show_update_popup(self):
        """
        open the default webbrowser to the update url
        """
        webbrowser.open(UPDATE_URL)

    def show_help_popup(self):
        messagebox.showinfo(
            "Welcome",
            """Welcome to simplebackup, here is some help to get you started:
\nIncluding a folder to backup
    - Press the 'Include Folder' button to add a folder to backup
    - Remove a entry by clicking on the list below
\nExcluding a folder from the backup
    - Press the 'Exclude Folder' button to skip a folder to backup
    - Remove a entry by clicking on the list below
\nSetting where backups are stored
    - Click the 'Backup Folder' button to set where backups should be placed
\nMultiple backup configs
    Use the 'Config' button in the titlebar to change varius settings like creating a new config
\nVersions to keep
    This will be the number of backup to keep in the backup folder
""")
        self.__app_config.show_help = False

    def handle_error_message(self, error_type: ERROR_TYPES):
        self.__statusbar.config(text="Failed")
        if error_type is ERROR_TYPES.NO_BACKUP_WRITE_PERMISION:
            messagebox.showerror("No Write Permission",
                                 ERROR_TYPES.NO_BACKUP_WRITE_PERMISION.value)
        elif error_type is ERROR_TYPES.NO_BACKUP_READ_PERMISION:
            messagebox.showerror("No Read Permission",
                                 ERROR_TYPES.NO_BACKUP_READ_PERMISION.value)
        elif error_type is ERROR_TYPES.NO_FILES_FOUND_TO_BACKUP:
            messagebox.showerror("No Files Found",
                                 ERROR_TYPES.NO_FILES_FOUND_TO_BACKUP.value)
        elif error_type is ERROR_TYPES.NO_BACKUP_PATH_FOUND:
            messagebox.showerror("No Backup Path Found",
                                 ERROR_TYPES.NO_BACKUP_PATH_FOUND.value)
        self.__progress.config(mode="determinate")
        self.enable_gui()

    def _layout(self):
        self.config(menu=self.__menu)
        self.__title_l.pack(fill=X, pady=10, padx=5)
        self.__curr_config_name_l.pack(fill=X, padx=5)
        self.__last_backup_l.pack(fill=X, padx=5)
        self.__set_versions_to_keep.pack(fill=X, padx=5)
        self.__versions_to_keep_l.pack(fill=X, padx=5)
        self.__inc_folder_bnt.pack(fill=X, padx=5)
        self.__included_folders_lb.pack(fill=X, padx=5)
        self.__excl_folder_bnt.pack(fill=X, padx=5)
        self.__excluded_folders_lb.pack(fill=X, padx=5)
        self.__backup_to_bnt.pack(fill=X, padx=5)
        self.__backup_folder_l.pack(fill=X, padx=5)
        self.__use_tar_l.pack(fill=X, padx=5)
        self.__use_tar.pack(fill=X, padx=5)
        self.__backup_start_bnt.pack(fill=X, padx=5)
        self.__progress.pack(fill=X)
        self.__statusbar.pack(side=BOTTOM, fill=X)
        self.wm_minsize(300, self.winfo_height())
        self.wm_resizable(True, False)
Example #27
0
class App_test(object):
    def __init__(self):
        self.win = Tk()
        self.win.title('12306火车票查询系统V2.6')
        self.win.geometry('860x400')
        self.creat_res()
        self.add_train_info()
        self.add_check_button()
        self.res_config()
        self.train_message = {}
        # self.get_train_args()
        self.win.mainloop()

    def creat_res(self):
        self.v = IntVar()  #车票查询
        self.v.set(True)
        self.temp = StringVar()  #开始站
        self.temp2 = StringVar()  #目的站
        self.start_mon = StringVar()  #出发月
        self.start_day = StringVar()  #出发日
        self.start_year = StringVar()  #出啊年
        self.E_startstation = Entry(self.win, textvariable=self.temp)
        self.E_endstation = Entry(self.win, textvariable=self.temp2)
        self.La_startstation = Label(self.win, text="出发站:")
        self.La_endstation = Label(self.win, text="目的站:")
        self.La_time = Label(self.win, text="请选择出发时间-年-月-日", fg="blue")
        self.B_search = Button(self.win, text="搜索")
        self.R_site = Radiobutton(self.win,
                                  text="车票查询",
                                  variable=self.v,
                                  value=True)
        self.R_price = Radiobutton(self.win,
                                   text="票价查询",
                                   variable=self.v,
                                   value=False)
        self.B_buy_tick = Button(self.win, text="购票")
        self.C_year = Combobox(self.win, textvariable=self.start_year)
        self.C_mon = Combobox(self.win, textvariable=self.start_mon)
        self.La_s = Label(self.win, text="--")
        self.C_day = Combobox(self.win, textvariable=self.start_day)
        self.S_move = Scrollbar(self.win)
        self.E_startstation.place(x=70, y=10, width=65, height=30)
        self.E_endstation.place(x=70, y=60, width=65, height=30)
        self.La_startstation.place(x=10, y=10, width=50, height=30)
        self.La_endstation.place(x=10, y=60, width=50, height=30)
        self.La_time.place(x=10, y=100, width=150, height=30)
        self.C_year.place(x=10, y=140, width=70, height=30)
        self.C_mon.place(x=100, y=140, width=50, height=30)
        self.C_day.place(x=100, y=180, width=50, height=30)
        self.La_s.place(x=80, y=140, width=20, height=30)
        self.B_search.place(x=10, y=180, width=50, height=30)
        self.S_move.place(x=834, y=40, width=30, height=350)
        self.B_buy_tick.place(x=10, y=260, width=80, height=40)
        self.R_site.place(x=10, y=230, width=70, height=30)
        self.R_price.place(x=90, y=230, width=70, height=30)

    def res_config(self):
        self.C_year.config(values=[x for x in range(2018, 2020)])
        self.C_mon.config(values=["{:02d}".format(x)
                                  for x in range(1, 13)])  #时间格式是2018-01-01
        self.C_day.config(values=["{:02d}".format(x) for x in range(1, 32)])
        self.B_search.config(command=self.search_train_message)
        self.S_move.config(command=self.tree.yview)
        self.tree.config(yscrollcommand=self.S_move.set)

    def add_train_info(self):
        lis_train = ["C" + str(x) for x in range(0, 15)]
        tuple_train = tuple(lis_train)
        self.tree = Treeview(self.win,
                             columns=tuple_train,
                             height=30,
                             show="headings")
        self.tree.place(x=168, y=40, width=670, height=350)
        train_info = [
            ' 车次 ', ' 出发/到达站', '出发/到达时间', '历时 ', '商/特座', '一等座', '二等座', '高软',
            '软卧', '动卧', '硬卧', '软座', '硬座', '无座', '其他'
        ]
        for i in range(0, len(lis_train)):
            self.tree.column(lis_train[i],
                             width=len(train_info[i]) * 11,
                             anchor='center')
            self.tree.heading(lis_train[i], text=train_info[i])

    def add_check_button(self):
        self.v1 = IntVar()
        self.v2 = IntVar()
        self.v3 = IntVar()
        self.v4 = IntVar()
        self.v5 = IntVar()
        self.v6 = IntVar()
        self.v7 = IntVar()
        self.v1.set("T")
        self.Check_total = Checkbutton(self.win,
                                       text="全部车次",
                                       variable=self.v1,
                                       onvalue='T')
        self.Check_total.place(x=168, y=7, width=80, height=30)
        self.Check_total = Checkbutton(self.win,
                                       text="G-高铁",
                                       variable=self.v2,
                                       onvalue='T')
        self.Check_total.place(x=258, y=7, width=70, height=30)
        self.Check_total = Checkbutton(self.win,
                                       text="D-动车",
                                       variable=self.v3,
                                       onvalue='T')
        self.Check_total.place(x=348, y=7, width=60, height=30)
        self.Check_total = Checkbutton(self.win,
                                       text="Z-直达",
                                       variable=self.v4,
                                       onvalue='T')
        self.Check_total.place(x=418, y=7, width=60, height=30)
        self.Check_total = Checkbutton(self.win,
                                       text="T-特快",
                                       variable=self.v5,
                                       onvalue='T')
        self.Check_total.place(x=488, y=7, width=60, height=30)
        self.Check_total = Checkbutton(self.win,
                                       text="K-快速",
                                       variable=self.v6,
                                       onvalue='T')
        self.Check_total.place(x=568, y=7, width=60, height=30)
        self.Check_total = Checkbutton(self.win,
                                       text="其他",
                                       variable=self.v7,
                                       onvalue='T')
        self.Check_total.place(x=648, y=7, width=60, height=30)

    def get_train_args(self):  #输出获得的日期,出发站代码,目的站代码
        date = self.start_year.get() + "-" + self.start_mon.get(
        ) + "-" + self.start_day.get()
        start_station = self.temp.get()
        end_station = self.temp2.get()
        start_station_str = ""
        end_station_str = ""
        count1, count2 = 0, 0
        with open("res/dict2.txt", mode='r', encoding='utf-8') as f:
            mes = f.readlines()
            for i in mes:
                d = json.loads(i)
                if start_station in d:
                    start_station_str = d[start_station]
                else:
                    count1 += 1
                if end_station in d:
                    end_station_str = d[end_station]
                else:
                    count2 += 1
            if count1 == len(mes) or count2 == len(mes):
                messagebox.showwarning(title="友情提示", message="无法找到车站数据")
        return date, start_station_str, end_station_str

    def is_leapyear(self):
        #先判断输入是否是日期,如果是日期执行方法体,
        a = self.C_year.get()
        b = self.C_mon.get()
        c = self.C_day.get()
        pa_year = '20[\d][\d]'  # 2018
        if re.compile(pa_year).findall(a) and b in [
                "{:02d}".format(x) for x in range(1, 13)
        ] and c in ["{:02d}".format(x) for x in range(1, 32)]:
            nowtime = time.localtime()
            now_time_sp = time.mktime(nowtime)
            start_time = a + "-" + b + "-" + c + " 23:59:29"  #"2018-08-09  23:59:29"
            start_timestrip = time.strptime(start_time, "%Y-%m-%d %H:%M:%S")
            start_times = time.mktime(start_timestrip)
            days = (start_times - now_time_sp) / 60 / 60 / 24
            print(days)
            print(a, b, c)
            if days > 29:
                messagebox.showerror(title="警告", message="大于30天无法获取数据")
            elif days < 0:
                messagebox.showerror(title="警告", message="小于1天无法获取数据")
            elif days > 0 and days < 30:
                if int(a) % 4 == 0 and int(a) % 100 != 0 or int(
                        a) % 400 == 0:  #如果是闰年
                    if (int(b) in (1, 3, 5, 7, 8, 10, 12) and int(c) > 31) or (
                        (int(b) in (4, 6, 9, 11)
                         and int(c) > 30)) or (int(b) == 2 and int(c) > 29):
                        messagebox.showerror(title="警告", message="你确定这个月有这一天么")
                else:
                    if (int(b) in (1, 3, 5, 8, 10, 12) and int(c) > 31) or (
                        (int(b) in (4, 6, 9, 11)
                         and int(c) > 30)) or (int(b) == 2 and int(c) > 28):
                        messagebox.showerror(title="警告", message="你确定这个月有这一天么")
        else:
            messagebox.showerror(title="警告", message="请输入正确格式的年:月:日")

    def manage_date(self):  #处理时间,闰年以及当天时间
        self.is_leapyear()

    def change_str(self, mm):
        for i, j in mm.items():
            with open("res/dict.txt", mode='r', encoding='utf-8') as f:
                mes = f.readlines()
                for s in mes:
                    d = json.loads(s)
                    if j[0] in d:
                        j[0] = d[j[0]]
                    if j[1] in d:
                        j[1] = d[j[1]]
        # print(self.new_train_message) #车次信息
        non_empty_str = ['']
        for m, n in mm.items():
            mm[m] = ['-' if x in non_empty_str else x for x in n]  # 替换''字符为'-'
        return mm

    def trans_train_dic(self):  #输出出发站-目的站-名字
        date, start_station, end_station = self.get_train_args()
        print(date, start_station, end_station)
        try:
            p = Pro_train(date, start_station, end_station)
            self.train_message = p.get_train_res()  # 获得车次信息字典 车次英文
            self.train_tick = p.get_tarin_ticket()  #获得票价信息
            # print(self.train_message) #车次信息
            self.new_train_message = self.train_message  #复制一份
            self.new_train_tick = self.train_tick
            self.new_train_message = self.change_str(self.new_train_message)
            self.new_train_tick = self.change_str(self.new_train_tick)
            return self.new_train_message, self.new_train_tick  # 中文字典
        except Exception as e:
            # messagebox.showerror(title="警告",message="无法解析数据,请重新选择")
            print("错误码:", e.args)

    def search_train_message(self):
        self.manage_date()  #处理日期-True-transe-view
        if self.v.get():
            self.view_list()
        else:
            self.view_price()

    def clear_tree(self):
        x = self.tree.get_children()
        for n in x:
            self.tree.delete(n)

    def view_list(self):  #显示到网格
        # 车次 出发/站 出发到达时间 历时 商务座31  一等座30 二等座29  高软20 软卧22 动卧 硬卧27 软座23 硬座28 无座25 其他21
        try:
            self.clear_tree()
            self.new_train_message, x = self.trans_train_dic()  #生成新车次字典
            for i, j in self.new_train_message.items():
                self.tree.insert("",
                                 "end",
                                 values=(i, j[0] + "->" + j[1],
                                         j[2] + "->" + j[3], j[4], j[5], j[6],
                                         j[7], j[8], j[9], j[10], j[11], j[12],
                                         j[13], j[14], j[15]))
        except Exception as e:
            # messagebox.showerror(title="警告",message="无法处理数据")
            print("错误:", e.args)

    def view_price(self):
        print("-------票价ok-------")
        try:
            self.clear_tree()
            y, self.new_train_tick = self.trans_train_dic()  #生成新车次字典
            for i, j in self.new_train_tick.items():
                self.tree.insert("",
                                 "end",
                                 values=(i, j[0] + "->" + j[1],
                                         j[2] + "->" + j[3], j[4], j[5], j[6],
                                         j[7], j[8], j[9], j[10], j[11], j[12],
                                         j[13], j[14], "-"))
        except Exception as e:
            # messagebox.showerror(title="警告",message="无法处理数据")
            print("错误:", e.args)
Example #28
0
    def __init__(self, **kwargs):
        super().__init__()
        title = "Simple Backup | V" + __version__
        self.wm_title(title)
        self.protocol("WM_DELETE_WINDOW", self.on_closing)

        self.__thread = None
        self.__files_found = 0
        self.__files_copied = 0

        config_fn = kwargs.get("config_fn", user_config_filepath())
        self.__app_config = Config_Handler(config_fn)
        self.__curr_config = self.__app_config.default_config_i

        self.__menu = Menu(self)
        self.__menu_file = Menu(self.__menu, tearoff=0)
        self.__menu_file.add_command(label="Quit", command=self.quit)
        self.__menu_config = Menu(self.__menu, tearoff=0)
        self.__menu_config.add_command(label="New", command=self.new_config)
        self.__menu_config.add_command(label="Load",
                                       command=self.switch_config)
        self.__menu_config.add_command(label="Change Default",
                                       command=self.change_default_config)
        self.__menu_config.add_command(label="Rename Current",
                                       command=self.rename_curr_conf)
        self.__menu_config.add_separator()
        self.__menu_config.add_command(label="Delete Current",
                                       command=self.delete_current_config)
        self.__menu_config.add_command(label="Delete All",
                                       command=self.reset_config)
        self.__menu_help = Menu(self.__menu, tearoff=0)
        self.__menu_help.add_command(label="Check for Updates",
                                     command=self.show_update_popup)
        self.__menu_help.add_command(label="About",
                                     command=self.show_about_popup)
        self.__menu.add_cascade(label="File", menu=self.__menu_file)
        self.__menu.add_cascade(label="Config", menu=self.__menu_config)
        self.__menu.add_cascade(label="Help", menu=self.__menu_help)

        self.__title_l = Label(self, text=title, font=(16))
        self.__curr_config_name_l = Label(self)
        self.__last_backup_l = Label(self)
        self.__set_versions_to_keep = Button(
            self,
            text="Set Versions To Keep",
            command=self.update_versions_to_keep)
        self.__versions_to_keep_l = Label(self)
        self.__inc_folder_bnt = Button(self,
                                       text="Include Another Folder",
                                       command=self.add_included_folder)
        self.__included_folders_lb = Listbox(self, height=4)
        self.__included_folders_lb.bind("<<ListboxSelect>>",
                                        self.remove_selected_included_folder)
        self.__included_folders_lb.bind('<FocusOut>',
                                        self.deselect_included_folder)
        self.__excl_folder_bnt = Button(self,
                                        text="Exclude Another Folder",
                                        command=self.add_excluded_folder)
        self.__excluded_folders_lb = Listbox(self, height=4)
        self.__excluded_folders_lb.bind("<<ListboxSelect>>",
                                        self.remove_selected_excluded_folder)
        self.__excluded_folders_lb.bind('<FocusOut>',
                                        self.deselect_excluded_folder)
        self.__backup_to_bnt = Button(self,
                                      text="Backup Folder",
                                      command=self.set_backup_folder)
        self.__backup_folder_l = Label(self)
        self.__use_tar_l = Label(self, text="Use Tar")
        self.__use_tar_var = BooleanVar(self)
        self.__use_tar_var.trace_add("write", self.use_tar_changed)
        self.__use_tar = Checkbutton(self, variable=self.__use_tar_var)
        self.__backup_start_bnt = Button(self,
                                         text="Start Backup",
                                         command=self.start_backup)
        self.__progress = Progressbar(self)
        self.__statusbar = Label(self, text="ok", relief=SUNKEN, anchor=W)
        self._load_display()
        self._layout()

        if self.__app_config.show_help:
            self.show_help_popup()
Example #29
0
 def make_peptide_frame(self, parent):
     pep_f = Frame(parent, borderwidth=1, relief="sunken")
     self.peptide = IntVar(pep_f, value=0)
     Checkbutton(pep_f,variable=self.peptide,text="get protein as FASTA")\
     .grid(row=1,column=1,sticky="NSW")
     return pep_f
Example #30
0
img4 = PhotoImage("check-nu", file='../images/lime/check-nu.png')
img5 = PhotoImage("check-dc", file='../images/lime/check-dc.png')
img6 = PhotoImage("check-du", file='../images/lime/check-du.png')

style = Style()
# both theme_create and theme_settings worked
style.theme_create( "yummy", parent="clam", settings={
#style.theme_settings('default', {
# start of theme extract
     'Checkbutton.indicator': {"element create":
          ('image', "check-nu",
           ('active', 'selected', "check-hc"),
           ('active', "check-hu"),
           ('disabled', 'selected', "check-dc"),
           ('selected', "check-nc"),
           ('disabled', "check-du"),
           { 'sticky': "w", 'padding':3}) # 'width':24,
         }
# end of theme extract - don't forget to add comma at end when inserting
     })

style.theme_use('yummy') # 'default'

widg = Checkbutton(fr, text='Cheese' ,width=-8)
widg1 = Checkbutton(fr, text='Tomato' ,width=-8)
widg.grid(column=0,row=11,sticky='nsew', padx=5, pady=5)
widg1.grid(column=0,row=12,sticky='nsew', padx=5, pady=5)
run_state(fr,widg,widg1)

root.mainloop()