|
82 | 82 | wdMaximumNumberOfColumns = 18 |
83 | 83 |
|
84 | 84 |
|
| 85 | +class MsoHyperlink(IntEnum): |
| 86 | + # See https://learn.microsoft.com/en-us/office/vba/api/office.msohyperlinktype |
| 87 | + RANGE = 0 |
| 88 | + SHAPE = 1 |
| 89 | + INLINE_SHAPE = 2 |
| 90 | + |
| 91 | + |
85 | 92 | class WdUnderline(DisplayStringIntEnum): |
86 | 93 | # Word underline styles |
87 | 94 | # see https://docs.microsoft.com/en-us/office/vba/api/word.wdunderline |
@@ -804,14 +811,14 @@ def activate(self): |
804 | 811 | initialDocument=self.obj, |
805 | 812 | ), |
806 | 813 | ) |
| 814 | + |
807 | 815 | # Handle activating links. |
| 816 | + link = self._getLinkAtCaretPosition() |
| 817 | + if link: |
| 818 | + link.follow() |
| 819 | + return |
808 | 820 | # It is necessary to expand to word to get a link as the link's first character is never actually in the link! |
809 | 821 | tempRange = self._rangeObj.duplicate |
810 | | - tempRange.expand(wdWord) |
811 | | - links = tempRange.hyperlinks |
812 | | - if links.count > 0: |
813 | | - links[1].follow() |
814 | | - return |
815 | 822 | tempRange.expand(wdParagraph) |
816 | 823 | fields = tempRange.fields |
817 | 824 | for field in (fields.item(i) for i in range(1, fields.count + 1)): |
@@ -847,6 +854,42 @@ def activate(self): |
847 | 854 | braille.handler.handleCaretMove(self) |
848 | 855 | return |
849 | 856 |
|
| 857 | + def _getLinkAtCaretPosition(self) -> comtypes.client.lazybind.Dispatch | None: |
| 858 | + # It is necessary to expand to word to get a link as the link's first character is never actually in the link! |
| 859 | + tempRange = self._rangeObj.duplicate |
| 860 | + tempRange.expand(wdWord) |
| 861 | + links = tempRange.hyperlinks |
| 862 | + if links.count > 0: |
| 863 | + return links[1] |
| 864 | + return None |
| 865 | + |
| 866 | + def _getShapeAtCaretPosition(self) -> comtypes.client.lazybind.Dispatch | None: |
| 867 | + # It is necessary to expand to word to get a shape as the link's first character is never actually in the link! |
| 868 | + tempRange = self._rangeObj.duplicate |
| 869 | + tempRange.expand(wdWord) |
| 870 | + shapes = tempRange.InlineShapes |
| 871 | + if shapes.count > 0: |
| 872 | + return shapes[1] |
| 873 | + return None |
| 874 | + |
| 875 | + def _getLinkDataAtCaretPosition(self) -> textInfos._Link | None: |
| 876 | + link = self._getLinkAtCaretPosition() |
| 877 | + if not link: |
| 878 | + return None |
| 879 | + match link.Type: |
| 880 | + case MsoHyperlink.RANGE: |
| 881 | + text = link.TextToDisplay |
| 882 | + case MsoHyperlink.INLINE_SHAPE: |
| 883 | + shape = self._getShapeAtCaretPosition() |
| 884 | + text = shape.AlternativeText |
| 885 | + case _: |
| 886 | + log.debugWarning(f"No text to display for link type {link.Type}") |
| 887 | + text = None |
| 888 | + return textInfos._Link( |
| 889 | + displayText=text, |
| 890 | + destination=link.Address, |
| 891 | + ) |
| 892 | + |
850 | 893 | def _expandToLineAtCaret(self): |
851 | 894 | lineStart = ctypes.c_int() |
852 | 895 | lineEnd = ctypes.c_int() |
|
0 commit comments