示例#1
0
 def validate_self(self) -> (bool, List[str]):
     """
     Validate this document against the article xml schema.
     :return: Tuple of boolean validation result and optional list of error messages.
     :raise UnrecognizedFileException if html parse fails
     """
     with open(self.get_path(), 'r') as file:
         html_string = file.read()
     self._valid, errors = Tools.validate(html_string, 'schema_article.xsd')
     return self._valid, errors
    def __init__(self, parent, articles: Dict[str, WhitebearDocumentArticle],
                 index: WhitebearDocumentIndex, css: WhitebearDocumentCSS):
        """
        Display a modal dialog with a message with the text being selectable.
        :param parent: Parent frame.
        """
        wx.Dialog.__init__(self,
                           parent,
                           style=wx.DEFAULT_DIALOG_STYLE,
                           title=Strings.label_upload,
                           size=(Numbers.upload_dialog_width,
                                 Numbers.upload_dialog_height))
        self.small_font = wx.Font(Numbers.text_field_font_size,
                                  wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL,
                                  wx.FONTWEIGHT_NORMAL, False)
        self.bold_small_font = wx.Font(Numbers.text_field_font_size,
                                       wx.FONTFAMILY_DEFAULT,
                                       wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_BOLD,
                                       False)
        self._config_manager: ConfigManager = ConfigManager.get_instance()
        self._articles = articles
        self._index = index
        self._css = css
        # Contains unique id and disk path for each file in the file list even those unchecked.
        self._upload_dict: Dict[int, Tuple[str, bool]] = {}
        self._finished_uploads: List[str] = []
        self._id_counter = 0
        self._invalid_files = 0
        self._sftp_thread = None
        # If a menu or index is invalid, upload must be prevented until the user fixes it in a different dialog.
        self._prevent_upload = False

        self._main_horizontal_sizer = wx.BoxSizer(wx.HORIZONTAL)
        self._right_vertical_sizer = wx.BoxSizer(wx.VERTICAL)
        self._config_sizer = wx.StaticBoxSizer(wx.VERTICAL, self,
                                               Strings.label_sftp)
        self._upload_info_sizer = wx.StaticBoxSizer(
            wx.HORIZONTAL, self, Strings.label_upload_information)

        # File list sizer
        self._filelist_sizer = wx.BoxSizer(wx.VERTICAL)
        self._file_list = wx.ListCtrl(self,
                                      -1,
                                      style=wx.LC_REPORT | wx.LC_SINGLE_SEL
                                      | wx.LC_HRULES)
        self._file_list.SetFont(self.small_font)
        self._file_list.InsertColumn(0,
                                     Strings.label_files_to_upload,
                                     format=wx.LIST_FORMAT_LEFT)
        self._file_list.SetColumnWidth(0, Numbers.upload_filelist_width)
        # Scrolling is slow because of checked checkboxes, empty boxes are ok.
        self._file_list.EnableCheckBoxes()
        self._add_button = wx.Button(self, wx.ID_ADD, Strings.button_add)
        self._filelist_sizer.Add(self._file_list,
                                 flag=wx.EXPAND,
                                 border=Numbers.widget_border_size,
                                 proportion=1)
        self._filelist_sizer.Add(self._add_button,
                                 flag=wx.ALIGN_CENTER_HORIZONTAL | wx.TOP,
                                 border=Numbers.widget_border_size)

        # IP, port sizer
        self._ip_sub_sizer = wx.BoxSizer(wx.HORIZONTAL)
        self._label_ip_port = wx.StaticText(self, -1,
                                            Strings.label_ip_port + ': ')
        self._field_ip_port = wx.TextCtrl(self, -1)
        self._ip_sub_sizer.Add(self._label_ip_port,
                               flag=wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL)
        self._ip_sub_sizer.Add(4, -1)
        self._ip_sub_sizer.Add(self._field_ip_port, proportion=1)
        self._config_sizer.Add(self._ip_sub_sizer,
                               flag=wx.EXPAND | wx.TOP | wx.LEFT | wx.RIGHT,
                               border=Numbers.widget_border_size)
        self._field_ip_port_tip = Tools.get_warning_tip(
            self._field_ip_port, Strings.label_ip_port)
        self._field_ip_port_tip.SetMessage(Strings.label_ip_port_tip)

        # User
        self._user_sub_sizer = wx.BoxSizer(wx.HORIZONTAL)
        self._label_user = wx.StaticText(self, -1, Strings.label_user + ': ')
        self._field_user = wx.TextCtrl(self, -1)
        self._user_sub_sizer.Add(self._label_user,
                                 flag=wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL)
        self._user_sub_sizer.Add(17, -1)
        self._user_sub_sizer.Add(self._field_user, proportion=1)
        self._config_sizer.Add(self._user_sub_sizer,
                               flag=wx.EXPAND | wx.TOP | wx.LEFT | wx.RIGHT,
                               border=Numbers.widget_border_size)
        self._field_user_tip = Tools.get_warning_tip(self._field_user,
                                                     Strings.label_user)
        self._field_user_tip.SetMessage(Strings.label_user_tip)

        # Key file
        self._keyfile_sub_sizer = wx.BoxSizer(wx.HORIZONTAL)
        self._label_keyfile = wx.StaticText(self, -1,
                                            Strings.label_key_file + ': ')
        self._field_keyfile = wx.TextCtrl(self, -1)
        self._keyfile_button = wx.Button(self, wx.ID_OPEN,
                                         Strings.button_browse)
        self._keyfile_sub_sizer.Add(self._label_keyfile,
                                    flag=wx.ALIGN_LEFT
                                    | wx.ALIGN_CENTER_VERTICAL)
        self._keyfile_sub_sizer.Add(self._field_keyfile, proportion=1)
        self._keyfile_sub_sizer.Add(self._keyfile_button,
                                    flag=wx.LEFT,
                                    border=Numbers.widget_border_size)
        self._config_sizer.Add(self._keyfile_sub_sizer,
                               flag=wx.EXPAND | wx.ALL,
                               border=Numbers.widget_border_size)
        self._field_keyfile_tip = Tools.get_warning_tip(
            self._field_keyfile, Strings.label_key_file)
        self._field_keyfile_tip.SetMessage(Strings.label_key_file_tip)

        # Upload bar
        self._gauge_sizer = wx.BoxSizer(wx.VERTICAL)
        self._upload_gauge = wx.Gauge(self, -1, style=wx.GA_VERTICAL)
        self._upload_gauge.SetRange(100)
        self._upload_gauge.SetValue(1)
        self._gauge_sizer.Add(self._upload_gauge, 1, flag=wx.EXPAND)

        # Upload statistics
        self._info_left_sizer = wx.BoxSizer(wx.VERTICAL)
        self._info_right_sizer = wx.BoxSizer(wx.VERTICAL)

        self._label_connection = wx.StaticText(self, -1,
                                               Strings.label_connection + ':')
        self._content_connection = wx.StaticText(self, -1, Strings.label_none)
        self._info_left_sizer.Add(self._label_connection,
                                  flag=wx.BOTTOM | wx.LEFT,
                                  border=Numbers.widget_border_size)
        self._info_right_sizer.Add(self._content_connection,
                                   flag=wx.BOTTOM,
                                   border=Numbers.widget_border_size)

        self._label_num_invalid_files = wx.StaticText(
            self, -1, Strings.label_invalid_files + ':')
        self._content_num_invalid_files = wx.StaticText(self, -1, '0')
        self._content_num_invalid_files.SetForegroundColour(wx.RED)
        font: wx.Font = self._content_num_invalid_files.GetFont()
        font.SetWeight(wx.FONTWEIGHT_BOLD)
        self._content_num_invalid_files.SetFont(font)
        self._info_left_sizer.Add(self._label_num_invalid_files,
                                  flag=wx.BOTTOM | wx.LEFT,
                                  border=Numbers.widget_border_size)
        self._info_right_sizer.Add(self._content_num_invalid_files,
                                   flag=wx.BOTTOM,
                                   border=Numbers.widget_border_size)

        self._label_num_files = wx.StaticText(
            self, -1, Strings.label_files_to_upload + ':')
        self._content_num_files = wx.StaticText(self, -1, '0')
        self._info_left_sizer.Add(self._label_num_files,
                                  flag=wx.BOTTOM | wx.LEFT,
                                  border=Numbers.widget_border_size)
        self._info_right_sizer.Add(self._content_num_files,
                                   flag=wx.BOTTOM,
                                   border=Numbers.widget_border_size)

        self._label_successful = wx.StaticText(
            self, -1, Strings.label_successful_uploads + ':')
        self._content_successful = wx.StaticText(self, -1, '0')
        self._content_successful.SetForegroundColour(Numbers.DARK_GREEN_COLOR)
        self._info_left_sizer.Add(self._label_successful,
                                  flag=wx.BOTTOM | wx.LEFT,
                                  border=Numbers.widget_border_size)
        self._info_right_sizer.Add(self._content_successful,
                                   flag=wx.BOTTOM,
                                   border=Numbers.widget_border_size)

        self._label_failed = wx.StaticText(self, -1,
                                           Strings.label_failed_uploads + ':')
        self._content_failed = wx.StaticText(self, -1, '0')
        self._content_failed.SetForegroundColour(wx.RED)
        self._info_left_sizer.Add(self._label_failed,
                                  flag=wx.BOTTOM | wx.LEFT,
                                  border=Numbers.widget_border_size)
        self._info_right_sizer.Add(self._content_failed,
                                   flag=wx.BOTTOM,
                                   border=Numbers.widget_border_size)

        self._label_current_file = wx.StaticText(
            self, -1, Strings.label_uploading_file + ':')
        self._content_current_file = wx.StaticText(self,
                                                   -1,
                                                   Strings.label_none,
                                                   style=wx.ST_ELLIPSIZE_MIDDLE
                                                   | wx.ST_NO_AUTORESIZE)
        self._info_left_sizer.Add(self._label_current_file,
                                  flag=wx.BOTTOM | wx.LEFT,
                                  border=Numbers.widget_border_size)
        self._info_right_sizer.Add(self._content_current_file,
                                   flag=wx.BOTTOM,
                                   border=Numbers.widget_border_size)

        self._content_percentage = wx.StaticText(self, -1, '0 %')
        self._info_right_sizer.Add(self._content_percentage,
                                   flag=wx.BOTTOM,
                                   border=Numbers.widget_border_size)

        self._upload_info_sizer.Add(self._info_left_sizer, 1, flag=wx.EXPAND)
        self._upload_info_sizer.Add(self._info_right_sizer, 2, flag=wx.EXPAND)

        self._structure_message = wx.StaticText(self, -1,
                                                Strings.label_server_structure)
        self._overwrite_message = wx.StaticText(self, -1,
                                                Strings.label_server_overwrite)

        # Upload button
        self._upload_button_sizer = wx.BoxSizer(wx.HORIZONTAL)
        self._upload_button = wx.Button(self,
                                        wx.ID_FILE,
                                        Strings.button_upload,
                                        style=wx.BU_EXACTFIT)
        self._button_to_upload()
        self._upload_button_sizer.AddStretchSpacer()
        self._upload_button_sizer.Add(self._upload_button,
                                      flag=wx.ALIGN_CENTER)
        self._upload_button_sizer.AddStretchSpacer()

        # Put it all together
        self._right_vertical_sizer.Add(self._config_sizer,
                                       flag=wx.RIGHT | wx.EXPAND,
                                       border=Numbers.widget_border_size)
        self._right_vertical_sizer.Add(self._upload_info_sizer,
                                       flag=wx.RIGHT | wx.EXPAND,
                                       border=Numbers.widget_border_size)
        self._right_vertical_sizer.Add(self._structure_message)
        self._right_vertical_sizer.Add(self._overwrite_message)
        self._right_vertical_sizer.Add(self._upload_button_sizer,
                                       1,
                                       flag=wx.EXPAND)
        self._main_horizontal_sizer.Add(self._filelist_sizer,
                                        flag=wx.EXPAND | wx.ALL,
                                        border=Numbers.widget_border_size)
        self._main_horizontal_sizer.Add(self._right_vertical_sizer,
                                        1,
                                        flag=wx.EXPAND)
        self._main_horizontal_sizer.Add(self._gauge_sizer, flag=wx.EXPAND)

        self.SetSizer(self._main_horizontal_sizer)

        self.Bind(wx.EVT_LIST_ITEM_CHECKED, self._check_handler,
                  self._file_list)
        self.Bind(wx.EVT_LIST_ITEM_UNCHECKED, self._check_handler,
                  self._file_list)
        self.Bind(wx.EVT_BUTTON, self._handle_buttons, self._add_button)
        self.Bind(wx.EVT_BUTTON, self._handle_buttons, self._keyfile_button)
        self.Bind(wx.EVT_BUTTON, self._handle_buttons, self._upload_button)
        self.Bind(wx.EVT_TEXT, self._handle_fields, self._field_ip_port)
        self.Bind(wx.EVT_TEXT, self._handle_fields, self._field_user)
        self.Bind(wx.EVT_TEXT, self._handle_fields, self._field_keyfile)
        self.Bind(wx.EVT_CLOSE, self._close_button_handler, self)

        self._display_dialog_contents()
