mindm.mindmanager_win module

Windows-specific implementation of the Mindmanager interface.

This module provides Windows platform-specific implementation for interacting with MindManager application, including functionality for manipulating topics, properties, relationships, and document structure.

class mindm.mindmanager_win.Mindmanager(charttype)

Bases: object

WINDOWS_LIBRARY_FOLDER = 'C:\\Users\\runneradmin\\AppData\\Local\\Mindjet\\MindManager\\26\\Library\\ENU'
__init__(charttype)
add_document(max_topic_level)
add_icons_to_topic(topic, mindmap_topic_icons, map_icons)
add_image_to_topic(topic, mindmap_topic_image)
add_relationship(guid1, guid2, label='')
add_subtopic_to_topic(topic, topic_text)
add_tag_to_topic(topic=None, tag_text='', topic_guid=None)
add_tags_to_topic(topic, mindmap_topic_tags)
create_map_icons(map_icons)
create_tags(tags: list[str], DUPLICATED_TAG: str)
document_exists()
finalize(max_topic_level)
get_active_document_object()
get_central_topic() MindmapTopic
get_guid_from_topic(topic) str
get_icons_from_topic(topic) list[MindmapIcon]
get_image_from_topic(topic) MindmapImage
get_level_from_topic(topic)
get_library_folder()
get_mindmanager_object()
static get_mindmanager_version()
get_mindmaptopic_from_topic(topic) MindmapTopic
get_mindmaptopic_from_topic_content(topic) MindmapTopic
get_mindmaptopic_from_topic_full(topic) MindmapTopic
get_notes_from_topic(topic) MindmapNotes
get_parent_from_topic(topic)
get_references_from_topic(topic) list[MindmapReference]
get_selection()
get_subtopics_from_topic(topic)
get_tags_from_topic(topic) list[MindmapTag]
get_text_from_topic(topic)
get_title_from_topic(topic)
get_topic_by_id(id)
get_version()
mindmanager_version = '26'
set_document_background_image(path)
set_notes_to_topic(topic, mindmap_topic_notes)
set_text_to_topic(topic, topic_text)
set_title_to_topic(topic, topic_rtf)
set_topic_from_mindmap_topic(topic, mindmap_topic, map_icons)
Source code for mindmanager_win.py
  1"""
  2Windows-specific implementation of the Mindmanager interface.
  3
  4This module provides Windows platform-specific implementation for interacting
  5with MindManager application, including functionality for manipulating topics,
  6properties, relationships, and document structure.
  7"""
  8
  9import os
 10import win32com.client
 11import winreg
 12import tempfile
 13
 14from mindmap.mindmap import MindmapLink, MindmapImage, MindmapNotes, MindmapIcon, MindmapTag, MindmapReference, MindmapTopic
 15
 16class Mindmanager:
 17
 18    @staticmethod
 19    def get_mindmanager_version():
 20        versions = ["26", "25", "24", "23", "22", "21", "20"]
 21        for version in versions:
 22            try:
 23                key = winreg.OpenKey(winreg.HKEY_CURRENT_USER, f"Software\\Mindjet\\MindManager\\{version}\\AddIns")
 24                winreg.CloseKey(key)
 25                return version
 26            except FileNotFoundError:
 27                continue
 28        return None
 29
 30    mindmanager_version = get_mindmanager_version()
 31    if mindmanager_version:
 32        WINDOWS_LIBRARY_FOLDER = os.path.join(os.environ.get("LOCALAPPDATA", ""), "Mindjet", "MindManager", mindmanager_version, "Library", "ENU")
 33    else:
 34        raise Exception("No MindManager version registry keys found.")
 35
 36    def __init__(self, charttype):
 37        self._version = Mindmanager.get_mindmanager_version()
 38        self._mindmanager = win32com.client.Dispatch("Mindmanager.Application")
 39        self._mindmanager.Options.BalanceNewMainTopics = True
 40        self._charttype = charttype
 41        self._library_folder = self.WINDOWS_LIBRARY_FOLDER
 42        self._document = self._mindmanager.ActiveDocument
 43    
 44    def get_mindmanager_object(self):
 45        return self._mindmanager
 46        
 47    def get_active_document_object(self):
 48        return self._mindmanager.ActiveDocument
 49        
 50    def get_library_folder(self):
 51        return self._library_folder
 52
 53    def get_version(self):
 54        return self._version
 55
 56    def set_document_background_image(self, path):
 57        try:
 58            background = self._document.Background
 59            if background.HasImage:
 60                background.RemoveImage()
 61            background.InsertImage(path)
 62            background.TileOption = 1  # center
 63            background.Transparency = 88
 64        except Exception as e:
 65            print(f"Error setting document background image: {e}")
 66
 67    def document_exists(self):
 68        try:
 69            return True if self._document else False
 70        except Exception as e:
 71            print(f"Error checking document existence: {e}")
 72            return False
 73
 74    def get_central_topic(self) -> 'MindmapTopic':
 75        try:
 76            topic = self._document.CentralTopic
 77            return self.get_mindmaptopic_from_topic(topic)
 78        except Exception as e:
 79            raise Exception(f"Error getting central topic: {e}")
 80        
 81    def get_mindmaptopic_from_topic(self, topic) -> 'MindmapTopic':
 82        mindmap_topic = MindmapTopic()
 83        mindmap_topic.guid=self.get_guid_from_topic(topic)
 84        mindmap_topic.text=self.get_text_from_topic(topic)
 85        mindmap_topic.rtf=self.get_title_from_topic(topic)
 86        mindmap_topic.level=self.get_level_from_topic(topic)
 87        return mindmap_topic
 88    
 89    def get_mindmaptopic_from_topic_content(self, topic) -> 'MindmapTopic':
 90        mindmap_topic = self.get_mindmaptopic_from_topic(topic)
 91        mindmap_topic.notes = self.get_notes_from_topic(topic)
 92        return mindmap_topic
 93    
 94    def get_mindmaptopic_from_topic_full(self, topic) -> 'MindmapTopic':
 95        mindmap_topic = self.get_mindmaptopic_from_topic(topic)
 96        mindmap_topic.notes = self.get_notes_from_topic(topic)
 97        mindmap_topic.links = self.get_links_from_topic(topic)
 98        mindmap_topic.image = self.get_image_from_topic(topic)
 99        mindmap_topic.icons = self.get_icons_from_topic(topic)
