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()
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_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
 15
 16class Mindmanager:
 17
 18    @staticmethod
 19    def get_mindmanager_version():
 20        versions = ["26", "25", "24", "23"]
 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):
 75        try:
 76            return self._document.CentralTopic
 77        except Exception as e:
 78            raise Exception(f"Error getting central topic: {e}")
 79    
 80    def get_topic_by_id(self, id):
 81        try:
 82            return self._document.FindByGuid(id)
 83        except Exception as e:
 84            print(f"Error in get_topic_by_id: {e}")
 85            return None
 86
 87    def get_selection(self):
 88        selection = []
 89        try:
 90            objs = self._document.Selection
 91            for obj in objs:
 92                try:
 93                    class_name = obj._oleobj_.GetTypeInfo().GetDocumentation(-1)[0]
 94                    if class_name == "ITopic":
 95                        selection.append(obj)
 96                except Exception as e:
 97                    print(f"Error in get_selection, getting class name: {e}")
 98                    continue
 99        except Exception as e:
100            print(f"Error in get_selection: {e}")
101        return selection
102
103    def get_level_from_topic(self, topic):
104        try:
105            return topic.Level
106        except Exception as e:
107            print(f"Error in get_level_from_topic: {e}")
108            return None
109
110    def get_text_from_topic(self, topic):
111        try:
112            return topic.Text.replace('"', '`').replace("'", "`").replace("\r", "").replace("\n", "")
113        except Exception as e:
114            print(f"Error in get_text_from_topic: {e}")
115            return ""
116
117    def get_title_from_topic(self, topic):
118        try:
119            title = topic.Title
120            text = title.TextRTF if title.TextRTF != '' else ''
121            return text
122        except Exception as e:
123            print(f"Error in get_title_from_topic: {e}")
124            return ""
125
126    def get_subtopics_from_topic(self, topic):
127        try:
128            return topic.AllSubTopics
129        except Exception as e:
130            print(f"Error in get_subtopics_from_topic: {e}")
131            return None
132    
133    def get_links_from_topic(self, topic) -> list[MindmapLink]:
134        hyperlinks = []
135        try:
136            if topic.HasHyperlink:
137                for hyperlink in topic.Hyperlinks:
138                    link = MindmapLink(
139                        text=hyperlink.Title,
140                        url=hyperlink.Address,
141                        guid=hyperlink.TopicLabelGuid
142                    )
143                    hyperlinks.append(link)
144        except Exception as e:
145            print(f"Error in get_links_from_topic: {e}")
146        return hyperlinks
147
148    def get_image_from_topic(self, topic) -> MindmapImage:
149        try:
150            if topic.HasImage:
151                image = topic.Image
152                with tempfile.NamedTemporaryFile(delete=False, suffix=".png") as tmp:
153                    temp_filename = tmp.name
154                image.Save(temp_filename, 3)  # 3=PNG
155                return MindmapImage(text=temp_filename)
156        except Exception as e:
157            print(f"Error in get_image_from_topic: {e}")
158        return None
159
160    def get_icons_from_topic(self, topic) -> list[MindmapIcon]:
161        icons = []
162        try:
163            user_icons = topic.UserIcons
164            if user_icons.Count > 0:
165                for icon in user_icons:
166                    if icon.Type == 1 and icon.IsValid == True:  # Stock Icon
167                        icons.append(MindmapIcon(
168                            text=icon.Name,
169                            index=icon.StockIcon
170                        ))
171                    elif icon.Type == 2 and icon.IsValid == True:
172                        with tempfile.NamedTemporaryFile(delete=False, suffix=".png") as tmp:
173                            temp_filename = tmp.name
174                        icon.Save(temp_filename, 3)  # 3=PNG
175                        icons.append(MindmapIcon(
176                            text=icon.Name,
177                            is_stock_icon=False,
178                            signature=icon.CustomIconSignature,
179                            path=temp_filename
180                        ))
181        except Exception as e:
182            print(f"Error in get_icons_from_topic: {e}")
183        return icons
184
185    def get_notes_from_topic(self, topic) -> MindmapNotes:
186        try:
187            notes = topic.Notes
188            topic_notes = None
189            if notes:
190                if notes.IsValid == True and not notes.IsEmpty:
191                    topic_notes = MindmapNotes()
192                    if notes.TextRTF != "":
193                        topic_notes.rtf = notes.TextRTF
194                    if notes.TextXHTML != "":
195                        topic_notes.xhtml = notes.TextXHTML
196                    if notes.Text != "":
197                        topic_notes.text = notes.Text
198            return topic_notes
199        except Exception as e:
200            print(f"Error in get_notes_from_topic: {e}")
201            return None
202
203    def get_tags_from_topic(self, topic) -> list[MindmapTag]:
204        tags = []
205        try:
206            text_labels = topic.TextLabels
207            if text_labels.Count > 0 and text_labels.IsValid == True:
208                for text_label in text_labels:
209                    if text_label.IsValid == True and text_label.GroupId == "":
210                        tags.append(MindmapTag(text=text_label.Name))
211        except Exception as e:
212            print(f"Error in get_tags_from_topic: {e}")
213        return tags
214
215    def get_references_from_topic(self, topic) -> list[MindmapReference]:
216        references = []
217        try:
218            relationships = topic.AllRelationships
219            if relationships.Count > 0 and relationships.IsValid == True:
220                for relation in relationships:
221                    if relation.IsValid == True:
222                        connected_topic_guid_1 = relation.ConnectedObject1
223                        connected_topic_guid_2 = relation.ConnectedObject2
224                        reference_direction = 1 if connected_topic_guid_1 == topic else 2
225                        references.append(MindmapReference(
226                            guid_1=str(connected_topic_guid_1.Guid),
227                            guid_2=str(connected_topic_guid_2.Guid),
228                            direction=reference_direction,
229                            label=''
230                        ))
231        except Exception as e:
232            print(f"Error in get_references_from_topic: {e}")
233        return references
234    
235    def get_guid_from_topic(self, topic) -> str:
236        try:
237            return topic.Guid
238        except Exception as e:
239            print(f"Error in get_guid_from_topic: {e}")
240            return ""
241        
242    def add_subtopic_to_topic(self, topic, topic_text):
243        try:
244            return topic.AddSubtopic(topic_text)
245        except Exception as e:
246            print(f"Error in add_subtopic_to_topic: {e}")
247            return None
248
249    def get_parent_from_topic(self, topic):
250        try:
251            return topic.ParentTopic
252        except Exception as e:
253            print(f"Error in get_parent_from_topic: {e}")
254            return None
255
256    def set_text_to_topic(self, topic, topic_text):
257        try:
258            topic.Text = topic_text
259        except Exception as e:
260            print(f"Error in set_text_to_topic: {e}")
261
262    def set_title_to_topic(self, topic, topic_rtf):
263        try:
264            if topic_rtf != "":
265                topic.Title.TextRTF = topic_rtf
266        except Exception as e:
267            print(f"Error in set_title_to_topic: {e}")
268
269    def add_tag_to_topic(self, topic=None, tag_text='', topic_guid=None):
270        try:
271            if topic_guid:
272                topic = self.get_topic_by_id(topic_guid)
273            if topic:
274                topic.TextLabels.AddTextLabelFromGroup(tag_text, '', True)
275        except Exception as e:
276            print(f"Error in add_tag_to_topic: {e}")
277
278    def set_topic_from_mindmap_topic(self, topic, mindmap_topic, map_icons):
279        self.set_text_to_topic(topic, mindmap_topic.text)
280        self.set_title_to_topic(topic, mindmap_topic.rtf)
281        self.add_tags_to_topic(topic, mindmap_topic.tags)
282        self.set_notes_to_topic(topic, mindmap_topic.notes)
283        self.add_icons_to_topic(topic, mindmap_topic.icons, map_icons)
284        self.add_image_to_topic(topic, mindmap_topic.image)
285        self.add_links_to_topic(topic, mindmap_topic.links)
286        return topic, topic.Guid
287    
288    def add_links_to_topic(self, topic, mindmap_topic_links):
289        try:
290            if mindmap_topic_links:
291                for topic_link in mindmap_topic_links:
292                    if topic_link.guid == "" and topic_link.url != "":
293                        link = topic.Hyperlinks.AddHyperlink(topic_link.url)
294                        link.Title = topic_link.text
295        except Exception as e:
296            print(f"Error in add_links_to_topic: {e}")
297
298    def add_image_to_topic(self, topic, mindmap_topic_image):
299        try:
300            if mindmap_topic_image:
301                topic.CreateImage(mindmap_topic_image.text)
302        except Exception as e:
303            print(f"Error in add_image_to_topic: {e}")
304
305    def add_icons_to_topic(self, topic, mindmap_topic_icons, map_icons):
306        try:
307            if len(mindmap_topic_icons) > 0:
308                for topic_icon in mindmap_topic_icons:
309                    if topic_icon.is_stock_icon:
310                        topic.UserIcons.AddStockIcon(topic_icon.index)
311                    else:
312                        if len(map_icons) > 0 and topic_icon.signature != "":
313                            topic.UserIcons.AddCustomIconFromMap(topic_icon.signature)
314                        else:
315                            if os.path.exists(topic_icon.path):
316                                topic.UserIcons.AddCustomIcon(topic_icon.path)
317        except Exception as e:
318            print(f"Error in add_icons_to_topic: {e}")
319
320    def set_notes_to_topic(self, topic, mindmap_topic_notes):
321        try:
322            if mindmap_topic_notes:
323                if mindmap_topic_notes.text:
324                    topic.Notes.Text = mindmap_topic_notes.text
325                else:
326                    if mindmap_topic_notes.xhtml:
327                        try:
328                            topic.Notes.TextXHTML = mindmap_topic_notes.xhtml
329                        except Exception as e:
330                            print(f"Error setting TextXHTML: {e}")
331                            print(f"Topic: `{topic.Text}`")
332                    else:
333                        if mindmap_topic_notes.rtf:
334                            topic.Notes.TextRTF = mindmap_topic_notes.rtf
335        except Exception as e:
336            print(f"Error in set_notes_to_topic: {e}")
337
338
339    def add_tags_to_topic(self, topic, mindmap_topic_tags):
340        try:
341            if len(mindmap_topic_tags) > 0:
342                for topic_tag in mindmap_topic_tags:
343                    topic.TextLabels.AddTextLabelFromGroup(topic_tag.text, '', True)
344        except Exception as e:
345            print(f"Error in add_tags_to_topic: {e}")
346
347    def create_map_icons(self, map_icons):
348        try:
349            if len(map_icons) > 0:
350                icon_groups = set(map_icon.group for map_icon in map_icons if map_icon.group)
351                for icon_group in icon_groups:
352                    group = self._document.MapMarkerGroups.AddIconMarkerGroup(icon_group)
353                    for map_icon in map_icons:
354                        if map_icon.group == icon_group:
355                            label = map_icon.text
356                            marker = group.AddCustomIconMarker(label, map_icon.path)
357                            map_icon.signature = marker.Icon.CustomIconSignature
358        except Exception as e:
359            print(f"Error in create_map_icons: {e}")
360
361    def create_tags(self, tags: list['str'], DUPLICATED_TAG: str):
362        try:
363            if len(tags) > 0:
364                map_marker_group = self._document.MapMarkerGroups.GetMandatoryMarkerGroup(10)
365                for tag in tags:
366                    map_marker_group.AddTextLabelMarker(tag)
367                if DUPLICATED_TAG != '' and DUPLICATED_TAG not in tags:
368                    map_marker_group.AddTextLabelMarker(DUPLICATED_TAG)
369        except Exception as e:
370            print(f"Error in create_tags: {e}")
371
372    def add_relationship(self, guid1, guid2, label=''):
373        try:
374            object1 = self.get_topic_by_id(guid1)
375            object2 = self.get_topic_by_id(guid2)
376            if object1 and object2:
377                if object1.ParentTopic == object2 or object2.ParentTopic == object1:
378                    return
379                object1.AllRelationships.AddToTopic(object2, label)
380        except Exception as e:
381            print(f"Error in add_relationship: {e}")
382
383    def add_topic_link(self, guid1, guid2, label=''):
384        try:
385            object1 = self.get_topic_by_id(guid1)
386            object2 = self.get_topic_by_id(guid2)
387            if object1 and object2:
388                hyperlinks = object1.Hyperlinks
389                link = hyperlinks.AddHyperlinkToTopicByGuid(guid2)
390                link.Title = label if label != "" else object2.Title.Text
391        except Exception as e:
392            print(f"Error in add_topic_link: {e}")
393
394    def add_document(self, max_topic_level):
395        try:
396            style = self._document.StyleXml
397            new_document = self._mindmanager.Documents.Add()
398            new_document.StyleXml = style
399            self._document = new_document
400        except Exception as e:
401            print(f"Error in add_document: {e}")
402
403    def finalize(self, max_topic_level):
404        try:
405            centralTopic = self._document.CentralTopic
406            layout = centralTopic.SubTopicsLayout
407            growthDirection = layout.CentralTopicGrowthDirection
408            cnt_subtopics = len(centralTopic.AllSubTopics)
409                               
410            # collapse/uncollapse outer topics
411            if max_topic_level > 3:
412                for topic in self._document.Range(2, True):  # 2 = all topics
413                    if topic.Level > 2:
414                        topic.Collapsed = True
415                    else:
416                        if topic.Level != 0:
417                            topic.Collapsed = False
418            else:
419                for topic in self._document.Range(2, True):  # 2 = all topics
420                    if topic.Level > 3:
421                        topic.Collapsed = True
422                    else:
423                        if topic.Level != 0:
424                            topic.Collapsed = False
425                            
426            # org chart            
427            if self._charttype == "orgchart" or self._charttype == "auto":
428                if max_topic_level > 2 and cnt_subtopics > 4:
429                    if growthDirection == 1:
430                        layout.CentralTopicGrowthDirection = 5
431                        
432            # radial map
433            if self._charttype == "radial" or self._charttype == "auto":
434                if max_topic_level > 2 and cnt_subtopics < 5:
435                    if growthDirection != 1:
436                        layout.CentralTopicGrowthDirection = 1
437                if max_topic_level < 3 and cnt_subtopics > 4:
438                    if growthDirection != 1:
439                        layout.CentralTopicGrowthDirection = 1
440
441            self._document.Zoom(1)
442            self._mindmanager.Visible = True
443        except Exception as e:
444            print(f"Error in finalize: {e}")