示例#3
0
    def __init__(self, parent, video: Video):
        """
        Display a dialog with information about the video where the user can edit it.
        :param parent: Parent frame.
        :param video: Video instance being edited by this dialog.
        """
        super().__init__(parent, title=Strings.label_dialog_edit_video,
                         size=(Numbers.edit_video_dialog_width, Numbers.edit_video_dialog_height),
                         style=wx.DEFAULT_DIALOG_STYLE)
        self._video = video
        self._config_manager = ConfigManager.get_instance()

        self._main_vertical_sizer = wx.BoxSizer(wx.VERTICAL)
        self._horizontal_sizer = wx.BoxSizer(wx.HORIZONTAL)
        self._vertical_sizer = wx.BoxSizer(wx.VERTICAL)
        self._information_sizer = wx.BoxSizer(wx.VERTICAL)

        # Title sub sizer
        self._title_sub_sizer = wx.BoxSizer(wx.HORIZONTAL)
        self._label_video_title = wx.StaticText(self, -1, Strings.label_link_title + ': ')
        self._field_video_link_title = wx.TextCtrl(self, -1)
        self._title_sub_sizer.Add(self._label_video_title, flag=wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL)
        self._title_sub_sizer.Add((5, -1))
        self._title_sub_sizer.Add(self._field_video_link_title, proportion=1)
        self._information_sizer.Add(self._title_sub_sizer, flag=wx.EXPAND | wx.TOP, border=Numbers.widget_border_size)
        self._field_video_link_title_tip = Tools.get_warning_tip(self._field_video_link_title,
                                                                 Strings.label_video_link_title)

        # Url sub sizer
        self._url_sub_sizer = wx.BoxSizer(wx.HORIZONTAL)
        self._label_video_url = wx.StaticText(self, -1, Strings.label_url + ': ')
        self._field_video_url = wx.TextCtrl(self, -1)
        self._url_sub_sizer.Add(self._label_video_url, flag=wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL)
        self._url_sub_sizer.Add((34, -1))
        self._url_sub_sizer.Add(self._field_video_url, proportion=1)
        self._information_sizer.Add(self._url_sub_sizer, flag=wx.EXPAND | wx.TOP, border=Numbers.widget_border_size)
        self._field_video_url_tip = Tools.get_warning_tip(self._field_video_url, Strings.label_url)

        # Size
        self._video_size_sub_sizer = wx.BoxSizer(wx.HORIZONTAL)
        self._label_video_size = wx.StaticText(self, -1, Strings.label_video_size + ': ')
        self._content_video_size = wx.StaticText(self, -1, Strings.label_none)
        self._video_size_sub_sizer.Add(self._label_video_size, flag=wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL)
        self._video_size_sub_sizer.Add(self._content_video_size, flag=wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL)
        self._information_sizer.Add(self._video_size_sub_sizer, flag=wx.EXPAND | wx.TOP,
                                    border=Numbers.widget_border_size)

        # Buttons
        self._button_sizer = wx.BoxSizer(wx.VERTICAL)
        grouping_sizer = wx.BoxSizer(wx.HORIZONTAL)
        self._cancel_button = wx.Button(self, wx.ID_CANCEL, Strings.button_cancel)
        self._ok_button = wx.Button(self, wx.ID_OK, Strings.button_ok)
        self._ok_button.SetDefault()
        grouping_sizer.Add(self._ok_button)
        grouping_sizer.Add((Numbers.widget_border_size, Numbers.widget_border_size))
        grouping_sizer.Add(self._cancel_button)
        self._button_sizer.Add(grouping_sizer, flag=wx.ALIGN_CENTER_HORIZONTAL)

        # Putting the sizers together
        self._vertical_sizer.Add(self._information_sizer, 0, flag=wx.EXPAND | wx.LEFT | wx.RIGHT | wx.TOP,
                                 border=Numbers.widget_border_size)
        self._horizontal_sizer.Add(self._vertical_sizer, 1)
        self._main_vertical_sizer.Add(self._horizontal_sizer, 1, flag=wx.EXPAND)
        self._main_vertical_sizer.Add(self._button_sizer, 0, flag=wx.EXPAND | wx.LEFT | wx.RIGHT | wx.BOTTOM,
                                      border=Numbers.widget_border_size)
        self.SetSizer(self._main_vertical_sizer)
        self._display_dialog_contents()

        # Bind handlers
        self.Bind(wx.EVT_BUTTON, self._handle_buttons, self._ok_button)
        self.Bind(wx.EVT_BUTTON, self._handle_buttons, self._cancel_button)

        self._original_url = self._video.get_url()[0]
        self._original_title = self._video.get_title()[0]
    def __init__(self, parent, menus: Dict[str, WhitebearDocumentMenu],
                 articles: Dict[str, WhitebearDocumentArticle],
                 css: WhitebearDocumentCSS, index: WhitebearDocumentIndex):
        """
        Display a dialog that allows editing additional data used in html generation.
        Default main title, author, contact, keywords, main page meta description. script, main page red/black text
        :param parent: The parent frame.
        :param menus: Currently loaded dictionary of menus.
        :param articles: Currently loaded dictionary of articles.
        :param css: Currently loaded css document.
        :param index: Currently loaded index document.
        """
        wx.Dialog.__init__(self,
                           parent,
                           title=Strings.label_dialog_new_document,
                           size=(Numbers.new_file_dialog_width,
                                 Numbers.new_file_dialog_height),
                           style=wx.DEFAULT_DIALOG_STYLE)

        self._config_manager: ConfigManager = ConfigManager.get_instance()
        self._doc = None
        self._menus = menus
        self._articles = articles
        self._css_document = css
        self._index = index
        self._article_image = None
        self._menu_item = None
        self._document_path = None

        self._main_vertical_sizer = wx.BoxSizer(wx.VERTICAL)
        self._horizontal_sizer = wx.BoxSizer(wx.HORIZONTAL)
        self._vertical_sizer = wx.BoxSizer(wx.VERTICAL)
        self._information_sizer = wx.BoxSizer(wx.VERTICAL)

        # Name sub sizer
        self._name_sub_sizer = wx.BoxSizer(wx.HORIZONTAL)
        self._label_file_name = wx.StaticText(self, -1,
                                              Strings.label_file_name + ': ')
        self._field_name = wx.TextCtrl(self, -1)
        self._name_sub_sizer.Add(self._label_file_name,
                                 flag=wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL)
        self._name_sub_sizer.Add(self._field_name, proportion=1)
        self._information_sizer.Add(self._name_sub_sizer,
                                    flag=wx.EXPAND | wx.TOP,
                                    border=Numbers.widget_border_size)
        self._field_name_tip = Tools.get_warning_tip(self._field_name,
                                                     Strings.label_file_name)
        self._field_name.SetBackgroundColour(Numbers.RED_COLOR)
        self._field_name_tip.SetMessage(Strings.warning_empty)

        choices: List[str] = [
            menu.get_page_name()[0] for menu in self._menus.values()
        ]
        choices.append('-')
        # Category sub sizer
        self._category_sub_sizer = wx.BoxSizer(wx.HORIZONTAL)
        self._label_category = wx.StaticText(
            self, -1, Strings.label_target_section + ': ')
        self._box_menu = wx.ComboBox(self,
                                     -1,
                                     choices=choices,
                                     style=wx.CB_DROPDOWN | wx.CB_SORT
                                     | wx.CB_READONLY)
        self._box_menu.SetSelection(0)
        self._box_menu.SetBackgroundColour(Numbers.RED_COLOR)
        self._category_sub_sizer.Add(self._label_category,
                                     flag=wx.ALIGN_LEFT
                                     | wx.ALIGN_CENTER_VERTICAL)
        self._category_sub_sizer.Add(16, -1)
        self._category_sub_sizer.Add(self._box_menu, proportion=1)
        self._information_sizer.Add(self._category_sub_sizer,
                                    flag=wx.EXPAND | wx.TOP,
                                    border=Numbers.widget_border_size)

        # Image buttons
        self._image_buttons_sub_sizer = wx.BoxSizer(wx.HORIZONTAL)
        self._menu_logo_button = wx.Button(
            self,
            wx.ID_FILE1,
            style=wx.BU_EXACTFIT | wx.BORDER_NONE,
            size=wx.Size(Numbers.menu_logo_image_size,
                         Numbers.menu_logo_image_size))
        self._menu_logo_button.Disable()
        self._menu_logo_button.SetBitmap(
            wx.Bitmap(
                wx.Image(Fetch.get_resource_path('menu_image.png'),
                         wx.BITMAP_TYPE_PNG)))
        self._main_image_button = wx.Button(self,
                                            wx.ID_FILE2,
                                            style=wx.BU_EXACTFIT
                                            | wx.BORDER_NONE)
        self._main_image_button.Disable()
        self._main_image_button.SetBitmap(
            wx.Bitmap(
                wx.Image(Fetch.get_resource_path('article_image.png'),
                         wx.BITMAP_TYPE_PNG)))
        self._image_buttons_sub_sizer.Add(self._main_image_button,
                                          1,
                                          flag=wx.EXPAND)
        self._image_buttons_sub_sizer.Add(Numbers.widget_border_size,
                                          Numbers.widget_border_size)
        self._image_buttons_sub_sizer.Add(self._menu_logo_button,
                                          1,
                                          flag=wx.EXPAND)
        self._information_sizer.Add(self._image_buttons_sub_sizer,
                                    flag=wx.EXPAND | wx.TOP,
                                    border=Numbers.widget_border_size)

        # Buttons
        self._button_sizer = wx.BoxSizer(wx.VERTICAL)
        grouping_sizer = wx.BoxSizer(wx.HORIZONTAL)
        self._cancel_button = wx.Button(self, wx.ID_CANCEL,
                                        Strings.button_cancel)
        self._ok_button = wx.Button(self, wx.ID_OK, Strings.button_ok)
        self._ok_button.SetDefault()
        self._ok_button.Disable()
        grouping_sizer.Add(self._ok_button)
        grouping_sizer.Add(
            (Numbers.widget_border_size, Numbers.widget_border_size))
        grouping_sizer.Add(self._cancel_button)
        grouping_sizer.Add(
            (Numbers.widget_border_size, Numbers.widget_border_size))
        self._button_sizer.Add(grouping_sizer, flag=wx.ALIGN_CENTER_HORIZONTAL)

        # Putting the sizers together
        self._vertical_sizer.Add(self._information_sizer,
                                 0,
                                 flag=wx.EXPAND | wx.LEFT | wx.RIGHT | wx.TOP,
                                 border=Numbers.widget_border_size)
        self._horizontal_sizer.Add(self._vertical_sizer, 1)
        self._main_vertical_sizer.Add(self._horizontal_sizer,
                                      1,
                                      flag=wx.EXPAND)
        self._main_vertical_sizer.Add(self._button_sizer,
                                      0,
                                      flag=wx.EXPAND | wx.LEFT | wx.RIGHT
                                      | wx.BOTTOM,
                                      border=Numbers.widget_border_size)
        self.SetSizer(self._main_vertical_sizer)

        # Bind handlers
        self.Bind(wx.EVT_BUTTON, self._handle_buttons, self._ok_button)
        self.Bind(wx.EVT_BUTTON, self._handle_buttons, self._cancel_button)
        self.Bind(wx.EVT_TEXT, self._handle_fields, self._field_name)
        self.Bind(wx.EVT_BUTTON, self._handle_image_buttons,
                  self._main_image_button)
        self.Bind(wx.EVT_BUTTON, self._handle_image_buttons,
                  self._menu_logo_button)
        self.Bind(wx.EVT_COMBOBOX, self._handle_fields, self._box_menu)

        # If there are no menus, disable the dialog.
        if not choices:
            self._field_name.Disable()
            self._box_menu.Disable()