100        mindmap_topic.tags = self.get_tags_from_topic(topic)
101        mindmap_topic.references = self.get_references_from_topic(topic)
102        return mindmap_topic
103    
104    def get_topic_by_id(self, id):
105        try:
106            return self._document.FindByGuid(id)
107        except Exception as e:
108            print(f"Error in get_topic_by_id: {e}")
109            return None
110
111    def get_selection(self):
112        selection = []
113        try:
114            objs = self._document.Selection
115            for obj in objs:
116                try:
117                    class_name = obj._oleobj_.GetTypeInfo().GetDocumentation(-1)[0]
118                    if class_name == "ITopic":
119                        selection.append(obj)
120                except Exception as e:
121                    print(f"Error in get_selection, getting class name: {e}")
122                    continue
123        except Exception as e:
124            print(f"Error in get_selection: {e}")
125        return selection
126
127    def get_level_from_topic(self, topic):
128        try:
129            return topic.Level
130        except Exception as e:
131            print(f"Error in get_level_from_topic: {e}")
132            return None
133
134    def get_text_from_topic(self, topic):
135        try:
136            return topic.Text.replace('"', '`').replace("'", "`").replace("\r", "").replace("\n", "")
137        except Exception as e:
138            print(f"Error in get_text_from_topic: {e}")
139            return ""
140
141    def get_title_from_topic(self, topic):
142        try:
143            title = topic.Title
144            text = title.TextRTF if title.TextRTF != '' else ''
145            return text
146        except Exception as e:
147            print(f"Error in get_title_from_topic: {e}")
148            return ""
149
150    def get_subtopics_from_topic(self, topic):
151        try:
152            return topic.AllSubTopics
153        except Exception as e:
154            print(f"Error in get_subtopics_from_topic: {e}")
155            return None
156    
157    def get_links_from_topic(self, topic) -> list[MindmapLink]:
158        hyperlinks = []
159        try:
160            if topic.HasHyperlink:
161                for hyperlink in topic.Hyperlinks:
162                    link = MindmapLink(
163                        text=hyperlink.Title,
164                        url=hyperlink.Address,
165                        guid=hyperlink.TopicLabelGuid
166                    )
167                    hyperlinks.append(link)
168        except Exception as e:
169            print(f"Error in get_links_from_topic: {e}")
170        return hyperlinks
171
172    def get_image_from_topic(self, topic) -> MindmapImage:
173        try:
174            if topic.HasImage:
175                image = topic.Image
176                with tempfile.NamedTemporaryFile(delete=False, suffix=".png") as tmp:
177                    temp_filename = tmp.name
178                image.Save(temp_filename, 3)  # 3=PNG
179                return MindmapImage(text=temp_filename)
180        except Exception as e:
181            print(f"Error in get_image_from_topic: {e}")
182        return None
183
184    def get_icons_from_topic(self, topic) -> list[MindmapIcon]:
185        icons = []
186        try:
187            user_icons = topic.UserIcons
188            if user_icons.Count > 0:
189                for icon in user_icons:
190                    if icon.Type == 1 and icon.IsValid == True:  # Stock Icon
191                        icons.append(MindmapIcon(
192                            text=icon.Name,
193                            index=icon.StockIcon
194                        ))
195                    elif icon.Type == 2 and icon.IsValid == True:
196                        with tempfile.NamedTemporaryFile(delete=False, suffix=".png") as tmp:
197                            temp_filename = tmp.name
198                        icon.Save(temp_filename, 3)  # 3=PNG
199                        icons.append(MindmapIcon(
200                            text=icon.Name,
201                            is_stock_icon=False,
202                            signature=icon.CustomIconSignature,
203                            path=temp_filename
204                        ))
205        except Exception as e:
206            print(f"Error in get_icons_from_topic: {e}")
207        return icons
208
209    def get_notes_from_topic(self, topic) -> MindmapNotes:
210        try:
211            notes = topic.Notes
212            topic_notes = None
213            if notes:
214                if notes.IsValid == True and not notes.IsEmpty:
215                    topic_notes = MindmapNotes()
216                    if notes.TextRTF != "":
217                        topic_notes.rtf = notes.TextRTF
218                    if notes.TextXHTML != "":
219                        topic_notes.xhtml = notes.TextXHTML
220                    if notes.Text != "":
221                        topic_notes.text = notes.Text
222            return topic_notes
223        except Exception as e:
224            print(f"Error in get_notes_from_topic: {e}")
225            return None
226
227    def get_tags_from_topic(self, topic) -> list[MindmapTag]:
228        tags = []
229        try:
230            text_labels = topic.TextLabels
231            if text_labels.Count > 0 and text_labels.IsValid == True:
232                for text_label in text_labels:
233                    if text_label.IsValid == True and text_label.GroupId == "":
234                        tags.append(MindmapTag(text=text_label.Name))
235        except Exception as e:
236            print(f"Error in get_tags_from_topic: {e}")
237        return tags
238
239    def get_references_from_topic(self, topic) -> list[MindmapReference]:
240        references = []
241        try:
242            relationships = topic.AllRelationships
243            if relationships.Count > 0 and relationships.IsValid == True:
244                for relation in relationships:
245                    if relation.IsValid == True:
246                        connected_topic_guid_1 = relation.ConnectedObject1
247                        connected_topic_guid_2 = relation.ConnectedObject2
248                        reference_direction = 1 if connected_topic_guid_1 == topic else 2
249                        references.append(MindmapReference(
250                            guid_1=str(connected_topic_guid_1.Guid),
251                            guid_2=str(connected_topic_guid_2.Guid),
252                            direction=reference_direction,
253                            label=''
254                        ))
255        except Exception as e:
256            print(f"Error in get_references_from_topic: {e}")
257        return references
258    
259    def get_guid_from_topic(self, topic) -> str:
260        try:
261            return topic.Guid
262        except Exception as e:
263            print(f"Error in get_guid_from_topic: {e}")
264            return ""
265        
266    def add_subtopic_to_topic(self, topic, topic_text):
267        try:
268            return topic.AddSubtopic(topic_text)
269        except Exception as e:
270            print(f"Error in add_subtopic_to_topic: {e}")
271            return None
272
273    def get_parent_from_topic(self, topic):
274        try:
275            return topic.ParentTopic
276        except Exception as e:
277            print(f"Error in get_parent_from_topic: {e}")
278            return None
279
280    def set_text_to_topic(self, topic, topic_text):
281        try:
282            topic.Text = topic_text
283        except Exception as e:
284            print(f"Error in set_text_to_topic: {e}")
285
286    def set_title_to_topic(self, topic, topic_rtf):
287        try:
288            if topic_rtf != "":
289                topic.Title.TextRTF = topic_rtf
290        except Exception as e:
291            print(f"Error in set_title_to_topic: {e}")
292
293    def add_tag_to_topic(self, topic=None, tag_text='', topic_guid=None):
294        try:
295            if topic_guid:
296                topic = self.get_topic_by_id(topic_guid)
297            if topic:
298                topic.TextLabels.AddTextLabelFromGroup(tag_text, '', True)
299        except Exception as e:
300            print(f"Error in add_tag_to_topic: {e}")
301
302    def set_topic_from_mindmap_topic(self, topic, mindmap_topic, map_icons):
303        self.set_text_to_topic(topic, mindmap_topic.text)
304        self.set_title_to_topic(topic, mindmap_topic.rtf)
305        self.add_tags_to_topic(topic, mindmap_topic.tags)
306        self.set_notes_to_topic(topic, mindmap_topic.notes)
307        self.add_icons_to_topic(topic, mindmap_topic.icons, map_icons)
308        self.add_image_to_topic(topic, mindmap_topic.image)
309        self.add_links_to_topic(topic, mindmap_topic.links)
310        return topic, topic.Guid
311    
312    def add_links_to_topic(self, topic, mindmap_topic_links):
313        try:
314            if mindmap_topic_links:
315                for topic_link in mindmap_topic_links:
316                    if topic_link.guid == "" and topic_link.url != "":
317                        link = topic.Hyperlinks.AddHyperlink(topic_link.url)
318                        link.Title = topic_link.text
319        except Exception as e:
320            print(f"Error in add_links_to_topic: {e}")
321
322    def add_image_to_topic(self, topic, mindmap_topic_image):
323        try:
324            if mindmap_topic_image:
325                topic.CreateImage(mindmap_topic_image.text)
326        except Exception as e:
327            print(f"Error in add_image_to_topic: {e}")
328
329    def add_icons_to_topic(self, topic, mindmap_topic_icons, map_icons):
330        try:
331            if len(mindmap_topic_icons) > 0:
332                for topic_icon in mindmap_topic_icons:
333                    if topic_icon.is_stock_icon:
334                        topic.UserIcons.AddStockIcon(topic_icon.index)
335                    else:
336                        if len(map_icons) > 0 and topic_icon.signature != "":
337                            topic.UserIcons.AddCustomIconFromMap(topic_icon.signature)
338                        else:
339                            if os.path.exists(topic_icon.path):
340                                topic.UserIcons.AddCustomIcon(topic_icon.path)
341        except Exception as e:
342            print(f"Error in add_icons_to_topic: {e}")
343
344    def set_notes_to_topic(self, topic, mindmap_topic_notes):
345        try:
346            if mindmap_topic_notes:
347                if mindmap_topic_notes.text:
348                    topic.Notes.Text = mindmap_topic_notes.text
349                else:
350                    if mindmap_topic_notes.xhtml:
351                        try:
352                            topic.Notes.TextXHTML = mindmap_topic_notes.xhtml
353                        except Exception as e:
354                            print(f"Error setting TextXHTML: {e}")
355                            print(f"Topic: `{topic.Text}`")
356                    else:
357                        if mindmap_topic_notes.rtf:
358                            topic.Notes.TextRTF = mindmap_topic_notes.rtf
359        except Exception as e:
360            print(f"Error in set_notes_to_topic: {e}")
361
362
363    def add_tags_to_topic(self, topic, mindmap_topic_tags):
364        try:
365            if len(mindmap_topic_tags) > 0:
366                for topic_tag in mindmap_topic_tags:
367                    topic.TextLabels.AddTextLabelFromGroup(topic_tag.text, '', True)
368        except Exception as e:
369            print(f"Error in add_tags_to_topic: {e}")
370
371    def create_map_icons(self, map_icons):
372        try:
373            if len(map_icons) > 0:
374                icon_groups = set(map_icon.group for map_icon in map_icons if map_icon.group)
375                for icon_group in icon_groups:
376                    group = self._document.MapMarkerGroups.AddIconMarkerGroup(icon_group)
377                    for map_icon in map_icons:
378                        if map_icon.group == icon_group:
379                            label = map_icon.text
380                            marker = group.AddCustomIconMarker(label, map_icon.path)
381                            map_icon.signature = marker.Icon.CustomIconSignature
382        except Exception as e:
383            print(f"Error in create_map_icons: {e}")
384
385    def create_tags(self, tags: list['str'], DUPLICATED_TAG: str):
386        try:
387            if len(tags) > 0:
388                map_marker_group = self._document.MapMarkerGroups.GetMandatoryMarkerGroup(10)
389                for tag in tags:
390                    map_marker_group.AddTextLabelMarker(tag)
391                if DUPLICATED_TAG != '' and DUPLICATED_TAG not in tags:
392                    map_marker_group.AddTextLabelMarker(DUPLICATED_TAG)
393        except Exception as e:
394            print(f"Error in create_tags: {e}")
395
396    def add_relationship(self, guid1, guid2, label=''):
397        try:
398            object1 = self.get_topic_by_id(guid1)
399            object2 = self.get_topic_by_id(guid2)
400            if object1 and object2:
401                if object1.ParentTopic == object2 or object2.ParentTopic == object1:
402                    return
403                object1.AllRelationships.AddToTopic(object2, label)
404        except Exception as e:
405            print(f"Error in add_relationship: {e}")
406
407    def add_topic_link(self, guid1, guid2, label=''):
408        try:
409            object1 = self.get_topic_by_id(guid1)
410            object2 = self.get_topic_by_id(guid2)
411            if object1 and object2:
412                hyperlinks = object1.Hyperlinks
413                link = hyperlinks.AddHyperlinkToTopicByGuid(guid2)
414                link.Title = label if label != "" else object2.Title.Text
415        except Exception as e:
416            print(f"Error in add_topic_link: {e}")
417
418    def add_document(self, max_topic_level):
419        try:
420            style = self._document.StyleXml
421            new_document = self._mindmanager.Documents.Add()
422            new_document.StyleXml = style
423            self._document = new_document
424        except Exception as e:
425            print(f"Error in add_document: {e}")
426
427    def finalize(self, max_topic_level):
428        try:
429            centralTopic = self._document.CentralTopic
430            layout = centralTopic.SubTopicsLayout
431            growthDirection = layout.CentralTopicGrowthDirection
432            cnt_subtopics = len(centralTopic.AllSubTopics)
433                               
434            # collapse/uncollapse outer topics
435            if max_topic_level > 3:
436                for topic in self._document.Range(2, True):  # 2 = all topics
437                    if topic.Level > 2:
438                        topic.Collapsed = True
439                    else:
440                        if topic.Level != 0:
441                            topic.Collapsed = False
442            else:
443                for topic in self._document.Range(2, True):  # 2 = all topics
444                    if topic.Level > 3:
445                        topic.Collapsed = True
446                    else:
447                        if topic.Level != 0:
448                            topic.Collapsed = False
449                            
450            # org chart            
451            if self._charttype == "orgchart" or self._charttype == "auto":
452                if max_topic_level > 2 and cnt_subtopics > 4:
453                    if growthDirection == 1:
454                        layout.CentralTopicGrowthDirection = 5
455                        
456            # radial map
457            if self._charttype == "radial" or self._charttype == "auto":
458                if max_topic_level > 2 and cnt_subtopics < 5:
459                    if growthDirection != 1:
460                        layout.CentralTopicGrowthDirection = 1
461                if max_topic_level < 3 and cnt_subtopics > 4:
462                    if growthDirection != 1:
463                        layout.CentralTopicGrowthDirection = 1
464
465            self._document.Zoom(1)
466            self._mindmanager.Visible = True
467        except Exception as e:
468            print(f"Error in finalize: {e}")