diff --git a/src/crystal/browser/__init__.py b/src/crystal/browser/__init__.py index bb3586d7..183012ee 100644 --- a/src/crystal/browser/__init__.py +++ b/src/crystal/browser/__init__.py @@ -362,6 +362,10 @@ def _suggested_url_or_url_pattern_for_selection(self) -> Optional[str]: def _suggested_source_for_selection(self) -> Optional[ResourceGroupSource]: return self.entity_tree.source_of_selected_entity + @property + def _suggested_name_for_selection(self) -> Optional[str]: + return self.entity_tree.name_of_selected_entity + # === Operations === def close(self) -> None: @@ -427,6 +431,7 @@ def root_url_exists(url: str) -> bool: self._frame, self._on_add_url_dialog_ok, url_exists_func=root_url_exists, initial_url=self._suggested_url_or_url_pattern_for_selection or '', + initial_name=self._suggested_name_for_selection or '', ) @fg_affinity @@ -444,7 +449,8 @@ def _on_add_group(self, event: wx.CommandEvent) -> None: self._frame, self._on_add_group_dialog_ok, self.project, initial_url_pattern=self._suggested_url_or_url_pattern_for_selection or '', - initial_source=self._suggested_source_for_selection) + initial_source=self._suggested_source_for_selection, + initial_name=self._suggested_name_for_selection or '') except CancelLoadUrls: pass diff --git a/src/crystal/browser/addgroup.py b/src/crystal/browser/addgroup.py index 60570409..e55ebbb8 100644 --- a/src/crystal/browser/addgroup.py +++ b/src/crystal/browser/addgroup.py @@ -28,6 +28,7 @@ def __init__(self, project: Project, initial_url_pattern: str='', initial_source: Optional[ResourceGroupSource]=None, + initial_name: str='', ) -> None: """ Arguments: @@ -36,6 +37,7 @@ def __init__(self, * project -- the project. * initial_url_pattern -- overrides the initial URL pattern displayed. * initial_source -- overrides the initial source displayed. + * initial_name -- overrides the initial name displayed. Raises: * CancelLoadUrls @@ -92,7 +94,7 @@ def __init__(self, content_sizer = wx.BoxSizer(wx.VERTICAL) content_sizer.Add( - self._create_fields(dialog, initial_url_pattern, initial_source), + self._create_fields(dialog, initial_url_pattern, initial_source, initial_name), flag=wx.EXPAND) content_sizer.Add(preview_box, proportion=1, flag=wx.EXPAND|preview_box_flags, border=preview_box_border) @@ -115,7 +117,8 @@ def __init__(self, def _create_fields(self, parent: wx.Window, initial_url_pattern: str, - initial_source: Optional[ResourceGroupSource] + initial_source: Optional[ResourceGroupSource], + initial_name: str, ) -> wx.Sizer: fields_sizer = wx.FlexGridSizer(cols=2, vgap=_FORM_ROW_SPACING, hgap=_FORM_LABEL_INPUT_SPACING) @@ -157,7 +160,7 @@ def _create_fields(self, fields_sizer.Add(wx.StaticText(parent, label='Name:', style=wx.ALIGN_RIGHT), flag=wx.EXPAND) self.name_field = wx.TextCtrl( - parent, + parent, value=initial_name, name='cr-add-group-dialog__name-field') self.name_field.Hint = 'Post' self.name_field.SetSelection(-1, -1) # select all upon focus diff --git a/src/crystal/browser/addrooturl.py b/src/crystal/browser/addrooturl.py index d33e2ea1..58732329 100644 --- a/src/crystal/browser/addrooturl.py +++ b/src/crystal/browser/addrooturl.py @@ -27,6 +27,7 @@ def __init__(self, on_finish: Callable[[str, str], None], url_exists_func: Callable[[str], bool], initial_url: str='', + initial_name: str='', ) -> None: """ Arguments: @@ -52,7 +53,7 @@ def __init__(self, bind(dialog, wx.EVT_CLOSE, self._on_close) bind(dialog, wx.EVT_WINDOW_DESTROY, self._on_destroyed) - dialog_sizer.Add(self._create_fields(dialog, initial_url), flag=wx.EXPAND|wx.ALL, + dialog_sizer.Add(self._create_fields(dialog, initial_url, initial_name), flag=wx.EXPAND|wx.ALL, border=_WINDOW_INNER_PADDING) dialog_sizer.Add(dialog.CreateButtonSizer(wx.OK|wx.CANCEL), flag=wx.EXPAND|wx.BOTTOM, border=_WINDOW_INNER_PADDING) @@ -75,7 +76,7 @@ def __init__(self, if os.environ.get('CRYSTAL_RUNNING_TESTS', 'False') == 'True': AddRootUrlDialog._last_opened = self - def _create_fields(self, parent: wx.Window, initial_url: str) -> wx.Sizer: + def _create_fields(self, parent: wx.Window, initial_url: str, initial_name: str) -> wx.Sizer: fields_sizer = wx.FlexGridSizer(rows=2, cols=2, vgap=_FORM_ROW_SPACING, hgap=_FORM_LABEL_INPUT_SPACING) fields_sizer.AddGrowableCol(1) @@ -115,7 +116,7 @@ def _create_fields(self, parent: wx.Window, initial_url: str) -> wx.Sizer: name_field_and_space = wx.BoxSizer(wx.HORIZONTAL) if True: self.name_field = wx.TextCtrl( - parent, + parent, value=initial_name, name='cr-add-url-dialog__name-field') self.name_field.Hint = 'Home' self.name_field.SetSelection(-1, -1) # select all upon focus diff --git a/src/crystal/browser/entitytree.py b/src/crystal/browser/entitytree.py index 114e1707..3b4b123c 100644 --- a/src/crystal/browser/entitytree.py +++ b/src/crystal/browser/entitytree.py @@ -2,6 +2,7 @@ from crystal.browser.icons import BADGED_TREE_NODE_ICON, TREE_NODE_ICONS from crystal.doc.generic import Link +from crystal.doc.html.soup import TEXT_LINK_TYPE_TITLE from crystal.model import ( Project, ProjectHasTooManyRevisionsError, Resource, ResourceGroup, ResourceGroupSource, @@ -102,6 +103,28 @@ def source_of_selected_entity(self) -> Optional[ResourceGroupSource]: ancestor_node_view = self._parent_of_node_view(ancestor_node_view) return None + @property + def name_of_selected_entity(self) -> Optional[str]: + entity = self.selected_entity + if isinstance(entity, (RootResource, ResourceGroup)): + return entity.name + elif isinstance(entity, Resource): + selected_node_view = self.view.selected_node + if selected_node_view is None: + return None + selected_node = self._node_for_node_view(selected_node_view) + if isinstance(selected_node, LinkedResourceNode): + for link in selected_node.links: + if (link.type_title == TEXT_LINK_TYPE_TITLE and + link.title is not None and + link.title != ''): + return link.title + return None + else: + return None + else: + return None + @staticmethod def _node_for_node_view(node_view: NodeView) -> Node: node = node_view.delegate diff --git a/src/crystal/doc/html/soup.py b/src/crystal/doc/html/soup.py index fb1cd605..6b40a990 100644 --- a/src/crystal/doc/html/soup.py +++ b/src/crystal/doc/html/soup.py @@ -57,6 +57,9 @@ class _XPaths: ) for T in _PARSER_LIBRARY_T_CHOICES} +TEXT_LINK_TYPE_TITLE = 'Link' + + def parse_html_and_links( html_bytes: bytes, declared_charset: Optional[str], @@ -119,7 +122,7 @@ def parse_html_and_links( embedded = False if tag_name == 'a': title = html.tag_string(tag) - type_title = 'Link' + type_title = TEXT_LINK_TYPE_TITLE # 'Link' elif tag_name == 'link' and ( ('rel' in tag_attrs and 'stylesheet' in tag_attrs['rel']) or ( 'type' in tag_attrs and tag_attrs['type'] == 'text/css') or (