示例#5
0
    def convert_to_html(self) -> None:
        """
        Converts this document into a html white bear article page.
        :return: None
        :raise UnrecognizedFileException if template file can not be validated.
        :raise UnrecognizedFileException if html parse fails.
        :raise UnrecognizedFileException if generated html fails validation.
        :raises UnrecognizedFileException if xml schema is incorrect.
        """
        with open(Fetch.get_resource_path('article_template.html'),
                  'r') as template:
            template_string = template.read()
        is_valid, errors = Tools.validate(template_string,
                                          'schema_article_template.xsd')
        if not is_valid:
            raise UnrecognizedFileException(
                Strings.exception_html_syntax_error + '\n' +
                'article_template.html ' + str(errors))

        parsed_template = BeautifulSoup(template_string, 'html5lib')

        # Fill title.
        title: Tag = parsed_template.find(name='title')
        title.string = self._page_name + ' - ' + self._menu_section.get_section_name(
        ) + ' | ' + Strings.page_name

        # Fill description.
        description = parsed_template.find_all(name='meta',
                                               attrs={
                                                   'name': 'description',
                                                   'content': True
                                               })
        if len(description) == 1:
            description[0]['content'] = self._meta_description
        else:
            raise UnrecognizedFileException(
                Strings.exception_parse_multiple_descriptions)

        # Fill keywords.
        keywords = parsed_template.find_all(name='meta',
                                            attrs={
                                                'name': 'keywords',
                                                'content': True
                                            })
        if len(keywords) == 1:
            keywords[0]['content'] = ', '.join(self._meta_keywords)
        else:
            raise UnrecognizedFileException(
                Strings.exception_parse_multiple_keywords)

        # Fill author.
        author = parsed_template.find_all(name='meta',
                                          attrs={
                                              'name': 'author',
                                              'content': True
                                          })
        if len(author) == 1:
            author[0]['content'] = self._config_manager.get_author()
        else:
            raise UnrecognizedFileException(
                Strings.exception_parse_multiple_authors)

        # Fill script.
        script = parsed_template.find(name='script')
        script.string = self._config_manager.get_script()

        # Fill global title.
        figure = parsed_template.find(name='header').figure
        figure.figcaption.string = self._config_manager.get_global_title()
        heading = parsed_template.find(name='h1', attrs={'id': 'heading'})
        heading.string = self._config_manager.get_global_title()

        # Activate correct menu, generate menu items according to menus.
        menu_container = parsed_template.find(name='nav')
        for instance in sorted(self._menus.values(),
                               key=lambda x: x.get_section_name(),
                               reverse=True):
            new_item = parsed_template.new_tag('a',
                                               attrs={
                                                   'class':
                                                   'menu',
                                                   'href':
                                                   instance.get_filename(),
                                                   'title':
                                                   instance.get_page_name()[0]
                                               })
            new_item.string = instance.get_page_name()[0]
            if instance.get_filename() == self._menu_section.get_filename():
                new_item['id'] = 'active'
            menu_container.append(new_item)

        # Fill main page title.
        article = parsed_template.find(name='article',
                                       attrs={'class': 'textPage'})
        article.h2.string = self._page_name

        # Fill date.
        parsed_template.find(name='p', attrs={
            'id': 'date'
        }).string = self._date

        # Fill main image.
        main_image_figure = parsed_template.find(name='figure',
                                                 attrs={'id': 'articleImg'})
        main_image_figure.a['href'] = self.get_article_image(
        ).get_full_filename()
        main_image_figure.a['title'] = self.get_article_image().get_link_title(
        )[0]
        main_image_figure.img['src'] = self.get_article_image(
        ).get_thumbnail_filename()
        main_image_figure.img['alt'] = self.get_article_image().get_image_alt(
        )[0]
        main_image_figure.figcaption.string = self.get_article_image(
        ).get_caption()[0]

        # Fill main text.
        text_section = parsed_template.find(name='section', attrs='mainText')
        if not self._enabled:
            # Save the disabled state into the html, once the article is enabled, this special class will be removed.
            text_section['class'] = 'mainText disabled'
        for element in self.get_main_text_elements():
            if isinstance(element, Heading):
                size = 'h3' if element.get_size() == Heading.SIZE_H3 else 'h4'
                text = element.get_text().get_text()
                color = element.get_text().get_color()
                new_h = parsed_template.new_tag(size)
                new_h.string = text
                if color != Strings.color_black:
                    # Black text is default, so ignore it.
                    new_h['class'] = color
                text_section.append(new_h)
            elif isinstance(element, ImageInText):
                new_div = parsed_template.new_tag('div',
                                                  attrs={'class': 'center'})
                href = element.get_full_filename()
                title = element.get_link_title()[0]
                src = element.get_thumbnail_filename()
                alt = element.get_image_alt()[0]
                width = element.get_thumbnail_size()[0]
                height = element.get_thumbnail_size()[1]
                new_a = parsed_template.new_tag('a',
                                                attrs={
                                                    'href': href,
                                                    'target': Strings.blank,
                                                    'title': title
                                                })
                new_img = parsed_template.new_tag('img',
                                                  attrs={
                                                      'src': src,
                                                      'alt': alt,
                                                      'width': width,
                                                      'height': height
                                                  })
                new_a.append(new_img)
                new_div.append(new_a)
                text_section.append(new_div)
            elif isinstance(element, Video):
                new_div = parsed_template.new_tag('div',
                                                  attrs={'class': 'center'})
                title = element.get_title()[0]
                width = element.get_size()[0]
                height = element.get_size()[1]
                src = element.get_url()[0]
                new_iframe = parsed_template.new_tag('iframe',
                                                     attrs={
                                                         'title': title,
                                                         'height': height,
                                                         'width': width,
                                                         'src': src,
                                                         'allowfullscreen':
                                                         None
                                                     })
                new_div.append(new_iframe)
                text_section.append(new_div)
            elif isinstance(element, Paragraph):
                new_p = parsed_template.new_tag('p')
                new_p = self._convert_text_contents(new_p, element,
                                                    parsed_template)
                text_section.append(new_p)
            elif isinstance(element, UnorderedList):
                new_ul = parsed_template.new_tag('ul')
                for par in element.get_paragraphs():
                    new_li = parsed_template.new_tag('li')
                    self._convert_text_contents(new_li, par, parsed_template)
                    new_ul.append(new_li)
                text_section.append(new_ul)

        # Fill aside images.
        aside = parsed_template.find(name='aside')
        for img in self._aside_images:
            new_figure = parsed_template.new_tag('figure')
            new_figcaption = parsed_template.new_tag(
                'figcaption', attrs={'class': 'photoCaption'})
            href = img.get_full_filename()
            title = img.get_link_title()[0]
            src = img.get_thumbnail_filename()
            alt = img.get_image_alt()[0]
            text = img.get_caption()[0]
            new_figcaption.string = text
            new_a = parsed_template.new_tag('a',
                                            attrs={
                                                'href': href,
                                                'target': Strings.blank,
                                                'title': title
                                            })
            # Width and height are different from the thumbnail here because the image expands in the page.
            new_img = parsed_template.new_tag(
                'img',
                attrs={
                    'src': src,
                    'alt': alt,
                    'width': Numbers.aside_thumbnail_width,
                    'height': Numbers.aside_thumbnail_height,
                    'class': 'imgAside'
                })
            new_a.append(new_img)
            new_figure.append(new_a)
            new_figure.append(new_figcaption)
            aside.append(new_figure)

        output = str(parsed_template)
        is_valid, errors = Tools.validate(output, 'schema_article.xsd')
        if not is_valid:
            raise UnrecognizedFileException(Strings.exception_bug + '\n' +
                                            self.get_filename() + ' \n' +
                                            str(errors))

        self._html = output
        # Save the fact that this file is changed into the list of file that we need to upload. This survives editor
        # exit and can be restored on start. This list is cleared when a file is uploaded.
        self._config_manager.store_not_uploaded(self.get_filename())
示例#6
0
    def convert_to_html(self) -> None:
        """
        Converts this document into a html white bear article page.
        :return: None
        :raise UnrecognizedFileException if template file can not be validated.
        :raise UnrecognizedFileException if html parse fails.
        :raise UnrecognizedFileException if generated html fails validation.
        :raises UnrecognizedFileException if xml schema is incorrect.
        """
        self.update_content()
        with open(Fetch.get_resource_path('index_template.html'),
                  'r') as template:
            template_string = template.read()
        is_valid, errors = Tools.validate(template_string,
                                          'schema_index_template.xsd')
        if not is_valid:
            raise UnrecognizedFileException(
                Strings.exception_html_syntax_error + '\n' +
                'index_template.html ' + str(errors))

        parsed_template = BeautifulSoup(template_string, 'html5lib')

        # Fill title.
        title: Tag = parsed_template.find(name='title')
        title.string = self._page_name + ' | ' + self._global_title

        # Fill description.
        description = parsed_template.find_all(name='meta',
                                               attrs={
                                                   'name': 'description',
                                                   'content': True
                                               })
        if len(description) == 1:
            description[0]['content'] = self._meta_description
        else:
            raise UnrecognizedFileException(
                Strings.exception_parse_multiple_descriptions)

        # Fill keywords.
        keywords = parsed_template.find_all(name='meta',
                                            attrs={
                                                'name': 'keywords',
                                                'content': True
                                            })
        if len(keywords) == 1:
            keywords[0]['content'] = self._meta_keywords
        else:
            raise UnrecognizedFileException(
                Strings.exception_parse_multiple_authors)

        # Fill author.
        author = parsed_template.find_all(name='meta',
                                          attrs={
                                              'name': 'author',
                                              'content': True
                                          })
        if len(author) == 1:
            author[0]['content'] = self._author
        else:
            raise UnrecognizedFileException(
                Strings.exception_parse_multiple_descriptions)

        # Fill script.
        script = parsed_template.find(name='script')
        script.string = self._script

        # Fill global title.
        figure = parsed_template.find(name='header').figure
        figure.figcaption.string = self._global_title
        heading = parsed_template.find(name='h1', attrs={'id': 'heading'})
        heading.string = self._global_title

        # Activate correct menu, generate menu items according to menus.
        menu_container = parsed_template.find(name='nav')
        for instance in sorted(self._menus.values(),
                               key=lambda x: x.get_section_name(),
                               reverse=True):
            new_item = parsed_template.new_tag('a',
                                               attrs={
                                                   'class':
                                                   'menu',
                                                   'href':
                                                   instance.get_filename(),
                                                   'title':
                                                   instance.get_page_name()[0]
                                               })
            new_item.string = instance.get_page_name()[0]
            if instance.get_filename() == self.get_filename():
                new_item['id'] = 'active'
            menu_container.append(new_item)

        # Fill main page title.
        article = parsed_template.find(name='article',
                                       attrs={'class': 'indexPage'})
        article.h2.string = self._page_name

        # Fill text.
        new_black_p = parsed_template.new_tag('p')
        new_black_p.string = self._black_text

        new_red_p = parsed_template.new_tag('p')
        new_strong = parsed_template.new_tag('strong', attrs={'class': 'red'})
        new_strong.string = self._red_text
        new_red_p.append(new_strong)

        article.h2.insert_after(new_red_p)
        article.h2.insert_after(new_black_p)

        # Fill news.
        news = parsed_template.find(name='h3', attrs={'id': 'news'})
        # Sort all articles by date.
        sorted_articles = sorted(self._articles.values(),
                                 key=lambda x: x.get_computable_date(),
                                 reverse=True)
        new_ul = parsed_template.new_tag('ul')
        limit = self._number_of_news
        for index, item in enumerate(sorted_articles):
            if index >= limit:
                break
            if item.test_self(self._config_manager.get_online_test()):
                new_li = parsed_template.new_tag('li')
                href = item.get_filename()
                title = item.get_page_name()[0]
                date = item.get_date()[0] + ' '
                new_a = parsed_template.new_tag('a',
                                                attrs={
                                                    'href': href,
                                                    'title': title
                                                })
                new_a.string = title

                new_li.string = date
                new_li.append(new_a)
                new_ul.append(new_li)
            else:
                # Add the next article to news.
                limit = limit + 1
        news.insert_after(new_ul)

        # Fill contact.
        contact = parsed_template.find(name='h3', attrs={'id': 'contact'})
        # Insert the author's contact as an image.
        image: wx.Bitmap = Tools.create_image(self._contact)
        image_path = os.path.join(self._working_directory,
                                  Strings.folder_images, Strings.contact_file)
        image.SaveFile(image_path, wx.BITMAP_TYPE_PNG)
        src = os.path.join(Strings.folder_images, Strings.contact_file)
        new_img = parsed_template.new_tag('img',
                                          attrs={
                                              'width': image.GetWidth(),
                                              'height': image.GetHeight(),
                                              'src': src,
                                              'alt':
                                              Strings.contact_default_alt
                                          })
        contact.insert_after(new_img)

        # Fill design.
        new_p = parsed_template.new_tag('p')
        new_p.string = 'Web design: ' + self._author
        new_img.insert_after(new_p)

        # Fill aside images from the newest articles.
        latest_images = []
        for article in sorted_articles:
            if article.is_enabled():
                images = article.get_aside_images()
                if images:
                    latest_images.append(images[0])
                if len(latest_images) >= Numbers.max_index_images:
                    break

        aside = parsed_template.find(name='aside')
        for img in latest_images:
            new_figure = parsed_template.new_tag('figure')
            new_figcaption = parsed_template.new_tag(
                'figcaption', attrs={'class': 'photoCaption'})
            href = img.get_full_filename()
            title = img.get_link_title()[0]
            src = img.get_thumbnail_filename()
            alt = img.get_image_alt()[0]
            text = img.get_caption()[0]
            new_figcaption.string = text
            new_a = parsed_template.new_tag('a',
                                            attrs={
                                                'href': href,
                                                'target': Strings.blank,
                                                'title': title
                                            })
            # Width and height are different from the thumbnail here because the image expands in the page.
            new_img = parsed_template.new_tag(
                'img',
                attrs={
                    'src': src,
                    'alt': alt,
                    'width': Numbers.aside_thumbnail_width,
                    'height': Numbers.aside_thumbnail_height,
                    'class': 'imgAside'
                })
            new_a.append(new_img)
            new_figure.append(new_a)
            new_figure.append(new_figcaption)
            aside.append(new_figure)

        output = str(parsed_template)
        is_valid, errors = Tools.validate(output, 'schema_index.xsd')
        if not is_valid:
            raise UnrecognizedFileException(Strings.exception_bug + '\n' +
                                            self.get_filename() + ' \n' +
                                            str(errors))

        self._html = output
示例#7
0
from Tools.Tools import Tools
d = Tools()
d.openBrower('http://www.baidu.com/')
d.closeBrower()
示例#8
0
    def __init__(self, parent, no_cancel: bool = False):
        """
        Display a dialog that allows editing additional data used in html generation.
        Default main title, author, contact, keywords, main page meta description. script, main page red/black text
        :param parent: The parent frame.
        :param no_cancel: Do not display cancel button. Used to force page setup completion.
        """
        super().__init__(parent,
                         title=Strings.label_dialog_page_setup,
                         size=(Numbers.page_setup_dialog_width,
                               Numbers.page_setup_dialog_height),
                         style=wx.CAPTION)

        self._config_manager: ConfigManager = ConfigManager.get_instance()
        # Multiple inheritance with spellchecked object was causing trouble, so we have our own method.
        self._checker = SpellCheckerWithIgnoreList(
            self._config_manager.get_spelling_lang())
        # This is used just for seo testing keywords and description.
        self._test_doc: WhitebearDocument = WhitebearDocument('')
        self._save_all = False

        self._main_vertical_sizer = wx.BoxSizer(wx.VERTICAL)
        self._horizontal_sizer = wx.BoxSizer(wx.HORIZONTAL)
        self._vertical_sizer = wx.BoxSizer(wx.VERTICAL)
        self._information_sizer = wx.BoxSizer(wx.VERTICAL)

        # Title sub sizer
        self._title_sub_sizer = wx.BoxSizer(wx.HORIZONTAL)
        self._label_main_title = wx.StaticText(
            self, -1, Strings.label_global_title + ': ')
        self._field_global_title = wx.TextCtrl(self, -1)
        self._title_sub_sizer.Add(self._label_main_title,
                                  flag=wx.ALIGN_LEFT
                                  | wx.ALIGN_CENTER_VERTICAL)
        self._title_sub_sizer.Add((2, -1))
        self._title_sub_sizer.Add(self._field_global_title, proportion=1)
        self._information_sizer.Add(self._title_sub_sizer,
                                    flag=wx.EXPAND | wx.TOP,
                                    border=Numbers.widget_border_size)
        self._field_global_title_tip = Tools.get_warning_tip(
            self._field_global_title, Strings.label_global_title)
        self._field_global_title_tip.SetMessage(Strings.label_main_title_tip)

        # Url sub sizer
        self._url_sub_sizer = wx.BoxSizer(wx.HORIZONTAL)
        self._label_url = wx.StaticText(self, -1,
                                        Strings.label_website_url + ': ')
        self._field_url = wx.TextCtrl(self, -1)
        self._url_sub_sizer.Add(self._label_url,
                                flag=wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL)
        self._url_sub_sizer.Add((44, -1))
        self._url_sub_sizer.Add(self._field_url, proportion=1)
        self._information_sizer.Add(self._url_sub_sizer,
                                    flag=wx.EXPAND | wx.TOP,
                                    border=Numbers.widget_border_size)
        self._field_url_tip = Tools.get_warning_tip(self._field_url,
                                                    Strings.label_website_url)
        self._field_url_tip.SetMessage(Strings.label_website_url_tip)

        # Author sub sizer
        self._author_sub_sizer = wx.BoxSizer(wx.HORIZONTAL)
        self._label_author = wx.StaticText(self, -1,
                                           Strings.label_author + ': ')
        self._field_author = wx.TextCtrl(self, -1)
        self._label_news = wx.StaticText(self, -1,
                                         Strings.label_number_of_news + ': ')
        self._news_spinner = wx.SpinCtrl(self,
                                         -1,
                                         style=wx.SP_ARROW_KEYS,
                                         min=Numbers.min_news,
                                         max=Numbers.max_news,
                                         initial=Numbers.default_news)
        self._author_sub_sizer.Add(self._label_author,
                                   flag=wx.ALIGN_LEFT
                                   | wx.ALIGN_CENTER_VERTICAL)
        self._author_sub_sizer.Add((20, -1))
        self._author_sub_sizer.Add(self._field_author, proportion=1)
        self._author_sub_sizer.Add(Numbers.widget_border_size,
                                   Numbers.widget_border_size)
        self._author_sub_sizer.Add(self._label_news,
                                   flag=wx.ALIGN_LEFT
                                   | wx.ALIGN_CENTER_VERTICAL)
        self._author_sub_sizer.Add(Numbers.widget_border_size,
                                   Numbers.widget_border_size)
        self._author_sub_sizer.Add(self._news_spinner, proportion=0.3)
        self._information_sizer.Add(self._author_sub_sizer,
                                    flag=wx.EXPAND | wx.TOP,
                                    border=Numbers.widget_border_size)
        self._field_author_tip = Tools.get_warning_tip(self._field_author,
                                                       Strings.label_author)
        self._field_author_tip.SetMessage(Strings.label_author_tip)

        # e-mail sub sizer
        self._contact_sub_sizer = wx.BoxSizer(wx.HORIZONTAL)
        self._label_contact = wx.StaticText(self, -1,
                                            Strings.label_contact + ': ')
        self._field_contact = wx.TextCtrl(self, -1)
        self._contact_sub_sizer.Add(self._label_contact,
                                    flag=wx.ALIGN_LEFT
                                    | wx.ALIGN_CENTER_VERTICAL)
        self._contact_sub_sizer.Add((14, -1))
        self._contact_sub_sizer.Add(self._field_contact, proportion=1)
        self._information_sizer.Add(self._contact_sub_sizer,
                                    flag=wx.EXPAND | wx.TOP,
                                    border=Numbers.widget_border_size)
        self._field_contact_tip = Tools.get_warning_tip(
            self._field_contact, Strings.label_contact)
        self._field_contact_tip.SetMessage(Strings.label_contact_tip)

        # Keywords sub sizer
        self._meta_keywords_sub_sizer = wx.BoxSizer(wx.HORIZONTAL)
        self._label_meta_keywords = wx.StaticText(
            self, -1, Strings.label_default_keywords + ': ')
        self._field_meta_keywords = wx.TextCtrl(self, -1)
        self._meta_keywords_sub_sizer.Add(self._label_meta_keywords,
                                          flag=wx.ALIGN_LEFT
                                          | wx.ALIGN_CENTER_VERTICAL)
        self._meta_keywords_sub_sizer.Add(self._field_meta_keywords,
                                          proportion=1)
        self._information_sizer.Add(self._meta_keywords_sub_sizer,
                                    flag=wx.EXPAND | wx.TOP,
                                    border=Numbers.widget_border_size)
        self._field_keywords_tip = Tools.get_warning_tip(
            self._field_meta_keywords, Strings.label_article_keywords)
        self._field_keywords_tip.SetMessage(Strings.label_default_keywords_tip)

        # --------------------------------------------------------------------------------------------------------------
        # Description sub sizer
        self._meta_description_sub_sizer = wx.BoxSizer(wx.VERTICAL)
        self._label_meta_description = wx.StaticText(
            self, -1, Strings.label_main_meta_description + ': ')
        self._field_meta_description = wx.TextCtrl(self,
                                                   -1,
                                                   size=wx.Size(-1, 60),
                                                   style=wx.TE_MULTILINE)
        self._meta_description_sub_sizer.Add(self._label_meta_description,
                                             flag=wx.ALIGN_LEFT)
        self._meta_description_sub_sizer.Add(3, 3)
        self._meta_description_sub_sizer.Add(self._field_meta_description,
                                             proportion=1,
                                             flag=wx.EXPAND)
        self._information_sizer.Add(self._meta_description_sub_sizer,
                                    flag=wx.EXPAND | wx.TOP,
                                    border=Numbers.widget_border_size)
        self._field_description_tip = Tools.get_warning_tip(
            self._field_meta_description, Strings.label_main_meta_description)
        self._field_description_tip.SetMessage(
            Strings.label_main_description_tip)

        # Script sub sizer
        self._script_sub_sizer = wx.BoxSizer(wx.VERTICAL)
        self._label_script = wx.StaticText(self, -1,
                                           Strings.label_script + ': ')
        self._field_script = wx.TextCtrl(self,
                                         -1,
                                         size=wx.Size(-1, 135),
                                         style=wx.TE_MULTILINE)
        self._script_sub_sizer.Add(self._label_script, flag=wx.ALIGN_LEFT)
        self._script_sub_sizer.Add(3, 3)
        self._script_sub_sizer.Add(self._field_script,
                                   proportion=1,
                                   flag=wx.EXPAND)
        self._information_sizer.Add(self._script_sub_sizer,
                                    flag=wx.EXPAND | wx.TOP,
                                    border=Numbers.widget_border_size)
        self._field_script_tip = Tools.get_warning_tip(self._field_script,
                                                       Strings.label_script)
        self._field_script_tip.SetMessage(Strings.label_script_tip)

        # Black text sub sizer
        self._black_text_sub_sizer = wx.BoxSizer(wx.VERTICAL)
        self._label_black_text = wx.StaticText(
            self, -1, Strings.label_main_page_text + ': ')
        self._field_black_text = wx.TextCtrl(self,
                                             -1,
                                             size=wx.Size(-1, 135),
                                             style=wx.TE_MULTILINE)
        self._black_text_sub_sizer.Add(self._label_black_text,
                                       flag=wx.ALIGN_LEFT)
        self._black_text_sub_sizer.Add(3, 3)
        self._black_text_sub_sizer.Add(self._field_black_text,
                                       proportion=1,
                                       flag=wx.EXPAND)
        self._information_sizer.Add(self._black_text_sub_sizer,
                                    flag=wx.EXPAND | wx.TOP,
                                    border=Numbers.widget_border_size)
        self._field_black_text_tip = Tools.get_warning_tip(
            self._field_black_text, Strings.label_main_page_text)
        self._field_black_text_tip.SetMessage(Strings.label_main_page_text_tip)

        # Red text sub sizer
        self._red_text_sub_sizer = wx.BoxSizer(wx.VERTICAL)
        self._label_red_text = wx.StaticText(
            self, -1, Strings.label_main_page_warning + ': ')
        self._label_red_text.SetForegroundColour(wx.RED)
        self._field_red_text = wx.TextCtrl(self,
                                           -1,
                                           size=wx.Size(-1, 135),
                                           style=wx.TE_MULTILINE)
        self._field_red_text.SetForegroundColour(wx.RED)
        self._red_text_sub_sizer.Add(self._label_red_text, flag=wx.ALIGN_LEFT)
        self._red_text_sub_sizer.Add(3, 3)
        self._red_text_sub_sizer.Add(self._field_red_text,
                                     proportion=1,
                                     flag=wx.EXPAND)
        self._information_sizer.Add(self._red_text_sub_sizer,
                                    flag=wx.EXPAND | wx.TOP,
                                    border=Numbers.widget_border_size)
        self._field_red_text_tip = Tools.get_warning_tip(
            self._field_red_text, Strings.label_main_page_warning)
        self._field_red_text_tip.SetMessage(
            Strings.label_main_page_warning_tip)

        # Buttons
        self._button_sizer = wx.BoxSizer(wx.VERTICAL)
        grouping_sizer = wx.BoxSizer(wx.HORIZONTAL)
        self._cancel_button = wx.Button(self, wx.ID_CANCEL,
                                        Strings.button_cancel)
        self._ok_button = wx.Button(self, wx.ID_OK, Strings.button_ok)
        self._ok_button.SetDefault()
        grouping_sizer.Add(self._ok_button)
        grouping_sizer.Add(
            (Numbers.widget_border_size, Numbers.widget_border_size))
        grouping_sizer.Add(self._cancel_button)
        grouping_sizer.Add(
            (Numbers.widget_border_size, Numbers.widget_border_size))
        self._button_sizer.Add(grouping_sizer, flag=wx.ALIGN_CENTER_HORIZONTAL)
        if no_cancel:
            self._cancel_button.Hide()

        # Putting the sizers together
        self._vertical_sizer.Add(self._information_sizer,
                                 0,
                                 flag=wx.EXPAND | wx.LEFT | wx.RIGHT | wx.TOP,
                                 border=Numbers.widget_border_size)
        self._horizontal_sizer.Add(self._vertical_sizer, 1)
        self._main_vertical_sizer.Add(self._horizontal_sizer,
                                      1,
                                      flag=wx.EXPAND)
        self._main_vertical_sizer.Add(self._button_sizer,
                                      0,
                                      flag=wx.EXPAND | wx.LEFT | wx.RIGHT
                                      | wx.BOTTOM | wx.TOP,
                                      border=Numbers.widget_border_size)
        self.SetSizer(self._main_vertical_sizer)

        # Bind handlers
        self.Bind(wx.EVT_BUTTON, self._handle_buttons, self._ok_button)
        self.Bind(wx.EVT_BUTTON, self._handle_buttons, self._cancel_button)

        self._display_dialog_contents()
示例#9
0
    def __init__(self, parent, link: Link):
        """
        Display a dialog with information about the link where the user can edit it.
        :param parent: Parent frame.
        :param link: the Link instance to display.
        """
        super().__init__(parent,
                         title=Strings.label_dialog_edit_link,
                         size=(Numbers.edit_link_dialog_width,
                               Numbers.edit_link_dialog_height),
                         style=wx.DEFAULT_DIALOG_STYLE)
        self._link = link
        self._config_manager = ConfigManager.get_instance()

        self._main_vertical_sizer = wx.BoxSizer(wx.VERTICAL)
        self._horizontal_sizer = wx.BoxSizer(wx.HORIZONTAL)
        self._vertical_sizer = wx.BoxSizer(wx.VERTICAL)
        self._information_sizer = wx.BoxSizer(wx.VERTICAL)

        # Link URL sub sizer
        self._url_sub_sizer = wx.BoxSizer(wx.HORIZONTAL)
        self._label_url = wx.StaticText(self, -1, Strings.label_url + ': ')
        choices = self._link.get_loaded_pages()
        choices.append(Strings.index + Strings.extension_html)
        self._field_url = wx.ComboBox(self,
                                      -1,
                                      choices=choices,
                                      style=wx.CB_DROPDOWN | wx.CB_SORT)
        # Fires when you type in the box
        self.Bind(wx.EVT_TEXT, self._combobox_handler, self._field_url)

        self._url_sub_sizer.Add(self._label_url,
                                flag=wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL)
        self._url_sub_sizer.Add((35, -1))
        self._url_sub_sizer.Add(self._field_url, proportion=1)
        self._information_sizer.Add(self._url_sub_sizer,
                                    flag=wx.EXPAND | wx.TOP,
                                    border=Numbers.widget_border_size)
        self._field_url_tip = Tools.get_warning_tip(self._field_url,
                                                    Strings.label_url)

        # Link title sub sizer
        self._title_sub_sizer = wx.BoxSizer(wx.HORIZONTAL)
        self._label_link_title = wx.StaticText(self, -1,
                                               Strings.label_link_title + ': ')
        self._field_link_title = wx.TextCtrl(self, -1)
        self._title_sub_sizer.Add(self._label_link_title,
                                  flag=wx.ALIGN_LEFT
                                  | wx.ALIGN_CENTER_VERTICAL)
        self._title_sub_sizer.Add((8, -1))
        self._title_sub_sizer.Add(self._field_link_title, proportion=1)
        self._information_sizer.Add(self._title_sub_sizer,
                                    flag=wx.EXPAND | wx.TOP,
                                    border=Numbers.widget_border_size)
        self._field_link_title_tip = Tools.get_warning_tip(
            self._field_link_title, Strings.label_link_title)

        # Link text sub sizer
        self._text_sub_sizer = wx.BoxSizer(wx.HORIZONTAL)
        self._label_link_text = wx.StaticText(self, -1,
                                              Strings.label_text + ': ')
        self._field_link_text = wx.TextCtrl(self, -1)
        self._text_sub_sizer.Add(self._label_link_text,
                                 flag=wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL)
        self._text_sub_sizer.Add((35, -1))
        self._text_sub_sizer.Add(self._field_link_text, proportion=1)
        self._information_sizer.Add(self._text_sub_sizer,
                                    flag=wx.EXPAND | wx.TOP,
                                    border=Numbers.widget_border_size)
        self._field_link_text_tip = Tools.get_warning_tip(
            self._field_link_text, Strings.label_text)

        # Target blank checkbox
        self._checkbox_target_blank = wx.CheckBox(
            self, -1, label=Strings.label_open_in_new_page)
        self._checkbox_target_blank.SetValue(True)
        self._checkbox_target_blank.Disable()
        # Local link checkbox
        self._checkbox_local = wx.CheckBox(self,
                                           -1,
                                           label=Strings.label_link_local)
        self._checkbox_local.Disable()
        self._information_sizer.Add(self._checkbox_target_blank,
                                    flag=wx.TOP,
                                    border=Numbers.widget_border_size)
        self._information_sizer.Add(self._checkbox_local,
                                    flag=wx.TOP,
                                    border=Numbers.widget_border_size)

        # Buttons
        self._button_sizer = wx.BoxSizer(wx.VERTICAL)
        grouping_sizer = wx.BoxSizer(wx.HORIZONTAL)
        self._cancel_button = wx.Button(self, wx.ID_CANCEL,
                                        Strings.button_cancel)
        self._ok_button = wx.Button(self, wx.ID_OK, Strings.button_ok)
        self._ok_button.SetDefault()
        self._delete_button = wx.Button(self, wx.ID_DELETE,
                                        Strings.button_remove_link)
        grouping_sizer.Add(self._ok_button)
        grouping_sizer.Add(
            (Numbers.widget_border_size, Numbers.widget_border_size))
        grouping_sizer.Add(self._cancel_button)
        grouping_sizer.Add(
            (Numbers.widget_border_size, Numbers.widget_border_size))
        grouping_sizer.Add(self._delete_button)
        self._button_sizer.Add(grouping_sizer, flag=wx.ALIGN_CENTER_HORIZONTAL)

        # Putting the sizers together
        self._vertical_sizer.Add(self._information_sizer,
                                 0,
                                 flag=wx.EXPAND | wx.LEFT | wx.RIGHT | wx.TOP,
                                 border=Numbers.widget_border_size)
        self._horizontal_sizer.Add(self._vertical_sizer, 1)
        self._main_vertical_sizer.Add(self._horizontal_sizer,
                                      1,
                                      flag=wx.EXPAND)
        self._main_vertical_sizer.Add(self._button_sizer,
                                      0,
                                      flag=wx.EXPAND | wx.LEFT | wx.RIGHT
                                      | wx.BOTTOM,
                                      border=Numbers.widget_border_size)
        self.SetSizer(self._main_vertical_sizer)
        self._display_dialog_contents()

        # Bind handlers
        self.Bind(wx.EVT_BUTTON, self._handle_buttons, self._ok_button)
        self.Bind(wx.EVT_BUTTON, self._handle_buttons, self._cancel_button)
        self.Bind(wx.EVT_BUTTON, self._handle_buttons, self._delete_button)

        self._original_text = self._link.get_text()[0]
        self._original_url = self._link.get_url()[0]
        self._original_title = self._link.get_title()[0]
    def convert_to_html(self) -> None:
        """
        Converts this document into a html white bear menu page.
        :return: None
        :raise UnrecognizedFileException if template file can not be validated.
        :raise UnrecognizedFileException if html parse fails.
        :raise UnrecognizedFileException if generated html fails validation.
        :raises UnrecognizedFileException if xml schema is incorrect.
        """
        with open(Fetch.get_resource_path('menu_template.html'), 'r') as template:
            template_string = template.read()
        is_valid, errors = Tools.validate(template_string, 'schema_menu_template.xsd')
        if not is_valid:
            raise UnrecognizedFileException(Strings.exception_html_syntax_error + '\n' + 'menu_template.html ' +
                                            str(errors))

        parsed_template = BeautifulSoup(template_string, 'html5lib')

        # Fill title.
        title: Tag = parsed_template.find(name='title')
        title.string = Strings.menu_title_stump + ' ' + self._page_name + ' | ' + Strings.page_name

        # Fill description.
        description = parsed_template.find_all(name='meta', attrs={'name': 'description', 'content': True})
        if len(description) == 1:
            description[0]['content'] = self._meta_description
        else:
            raise UnrecognizedFileException(Strings.exception_parse_multiple_descriptions)

        # Fill keywords.
        keywords = parsed_template.find_all(name='meta', attrs={'name': 'keywords', 'content': True})
        if len(keywords) == 1:
            keywords[0]['content'] = ', '.join(self._meta_keywords)
        else:
            raise UnrecognizedFileException(Strings.exception_parse_multiple_keywords)

        # Fill author.
        author = parsed_template.find_all(name='meta', attrs={'name': 'author', 'content': True})
        if len(author) == 1:
            author[0]['content'] = self._config_manager.get_author()
        else:
            raise UnrecognizedFileException(Strings.exception_parse_multiple_authors)

        # Fill script.
        script = parsed_template.find(name='script')
        script.string = self._config_manager.get_script()

        # Fill global title.
        figure = parsed_template.find(name='header').figure
        figure.figcaption.string = self._config_manager.get_global_title()
        heading = parsed_template.find(name='h1', attrs={'id': 'heading'})
        heading.string = self._config_manager.get_global_title()

        # Activate correct menu, generate menu items according to menus.
        menu_container = parsed_template.find(name='nav')
        for instance in sorted(self._menus.values(), key=lambda x: x.get_section_name(), reverse=True):
            new_item = parsed_template.new_tag('a', attrs={'class': 'menu', 'href': instance.get_filename(),
                                                           'title': instance.get_page_name()[0]})
            new_item.string = instance.get_page_name()[0]
            if instance.get_filename() == self._file_name:
                new_item['id'] = 'active'
            menu_container.append(new_item)

        # Fill main page title.
        article = parsed_template.find(name='article', attrs={'class': 'menuPage'})
        article.h2.string = self._page_name

        # Fill menu items.
        menu_container = parsed_template.find(name='nav', attrs={'class': 'sixItems'})
        for item in self._menu_items:
            item: MenuItem
            attrs = {'class': 'link'}
            if not item.get_article():
                # Skip deleted articles.
                continue
            if not item.get_article().test_self(self._config_manager.get_online_test()):
                # Hide this menu item because this article is not yet finished or is deleted. The item will be available
                # for future parsing though so the editor will load the menu item correctly for the unfinished article.
                attrs['class'] = 'link hidden'
            new_div = parsed_template.new_tag('div', attrs=attrs)
            href = item.get_link_href()
            title = item.get_link_title()[0]
            width = item.get_image_size()[0]
            height = item.get_image_size()[1]
            src = item.get_filename()
            alt = item.get_image_alt()[0]
            text = item.get_article_name()[0]
            new_a = parsed_template.new_tag('a', attrs={'href': href, 'title': title})
            new_img = parsed_template.new_tag('img', attrs={'width': width, 'height': height, 'src': src, 'alt': alt})
            new_p = parsed_template.new_tag('p')
            new_p.string = text

            new_a.append(new_img)
            new_div.append(new_a)
            new_div.append(new_p)
            menu_container.append(new_div)

        output = str(parsed_template)
        is_valid, errors = Tools.validate(output, 'schema_menu.xsd')
        if not is_valid:
            raise UnrecognizedFileException(Strings.exception_bug + '\n' + self.get_filename() + ' \n' + str(errors))

        self._html = output
示例#11
0
'''
Created on 2 Jul 2019

@author: wvx67826
'''
import numpy as np
from astropy.io import ascii
import matplotlib.pyplot as plt
from Tools.Tools import Tools

dr = Tools()
folder = "Y:\\SQUID\\Relm\\3dice\\"
filename = folder + "HvM_NoAu_00001.dat"
with open(filename, 'r') as f:
    meta = True
    tMeta = []
    tData = []
    # break up the meta and data
    for line in f:
        tMeta.append(line)
        if not meta:
            tData.append(line)
        if "[Data]" in line:
            meta = False

k = np.genfromtxt(tData, names=True, delimiter=",")
l = ascii.read(tData, delimiter=',')
print l["Magnetic Field (Oe)"][0]

x = "Magnetic Field (Oe)"
y = "Moment (emu)"  #"DC Moment Fixed Ctr (emu)" #"Moment (emu)"#
    def __init__(self, parent, item: MenuItem, work_dir: str):
        """
        Display a dialog with information about the image where the user can edit it.
        :param parent: Parent frame.
        :param item: MenuItem instance being edited by this dialog.
        :param work_dir: Working directory of the editor.
        """
        super().__init__(parent,
                         title=Strings.label_dialog_edit_menu_item,
                         size=(Numbers.edit_aside_image_dialog_width,
                               Numbers.edit_menu_item_dialog_height),
                         style=wx.DEFAULT_DIALOG_STYLE)

        self._work_dir = work_dir
        self._original_item: MenuItem = item
        self._item_copy: MenuItem = self._original_item.copy()
        self._item_copy.test_self()

        self._alt_lock = False
        self._title_lock = False

        self._main_vertical_sizer = wx.BoxSizer(wx.VERTICAL)
        self._horizontal_sizer = wx.BoxSizer(wx.HORIZONTAL)
        self._vertical_sizer = wx.BoxSizer(wx.VERTICAL)
        self._information_sizer = wx.BoxSizer(wx.VERTICAL)

        # Disk location
        self._full_disk_location_sub_sizer = wx.BoxSizer(wx.HORIZONTAL)
        self.label_image_full_path = wx.StaticText(self, -1,
                                                   Strings.label_image + ': ')
        self.content_image_full_path = wx.StaticText(
            self,
            -1,
            Strings.label_none,
            style=wx.ST_ELLIPSIZE_MIDDLE | wx.ST_NO_AUTORESIZE)
        self._full_disk_location_sub_sizer.Add(self.label_image_full_path,
                                               flag=wx.ALIGN_LEFT
                                               | wx.ALIGN_CENTER_VERTICAL)
        self._full_disk_location_sub_sizer.Add(self.content_image_full_path,
                                               1,
                                               flag=wx.EXPAND)
        self._information_sizer.Add(self._full_disk_location_sub_sizer,
                                    flag=wx.EXPAND | wx.TOP,
                                    border=Numbers.widget_border_size)

        # Link href
        self._href_sub_sizer = wx.BoxSizer(wx.HORIZONTAL)
        self._label_href = wx.StaticText(self, -1, Strings.label_target + ': ')
        self._content_href = wx.StaticText(self,
                                           -1,
                                           Strings.label_none,
                                           style=wx.ST_ELLIPSIZE_MIDDLE
                                           | wx.ST_NO_AUTORESIZE)
        self._href_sub_sizer.Add(self._label_href,
                                 flag=wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL)
        self._href_sub_sizer.Add(self._content_href, 1, flag=wx.EXPAND)
        self._information_sizer.Add(self._href_sub_sizer,
                                    flag=wx.EXPAND | wx.TOP,
                                    border=Numbers.widget_border_size)

        # Original size
        self._image_size_sub_sizer = wx.BoxSizer(wx.HORIZONTAL)
        self._label_image_size = wx.StaticText(self, -1,
                                               Strings.label_size + ': ')
        self._content_image_size = wx.StaticText(self, -1, Strings.label_none)
        self._image_size_sub_sizer.Add(self._label_image_size,
                                       flag=wx.ALIGN_LEFT
                                       | wx.ALIGN_CENTER_VERTICAL)
        self._image_size_sub_sizer.Add((16, -1))
        self._image_size_sub_sizer.Add(self._content_image_size,
                                       flag=wx.ALIGN_LEFT
                                       | wx.ALIGN_CENTER_VERTICAL)
        self._information_sizer.Add(self._image_size_sub_sizer,
                                    flag=wx.EXPAND | wx.TOP,
                                    border=Numbers.widget_border_size)

        # Image name sub sizer
        self._name_sub_sizer = wx.BoxSizer(wx.HORIZONTAL)
        self._label_item_name = wx.StaticText(self, -1,
                                              Strings.label_menu_name + ': ')
        self._field_item_name = wx.TextCtrl(self, -1)
        self._name_sub_sizer.Add(self._label_item_name,
                                 flag=wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL)
        self._name_sub_sizer.Add((22, -1))
        self._name_sub_sizer.Add(self._field_item_name, proportion=1)
        self._information_sizer.Add(self._name_sub_sizer,
                                    flag=wx.EXPAND | wx.TOP,
                                    border=Numbers.widget_border_size)
        self._field_item_name_tip = Tools.get_warning_tip(
            self._field_item_name, Strings.label_menu_item_name)

        # Image link title sub sizer
        self._title_sub_sizer = wx.BoxSizer(wx.HORIZONTAL)
        self._label_image_title = wx.StaticText(
            self, -1, Strings.label_link_title + ': ')
        self._field_image_link_title = wx.TextCtrl(self, wx.ID_FILE2)
        self._title_sub_sizer.Add(self._label_image_title,
                                  flag=wx.ALIGN_LEFT
                                  | wx.ALIGN_CENTER_VERTICAL)
        self._title_sub_sizer.Add((44, -1))
        self._title_sub_sizer.Add(self._field_image_link_title, proportion=1)
        self._information_sizer.Add(self._title_sub_sizer,
                                    flag=wx.EXPAND | wx.TOP,
                                    border=Numbers.widget_border_size)
        self._field_image_link_title_tip = Tools.get_warning_tip(
            self._field_image_link_title,
            Strings.label_article_image_link_title)

        # Image alt sub sizer
        self._alt_sub_sizer = wx.BoxSizer(wx.HORIZONTAL)
        self._label_image_alt = wx.StaticText(
            self, -1, Strings.label_alt_description + ': ')
        self._field_image_alt = wx.TextCtrl(self, wx.ID_FILE1)
        self._alt_sub_sizer.Add(self._label_image_alt,
                                flag=wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL)
        self._alt_sub_sizer.Add((5, -1))
        self._alt_sub_sizer.Add(self._field_image_alt, proportion=1)
        self._information_sizer.Add(self._alt_sub_sizer,
                                    flag=wx.EXPAND | wx.TOP,
                                    border=Numbers.widget_border_size)
        self._field_image_alt_tip = Tools.get_warning_tip(
            self._field_image_alt, Strings.label_article_image_alt)

        # Image preview
        self._image_sizer = wx.BoxSizer(wx.VERTICAL)
        placeholder_image: wx.Image = wx.Image(Numbers.menu_logo_image_size,
                                               Numbers.menu_logo_image_size)
        placeholder_image.Replace(0, 0, 0, 245, 255, 255)
        self._bitmap = wx.StaticBitmap(self, -1, wx.Bitmap(placeholder_image))

        # Item name
        menu_text_field_font = wx.Font(Numbers.text_field_font_size,
                                       wx.FONTFAMILY_DEFAULT,
                                       wx.FONTSTYLE_NORMAL,
                                       wx.FONTWEIGHT_NORMAL, False)
        self._content_item_name = wx.StaticText(
            self,
            -1,
            Strings.label_article_menu_logo_name_placeholder,
            style=wx.ALIGN_CENTRE_HORIZONTAL)
        self._content_item_name.SetMaxSize((Numbers.menu_logo_image_size, -1))
        self._content_item_name.SetFont(menu_text_field_font)
        self._image_sizer.Add(self._bitmap, flag=wx.CENTER | wx.ALL, border=1)
        self._image_sizer.Add(self._content_item_name,
                              flag=wx.CENTER | wx.ALL,
                              border=1)

        # Buttons
        self._button_sizer = wx.BoxSizer(wx.VERTICAL)
        grouping_sizer = wx.BoxSizer(wx.HORIZONTAL)
        self._cancel_button = wx.Button(self, wx.ID_CANCEL,
                                        Strings.button_cancel)
        self._ok_button = wx.Button(self, wx.ID_OK, Strings.button_ok)
        self._ok_button.SetDefault()
        self._browse_button = wx.Button(self, wx.ID_OPEN,
                                        Strings.button_browse)
        self._add_button = wx.Button(self, wx.ID_ADD, Strings.button_add)
        grouping_sizer.Add(self._ok_button)
        grouping_sizer.Add(
            (Numbers.widget_border_size, Numbers.widget_border_size))
        grouping_sizer.Add(self._cancel_button)
        grouping_sizer.Add(
            (Numbers.widget_border_size, Numbers.widget_border_size))
        grouping_sizer.Add(self._browse_button)
        grouping_sizer.Add(
            (Numbers.widget_border_size, Numbers.widget_border_size))
        grouping_sizer.Add(self._add_button)
        self._button_sizer.Add(grouping_sizer, flag=wx.ALIGN_CENTER_HORIZONTAL)

        # Putting the sizers together
        self._vertical_sizer.Add(self._information_sizer,
                                 0,
                                 flag=wx.EXPAND | wx.LEFT | wx.RIGHT | wx.TOP,
                                 border=Numbers.widget_border_size)
        self._horizontal_sizer.Add(self._vertical_sizer, 1)
        self._horizontal_sizer.Add(self._image_sizer,
                                   0,
                                   flag=wx.TOP | wx.RIGHT | wx.EXPAND,
                                   border=Numbers.widget_border_size)
        self._main_vertical_sizer.Add(self._horizontal_sizer,
                                      1,
                                      flag=wx.EXPAND)
        self._main_vertical_sizer.Add(self._button_sizer,
                                      0,
                                      flag=wx.EXPAND | wx.LEFT | wx.RIGHT
                                      | wx.BOTTOM,
                                      border=Numbers.widget_border_size)
        self.SetSizer(self._main_vertical_sizer)

        # Bind handlers
        self.Bind(wx.EVT_BUTTON, self._handle_buttons, self._ok_button)
        self.Bind(wx.EVT_BUTTON, self._handle_buttons, self._cancel_button)
        self.Bind(wx.EVT_TEXT, self._handle_name_change, self._field_item_name)
        self.Bind(wx.EVT_BUTTON, self._handle_buttons, self._browse_button)
        self.Bind(wx.EVT_BUTTON, self._handle_buttons, self._add_button)
        self.Bind(wx.EVT_TEXT, self._lock_fields, self._field_image_alt)
        self.Bind(wx.EVT_TEXT, self._lock_fields, self._field_image_link_title)
示例#13
0
    def __init__(self, parent, menus: Dict[str, WhitebearDocumentMenu],
                 work_dir: str):
        """
        Display a dialog that allows editing additional data used in html generation.
        Default main title, author, contact, keywords, main page meta description. script, main page red/black text
        :param parent: The parent frame.
        :param menus: A dictionary of filename.html, WhitebearDocumentMenu
        :param work_dir: Working directory of the editor.
        """
        super().__init__(parent,
                         title=Strings.label_dialog_edit_menu,
                         size=(Numbers.edit_menu_dialog_width,
                               Numbers.edit_menu_dialog_height),
                         style=wx.CAPTION)

        self._config_manager: ConfigManager = ConfigManager.get_instance()
        self._menus = menus
        self._menu = None
        self._save_all = False
        self._work_dir = work_dir

        self._main_horizontal_sizer = wx.BoxSizer(wx.HORIZONTAL)
        self._left_vertical_sizer = wx.BoxSizer(wx.VERTICAL)
        self._right_vertical_sizer = wx.BoxSizer(wx.VERTICAL)
        self._information_sizer = wx.BoxSizer(wx.VERTICAL)

        # Menu list
        choices = list(self._menus.keys())
        self._menu_list = wx.ListBox(self,
                                     -1,
                                     size=(Numbers.minimal_panel_size, -1),
                                     choices=choices,
                                     style=wx.LB_SINGLE)
        if self._menus:
            self._menu_list.SetSelection(0)
        self._add_button = wx.Button(self, wx.ID_ADD, Strings.button_add)
        self._left_vertical_sizer.Add(self._menu_list,
                                      1,
                                      flag=wx.TOP | wx.LEFT,
                                      border=Numbers.widget_border_size)
        self._left_vertical_sizer.Add(self._add_button,
                                      flag=wx.ALL | wx.ALIGN_CENTER_HORIZONTAL,
                                      border=Numbers.widget_border_size)

        # Page name sub sizer
        self._page_name_sub_sizer = wx.BoxSizer(wx.HORIZONTAL)
        self._label_page_name = wx.StaticText(self, -1,
                                              Strings.label_menu_name + ': ')
        self._field_page_name = wx.TextCtrl(self, -1)
        self._page_name_sub_sizer.Add(self._label_page_name,
                                      flag=wx.ALIGN_LEFT
                                      | wx.ALIGN_CENTER_VERTICAL)
        self._page_name_sub_sizer.Add((2, -1))
        self._page_name_sub_sizer.Add(self._field_page_name, proportion=1)
        self._information_sizer.Add(self._page_name_sub_sizer,
                                    flag=wx.EXPAND | wx.TOP,
                                    border=Numbers.widget_border_size)
        self._field_page_name_tip = Tools.get_warning_tip(
            self._field_page_name, Strings.label_menu_name)
        self._field_page_name_tip.SetMessage(Strings.label_menu_name)

        # Keywords sub sizer
        self._meta_keywords_sub_sizer = wx.BoxSizer(wx.HORIZONTAL)
        self._label_meta_keywords = wx.StaticText(
            self, -1, Strings.label_default_keywords + ': ')
        self._field_meta_keywords = wx.TextCtrl(self, -1)
        self._meta_keywords_sub_sizer.Add(self._label_meta_keywords,
                                          flag=wx.ALIGN_LEFT
                                          | wx.ALIGN_CENTER_VERTICAL)
        self._meta_keywords_sub_sizer.Add((15, -1))
        self._meta_keywords_sub_sizer.Add(self._field_meta_keywords,
                                          proportion=1)
        self._information_sizer.Add(self._meta_keywords_sub_sizer,
                                    flag=wx.EXPAND | wx.TOP,
                                    border=Numbers.widget_border_size)
        self._field_keywords_tip = Tools.get_warning_tip(
            self._field_meta_keywords, Strings.label_menu_meta_keywords)
        self._field_keywords_tip.SetMessage(Strings.label_menu_meta_keywords)

        # --------------------------------------------------------------------------------------------------------------
        # Description sub sizer
        self._meta_description_sub_sizer = wx.BoxSizer(wx.VERTICAL)
        self._label_meta_description = wx.StaticText(
            self, -1, Strings.label_meta_description + ': ')
        self._field_meta_description = wx.TextCtrl(self,
                                                   -1,
                                                   size=(-1, 121),
                                                   style=wx.TE_MULTILINE)
        self._meta_description_sub_sizer.Add(self._label_meta_description,
                                             flag=wx.ALIGN_LEFT)
        self._meta_description_sub_sizer.Add(3, 3)
        self._meta_description_sub_sizer.Add(self._field_meta_description,
                                             proportion=1,
                                             flag=wx.EXPAND)
        self._information_sizer.Add(self._meta_description_sub_sizer,
                                    1,
                                    flag=wx.EXPAND | wx.TOP | wx.BOTTOM,
                                    border=Numbers.widget_border_size)
        self._field_description_tip = Tools.get_warning_tip(
            self._field_meta_description, Strings.label_meta_description)
        self._field_description_tip.SetMessage(
            Strings.label_menu_meta_description)

        # Buttons
        self._button_sizer = wx.BoxSizer(wx.VERTICAL)
        grouping_sizer = wx.BoxSizer(wx.HORIZONTAL)
        self._ok_button = wx.Button(self, wx.ID_OK, Strings.button_save)
        self._cancel_button = wx.Button(self, wx.ID_CANCEL,
                                        Strings.button_cancel)
        self._ok_button.SetDefault()
        self._spellcheck_button = wx.Button(self, wx.ID_SPELL_CHECK,
                                            Strings.button_spellcheck)
        grouping_sizer.Add(self._ok_button)
        grouping_sizer.Add(
            (Numbers.widget_border_size, Numbers.widget_border_size))
        grouping_sizer.Add(self._cancel_button)
        grouping_sizer.Add(
            (Numbers.widget_border_size, Numbers.widget_border_size))
        grouping_sizer.Add(self._spellcheck_button)
        self._button_sizer.Add(grouping_sizer, flag=wx.ALIGN_CENTER_HORIZONTAL)

        # Putting the sizers together
        self._right_vertical_sizer.Add(self._information_sizer,
                                       0,
                                       flag=wx.EXPAND | wx.LEFT | wx.RIGHT
                                       | wx.TOP,
                                       border=Numbers.widget_border_size)
        self._main_horizontal_sizer.Add(self._left_vertical_sizer,
                                        flag=wx.EXPAND)
        self._main_horizontal_sizer.Add(self._right_vertical_sizer,
                                        1,
                                        flag=wx.EXPAND)
        self._right_vertical_sizer.Add(self._button_sizer,
                                       flag=wx.EXPAND | wx.LEFT | wx.RIGHT
                                       | wx.BOTTOM,
                                       border=Numbers.widget_border_size)
        self.SetSizer(self._main_horizontal_sizer)

        # Bind handlers
        self.Bind(wx.EVT_BUTTON, self._handle_buttons, self._ok_button)
        self.Bind(wx.EVT_BUTTON, self._handle_buttons, self._cancel_button)
        self.Bind(wx.EVT_BUTTON, self._handle_buttons, self._spellcheck_button)
        self.Bind(wx.EVT_BUTTON, self._handle_new_menu_button,
                  self._add_button)
        self.Bind(wx.EVT_LISTBOX, self._menu_list_handler, self._menu_list)
        for field in (self._field_page_name, self._field_meta_keywords,
                      self._field_meta_description):
            self.Bind(wx.EVT_TEXT, self._text_handler, field)

        if not self._menus:
            # Disable all but the new menu button.
            self._field_page_name.Disable()
            self._field_meta_keywords.Disable()
            self._field_meta_description.Disable()
            self._ok_button.Disable()

        self._display_dialog_contents()
    def _validate_fields(self) -> bool:
        """
        Validate configuration fields.
        :return: True if validation passed
        """
        result = True
        # Check IP:port
        ip_port = self._field_ip_port.GetValue().split(':', 2)
        try:
            if not self._field_ip_port.GetValue():
                self._field_ip_port_tip.SetMessage(Strings.label_ip_port_tip)
                Tools.set_field_background(self._field_ip_port,
                                           Numbers.RED_COLOR)
            elif len(ip_port) > 2 or len(
                    ip_port) < 2 or not ip_port[0] or not ip_port[1]:
                self._field_ip_port_tip.SetMessage(
                    Strings.warning_incorrect_format)
                Tools.set_field_background(self._field_ip_port,
                                           Numbers.RED_COLOR)
                result = False
            elif int(ip_port[1]) < 1 or int(ip_port[1]) > 65535:
                self._field_ip_port_tip.SetMessage(
                    Strings.warning_incorrect_port)
                Tools.set_field_background(self._field_ip_port,
                                           Numbers.RED_COLOR)
                result = False
            ip = ip_port[0].split('.', 4)
            if len(ip) < 4 or len(ip) > 4 or not ip:
                self._field_ip_port_tip.SetMessage(
                    Strings.warning_incorrect_ip_format)
                Tools.set_field_background(self._field_ip_port,
                                           Numbers.RED_COLOR)
                result = False
            for num in ip:
                if int(num) < 0 or int(num) > 255:
                    self._field_ip_port_tip.SetMessage(
                        Strings.warning_incorrect_ip_format)
                    Tools.set_field_background(self._field_ip_port,
                                               Numbers.RED_COLOR)
                    result = False
        except ValueError as _:
            self._field_ip_port_tip.SetMessage(
                Strings.warning_incorrect_format)
            Tools.set_field_background(self._field_ip_port, Numbers.RED_COLOR)
            result = False
        if result:
            self._field_ip_port_tip.SetMessage(Strings.label_ip_port_tip)
            Tools.set_field_background(self._field_ip_port,
                                       Numbers.GREEN_COLOR)
            self._config_manager.store_ip_port(self._field_ip_port.GetValue())

        # Check username
        username = self._field_user.GetValue()
        if len(username) > Numbers.default_max_length or len(username) < 1:
            self._field_user_tip.SetMessage(Strings.seo_error_length + ': 1-' +
                                            str(Numbers.default_max_length))
            Tools.set_field_background(self._field_user, Numbers.RED_COLOR)
            result = False
        else:
            self._field_user_tip.SetMessage(Strings.label_user_tip)
            Tools.set_field_background(self._field_user, Numbers.GREEN_COLOR)
            self._config_manager.store_user(self._field_user.GetValue())

        # Check keyfile existence
        key_path = self._field_keyfile.GetValue()
        if not os.path.exists(key_path) or not os.access(key_path, os.R_OK):
            self._field_keyfile_tip.SetMessage(
                Strings.warning_keyfile_inaccessible)
            Tools.set_field_background(self._field_keyfile, Numbers.RED_COLOR)
            result = False
        elif oct(stat.S_IMODE(os.stat(key_path).st_mode)) != oct(
                Numbers.private_key_permissions):
            self._field_keyfile_tip.SetMessage(
                Strings.warning_keyfile_permissions)
            Tools.set_field_background(self._field_keyfile, Numbers.RED_COLOR)
            result = False
        else:
            self._field_keyfile_tip.SetMessage(Strings.label_key_file_tip)
            Tools.set_field_background(self._field_keyfile,
                                       Numbers.GREEN_COLOR)
            self._config_manager.store_keyfile(self._field_keyfile.GetValue())

        if not result or self._count_checked_files(
        ) == 0 or self._prevent_upload:
            self._upload_button.Disable()
            if self._prevent_upload:
                self._content_num_invalid_files.SetLabelText(
                    str(self._invalid_files) + ' - ' +
                    Strings.warning_fatal_invalidity)
        else:
            self._upload_button.Enable()
        return result
示例#15
0
class Yhdlogin():
    def __init__(self):
        self.instance = Tools()

    def login(self, username, password):
        # self.instance.openBrower("http://www.yhd.com/")
        # self.instance.wait(3)
        self.instance.clickEvent("class_name", "hd_login_link")
        self.instance.wait(3)
        self.instance.inputEvent("name", "credentials.username", username)
        self.instance.inputEvent("name", "credentials.password", password)
        self.instance.clickEvent("id", "login_button")
        self.instance.wait(2)
        try:
            get_text = self.instance.getText("class_name", "hd_login_name")
            self.instance.moveElement("class_name", "hd_login_name")
            self.instance.clickEvent("class_name", "hd_login_out")
        except:
            get_text = self.instance.getText("class_name", "error_tips")

        return get_text
示例#16
0
    def __init__(self, parent, work_dir: str):
        """
        This dialog helps with adding a new menu logo into the folder structure of the website.
        Display a dialog with information about the image where the user can edit it.
        :param parent: Parent frame.
        :param work_dir: The working directory of the editor.
        """
        wx.Dialog.__init__(self, parent, title=Strings.label_dialog_add_logo,
                           size=(Numbers.add_logo_dialog_width, Numbers.add_logo_dialog_height),
                           style=wx.DEFAULT_DIALOG_STYLE)

        self._main_vertical_sizer = wx.BoxSizer(wx.VERTICAL)
        self._horizontal_sizer = wx.BoxSizer(wx.HORIZONTAL)
        self._vertical_sizer = wx.BoxSizer(wx.VERTICAL)
        self._information_sizer = wx.BoxSizer(wx.VERTICAL)
        self._image_path = None
        self._image_name = None
        self._menu_image = None
        self._logos_path = None
        self._working_directory = work_dir
        self._file_path = None
        self._config_manager = ConfigManager.get_instance()

        # Disk location
        self._original_disk_location_sub_sizer = wx.BoxSizer(wx.HORIZONTAL)
        self._label_image_original_path = wx.StaticText(self, -1, Strings.label_image + ': ')
        self._content_image_original_path = wx.StaticText(self, -1, Strings.label_none,
                                                          style=wx.ST_ELLIPSIZE_MIDDLE | wx.ST_NO_AUTORESIZE)
        self._original_disk_location_sub_sizer.Add(self._label_image_original_path,
                                                   flag=wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL)
        self._original_disk_location_sub_sizer.Add(self._content_image_original_path, 1, flag=wx.EXPAND)
        self._information_sizer.Add(self._original_disk_location_sub_sizer, flag=wx.EXPAND | wx.TOP,
                                    border=Numbers.widget_border_size)

        # Original size
        self._image_original_size_sub_sizer = wx.BoxSizer(wx.HORIZONTAL)
        self._label_image_size = wx.StaticText(self, -1, Strings.label_size + ': ')
        self._content_image_size = wx.StaticText(self, -1, Strings.label_none,
                                                 style=wx.ST_ELLIPSIZE_MIDDLE | wx.ST_NO_AUTORESIZE)
        self._image_original_size_sub_sizer.Add(self._label_image_size,
                                                flag=wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL)
        self._image_original_size_sub_sizer.Add((14, -1))
        self._image_original_size_sub_sizer.Add(self._content_image_size, 1, flag=wx.EXPAND)
        self._information_sizer.Add(self._image_original_size_sub_sizer, flag=wx.EXPAND | wx.TOP,
                                    border=Numbers.widget_border_size)

        # Image name sub sizer
        self._name_sub_sizer = wx.BoxSizer(wx.HORIZONTAL)
        self._label_image_name = wx.StaticText(self, -1, Strings.label_name + ': ')
        self._field_image_name = wx.TextCtrl(self, -1)
        self._field_image_name.Disable()
        self._name_sub_sizer.Add(self._label_image_name, flag=wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL)
        self._name_sub_sizer.Add((5, -1))
        self._name_sub_sizer.Add(self._field_image_name, proportion=1)
        self._information_sizer.Add(self._name_sub_sizer, flag=wx.EXPAND | wx.TOP, border=Numbers.widget_border_size)
        self._field_image_name_tip = Tools.get_warning_tip(self._field_image_name, Strings.label_image_name)
        self._field_image_name_tip.SetMessage('')

        # Image preview
        self._image_sizer = wx.BoxSizer(wx.VERTICAL)
        self._bitmap = wx.StaticBitmap(self, -1, wx.Bitmap(wx.Image(Fetch.get_resource_path('menu_image_missing.png'),
                                                                    wx.BITMAP_TYPE_PNG)))
        self._image_sizer.Add(self._bitmap, flag=wx.ALL, border=1)

        # Buttons
        self._button_sizer = wx.BoxSizer(wx.VERTICAL)
        grouping_sizer = wx.BoxSizer(wx.HORIZONTAL)
        self._cancel_button = wx.Button(self, wx.ID_CANCEL, Strings.button_cancel)
        self._save_button = wx.Button(self, wx.ID_OK, Strings.button_save)
        self._browse_button = wx.Button(self, wx.ID_OPEN, Strings.button_browse)
        self._save_button.Disable()
        self._browse_button.SetDefault()
        grouping_sizer.Add(self._save_button)
        grouping_sizer.Add((Numbers.widget_border_size, Numbers.widget_border_size))
        grouping_sizer.Add(self._cancel_button)
        grouping_sizer.Add((Numbers.widget_border_size, Numbers.widget_border_size))
        grouping_sizer.Add(self._browse_button)
        self._button_sizer.Add(grouping_sizer, flag=wx.ALIGN_CENTER_HORIZONTAL)

        # Putting the sizers together
        self._vertical_sizer.Add(self._information_sizer, 0, flag=wx.EXPAND | wx.LEFT | wx.RIGHT | wx.TOP,
                                 border=Numbers.widget_border_size)
        self._horizontal_sizer.Add(self._vertical_sizer, 1)
        self._horizontal_sizer.Add(self._image_sizer, flag=wx.TOP | wx.RIGHT, border=Numbers.widget_border_size)
        self._main_vertical_sizer.Add(self._horizontal_sizer, 1, flag=wx.EXPAND)
        self._main_vertical_sizer.Add(self._button_sizer, 0, flag=wx.EXPAND | wx.LEFT | wx.RIGHT | wx.BOTTOM,
                                      border=Numbers.widget_border_size)
        self.SetSizer(self._main_vertical_sizer)

        # Bind handlers
        self.Bind(wx.EVT_BUTTON, self._handle_buttons, self._save_button)
        self.Bind(wx.EVT_BUTTON, self._handle_buttons, self._cancel_button)
        self.Bind(wx.EVT_BUTTON, self._handle_buttons, self._browse_button)
        self.Bind(wx.EVT_TEXT, self._switch_default_button, self._field_image_name)
示例#17
0
 def __init__(self):
     self.instance = Tools()
示例#18
0
    def _seo_test(self) -> bool:
        """
        SEO test meta keywords and meta description.
        :return: True if seo is ok.
        """
        result = True
        # Keywords test.
        # Spellcheck here is a part of the seo tests.
        correct, message, color = self._test_doc.seo_test_keywords(
            self._field_meta_keywords.GetValue())
        result = result and correct
        self._field_meta_keywords.SetBackgroundColour(color)
        self._field_keywords_tip.SetMessage(
            Strings.label_default_keywords_tip + '\n\n' + Strings.seo_check +
            '\n' + message)

        # Description test.
        correct, message, color = self._test_doc.seo_test_description(
            self._field_meta_description.GetValue())
        result = result and correct
        Tools.set_field_background(self._field_meta_description, color)
        self._field_description_tip.SetMessage(
            Strings.label_main_description_tip + '\n\n' + Strings.seo_check +
            '\n' + message)

        # Check emptiness.
        # Check length and spelling.
        for sp, field, tip, msg in ((True, self._field_global_title,
                                     self._field_global_title_tip,
                                     Strings.label_main_title_tip),
                                    (True, self._field_author,
                                     self._field_author_tip,
                                     Strings.label_author_tip),
                                    (False, self._field_contact,
                                     self._field_contact_tip,
                                     Strings.label_contact_tip),
                                    (False, self._field_url,
                                     self._field_url_tip,
                                     Strings.label_website_url_tip),
                                    (False, self._field_script,
                                     self._field_script_tip,
                                     Strings.label_script_tip),
                                    (True, self._field_black_text,
                                     self._field_black_text_tip,
                                     Strings.label_main_page_text_tip),
                                    (True, self._field_red_text,
                                     self._field_red_text_tip,
                                     Strings.label_main_page_warning_tip)):
            if field in (self._field_global_title, self._field_author, self._field_contact, self._field_url) and \
                    (len(field.GetValue()) > Numbers.default_max_length or len(field.GetValue()) < 1):
                result = False
                Tools.set_field_background(field, Numbers.RED_COLOR)
                tip.SetMessage(msg + '\n\n' + Strings.seo_check + '\n' +
                               Strings.seo_error_length + ': 1 - ' +
                               str(Numbers.default_max_length))
            elif field in (self._field_script, self._field_black_text,
                           self._field_red_text) and not field.GetValue():
                result = False
                Tools.set_field_background(field, Numbers.RED_COLOR)
                tip.SetMessage(msg + '\n\n' + Strings.seo_check + '\n' +
                               Strings.seo_error_not_empty)
            elif not self._spell_check(field.GetValue()) and sp:
                # Run spellcheck on this field.
                # In other cases spellcheck is done by the object copy and error messages are set in it.
                # Here we do not have the copy and have to do it as part of this method again.
                # Keywords and description already have a spellcheck in their builtin seo test.
                result = False
                Tools.set_field_background(field, Numbers.RED_COLOR)
                tip.SetMessage(msg + '\n\n' + Strings.seo_check + '\n' +
                               Strings.spelling_error)
            else:
                Tools.set_field_background(field, Numbers.GREEN_COLOR)
                tip.SetMessage(msg + '\n\n' + Strings.seo_check + '\n' +
                               Strings.status_ok)

        return result
示例#19
0
    def __init__(self, parent, image: ImageInText, working_dir: str):
        """
        Display a dialog with information about the image where the user can edit it.
        :param parent: Parent frame.
        :param image: ImageInText instance being edited by this dialog.
        :param working_dir: Working directory of the editor
        """
        super().__init__(parent, title=Strings.label_dialog_edit_image,
                         size=(Numbers.edit_text_image_dialog_width, Numbers.edit_text_image_dialog_height),
                         style=wx.DEFAULT_DIALOG_STYLE)
        self._work_dir = working_dir
        self._original_image: ImageInText = image
        self._image_copy: ImageInText = self._original_image.copy()
        self._image_copy.test_self()

        self._alt_lock = False

        self._main_vertical_sizer = wx.BoxSizer(wx.VERTICAL)
        self._horizontal_sizer = wx.BoxSizer(wx.HORIZONTAL)
        self._vertical_sizer = wx.BoxSizer(wx.VERTICAL)
        self._information_sizer = wx.BoxSizer(wx.VERTICAL)

        # Disk locations
        self._full_disk_location_sub_sizer = wx.BoxSizer(wx.HORIZONTAL)
        self._label_image_full_path = wx.StaticText(self, -1, Strings.label_image_path + ': ')
        self._content_image_full_path = wx.StaticText(self, -1, Strings.label_none,
                                                      style=wx.ST_ELLIPSIZE_MIDDLE | wx.ST_NO_AUTORESIZE)
        self._full_disk_location_sub_sizer.Add(self._label_image_full_path,
                                               flag=wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL)
        self._full_disk_location_sub_sizer.Add(self._content_image_full_path, 1, flag=wx.EXPAND)
        self._information_sizer.Add(self._full_disk_location_sub_sizer, flag=wx.EXPAND | wx.TOP,
                                    border=Numbers.widget_border_size)

        self._thumb_disk_location_sub_sizer = wx.BoxSizer(wx.HORIZONTAL)
        self._label_image_thumbnail_path = wx.StaticText(self, -1, Strings.label_image_thumbnail_path + ': ')
        self._content_image_thumbnail_path = wx.StaticText(self, -1, Strings.label_none,
                                                           style=wx.ST_ELLIPSIZE_MIDDLE | wx.ST_NO_AUTORESIZE)
        self._thumb_disk_location_sub_sizer.Add(self._label_image_thumbnail_path,
                                                flag=wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL)
        self._thumb_disk_location_sub_sizer.Add(self._content_image_thumbnail_path, 1, flag=wx.EXPAND)
        self._information_sizer.Add(self._thumb_disk_location_sub_sizer, flag=wx.EXPAND | wx.TOP,
                                    border=Numbers.widget_border_size)

        # Original size
        self._image_original_size_sub_sizer = wx.BoxSizer(wx.HORIZONTAL)
        self._label_image_original_size = wx.StaticText(self, -1, Strings.label_original_size + ': ')
        self._content_image_original_size = wx.StaticText(self, -1, Strings.label_none)
        self._image_original_size_sub_sizer.Add(self._label_image_original_size,
                                                flag=wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL)
        self._image_original_size_sub_sizer.Add((16, -1))
        self._image_original_size_sub_sizer.Add(self._content_image_original_size,
                                                flag=wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL)
        self._information_sizer.Add(self._image_original_size_sub_sizer, flag=wx.EXPAND | wx.TOP,
                                    border=Numbers.widget_border_size)

        # Thumbnail size
        self._image_thumbnail_size_sub_sizer = wx.BoxSizer(wx.HORIZONTAL)
        self._label_image_thumbnail_size = wx.StaticText(self, -1, Strings.label_thumbnail_size + ': ')
        self._content_image_thumbnail_size = wx.StaticText(self, -1, Strings.label_none)
        self._image_thumbnail_size_sub_sizer.Add(self._label_image_thumbnail_size,
                                                 flag=wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL)
        self._image_thumbnail_size_sub_sizer.Add(self._content_image_thumbnail_size,
                                                 flag=wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL)
        self._information_sizer.Add(self._image_thumbnail_size_sub_sizer, flag=wx.EXPAND | wx.TOP,
                                    border=Numbers.widget_border_size)

        # Image link title sub sizer
        self._title_sub_sizer = wx.BoxSizer(wx.HORIZONTAL)
        self._label_image_title = wx.StaticText(self, -1, Strings.label_link_title + ': ')
        self._field_image_link_title = wx.TextCtrl(self, -1)
        self._title_sub_sizer.Add(self._label_image_title, flag=wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL)
        self._title_sub_sizer.Add((44, -1))
        self._title_sub_sizer.Add(self._field_image_link_title, proportion=1)
        self._information_sizer.Add(self._title_sub_sizer, flag=wx.EXPAND | wx.TOP, border=Numbers.widget_border_size)
        self._field_image_link_title_tip = Tools.get_warning_tip(self._field_image_link_title,
                                                                 Strings.label_article_image_link_title)

        # Image alt sub sizer
        self._alt_sub_sizer = wx.BoxSizer(wx.HORIZONTAL)
        self._label_image_alt = wx.StaticText(self, -1, Strings.label_alt_description + ': ')
        self._field_image_alt = wx.TextCtrl(self, wx.ID_FILE2)
        self._alt_sub_sizer.Add(self._label_image_alt, flag=wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL)
        self._alt_sub_sizer.Add((5, -1))
        self._alt_sub_sizer.Add(self._field_image_alt, proportion=1)
        self._information_sizer.Add(self._alt_sub_sizer, flag=wx.EXPAND | wx.TOP, border=Numbers.widget_border_size)
        self._field_image_alt_tip = Tools.get_warning_tip(self._field_image_alt, Strings.label_article_image_alt)

        # Target blank checkbox all link always open in new page
        self._checkbox_target_blank = wx.CheckBox(self, -1, label=Strings.label_open_in_new_page)
        self._checkbox_target_blank.SetValue(True)
        self._checkbox_target_blank.Disable()
        self._information_sizer.Add(self._checkbox_target_blank, flag=wx.TOP, border=Numbers.widget_border_size)

        # Image preview
        self._image_sizer = wx.BoxSizer(wx.VERTICAL)
        placeholder_image: wx.Image = wx.Image(Numbers.main_image_width, Numbers.main_image_height)
        placeholder_image.Replace(0, 0, 0, 245, 255, 255)
        self._bitmap = wx.StaticBitmap(self, -1, wx.Bitmap(placeholder_image))
        self._image_sizer.Add(self._bitmap, flag=wx.ALL, border=1)

        # Buttons
        self._button_sizer = wx.BoxSizer(wx.VERTICAL)
        grouping_sizer = wx.BoxSizer(wx.HORIZONTAL)
        self._cancel_button = wx.Button(self, wx.ID_CANCEL, Strings.button_cancel)
        self._ok_button = wx.Button(self, wx.ID_OK, Strings.button_ok)
        self._ok_button.SetDefault()
        self._browse_button = wx.Button(self, wx.ID_OPEN, Strings.button_browse)
        self._add_button = wx.Button(self, wx.ID_ADD, Strings.button_add)
        grouping_sizer.Add(self._ok_button)
        grouping_sizer.Add((Numbers.widget_border_size, Numbers.widget_border_size))
        grouping_sizer.Add(self._cancel_button)
        grouping_sizer.Add((Numbers.widget_border_size, Numbers.widget_border_size))
        grouping_sizer.Add(self._browse_button)
        grouping_sizer.Add((Numbers.widget_border_size, Numbers.widget_border_size))
        grouping_sizer.Add(self._add_button)
        self._button_sizer.Add(grouping_sizer, flag=wx.ALIGN_CENTER_HORIZONTAL)

        # Putting the sizers together
        self._vertical_sizer.Add(self._information_sizer, 0, flag=wx.EXPAND | wx.LEFT | wx.RIGHT | wx.TOP,
                                 border=Numbers.widget_border_size)
        self._horizontal_sizer.Add(self._vertical_sizer, 1)
        self._horizontal_sizer.Add(self._image_sizer, flag=wx.TOP | wx.RIGHT, border=Numbers.widget_border_size)
        self._main_vertical_sizer.Add(self._horizontal_sizer, 1, flag=wx.EXPAND)
        self._main_vertical_sizer.Add(self._button_sizer, 0, flag=wx.EXPAND | wx.LEFT | wx.RIGHT | wx.BOTTOM,
                                      border=Numbers.widget_border_size)
        self.SetSizer(self._main_vertical_sizer)
        self._display_dialog_contents()

        # Disable auto copy of fields if the fields contain different data.
        if self._field_image_alt.GetValue() != self._field_image_link_title.GetValue():
            self._alt_lock = True

        # Bind handlers
        self.Bind(wx.EVT_BUTTON, self._handle_buttons, self._ok_button)
        self.Bind(wx.EVT_BUTTON, self._handle_buttons, self._cancel_button)
        self.Bind(wx.EVT_BUTTON, self._handle_buttons, self._browse_button)
        self.Bind(wx.EVT_BUTTON, self._handle_buttons, self._add_button)

        self.Bind(wx.EVT_TEXT, self._handle_edit, self._field_image_link_title)
        self.Bind(wx.EVT_TEXT, self._lock_fields, self._field_image_alt)