# -*- coding: utf-8 -*- ##from __future__ import unicode_literals # #Editor Assistant #Adds some capabilities to the python editor #as a new task panel dialog #https://forum.freecadweb.org/viewtopic.php?f=22&t=67242 #2022, LGPL2.1 or later # # #OS: Windows 10 build 19045 #OS: Windows 10 build 19045 #OS: Ubuntu 20.04.3 LTS (KDE/plasma) #OS: Linux Mint 20.1 (X-Cinnamon/cinnamon) #Word size of FreeCAD: 64-bit #Word size of FreeCAD: 64-bit #Word size of FreeCAD: 64-bit #Word size of FreeCAD: 64-bit #Version: 0.21.2.33771 (Git) #Version: 0.22.0dev.38079 (Git) #Version: 0.22.0dev.37928 (Git) AppImage #Version: 0.22.0dev.37928 (Git) AppImage #Build type: Release #Build type: Release #Build type: Release #Build type: Release #Branch: releases/FreeCAD-0-21 #Branch: main #Branch: main #Branch: main #Hash: b9bfa5c5507506e4515816414cd27f4851d00489 #Hash: de508e437d13e7eb35baffceea496fb9107888cb #Hash: e7699b531eba4bee262f7214699f07b96f66ba7b #Hash: e7699b531eba4bee262f7214699f07b96f66ba7b #Python 3.8.10, Qt 5.15.2, Coin 4.0.1, Vtk 8.2.0, OCC 7.6.3 #Python 3.11.9, Qt 5.15.13, Coin 4.0.2, Vtk 9.2.6, OCC 7.7.2 #Python 3.11.9, Qt 5.15.13, Coin 4.0.2, Vtk 9.2.6, OCC 7.7.2 #Python 3.11.9, Qt 5.15.13, Coin 4.0.2, Vtk 9.2.6, OCC 7.7.2 #Locale: French/Mars (fr_MA) #Locale: French/Mars (fr_MA) #Locale: French/Mars (fr_MA) #Locale: C/Default (C) # # __title__ = "Editor_Assistant" __author__ = "TheMarkster" __url__ = "https://forum.freecad.org/viewtopic.php?f=22&t=67242" __github__ = "https://github.com/mwganson/Editor_Assistant/" __wiki__ = "https://wiki.freecad.org/Macro_Editor_Assistant" __forum__ = "https://forum.freecad.org/viewtopic.php?t=67242" __requires__= "0.21.2.33771 and higher" __version__ = "2.05" __date__ = "2026/07/21" # ## ####path######################################################################### global path ; path = "" # #path = FreeCAD.ConfigGet(u"AppHomePath") # path FreeCAD installation #path = FreeCAD.ConfigGet(u"UserAppData") # path FreeCAD User data #path = "your path" # your directory path param = FreeCAD.ParamGet(u"User parameter:BaseApp/Preferences/Macro")# macro path path = param.GetString(u"MacroPath","") + "/" # macro path path = path.replace(u"\\","/") # convert the "\" to "/" #print( u"Path for the icons : " , path ) # ################################################################################# ## try: import shiboken6 as shiboken #FreeCAD.Console.PrintMessage("Editor Assistant: Shiboken imported\n") except: FreeCAD.Console.PrintWarning("Editor Assistant: Cannot import shiboken6, trying shiboken2...\n") try: import shiboken2 as shiboken except: FreeCAD.Console.PrintWarning("Editor Assistant: Cannot import shiboken2, setting shiboken to None...\n") shiboken = None pg = FreeCAD.ParamGet("User parameter:Plugins/"+__title__) pg.SetString("Version", __version__ + " (" + __date__ + ")") COLOR_ACTIVE_TAB = pg.GetString("ColorActiveTab", "#B3F88C") # "0"= color system , "#B3F88C"= color code html pg.SetString(u"ColorActiveTab", "#B3F88C") COLOR_ERROR_DETECTED = pg.GetString("COLOR_ERROR_DETECTED", "#a40000") # "0"= color system , "#a40000"= color code html pg.SetString(u"COLOR_ERROR_DETECTED", "#a40000") switch_Unicode_Read_File = pg.GetBool("switch_Unicode_Read_File", 0) pg.SetBool("switch_Unicode_Read_File",switch_Unicode_Read_File) setPathFileBackup = pg.GetString("setPathFileBackup", path) pg.SetString("setPathFileBackup", setPathFileBackup) setPathFileSecondStorage = pg.GetString("setPathFileSecondStorage", "") pg.SetString("setPathFileSecondStorage", setPathFileSecondStorage) setFormatBackupDateTime = "yyyy_MM_dd_HH_mm_ss" #setFormatBackupDateTime = pg.GetString("setFormatBackupDateTime", "yyyy_MM_dd_HH_mm_ss") #pg.SetString(u"setFormatBackupDateTime", setFormatBackupDateTime) switchReplaceInterrogationFFFD = pg.GetBool("switchReplaceInterrogationFFFD", False) pg.SetBool("switchReplaceInterrogationFFFD", switchReplaceInterrogationFFFD) switchDisplayConsolePrintError = pg.GetBool("switchDisplayConsolePrintError", True) pg.SetBool("switchDisplayConsolePrintError", switchDisplayConsolePrintError) switchFrameInfoBackUpOnFile = pg.GetBool("switchFrameInfoBackUpOnFile", False) pg.SetBool("switchFrameInfoBackUpOnFile", switchFrameInfoBackUpOnFile) switchFrameInfoOnBeginOrEnd = pg.GetBool("switchFrameInfoOnBeginOrEnd", False) pg.SetBool("switchFrameInfoOnBeginOrEnd", switchFrameInfoOnBeginOrEnd) switchMemoBakUpDisplayOnComboBox = pg.GetBool("switchMemoBakUpDisplayOnComboBox", True) pg.SetBool("switchMemoBakUpDisplayOnComboBox", switchMemoBakUpDisplayOnComboBox) switchMemoIncludeOnFile = pg.GetBool("switchMemoIncludeOnFile", True) pg.SetBool("switchMemoIncludeOnFile", switchMemoIncludeOnFile) UNDO_QUEUE_MAX_SIZE = pg.GetInt("UndoQueueMaxSize", 100) pg.SetInt("UndoQueueMaxSize",UNDO_QUEUE_MAX_SIZE) BOOKMARK_MARKER = pg.GetString("BookmarkMarker","#"+"#:") #+ is so we don't toggle this accidentally pg.SetString("BookmarkMarker", BOOKMARK_MARKER) MAX_ICONIZED_BUTTON_WIDTH = pg.GetInt("MaxIconizedButtonWidth", 32) pg.SetInt("MaxIconizedButtonWidth", MAX_ICONIZED_BUTTON_WIDTH) import PySide from PySide import QtCore, QtGui, QtWidgets from PySide.QtGui import QImage, QPainter #from PySide.QtCore import * #from PySide.QtGui import * #from PySide.QtWidgets import * import FreeCAD, FreeCADGui import difflib import json import re, itertools import random import operator from operator import itemgetter, attrgetter, methodcaller # pour sort dans un tableau import os, platform, sys, shutil import importlib import modulefinder from modulefinder import ModuleFinder import logging import traceback ## used for help -> reference menus global setPathLatestDirectory #; setPathLatestDirectory = "C:\ ???" setPathLatestDirectory = pg.GetString("setPathLatestDirectory") if setPathLatestDirectory == "": setPathLatestDirectory = path pg.SetString("setPathLatestDirectory", setPathLatestDirectory) global duplicate_Find ; duplicate_Find = [] global duplicate_Replace; duplicate_Replace = [] global duplicate_Indent_Memo; duplicate_Indent_Memo = [] global fileNameBAK ; fileNameBAK = "" global buttonDelBak ; buttonDelBak = False global takenBakFiles ; takenBakFiles = [] hasQtXmlPatterns = False try: from PySide import QtXmlPatterns hasQtXmlPatterns = True except ImportError: pass hasQtXml = False try: from PySide import QtXml hasQtXml = True except ImportError: pass hasQtWidgets = False try: from PySide import QtWidgets hasQtWidgets = True except ImportError: pass hasQtHelp = False try: from PySide import QtHelp hasQtHelp = True except ImportError: pass hasQtNetwork = False try: from PySide import QtNetwork hasQtNetwork = True except ImportError: pass hasQtMultimedia = False try: from PySide import QtMultimedia hasQtMultimedia = True except ImportError: pass hasQtOpenGL = False try: from PySide import QtOpenGL hasQtOpenGL = True except ImportError: pass hasQtPrintSupport = False try: from PySide import QtPrintSupport hasQtPrintSupport = True except ImportError: pass hasQtSql = False try: from PySide import QtSql hasQtSql = True except ImportError: pass hasQtSvg = False try: from PySide import QtSvg hasQtSvg = True except ImportError: pass hasQtTest = False try: from PySide import QtTest hasQtTest = True except ImportError: pass mw = FreeCADGui.getMainWindow() class FindEdit(QtWidgets.QLineEdit): def __init__(self, parent=None, form=None): super(FindEdit, self).__init__() self.form = form self.setContextMenuPolicy(QtCore.Qt.CustomContextMenu) self.customContextMenuRequested.connect(self.__contextMenu) self.installEventFilter(self) self.setToolTip("Double click to set text from current selection in editor") def eventFilter(self, watched, event): if watched == self and event.type() == QtCore.QEvent.MouseButtonDblClick: if shiboken and shiboken.isValid(self.form.currentEditor) and self.form.currentEditor: sel = self.form.currentEditor.textCursor().selectedText() if sel: self.setText(sel) else: self.form.toast("Nothing selected in editor","Error") else: self.form.toast("Editor is invalid","Error") elif hasattr(self.form, "findEdit") and watched == self.form.findEdit and event.type() == QtCore.QEvent.KeyPress and event.key() == QtCore.Qt.Key_Down: self.form.replaceEdit.setFocus() event.accept() elif hasattr(self.form, "replaceEdit") and watched == self.form.replaceEdit and event.type() == QtCore.QEvent.KeyPress and event.key() == QtCore.Qt.Key_Up: self.form.findEdit.setFocus() event.accept() return QtWidgets.QLineEdit.eventFilter(self, watched, event) def __contextMenu(self): self._normalMenu = self.createStandardContextMenu() self._addCustomMenuItems(self._normalMenu) self._normalMenu.exec(QtGui.QCursor.pos()) def _addCustomMenuItems(self, menu): menu.addSeparator() action = QtGui.QAction("Use selected", self) action.triggered.connect(self.useSelected) action.setEnabled(self.form.currentEditor.textCursor().selectedText() != "" if self.form.currentEditor else False) menu.addAction(action) actionClear = QtGui.QAction("Clear", self) actionClear.triggered.connect(self.clear) actionClear.setEnabled(len(self.text())) menu.addAction(actionClear) actionHighlight = QtGui.QAction("Highlight",self) actionHighlight.triggered.connect(self.highlight) actionHighlight.setEnabled(len(self.text())) if self == self.form.findEdit: menu.addAction(actionHighlight) def highlight(self): if self == self.form.findEdit: self.form.highlightFromFind() def clear(self): self.setText("") def useSelected(self): txt_cur = self.form.currentEditor.textCursor() txt = txt_cur.selectedText() self.setText(txt) class CustomQWidget(QtWidgets.QWidget): def __init__(self, parent=None, form=None): super(CustomQWidget, self).__init__() self.form = form self.hide() self.setAttribute(QtCore.Qt.WA_DeleteOnClose, True) def setFound(self,found): self.form.found = found class FileFilterProxyModel (QtCore.QSortFilterProxyModel): """Used when setting up drag/drop from file browser to drag/drop macro file to forum""" def __init__(self, path): super(FileFilterProxyModel, self).__init__() self.path = path #path is full path to macro file def filterAcceptsRow(self, sourceRow, sourceParent): idx0 = self.sourceModel().index(sourceRow, 0, sourceParent) fileModel = self.sourceModel() #idx0.data() returns a string, such as "Macros" or "C:" if fileModel.isDir(idx0) and not idx0.data() in self.path: return False #do not show this folder else: return True class TaskEditorAssistant: def __init__(self): #super(TaskEditorAssistant, self).__init__(mw, QtCore.Qt.Tool) #GetInt(), SetInt(), GetFloat(), SetFloat(), GetBool(), SetBool(), GetString(), SetString() self.isTabbed=False self.found = False #find result self.lastHighlightMode = "find" #can be None, "find", or "selection" self.gotoLineDict = {} #to save goto line edit value for each editor self.editorDict = {} self.editors = [] self.parents = [] self.grandparents = [] self.titles = [] self.templateDictString = self.getTemplateString() self.undoQueue = [] #dictionary list {reason, old_text, name, tc} self.redoQueue = [] #tc holds a tuple (start, end) of selected text position self.snaps = [] #dictionary list {reason, old_text, name, tc} self.currentEditor = None self.timers = [] #toasts use this self.toastsLog = [tuple(["No previous toasts","Message"])] self.getEditors() self.blockSignals = False self.form = CustomQWidget(form=self) self.form.setObjectName("Editor assistant") self.form.setWindowTitle(" Editor assistant v"+__version__) self.form.setWindowIcon(QIconFromXPMString(__icon__)) self.Indent_Memo = "" for ed in self.editors: self.editorDict [ed.parent().parent().windowTitle()] = ed self.mdi = mw.findChild(QtWidgets.QMdiArea) self.mdi.subWindowActivated.connect(self.onSubWindowActivated) #self.layout = VBox = main layout (rest are all HBox) #topLabelLayout = toast label #editorLayout = editor list widget #refreshLayout = refresh button + goto menu button + goto line edit #gotoLayout = goto home button + goto end button (hidden by default) #undoLayout = undo + pop undos + redo #findEditLayout = Find edit + search + search previous + clear #findEditLayout2 = ComboBox_Find #replaceEditLayout = Replace edit + replace + replace all + reverse #replaceEditLayout2 = ComboBox_replace #indentLayout = unindent button + indent button + combo box indent memo + match case checkbox + whole words checkbox #snapLayout = snap button + discard button + snap menu + pop button #consoleLayout = to console label + console line edit self.layout = QtWidgets.QVBoxLayout() self.form.setLayout(self.layout) topLabelLayout = QtWidgets.QHBoxLayout() self.mainMenuBtn = QtWidgets.QPushButton() self.mainMenuBtn.setIcon(QIconFromXPMString(__icon__)) self.mainMenuBtn.setMaximumWidth(MAX_ICONIZED_BUTTON_WIDTH) self.mainMenuBtn.setToolTip("Main menu") self.mainMenuBtn.clicked.connect(self.onMainMenuBtnClicked) topLabelLayout.addWidget(self.mainMenuBtn) topLabelLayout.addStretch() self.msgBtn = QtWidgets.QPushButton() self.msgBtn.clicked.connect(self.onMsgBtnClicked) self.msgBtn.setIcon(QIconFromXPMString(File_Dialog_Info_View_icon)) self.msgBtn.setFixedWidth(300) self.msgBtn.setToolTip("Toast message area," + "\n" + "click to see most recent message displayed in the report view") topLabelLayout.addWidget(self.msgBtn) self.layout.addLayout(topLabelLayout) editorLayout = QtWidgets.QHBoxLayout() showEditorList = pg.GetBool("ShowEditorList",True) self.editorList = QtWidgets.QListWidget() editorListMinimumHeight = pg.GetInt("EditorListMinimumHeight",32) pg.SetInt("EditorListMinimumHeight", editorListMinimumHeight) self.editorList.setMinimumHeight(editorListMinimumHeight) self.editorList.currentItemChanged.connect(self.onEditorListCurrentItemChanged) self.editorList.doubleClicked.connect(self.onRefreshBtnClicked) self.editorList.setToolTip("Open editors, press Refresh to update") editorLayout.addWidget(self.editorList) if not showEditorList: self.editorList.setVisible(showEditorList) self.layout.addLayout(editorLayout) self.populateList() refreshLayout = QtWidgets.QHBoxLayout() showRefreshLine = pg.GetBool("ShowRefreshLine", True) ShowRunMacroBtn = pg.GetBool("ShowRunMacroBtn", True) ShowRunBackUpAction = pg.GetBool("ShowRunBackUpAction", True) ShowRunShowFilesBak = pg.GetBool("ShowRunShowFilesBak", True) self.refreshBtn = QtWidgets.QPushButton()#"Refresh" self.refreshBtn.setToolTip("Refresh list of editors in the list widget above") self.refreshBtn.setIcon(QIconFromXPMString(BrowserReload_icon)) self.refreshBtn.setMaximumWidth(MAX_ICONIZED_BUTTON_WIDTH) self.refreshBtn.clicked.connect(self.onRefreshBtnClicked) refreshLayout.addWidget(self.refreshBtn) self.gotoLineEdit = QtWidgets.QLineEdit() self.gotoLineEdit.returnPressed.connect(self.onGotoLineEditReturnPressed) self.gotoLineEdit.textChanged.connect(self.onGotoLineEditTextChanged) self.gotoLineEdit.setPlaceholderText("Goto Line numbers") self.gotoMenuBtn = QtWidgets.QPushButton() self.gotoMenuBtn.setToolTip(f"\ Goto menu\n\ Line numbers = comma separated lines in Goto line edit\n\ Bookmarks = lines with {BOOKMARK_MARKER} bookmark description\n\ Find results = results of searches for text in Find line edit\n\ ") self.gotoMenuBtn.clicked.connect(self.onGotoMenuBtnClicked) self.gotoMenuBtn.setIcon(QIconFromXPMString(snap_Menu_Btn_icon)) self.gotoMenuBtn.setMaximumWidth(MAX_ICONIZED_BUTTON_WIDTH) refreshLayout.addWidget(self.gotoMenuBtn) refreshLayout.addWidget(self.gotoLineEdit) self.layout.addLayout(refreshLayout) if not showRefreshLine: self.refreshBtn.setVisible(showRefreshLine) self.gotoMenuBtn.setVisible(showRefreshLine) self.gotoLineEdit.setVisible(showRefreshLine) self.runMacroBtn = QtWidgets.QPushButton() self.runMacroBtn.setIcon(QIconFromXPMString(runSave_icon)) self.runMacroBtn.setMaximumWidth(MAX_ICONIZED_BUTTON_WIDTH) self.runMacroBtn.setToolTip("" "Save and Run the macro." + "
" "The executed code has the extension .FCMacro and .py other extensions are ignored" + "
" "It is possible the macro may not work with this button" + "
" "ex: macro search data in another macro or" + "
" "the macro depends on another macro with one error or..." + "
" "Then try run with the conventional method." + "
" "
" "Options : " + "(Tools > Parameters > Plugins > Editor_Assistant)" + "
" "
" "switch_Unicode_Read_File" + "
" "True : only in read file, detect 'UnicodeDecodeError' display Toast, stop the run" + "
" "False: only in read file, skip error detection not display Toast, skip or not the run (by default)" + "
" "Actual : " + str(switch_Unicode_Read_File) + "" + "
" "
" "switchMemoIncludeOnFile" + "
" "You can include one little memo, this memo is adding in the name of file" + "
" "This memo is displayed while hovering the list on ComboBox" + "
" "The maximum lenght of the path + name + memo is automatically cut off to 255 characters" + "
" "Actual : '" + str(switchMemoIncludeOnFile) + "'" + "
" "
" "Save one backup file in desidered directory" + "
" "The button display and give the number of backup file" + "
" "Press the button for delette the complete file(s) and directory" + "
" "
" "setPathFileBackup" + "
" "Path for the backup files (Default: the macro directory)" + "
" "Actual : '" + setPathFileBackup + "'
" "
" "setPathFileSecondStorage" + "
" "You have the possibility to save the macro in a second storage space" + "
" "This option save the file only if the code is good" + "
" "Go to preferences space and give the path in the setPathFileSecondStorage variable" + "
" "If setPathFileSecondStorage is empty the function is ignored" + "
" "If the path is erroneous the function is also ignored" + "
" "Actual : '" + setPathFileSecondStorage + "'" + "
" "
" "switchDisplayConsolePrintError" + "
" "Display or not the complete error info in the reportView" + "
" "Actual : '" + str(switchDisplayConsolePrintError) + "'" + "
" "
" "") if not ShowRunMacroBtn: self.runMacroBtn.setVisible(ShowRunMacroBtn) self.runMacroBtn.clicked.connect(self.runMacroBtnClicked) self.fileBackupDelBtn = QtWidgets.QPushButton() self.fileBackupDelBtn.setIcon(QIconFromXPMString(directory_Backup_Empty_icon)) self.fileBackupDelBtn.setMaximumWidth(MAX_ICONIZED_BUTTON_WIDTH * 2) # enlarge button if not ShowRunBackUpAction: self.fileBackupDelBtn.setVisible(ShowRunBackUpAction) self.fileBackupDelBtn.clicked.connect(self.fileBackupDelBtnClicked) self.ComboBox_Bak_Files = QtWidgets.QComboBox() self.ComboBox_Bak_Files.setMaxVisibleItems(25) self.ComboBox_Bak_Files.setEditable(False) # not editable ## later #self.ComboBox_Bak_Files.setEditable(True) # editable self.ComboBox_Bak_Files.setFixedWidth(270) if not ShowRunShowFilesBak: self.ComboBox_Bak_Files.setVisible(ShowRunShowFilesBak) QtCore.QObject.connect(self.ComboBox_Bak_Files, QtCore.SIGNAL("textActivated (QString)"), self.on_ComboBox_Bak_Files_Clicked) self.ComboBox_Bak_Files.textHighlighted.connect(self.on_Header_Bak_File_Info) ## later #self.ComboBox_Bak_Files.currentTextChanged.connect(self.on_Header_Bak_File_Info_Changed) # avec editable runMacroLayout = QtWidgets.QHBoxLayout() runMacroLayout.addWidget(self.runMacroBtn) runMacroLayout.addWidget(self.fileBackupDelBtn) runMacroLayout.addStretch() runMacroLayout.addWidget(self.ComboBox_Bak_Files) self.layout.addLayout(runMacroLayout) gotoLayout = QtWidgets.QHBoxLayout() showGotoLine = pg.GetBool("ShowGotoLine", True) self.gotoHomeBtn = QtWidgets.QPushButton() self.gotoHomeBtn.setIcon(QIconFromXPMString(home_icon)) self.gotoHomeBtn.setMaximumWidth(MAX_ICONIZED_BUTTON_WIDTH) self.gotoHomeBtn.setToolTip("Go to first line") self.gotoHomeBtn.clicked.connect(self.onGotoHomeBtnClicked) gotoLayout.addWidget(self.gotoHomeBtn) self.gotoEndBtn = QtWidgets.QPushButton() self.gotoEndBtn.setIcon(QIconFromXPMString(end_icon)) self.gotoEndBtn.setMaximumWidth(MAX_ICONIZED_BUTTON_WIDTH) self.gotoEndBtn.setToolTip("Go to last line") self.gotoEndBtn.clicked.connect(self.onGotoEndBtnClicked) gotoLayout.addWidget(self.gotoEndBtn) gotoLayout.addStretch() self.previousBookmarkBtn = QtWidgets.QPushButton("") nextIcon = QIconFromXPMString(next_bookmark_icon) prevIcon = QtGui.QPixmap(nextIcon.pixmap(64,64)).transformed(QtGui.QTransform().scale(-1,1), QtCore.Qt.SmoothTransformation) self.previousBookmarkBtn.setIcon(prevIcon) self.previousBookmarkBtn.setMaximumWidth(MAX_ICONIZED_BUTTON_WIDTH) gotoLayout.addWidget(self.previousBookmarkBtn) self.previousBookmarkBtn.setToolTip("Goto previous bookmark") self.previousBookmarkBtn.clicked.connect(self.previousBookmark) self.nextBookmarkBtn = QtWidgets.QPushButton() self.nextBookmarkBtn.setIcon(QIconFromXPMString(next_bookmark_icon)) self.nextBookmarkBtn.setMaximumWidth(MAX_ICONIZED_BUTTON_WIDTH) gotoLayout.addWidget(self.nextBookmarkBtn) self.nextBookmarkBtn.setToolTip("Goto next bookmark") self.nextBookmarkBtn.clicked.connect(self.nextBookmark) self.toggleBookmarkBtn = QtWidgets.QPushButton("") self.toggleBookmarkBtn.setIcon(QIconFromXPMString(toggle_bookmark_icon)) self.toggleBookmarkBtn.setMaximumWidth(MAX_ICONIZED_BUTTON_WIDTH) gotoLayout.addWidget(self.toggleBookmarkBtn) self.toggleBookmarkBtn.setToolTip("Toggle bookmark") self.toggleBookmarkBtn.clicked.connect(self.toggleBookmark) self.removeAllBookmarksBtn = QtWidgets.QPushButton() self.removeAllBookmarksBtn.setIcon(QIconFromXPMString(remove_all_bookmarks_icon)) self.removeAllBookmarksBtn.setMaximumWidth(MAX_ICONIZED_BUTTON_WIDTH) gotoLayout.addWidget(self.removeAllBookmarksBtn) self.removeAllBookmarksBtn.setToolTip("Remove all bookmarks") self.removeAllBookmarksBtn.clicked.connect(self.removeAllBookmarks) self.layout.addLayout(gotoLayout) if not showGotoLine: self.gotoHomeBtn.setVisible(showGotoLine) self.gotoEndBtn.setVisible(showGotoLine) showUndoLine = pg.GetBool("ShowUndoLine",True) undoLayout = QtWidgets.QHBoxLayout() self.undoBtn = QtWidgets.QPushButton() self.undoBtn.setEnabled(False) undoLayout.addWidget(self.undoBtn) self.undoBtn.clicked.connect(self.onUndoBtnClicked) self.undoBtn.setIcon(QIconFromXPMString(undo_icon)) self.undoClearBtn = QtWidgets.QPushButton() self.undoClearBtn.setIcon(QIconFromXPMString(Reset_Button_icon)) self.undoClearBtn.setMaximumWidth(MAX_ICONIZED_BUTTON_WIDTH) self.undoClearBtn.setToolTip("Purge undo/redo queues. Clears both queues.") self.undoClearBtn.clicked.connect(self.onUndoClearBtnClicked) self.undoClearBtn.setEnabled(False) undoLayout.addWidget(self.undoClearBtn) self.redoBtn = QtWidgets.QPushButton() self.redoBtn.setEnabled(False) undoLayout.addWidget(self.redoBtn) self.redoBtn.clicked.connect(self.onRedoBtnClicked) self.redoBtn.setIcon(QIconFromXPMString(redo_icon)) self.redoBtn if not showUndoLine: self.undoBtn.setVisible(showUndoLine) self.redoBtn.setVisible(showUndoLine) self.undoClearBtn.setVisible(showUndoLine) self.layout.addLayout(undoLayout) showFindLine = pg.GetBool("ShowFindLine",True) findEditLayout = QtWidgets.QHBoxLayout() self.Clear_FindReplaceCB = QtWidgets.QPushButton() #"Clear" self.Clear_FindReplaceCB.setToolTip("Clear the fields Find / Replace") self.Clear_FindReplaceCB.setIcon(QIconFromXPMString(Reset_Button_icon)) self.Clear_FindReplaceCB.setMaximumWidth(MAX_ICONIZED_BUTTON_WIDTH) self.Clear_FindReplaceCB.clicked.connect(self.on_Clear_FindReplaceCB_Clicked) findEditLayout.addWidget(self.Clear_FindReplaceCB) self.Refresh_Aqua_HighlightS = QtWidgets.QPushButton() #"Refresh_Aqua_Highlight Search" self.Refresh_Aqua_HighlightS.setToolTip("Refresh / Restaure Highlight Selection (Find)") self.Refresh_Aqua_HighlightS.setIcon(QIconFromXPMString(Btn_Refresh_Aqua_Highlight_icon)) self.Refresh_Aqua_HighlightS.setMaximumWidth(MAX_ICONIZED_BUTTON_WIDTH) self.Refresh_Aqua_HighlightS.clicked.connect(self.on_Refresh_Aqua_HighlightS_clicked) findEditLayout.addWidget(self.Refresh_Aqua_HighlightS) self.findEdit = FindEdit(form=self) self.findEdit.setPlaceholderText("Find:") self.findEdit.returnPressed.connect(self.onFindEditReturnPressed) self.findEdit.textChanged.connect(self.onFindEditTextChanged) findEditLayout.addWidget(self.findEdit) self.findBtn = QtWidgets.QPushButton() self.findBtn.setIcon(QIconFromXPMString(find_next_icon)) self.findBtn.setMaximumWidth(MAX_ICONIZED_BUTTON_WIDTH) self.findBtn.setToolTip("Find next\nCtrl+Click = Find from start\nAlt+Click = Find from selection") self.findBtn.clicked.connect(self.onFindBtnClicked) self.findBackBtn = QtWidgets.QPushButton() self.findBackBtn.setIcon(QIconFromXPMString(find_previous_icon)) self.findBackBtn.setMaximumWidth(MAX_ICONIZED_BUTTON_WIDTH) self.findBackBtn.setToolTip("Find previous\nCtrl+Click = Find from end\nAlt+Click = Find from selection") self.findBackBtn.clicked.connect(self.onFindBackBtnClicked) findEditLayout.addWidget(self.findBtn) findEditLayout.addWidget(self.findBackBtn) showFindLine2 = pg.GetBool("ShowFindLine2",False) findEditLayout2 = QtWidgets.QHBoxLayout() self.ComboBox_Find = QtWidgets.QComboBox() self.ComboBox_Find.setMaxVisibleItems(16) self.ComboBox_Find.setDuplicatesEnabled(False) # not work ? self.ComboBox_Find.setEditable(True) # editable #QtCore.QObject.connect(self.ComboBox_Find, QtCore.SIGNAL("currentIndexChanged(QString)"), self.on_ComboBox_Find_Clicked) QtCore.QObject.connect(self.ComboBox_Find, QtCore.SIGNAL("textActivated (QString)"), self.on_ComboBox_Find_Clicked) findEditLayout2.addWidget(self.ComboBox_Find) if not showFindLine: self.findEdit.setVisible(showFindLine) self.findBtn.setVisible(showFindLine) self.findBackBtn.setVisible(showFindLine) self.Clear_FindReplaceCB.setVisible(showFindLine) self.Refresh_Aqua_HighlightS.setVisible(showFindLine) if not showFindLine2: self.ComboBox_Find.setVisible(showFindLine2) self.layout.addLayout(findEditLayout) self.layout.addLayout(findEditLayout2) showReplaceLine = pg.GetBool("ShowReplaceLine",True) replaceEditLayout = QtWidgets.QHBoxLayout() self.Reverse_FindReplaceCB = QtWidgets.QPushButton() #"Reverse" self.Reverse_FindReplaceCB.setToolTip("Reverse the fields Find / Replace") self.Reverse_FindReplaceCB.setMaximumWidth(MAX_ICONIZED_BUTTON_WIDTH) self.Reverse_FindReplaceCB.setIcon(QIconFromXPMString(reverse_find_replace_icon)) self.Reverse_FindReplaceCB.clicked.connect(self.on_Reverse_FindReplaceCB_Clicked) replaceEditLayout.addWidget(self.Reverse_FindReplaceCB) self.Refresh_Aqua_HighlightR = QtWidgets.QPushButton() #"Refresh_Aqua_Highlight Search" self.Refresh_Aqua_HighlightR.setToolTip("Refresh / Restaure Highlight Selection (Replace)") self.Refresh_Aqua_HighlightR.setIcon(QIconFromXPMString(Btn_Refresh_Aqua_Highlight_icon)) self.Refresh_Aqua_HighlightR.setMaximumWidth(MAX_ICONIZED_BUTTON_WIDTH) self.Refresh_Aqua_HighlightR.clicked.connect(self.on_Refresh_Aqua_HighlightR_clicked) replaceEditLayout.addWidget(self.Refresh_Aqua_HighlightR) self.replaceEdit = FindEdit(form=self) self.replaceEdit.setPlaceholderText("Replace:") replaceEditLayout.addWidget(self.replaceEdit) self.replaceBtn = QtWidgets.QPushButton() self.replaceBtn.setToolTip("Replace current selection and find next") self.replaceBtn.clicked.connect(self.onReplaceBtnClicked) self.replaceBtn.setIcon(QIconFromXPMString(replace_icon)) self.replaceBtn.setMaximumWidth(MAX_ICONIZED_BUTTON_WIDTH) self.replaceAllBtn = QtWidgets.QPushButton() self.replaceAllBtn.setToolTip("Replace all\nCtrl+Click = Replace only in selection") self.replaceAllBtn.setIcon(QIconFromXPMString(replace_all_icon)) self.replaceAllBtn.setMaximumWidth(MAX_ICONIZED_BUTTON_WIDTH) self.replaceAllBtn.clicked.connect(self.onReplaceAllBtnClicked) replaceEditLayout.addWidget(self.replaceBtn) replaceEditLayout.addWidget(self.replaceAllBtn) showReplaceLine2 = pg.GetBool("ShowReplaceLine2",False) replaceEditLayout2 = QtWidgets.QHBoxLayout() self.ComboBox_replace = QtWidgets.QComboBox() self.ComboBox_replace.setMaxVisibleItems(16) self.ComboBox_replace.setDuplicatesEnabled(False) # not work ? self.ComboBox_replace.setEditable(True) # editable #QtCore.QObject.connect(self.ComboBox_replace, QtCore.SIGNAL("currentIndexChanged(QString)"), self.on_ComboBox_Replace_Clicked) QtCore.QObject.connect(self.ComboBox_Find, QtCore.SIGNAL("textActivated (QString)"), self.on_ComboBox_Find_Clicked) replaceEditLayout2.addWidget(self.ComboBox_replace) if not showReplaceLine: self.replaceEdit.setVisible(showReplaceLine) self.Refresh_Aqua_HighlightR.setVisible(showReplaceLine) self.replaceBtn.setVisible(showReplaceLine) self.replaceAllBtn.setVisible(showReplaceLine) self.Reverse_FindReplaceCB.setVisible(showReplaceLine) self.Clear_FindReplaceCB.setVisible(showReplaceLine) if not showReplaceLine2: self.ComboBox_replace.setVisible(showReplaceLine2) self.layout.addLayout(replaceEditLayout) self.layout.addLayout(replaceEditLayout2) showIndentLine = pg.GetBool("ShowIndentLine", True) indentLayout = QtWidgets.QHBoxLayout() self.indentBackBtn = QtWidgets.QPushButton() self.indentBackBtn.setIcon(QIconFromXPMString(unindent_icon)) self.indentBackBtn.setMaximumWidth(MAX_ICONIZED_BUTTON_WIDTH) self.indentBackBtn.setToolTip("Decrease indentation of selection") self.indentBackBtn.clicked.connect(self.onIndentBackBtnClicked) indentLayout.addWidget(self.indentBackBtn) self.indentBtn = QtWidgets.QPushButton() self.indentBtn.setIcon(QIconFromXPMString(indent_icon)) self.indentBtn.setMaximumWidth(MAX_ICONIZED_BUTTON_WIDTH) self.indentBtn.setToolTip("Increase indentation of selection") self.indentBtn.clicked.connect(self.onIndentBtnClicked) indentLayout.addWidget(self.indentBtn) self.ComboBox_Indent_Memo = QtWidgets.QComboBox() self.ComboBox_Indent_Memo.setMaxVisibleItems(16) self.ComboBox_Indent_Memo.setToolTip("Insert the text in front on line(s) selected instead of the indentation " + "\n" "(the button indentation icon change)" + "\n" "Ex: '#ori'" + "\n" "Validate by Enter" + "\n" "If the field is empty the normal indentation is used" + "\n") self.ComboBox_Indent_Memo.setDuplicatesEnabled(False) # not work ? self.ComboBox_Indent_Memo.setEditable(True) # editable QtCore.QObject.connect(self.ComboBox_Indent_Memo, QtCore.SIGNAL("currentIndexChanged(QString)"), self.on_ComboBox_Indent_Memo_Clicked) QtCore.QObject.connect(self.ComboBox_Indent_Memo, QtCore.SIGNAL("editTextChanged (QString)"), self.on_ComboBox_Indent_Memo_Changed_Clicked) indentLayout.addWidget(self.ComboBox_Indent_Memo) #indentLayout.addStretch() self.matchWholeCheckBox = QtWidgets.QCheckBox() self.matchWholeCheckBox.setIcon(QIconFromXPMString(match_whole_word_icon)) self.matchWholeCheckBox.setMaximumWidth(MAX_ICONIZED_BUTTON_WIDTH + 5) self.matchWholeCheckBox.setToolTip("Match whole words") self.matchWholeCheckBox.stateChanged.connect(self.onMatchWholeCheckBoxStateChanged) self.matchCaseCheckBox = QtWidgets.QCheckBox() self.matchCaseCheckBox.stateChanged.connect(self.onMatchCaseCheckBoxStateChanged) self.matchCaseCheckBox.setMaximumWidth(MAX_ICONIZED_BUTTON_WIDTH + 5) self.matchCaseCheckBox.setIcon(QIconFromXPMString(match_case_icon)) self.matchCaseCheckBox.setToolTip("Match case") self.loopCheckBox = QtWidgets.QCheckBox() loop_icon = reverse_find_replace_icon.replace("#EF2B29","#3F48CC").replace("#8AE138","#3F48CC") loop_icon = loop_icon.replace("#4E990D","black").replace("#A70002","black") self.loopCheckBox.setMaximumWidth(MAX_ICONIZED_BUTTON_WIDTH + 5) self.loopCheckBox.setIcon(QIconFromXPMString(loop_icon)) self.loopCheckBox.setCheckState(QtCore.Qt.Checked) self.loopCheckBox.setToolTip ("Loop to start/end if text not found") indentLayout.addWidget(self.matchCaseCheckBox) indentLayout.addWidget(self.matchWholeCheckBox) indentLayout.addWidget(self.loopCheckBox) self.matchCaseCheckBox.stateChanged.connect(self.onFindEditTextChanged) if not showIndentLine: self.indentBackBtn.setVisible(showIndentLine) self.indentBackBtn.setVisible(showIndentLine) self.indentBackBtn.setVisible(showIndentLine) self.loopCheckBox.setVisible(showIndentLine) self.matchCaseCheckBox.setVisible(showIndentLine) self.matchWholeCheckBox.setVisible(showIndentLine) self.layout.addLayout(indentLayout) showSnapsLine = pg.GetBool("ShowSnapLine",True) snapLayout = QtWidgets.QHBoxLayout() self.takeSnapBtn = QtWidgets.QPushButton() self.takeSnapBtn.setIcon(QIconFromXPMString(snapshot_icon)) self.takeSnapBtn.setMaximumWidth(MAX_ICONIZED_BUTTON_WIDTH) self.takeSnapBtn.setToolTip("Take a snapshot of the text") self.snapCenterBtn = QtWidgets.QPushButton() self.snapMenuBtn = QtWidgets.QPushButton() snapCenterBtnLayout = QtWidgets.QHBoxLayout() snapCenterBtnLayoutMargins = QtCore.QMargins(0,0,0,0) snapCenterBtnLayout.setContentsMargins(snapCenterBtnLayoutMargins) snapCenterBtnLayout.setSpacing(0) self.snapCenterBtn.setLayout(snapCenterBtnLayout) self.snapCenterBtn.setMaximumWidth(MAX_ICONIZED_BUTTON_WIDTH *2) self.discardSnapBtn = QtWidgets.QPushButton() self.discardSnapBtn.setIcon(QIconFromXPMString(Reset_Button_icon)) self.discardSnapBtn.setMaximumWidth(MAX_ICONIZED_BUTTON_WIDTH) self.discardSnapBtn.clicked.connect(self.discardSnap) self.discardSnapBtn.setToolTip("Discard the latest snap") snapCenterBtnLayout.addWidget(self.discardSnapBtn) snapCenterBtnLayout.addWidget(self.snapMenuBtn) self.snapMenuBtn.setIcon(QIconFromXPMString(snap_Menu_Btn_icon)) self.snapMenuBtn.setMaximumWidth(MAX_ICONIZED_BUTTON_WIDTH) self.snapMenuBtn.setToolTip("\ Snapshots menu\n\ Restore = replace current text with snap and keep snap\n\ Restore to clipboard and keep snap in memory\n\ Restore to Text document and keep snap in memory\n\ Restore any = Possibility to restore to different document or a snap out of order\n\ Save to new text file and keep snap in memory\n\ Save all snaps to JSON file and keep all in memory\n\ Load = load all snaps from JSON file, replacing any in memory\n\ Pop = restore and discard snap\n\ Diff = show difference between snap and current text\n\ ") self.popSnapBtn = QtWidgets.QPushButton("Restore") self.popSnapBtn.setVisible(showSnapsLine) self.takeSnapBtn.clicked.connect(self.onTakeSnapBtnClicked) self.snapMenuBtn.clicked.connect(self.onSnapMenuBtnClicked) self.popSnapBtn.clicked.connect(self.onPopSnapBtnClicked) snapLayout.addWidget(self.takeSnapBtn) snapLayout.addWidget(self.snapCenterBtn) snapLayout.addWidget(self.popSnapBtn) self.layout.addLayout(snapLayout) if not showSnapsLine: self.takeSnapBtn.setVisible(showSnapsLine) self.snapCenterBtn.setVisible(showSnapsLine) self.discardSnapBtn.setVisible(showSnapsLine) self.snapMenuBtn.setVisible(showSnapsLine) showConsoleLine = pg.GetBool("ShowConsoleLine", True) consoleLayout = QtWidgets.QHBoxLayout() self.consoleLabel = QtWidgets.QLabel("To console:") consoleLayout.addWidget(self.consoleLabel) self.consoleEdit = QtWidgets.QLineEdit() self.consoleEdit.returnPressed.connect(self.onConsoleEditReturnPressed) self.consoleEdit.setToolTip("Access QPlainTextEdit of current editor directly.\n\ Enter command here and press return\n\ Variable 'editor' will remain afterwards for direct access from the console.\n\ Type 'help(editor)' in the console for help.\n\ ") choices = ["editor.selectAll()", "qSearch('QLineEdit')", "wSearch('topological naming problem')", "search('Part.makeFace')", "help('Qt.Key')", "menu('Draft')", "dlg.close()", "dlg.highlight('def', 'yellow')", "help('numpy')", "dlg.refresh()"] self.consoleEdit.setText(random.choice(choices)) self.consoleSendBtn = QtWidgets.QPushButton("Send") self.consoleSendBtn.clicked.connect(self.onConsoleBtnClicked) consoleLayout.addWidget(self.consoleEdit) self.layout.addLayout(consoleLayout) if not showConsoleLine: self.consoleLabel.setVisible(showConsoleLine) self.consoleEdit.setVisible(showConsoleLine) self.updateSnapBtns() def getEditors(self): self.editors = [child for child in mw.findChildren(QtWidgets.QPlainTextEdit) if child.objectName() != "Python console"] self.parents = [ed.parent() for ed in self.editors] self.grandparents = [p.parent() for p in self.parents] self.titles = [g.windowTitle() for g in self.grandparents] if hasattr(self, "editorList") and shiboken and shiboken.isValid(self.editorList): curNames = [self.editorList.item(ii).text() for ii in range(0, self.editorList.count())] for ii,title in enumerate(self.titles): if not title in curNames: cursor = self.editors[ii].textCursor() self.takeSnap(title, cursor, "Auto snapshot",self.editors[ii].toPlainText()) else: for ii,title in enumerate(self.titles): cursor = self.editors[ii].textCursor() self.takeSnap(title, cursor, "Auto snapshot",self.editors[ii].toPlainText()) ##https://doc.qt.io/qt-6/stylesheet-examples.html if (COLOR_ACTIVE_TAB == "0") or (COLOR_ACTIVE_TAB == ""): mw.findChild(QtWidgets.QMdiArea).setStyleSheet("QTabBar::tab:selected, QTabBar::tab:hover {background-color: QPalette.Base;}") else: #mw.findChild(QtWidgets.QMdiArea).setStyleSheet("QTabBar::tab:selected, QTabBar::tab:hover {background-color: " + COLOR_ACTIVE_TAB + ";}") mw.findChild(QtWidgets.QMdiArea).setStyleSheet("QTabBar::tab:selected, QTabBar::tab:only-one {background-color: " + COLOR_ACTIVE_TAB + ";}") def highlightFromSelection(self): editor = self.currentEditor if not editor: self.toast("No editor","Error") return txt = self.currentEditor.textCursor().selectedText() if not txt: self.toast("Nothing selected","Error") return self.lastHighlightMode = "selection" self.highlight(txt) def highlightFromFind(self): editor = self.currentEditor if not editor: self.toast("No editor","Error") return txt = self.findEdit.text() self.lastHighlightMode = "find" self.highlight(txt) def highlight(self, txt, color="aqua"): """highlight occurrences of txt with background color""" if not self.currentEditor: self.toast("No current editor","Error") return if not txt: return plainText = self.currentEditor.toPlainText() indices = self.reFindIndices(plainText, txt, 0) extraSelections = [] count = len(indices) for ind in indices: extraSelection = QtWidgets.QTextEdit.ExtraSelection() extraSelection.cursor = self.currentEditor.textCursor() extraSelection.cursor.setPosition(ind[0]) extraSelection.cursor.setPosition(ind[1], QtGui.QTextCursor.KeepAnchor) extraSelection.format.setBackground(QtGui.QColor(color)) extraSelections.append(extraSelection) self.currentEditor.setExtraSelections(extraSelections) self.toast(f"Highlighted {count} occurrences of {txt}","Message") def setIconCurrentEditor(self, fileNameBAK = ""): # change icon in backUp button try: lenBackUpFile = 0 lenBackUpFile = len(os.listdir(fileNameBAK)) self.fileBackupDelBtn.setText(str(lenBackUpFile)) self.fileBackupDelBtn.setIcon(QIconFromXPMString(directory_Backup_Taken_icon)) self.fileBackupDelBtn.setToolTip("Number of .bak file stored" + "\n" + "Actual : " + str(lenBackUpFile) + " file(s)" + "\n" "Push the button for delette complete file(s) and directory" + "\n" "If the button is not visible the feature not run") except Exception: try: self.fileBackupDelBtn.setText("") self.fileBackupDelBtn.setIcon(QIconFromXPMString(directory_Backup_Empty_icon)) self.fileBackupDelBtn.setToolTip("Number of .bak file stored" + "\n" + "Push the button for delette complete file(s) and directory" + "\n" "If the button is not visible the feature not run") except Exception: None try: self.ComboBox_Bak_Files.setToolTip("" "Click the backup file for reload the .BAK file" + "
" "One new text document is created" + "
" "
" "" + fileNameBAK + "
" "
" "Format of file saved, example:" + "
" "C:/MyPath/MyMacro.FCMacro.BAK_2023_11_26_19_29_34_##my_memo" + "
" "
" " C:/MyPath/ " + "
" "\t the complete path of .Bak file (modifiable by : setPathFileBackup)" + "
" " MyMacro.FCMacro " + "
" "\t the real name of the macro can be FCMacro or py" + "
" " .BAK_2023_11_26_19_29_34 " + "
" "\t the Bak extension with the date and time format YYYY_MM_DD_HH_MM_SS" + "
" " _##" + "
" "\t the key separation of file to memo (not modifiable)" + "
" " my_memo " + "
" "\t the memo attached on file" + "
" "
" "PS: all spaces of the memo are replaced by the character underline '_'" + "
" "
" "Options : " + "(Tools > Parameters > Plugins > Editor_Assistant)"+ "
" "
" "switchMemoIncludeOnFile" + "
" "You can include one little memo, this memo is adding in the name of file" + "
" "This memo is displayed while hovering the list on ComboBox" + "
" "The maximum lenght of the path + name + memo is automatically cut off to 255 characters" + "
" "Actual : '" + str(switchMemoIncludeOnFile) + "'" + "
" "
" "switchFrameInfoBackUpOnFile
" "Write info of backup file loaded
" "Actual : " + "'" + str(switchFrameInfoBackUpOnFile) + "'
" "
" "switchFrameInfoOnBeginOrEnd
" "Choice the position of the info : Begin (True)/End (False) of the file
" "Actual : " + "'" + str(switchFrameInfoOnBeginOrEnd) + "'
" "
" "switchMemoBakUpDisplayOnComboBox
" "Display the memo of the file in the ComboBox
" "Actual : " + "'" + str(switchMemoBakUpDisplayOnComboBox) + "'
" "
" "If the ComboBox is not visible the feature not run" + "
" "") except Exception: None def setCurrentEditor(self, name="", focus=True): global fileNameBAK if shiboken and not shiboken.isValid(self.editorList): return if name: if not name in self.editorDict: self.getEditors() self.currentEditor = self.editorDict[name] if name in self.titles: self.blockSignals=True self.editorList.setCurrentRow(self.titles.index(name)) self.blockSignals=False else: if self.editorList.currentItem(): name = self.editorList.currentItem().text() self.currentEditor = self.editorDict[name] if shiboken and shiboken.isValid(self.currentEditor) and self.currentEditor and not self.currentEditor.hasFocus(): if focus and self.form.parent(): self.form.parent().hide() self.currentEditor.setFocus() self.form.parent().show() if (name.find("\\") == -1) and (name.find("/") == -1): ## for case drag/drop the complete path is already given nameBAK = name else: nameBAK = name.split("[")[0].split("/")[-1] # case drag/drop !? nameBAK = nameBAK.replace("[*]","") # case drag/drop !? fileNameBAK = setPathFileBackup + nameBAK + ".BAK" self.setIconCurrentEditor(fileNameBAK) self.setListFilesBak(fileNameBAK) def onSubWindowActivated(self, arg1): if hasattr(self, "editorList") and shiboken and not shiboken.isValid(self.editorList): return sub = self.mdi.activeSubWindow() ed = sub.findChild(QtWidgets.QPlainTextEdit) if sub else None if ed: p = ed.parent() gp = p.parent() name = gp.windowTitle() ed.setMaximumWidth(1600) if not name in self.editorDict: QtCore.QTimer().singleShot(50, self.refresh) def FreeCAD_Console_PrintError(self, txt): switchDisplayConsolePrintError = pg.GetBool("switchDisplayConsolePrintError") if switchDisplayConsolePrintError: FreeCAD.Console.PrintMessage("_____Info Editor assistant_____Begin" + "\n") FreeCAD.Console.PrintError(str(txt) + "\n") FreeCAD.Console.PrintMessage("_____Info Editor assistant_____End" + "\n") def fileBackupDelBtnClicked(self): global fileNameBAK global buttonDelBak if ".FCMACRO - " in fileNameBAK.upper(): ##cause : /media/mint/cd01/Macro/000x.FCMacro - Editor.BAK fileNameBAK = fileNameBAK.split(".FCMacro - ")[0] + ".FCMacro" + ".BAK" ##result: /media/mint/cd01/Macro/000x.FCMacro.BAK elif ".PY - " in fileNameBAK.upper(): ##cause : /media/mint/cd01/Macro/000x.py - Editor.BAK fileNameBAK = fileNameBAK.split(".py - ")[0] + ".py" + ".BAK" ##result: /media/mint/cd01/Macro/000x.py.BAK if (fileNameBAK != "") and (os.path.exists(fileNameBAK)): lenBackUpFile = 0 lenBackUpFile = len(os.listdir(fileNameBAK)) self.infoBackupNewInputDialog(title = "Warning Delete BAK", backUp_Or_Info = False, texto = "" + "Warning Delete BAK" + "" + "

" + "Delete the complete " + "" + ".BAK" + "" + " directory" + "

" + "Number of .BAK file(s) : " + "" + str(lenBackUpFile) + "" + "

" + "Name of .BAK directory : " + "

" + "" + str(fileNameBAK) + "") if buttonDelBak == True: try: try: FreeCAD.ActiveDocument.openTransaction("Del_BAK") # memorise les actions (avec annuler restore) except Exception: None shutil.rmtree(fileNameBAK) # del the complete directory and files self.ComboBox_Bak_Files.clear() except OSError as erreur: self.FreeCAD_Console_PrintError(erreur) # in windows the error can be cause to the name shortcut ex: C:\....\BACKUP~1\EDITOR~1.BAK\EDITOR~2.BAK self.toast(str(erreur),"Error") self.setIconCurrentEditor(fileNameBAK) else: self.FreeCAD_Console_PrintError(os.path.exists(fileNameBAK)) self.toast(str(os.path.exists(fileNameBAK)),"Error") def colorError(self, text_cursor=""): lenTextDetected = len(text_cursor.selectedText()) extraSelection = QtWidgets.QTextEdit.ExtraSelection() extraSelection.cursor = self.currentEditor.textCursor() text_cursor.clearSelection() extraSelection.format.setBackground(QtGui.QColor(COLOR_ERROR_DETECTED)) self.currentEditor.setExtraSelections([extraSelection]) ####################################################################### ########## infoBackupNewInputDialog() global memo_Testing; memo_Testing = [] global memo_Last_memo_Entry; memo_Last_memo_Entry = "" def on_Dialog_accept(self): global memo_Testing global memo_Last_memo_Entry self.run = False if self.lineEdit_memo_Bak_Txt.text() != "": memox = memo_Last_memo_Entry = self.lineEdit_memo_Bak_Txt.text() memo_Testing.append((memox, True)) self.ComboBox_Memo.addItem(memox) else: memo_Testing.append(("", True)) memo_Testing = memo_Testing[0] self.Dialog_memo_Bak.setVisible(False) self.Dialog_memo_Bak.deleteLater() def on_Dialog_cancel(self): global memo_Testing memo_Testing.append(("", False)) memo_Testing = memo_Testing[0] self.run = False self.Dialog_memo_Bak.deleteLater() def on_Dialog_accept_Delete(self): global buttonDelBak buttonDelBak = True self.run = False self.Dialog_memo_Bak.setVisible(False) self.Dialog_memo_Bak.deleteLater() def infoBackupNewInputDialog(self, title = "", backUp_Or_Info = True, texto = ""): # instead QtWidgets.QInputDialog, here for adding QComboBox and texto global memo_Last_memo_Entry global memo_Testing global buttonDelBak buttonDelBak = False memo_Testing = [] grid = QtWidgets.QGridLayout() self.Dialog_memo_Bak = QtWidgets.QDialog() self.Dialog_memo_Bak.setWindowModality(QtCore.Qt.ApplicationModal) self.Dialog_memo_Bak.setWindowTitle(title) self.Dialog_memo_Bak.setLayout(grid) self.buttonAccept = QtWidgets.QPushButton() self.buttonAccept.setIcon(QIconFromXPMString(accept_Template_icon)) grid.addWidget(self.buttonAccept,2, 0) self.buttonReject = QtWidgets.QPushButton() self.buttonReject.setText("Abord") self.buttonReject.setIcon(QIconFromXPMString(reject_Template_icon)) self.buttonReject.setToolTip("Abord the command") self.buttonReject.clicked.connect(self.on_Dialog_cancel) grid.addWidget(self.buttonReject,2, 1) if backUp_Or_Info == False: #backUp_Or_Info = False = Warning window self.Dialog_memo_Bak.resize(300, 100) self.Dialog_memo_Bak.setWindowIcon(QIconFromXPMString(msgBtn_Warning_icon)) self.buttonAccept.setText("Ok Delete") self.buttonAccept.setToolTip("Delete the complete directory") self.buttonAccept.clicked.connect(self.on_Dialog_accept_Delete) label = QtGui.QLabel() label.setVisible(False) #### #### def QIconFromXPMString(xpm_string): # cutted for use here xpm = msgBtn_Warning_icon.replace("\"","").replace(',','').splitlines()[4:-1] for line in reversed(xpm): if line.startswith("/*") and line.endswith("*/"): xpm.pop(xpm.index(line)) pixmap = QtGui.QPixmap(xpm) #### icon = QtGui.QIcon(pixmap) #### return icon #### label.setPixmap(QtGui.QPixmap(pixmap)) grid.addWidget(label,0, 0) label2 = QtGui.QLabel() label2.setText(str(texto)) grid.addWidget(label2,0, 1) self.Dialog_memo_Bak.show() label.show() # center screen ecran = FreeCADGui.getMainWindow().frameGeometry() fenetre = self.Dialog_memo_Bak.frameGeometry() xF = fenetre.width() yF = fenetre.height() xW = (ecran.width()/2) - (xF/2) yW = (ecran.height()/2)- (yF/2) self.Dialog_memo_Bak.setGeometry(xW, yW, xF, yF) #### else: # backUp_Or_Info = True = Yes/No run self.Dialog_memo_Bak.setMinimumWidth(200) self.Dialog_memo_Bak.setWindowIcon(QIconFromXPMString(__icon__)) self.buttonAccept.clicked.connect(self.on_Dialog_accept) self.buttonAccept.setText("Ok Run") self.buttonAccept.setToolTip("Run the macro") self.ComboBox_Memo = QtWidgets.QComboBox() self.ComboBox_Memo.addItem(memo_Last_memo_Entry) self.ComboBox_Memo.setToolTip("Latest memo entry") QtCore.QObject.connect(self.ComboBox_Memo, QtCore.SIGNAL("textActivated (QString)"), self.on_ComboBox_Memo_Clicked) grid.addWidget(self.ComboBox_Memo, 0, 0, 1, 2) self.lineEdit_memo_Bak_Txt = QtWidgets.QLineEdit() self.lineEdit_memo_Bak_Txt.setPlaceholderText("Memo text goes here") grid.addWidget(self.lineEdit_memo_Bak_Txt, 1, 0, 1, 2) self.Dialog_memo_Bak.show() self.run = True while self.run: #https://forum.freecadweb.org/viewtopic.php?f=22&t=41377 QtWidgets.QApplication.instance().processEvents() def on_ComboBox_Memo_Clicked(self, text): #self.lineEdit_memo_Bak_Txt.clear() self.lineEdit_memo_Bak_Txt.setText(text) ########## infoBackupNewInputDialog() ####################################################################### def saveFileSecondStorage(self, text = "", storeFile = ""): storePath = pg.GetString("setPathFileSecondStorage") if storePath != "": if (storePath[-1] == "/") or (storePath[-1] == "\\"): None else: storePath = storePath + "/" try: fileSaveSecondStorage = open(storePath + storeFile,'w') # save and display the window Yes/No (case execute macro with EditorAss and work in a 3D window) fileSaveSecondStorage.write(text) except Exception: self.toast("The path " + storePath + " not exist","Error") finally: try: fileSaveSecondStorage.close() except Exception: None def runMacroBtnClicked(self): global path global fileNameBAK global memo_Testing try: FreeCAD.ActiveDocument.openTransaction("EdAss") # memorise les actions (avec annuler restore) except Exception: None self.refresh() try: windowTitleName0 = Gui.getMainWindow().findChild(QtWidgets.QMdiArea).currentSubWindow().windowTitle() windowName0 = self.editorList.currentItem().text() windowName = windowName0.split("[")[0] #Air_Foild_00_PY.py #Air_Foild_00.FCMacro macroName = windowName.split(".")[0] #Air_Foild_00_PY #Air_Foild_00 dummy = windowName.split(".")[1].upper() dummy = dummyPy = dummy.split("[")[0].upper() #PY #FCMACRO except Exception: dummy = dummyPy = "" if (dummy == "FCMACRO" or dummyPy == "PY"): filename = windowName if (windowName.find("\\") == -1) and (windowName.find("/") == -1): ## for case drag/drop the complete path is already given filename = path + windowName filenameSecondStorage = windowName switchAllIsGood = True try: FreeCAD.ActiveDocument.openTransaction("Run Macro") except Exception: None if self.fileBackupDelBtn.isVisible(): # save Bak file #### curLine = self.getLineNumberAtCursor() #### self.infoBackupNewInputDialog(title = "Info Backup") # QDialog with comboView and icon in Button #### if str(memo_Testing[1]) == "True": memo_Bak_Txt = memo_Testing[0] ii = "" if memo_Bak_Txt != "": for i in memo_Bak_Txt: if i in "\x3c\x3e\x3a\x22\x2f\x5c\x7C\x3f\x2a\x2e\x20": i = "_" ii += i memo_Bak_Txt = "_##" + ii else: memo_Bak_Txt = "_##Curent_Line_" + str(curLine) # ici self.addBookmark([f"Bookmark line {curLine} last line of work ", curLine]) # for the file copy plainText = self.getText() #### now = QtCore.QDateTime.currentDateTime().toString(setFormatBackupDateTime) windowName2 = windowName.split("[")[0].split("/")[-1] # case drag/drop !? "000x.FCMacro[*] - Editor.BAK" windowName2 = windowName2.replace("[*]","") fileNameBAK = setPathFileBackup + windowName2 + ".BAK" try: os.makedirs(fileNameBAK, exist_ok=True) #11:59:18 OSError: [WinError 123] La syntaxe du nom de fichier, de repertoire ou de volume est incorrecte ex: 'C:/Users/xxxx/AppData/Roaming/FreeCAD/Macro/C:' add "C:" except OSError as erreur: self.FreeCAD_Console_PrintError(erreur) self.toast(str(erreur),"Error") completeBakName = fileNameBAK + "/" + windowName2 + ".BAK_" + now + memo_Bak_Txt #complete name with memo if len(completeBakName) > 255: completeBakName = completeBakName[:255] # cut 255 characters try: fileSave = open(completeBakName, 'w') # .BAK_ + setFormatBackupDateTime default: "yyyy-MM-dd_hhmmss" try: fileSave.write(plainText) # .Bak file self.setListFilesBak(fileNameBAK) # upgrade # .py .FCMacro file except (UnicodeEncodeError): # character '\ufffd' RuntimeError, TypeError, NameError): # only in write file switch True detect "UnicodeDecodeError, UnicodeEncodeError" display toast switchAllIsGood = False # not .Bak file try: fileSave.close() except Exception as e: classErr = str(sys.exc_info()[0]) # error detected in editor_assistant_dlg.FCMacro self.toast(str(erreur),"Error") self.FreeCAD_Console_PrintError(str(erreur)) switchAllIsGood = False # not .Bak file try: os.remove(completeBakName) except Exception: None #### search formule for positioned the cursor example in position point 49710 (characters) erreur = str(traceback.format_exc()) # error detected in executed macro and position the cursor in a eroneous line erreur = errorSave = str(erreur.split("UnicodeEncodeError:")[1]) lineErrorStr = erreur.split("position")[1].split(":")[0] if "-" in lineErrorStr: # a cause de ex: ' 2261-2267' dummy = "" dummy = str(lineErrorStr) lineErrorStr = dummy.split("-")[0] lineError = int(lineErrorStr) # position error ex: 49710 #### begin calcul position X and Y of text ex: position 49710 numberCR = plainText.count('\n', 0, lineError) # line error (number of "\n" Carriage return) text_cursor = self.currentEditor.textCursor() text_cursor.setPosition(lineError) pos01 = text_cursor.blockNumber() # 767 text_cursor.setPosition(lineError - numberCR) pos02 = text_cursor.blockNumber() # 752 pos03 = pos01 - pos02 # 15 text_cursor.setPosition(lineError - numberCR + pos03) # 48958 ( = 752, 106) text_cursor.positionInBlock() self.currentEditor.setTextCursor(text_cursor) line_y = text_cursor.blockNumber() + 1 # 753 colon_x = text_cursor.columnNumber() + 1 # 107 self.gotoLineEdit.setText(str(line_y)) self.currentEditor.centerCursor() # text_cursor.setPosition(lineError - numberCR + pos03 + 1, QtGui.QTextCursor.KeepAnchor) # for select 1 character self.currentEditor.setTextCursor(text_cursor) #### end calcul position X and Y of text self.colorError(text_cursor) classErr = str(sys.exc_info()[0]) # # error detected in editor_assistant_dlg.FCMacro self.toast("Error on line : (" + str(line_y) + "," + str(colon_x) + " : " + classErr + "\n" + " " + errorSave + " (Bak not saved)") self.toast("Error on line : (" + str(line_y) + "," + str(colon_x) + ")" + "\n" + " : " + classErr + "\n" + " (Bak not saved)", "Python") self.FreeCAD_Console_PrintError(erreur) finally: try: fileSave.close() except OSError as erreur: classErr = str(sys.exc_info()[0]) # error detected in editor_assistant_dlg.FCMacro self.toast(str(erreur),"Error") self.FreeCAD_Console_PrintError(str(erreur)) switchAllIsGood = False # not .Bak file self.setIconCurrentEditor(fileNameBAK) None except OSError as erreur: classErr = str(sys.exc_info()[0]) # error detected in editor_assistant_dlg.FCMacro self.toast(str(erreur),"Error") self.FreeCAD_Console_PrintError(str(erreur)) switchAllIsGood = False # not .Bak file curLine = self.getLineNumberAtCursor() self.toggleBookmark() # delete for restitue the original document if (switchAllIsGood) and (str(memo_Testing[1]) == "True"): plainText = self.getText() if windowName0 == windowTitleName0: Gui.SendMsgToActiveView("Save") # save without display the window Yes/No (if it is in a 3D View, the 3D View is saved in a .FCstd file) else: try: fileSave = fileSaveSecondStorage = open(filename,'w') # save and display the window Yes/No (case execute macro with EditorAss and work in a 3D window) fileSave.write(plainText) except (UnicodeEncodeError): # character '\ufffd' RuntimeError, TypeError, NameError): # only in write file switch True detect "UnicodeDecodeError, UnicodeEncodeError" display toast None finally: fileSave.close() try: switch_Unicode_Read_File = pg.GetBool("switch_Unicode_Read_File") if switch_Unicode_Read_File == 0: with open(filename, 'r',errors='ignore') as file: # only in read file switch False not error detection not display toast skip or not run data = file.read() else: with open(filename, 'r') as file: data = file.read() except (UnicodeDecodeError, RuntimeError, TypeError, NameError, FileNotFoundError): # only in read file switch True detect "UnicodeDecodeError" display toast stop the run self.toast(str(sys.exc_info()[0]),"Python") finally: #except OSError: try: file.close() except Exception: None my_name = 'my_macro' my_spec = importlib.util.spec_from_loader(my_name, loader=None) my_macro = importlib.util.module_from_spec(my_spec) my_macro.FreeCAD = FreeCAD my_macro.App = FreeCAD my_macro.Gui = FreeCADGui my_macro.FreeCADGui = FreeCADGui try: exec(data, my_macro.__dict__) self.saveFileSecondStorage(text = plainText, storeFile = filenameSecondStorage) # save only if the code is good except Exception as err: erreur = str(traceback.format_exc()) # !! error detected in executed macro and position the cursor in a eroneous line counterCirconflex = erreur.count("^") counterCirconflexPos = erreur.find("^") numberCRCirconflex = erreur.count('\n') # line error (number of "\n" Carriage return) argument = str(err.args) lineError = colError = lineColError = switchSelectCompleteLine = 0 text_cursor = self.currentEditor.textCursor() try: lineError = err.lineno except Exception: lineError = 0 None if str(type(err)) == "": # if error detected and not line detected : select all correspondence word (variable) wordError = (str(err.args).replace("'","").split(",")[0].split(" "))[2] lineError = None self.findEdit.setText(wordError) self.onFindBtnClicked(True) # change every run ## errS = str(erreur).split("\n") try: lineError = errS[-3].split() lineError = lineError[3].split(",") lineError = int(lineError[0]) except TypeError: self.matchCaseCheckBox.setChecked(True) #??? ## self.gotoLine(lineError) self.gotoLineEdit.setText(str(lineError)) try: self.matchCaseCheckBox.setChecked(True) #??? text_cursor = self.currentEditor.textCursor() pos01 = text_cursor.blockNumber() pos02 = text_cursor.position() numberCR = plainText.count('\n', 0, pos02) # line error (number of "\n" Carriage return) curPos = pos03 = pos01 + pos02 - numberCR + colError text_cursor.setPosition(pos03) text_cursor.select(QtGui.QTextCursor.WordUnderCursor) # select the word if not text_cursor.hasSelection() or switchSelectCompleteLine == True: text_cursor.select(QtGui.QTextCursor.LineUnderCursor) # select the complete line text (case not line number) self.currentEditor.centerCursor() self.currentEditor.setTextCursor(text_cursor) self.colorError(text_cursor) except Exception: None else: if str(type(err)) == "": errS = str(erreur).split("\n") lineError = errS[-3].split() lineError = lineError[3].split(",") lineError = int(lineError[0]) elif str(type(err)) == "": lineError = err.lineno colError = err.offset elif str(type(err)) == "": # verifier erreur si l'indentation est negative (fccircularText line 3147) lineError = err.lineno colError = err.offset elif str(type(err)) == "": lineError = err.lineno colError = err.offset #### elif str(type(err)) == "": lineColError = erreur.replace("'"," ") lineError = int(lineColError.split('"",')[-1].split("line")[1].split(",")[0]) switchSelectCompleteLine = True elif str(type(err)) == "": lineColError = erreur.replace("'"," ") lineError = int(lineColError.split('"",')[-1].split("line")[1].split(",")[0]) switchSelectCompleteLine = True else: lineError = erreur.split("\n") #ori for i00 in reversed(lineError): for i00 in lineError: if "line" in i00: i01 = i00.replace(",","").split() for i02 in i01: try: lineError = int(i02) break except Exception: None # to do #### self.gotoLine(lineError) self.gotoLineEdit.setText(str(lineError)) text_cursor = self.currentEditor.textCursor() pos01 = text_cursor.blockNumber() pos02 = text_cursor.position() numberCR = plainText.count('\n', 0, pos02) # line error (number of "\n" Carriage return) curPos = pos03 = pos01 + pos02 - numberCR + colError text_cursor.setPosition(pos03) #### # if str(type(err)) == "": # erreurSplit = erreur.split("NameError: name")[1] # erreurSplit = erreurSplit.split()[0] # text_cursor.setPosition(pos03 + len(erreurSplit)-2) # if len(erreurSplit) == 3: # text_cursor.setPosition(pos03 + len(erreurSplit)-2) # curPos = pos03 + len(erreurSplit)-2 # else: # text_cursor.setPosition(pos03 + len(erreurSplit)) # curPos = pos03 + len(erreurSplit) #### if str(type(err)) == "": text_cursor.setPosition(pos03-1) curPos = pos03 - 1 argument = argument[:50] + " ..." text_cursor.select(QtGui.QTextCursor.WordUnderCursor) # select the word if not text_cursor.hasSelection() or switchSelectCompleteLine == True: text_cursor.select(QtGui.QTextCursor.LineUnderCursor) # select the complete line text (case not line number) self.currentEditor.centerCursor() self.currentEditor.setTextCursor(text_cursor) self.colorError(text_cursor) #### # lenTextDetected = len(text_cursor.selectedText()) # text_cursor.clearSelection() # extraSelection = QtWidgets.QTextEdit.ExtraSelection() # extraSelection.cursor = self.currentEditor.textCursor() # #extraSelection.cursor.setPosition(pos01) # #extraSelection.cursor.setPosition(curPos - lenTextDetected, QtGui.QTextCursor.KeepAnchor) # color = QColor(COLOR_ERROR_DETECTED) #a40000 # extraSelection.format.setBackground(QtGui.QColor(color)) # self.currentEditor.setExtraSelections([extraSelection]) #### ## self.highlight(text_cursor.selectedText(),color="red") self.currentEditor.centerCursor() self.currentEditor.setTextCursor(text_cursor) classErr = str(sys.exc_info()[0]) # # error detected in editor_assistant_dlg.FCMacro self.toast(str(erreur),"Error") self.toast("Error on line : " + str(lineError) + "\n" + argument + "\n" + " : " + str(classErr), "Python") self.FreeCAD_Console_PrintError(erreur) def refresh(self): self.onRefreshBtnClicked(True) #self.getEditors() #cur = self.mdi.currentSubWindow() #ed = cur.findChild(QtWidgets.QPlainTextEdit) if cur else None #if ed: # p = ed.parent() # gp = p.parent() # curName = gp.windowTitle() # self.setCurrentEditor(curName) def checkForTabs(self): txt = self.getText() counterTab = txt.count("\t") counterInterrogation = txt.count("\ufffd") counterTabStr = counterInterogationStr = CReturn = "" if counterTab > 0: counterTabStr = "contains (" + str(counterTab) + ") tabs." CReturn = "\n" + " " if counterInterrogation > 0: switchReplaceInterrogationFFFD = pg.GetBool("switchReplaceInterrogationFFFD") if switchReplaceInterrogationFFFD: txt = txt.replace("\ufffd", "_") self.currentEditor.setPlainText(txt) counterInterogationStr = "contains (" + str(counterInterrogation) + ") character ufffd '\ufffd' " + "\n" + "replaced by '_'." if counterTab + counterInterrogation != 0: self.toast(f"{self.editorList.currentItem().text()}: " + counterTabStr + CReturn + counterInterogationStr, "Warning") def onEditorListCurrentItemChanged(self, current, previous): if self.blockSignals: return self.onRefreshBtnClicked(True) self.currentEditor.setFocus() if not self.currentEditor.hasFocus(): self.toast(f"cannot set focus on {self.editorList.currentItem().text()}","Warning") self.checkForTabs() self.onFindEditTextChanged(None) self.updateUndoBtn() self.updateSnapBtns() name = self.editorList.currentItem().text() if self.editorList.currentItem() else "" if name: if name in self.gotoLineDict: self.gotoLineEdit.setText(self.gotoLineDict[name]) else: self.gotoLineEdit.setText("") def doCommand(self, cmd): FreeCADGui.doCommand(cmd) def setText(self, name, txt, reason): old_text = self.getText(name) old_cursor = self.editorDict[name].textCursor() self.editorDict[name].setPlainText(txt) self.setModified(name, old_text, reason, self.getTC(old_cursor)) def getTC(self, text_cursor): return tuple([text_cursor.selectionStart(), text_cursor.selectionEnd()]) def setTextCursor(self, name, tc): ed = self.editorDict[name] text_cursor = ed.textCursor() text_cursor.setPosition(tc[0]) text_cursor.setPosition(tc[1], QtGui.QTextCursor.KeepAnchor) ed.setTextCursor(text_cursor) def getText(self, name=None): if not name: self.onRefreshBtnClicked(True) if not self.editorList.currentItem(): self.toast("No editor","Error") return "" else: name = self.editorList.currentItem().text() return self.editorDict[name].toPlainText() if name in self.editorDict else "" def filterBackSlashes(self, instring): txt = instring.replace('\\t',chr(9)).replace('\\n',chr(10)).replace('\\r',chr(13)) txt = txt.replace('\\b',chr(8)).replace('\\f',chr(12)).replace('\'',chr(39)) txt = txt.replace('\\',chr(92)) return txt def replace(self, name, txt, newTxt): """replace txt with newTxt in editor name""" #only used by replace all if not txt: self.toast("nothing to replace","Error") return inSelectionOnly = False modifiers = QtGui.QGuiApplication.keyboardModifiers() if modifiers == QtCore.Qt.ControlModifier: inSelectionOnly = True if not inSelectionOnly: fullText = self.getText(name) else: fullText = self.currentEditor.textCursor().selectedText() txt = self.filterBackSlashes(txt) indices = self.reFindIndices(fullText, txt, 0) chunks = [] last = -1 for ii,i in enumerate(reversed(indices)): if ii == 0: chunks.insert(0, fullText[i[1]:]) else: chunks.insert(0, fullText[i[1]:last]) chunks.insert(0, newTxt) last = i[0] chunks.insert(0, fullText[:last]) newText = "".join(chunks) count = len(indices) self.toast(f"{count} instances of {txt} replaced in {name}","Message") if not count == 0: if not inSelectionOnly: self.setText(name, newText, f"replace {txt}") else: self.setModified(name,self.currentEditor.toPlainText(), "Replace in selection",self.getTC(self.currentEditor.textCursor())) tc = self.currentEditor.textCursor() tc.setKeepPositionOnInsert(True) tc.insertText(newText) self.currentEditor.setTextCursor(tc) def reFindIndices(self, plainText, txt, searchFrom = 0): """replaces plainText.find(txt, searchFrom=0) with same find using re respecting states of match case checkbox and whole words checkbox returns list of tuples[(idx, idx2),(idx, idx2),...]""" flags = 0 if self.matchCaseCheckBox.isChecked() else re.IGNORECASE compiled = re.compile(r"\b" + re.escape(txt) + r"\b", flags=flags) if self.matchWholeCheckBox.isChecked() else re.compile(re.escape(txt), flags=flags) reIter = compiled.finditer(plainText, pos=searchFrom) indices = [] for ii, match in enumerate(reIter): indices.append(match.span()) return indices def onMatchCaseCheckBoxStateChanged(self, arg1): if self.lastHighlightMode == "selection": self.highlightFromSelection() elif self.lastHighlightMode == "find": self.highlightFromFind() def onMatchWholeCheckBoxStateChanged(self, arg1): if self.lastHighlightMode == "selection": self.highlightFromSelection() elif self.lastHighlightMode == "find": self.highlightFromFind() def find(self, name, txt, backward = False): self.setCurrentEditor() if not self.currentEditor: self.toast("No editor selected") return if not txt: self.toast("Nothing to find.") return str1 = "'" findFlagsList = [] if self.matchCaseCheckBox.isChecked(): findFlagsList.append("QtGui.QTextDocument.FindFlag.FindCaseSensitively") if self.matchWholeCheckBox.isChecked(): findFlagsList.append("QtGui.QTextDocument.FindFlag.FindWholeWords") if backward: findFlagsList.append("QtGui.QTextDocument.FindFlag.FindBackward") if findFlagsList: str1 = "', " findFlags = "|".join(findFlagsList) else: findFlags = "" newtxt = txt.replace('"', '\\"').replace("'","\\'") cmd = """ from PySide import QtGui, QtWidgets __editors__ = [child for child in FreeCADGui.getMainWindow().findChildren(QtWidgets.QPlainTextEdit)] __parents__ = [ed.parent() for ed in __editors__] __grandparents__ = [p.parent().windowTitle() for p in __parents__] __editor__ = __editors__[__grandparents__.index('""" + name + """')] __dlg__ = Gui.getMainWindow().findChild(QtWidgets.QWidget,"Editor assistant") __dlg__.setFound(__editor__.find('""" + newtxt + str1 + findFlags + """)) __editor__.centerCursor() del(__editors__, __parents__, __grandparents__, __editor__,__dlg__) """ self.doCommand(cmd) def qSearch(self,txt): qText = txt.replace(" ","+") queryUrl = f"https://wiki.qt.io/index.php?search={qText}&title=Special%3ASearch&go=Go" import webbrowser webbrowser.open_new_tab(queryUrl) def wSearch(self, txt): """open a new tab in default browser the wiki search page, search results for txt""" qText = txt.replace(" ","+") queryUrl = f"https://wiki.freecadweb.org/index.php?search={qText}&title=Special%3ASearch&go=Go" import webbrowser webbrowser.open_new_tab(queryUrl) def search(self,txt): """do a search for txt on github FreeCAD repo""" import webbrowser qText = txt.replace(" ","+") queryUrl = f"https://github.com/FreeCAD/FreeCAD/search?q={qText}" webbrowser.open_new_tab(queryUrl) def onMsgBtnClicked(self, arg1): self.toast("Toast log sent to report view","Information",log=False) self.print("Toasts log:\n") for ii,toast in enumerate(self.toastsLog): if ii==0: continue self.print(f"{ii}) {toast[0]}",toast[1]) def onConsoleEditReturnPressed(self): self.onConsoleBtnClicked(True) def toast(self,msg,msgType='Error',length=5000,log=True,priority="high"): if not hasattr(self, "msgBtn") or bool (shiboken and not shiboken.isValid(self.msgBtn)): return self.timers.append(msg) if priority == "high" or not self.msgBtn.text(): self.msgBtn.setText(msg) if log: self.toastsLog.append(tuple([msg, msgType])) if msgType == 'Error': self.msgBtn.setStyleSheet("color:red") self.msgBtn.setIcon(QIconFromXPMString(msgBtn_Critical_icon)) elif msgType == 'Python': self.msgBtn.setStyleSheet("color:yellow;background-color:red;font-weight:bold") self.msgBtn.setIcon(QIconFromXPMString(pythonPY_icon)) elif msgType == 'Message': self.msgBtn.setStyleSheet("color:black") elif msgType == 'Warning': self.msgBtn.setStyleSheet("color:yellow;background-color:navy;font-weight:bold") self.msgBtn.setIcon(QIconFromXPMString(msgBtn_Warning_icon)) elif msgType == 'Information': self.msgBtn.setStyleSheet("color:blue") #self.msgBtn.setIcon(QIconFromXPMString(File_Dialog_Info_View_icon)) QtCore.QTimer().singleShot(length,self.clearToast) def clearToast(self): #in case there are new messages we don't want to delete them yet, let their timers do it later if shiboken and not shiboken.isValid(self.msgBtn) or not self.form or not self.form.parent(): return if len(self.timers) == 1: self.msgBtn.setText("") self.msgBtn.setStyleSheet("color:black") self.msgBtn.setIcon(QIconFromXPMString(File_Dialog_Info_View_icon)) self.timers.pop() elif len(self.timers) > 1: self.timers.pop() def onConsoleBtnClicked(self, arg1): self.onRefreshBtnClicked(True) consoleCmd = self.consoleEdit.text() consoleCmd = consoleCmd.replace("qsearch","qSearch") consoleCmd = consoleCmd.replace("dir(", "dlg.dir(") consoleCmd = consoleCmd.replace("help(", "dlg.showHelp(") consoleCmd = consoleCmd.replace("menu(","dlg.makeReferenceMenu(") if not "qSearch" in consoleCmd: consoleCmd = consoleCmd.replace("search(", "dlg.search(") consoleCmd = consoleCmd.replace("qSearch(", "dlg.qSearch(") consoleCmd = consoleCmd.replace("wSearch(", "dlg.wSearch(") consoleCmd = consoleCmd.replace("\\n",chr(10)) name = self.editorList.currentItem().text() if self.editorList.currentItem() else "" if not name: self.toast("No editor selected") if name: old_text = self.getText(name) old_cursor = self.editorDict[name].textCursor() cmd = """ from PySide import QtGui from PySide import QtWidgets __editors__ = [child for child in FreeCADGui.getMainWindow().findChildren(QtWidgets.QPlainTextEdit)] __parents__ = [ed.parent() for ed in __editors__] __grandparents__ = [p.parent().windowTitle() for p in __parents__] editor = __editors__[__grandparents__.index('""" + name + """')] dlg = Gui.getMainWindow().findChild(QtWidgets.QWidget,"Editor assistant").form """+ consoleCmd + """ del(__editors__, __parents__, __grandparents__) """ else: #not name if consoleCmd.startswith("editor"): self.toast("No open editor","Error") return cmd = """ from PySide import QtGui from PySide import QtWidgets dlg = Gui.getMainWindow().findChild(QtWidgets.QWidget,"Editor assistant").form """+ consoleCmd + """ """ self.doCommand(cmd) if name: if not old_text == self.getText(): self.setModified(name, old_text, "Console command", self.getTC(old_cursor)) self.toast("editor now available as variable in python console","Message") pyconsole = mw.findChild(QtWidgets.QPlainTextEdit,"Python console") pyconsole.setFocus() self.form.parent().hide() pyconsole.parent().show() self.form.parent().show() def onFindEditReturnPressed(self): self.onFindBtnClicked(True) def on_ComboBox_Find_Clicked(self, text): global duplicate_Find if text not in duplicate_Find: duplicate_Find.append(text) duplicate_Find = sorted(list(set(duplicate_Find))) # sort self.ComboBox_Find.addItem(text) self.ComboBox_Find.setCurrentText(text) self.findEdit.setText(text) def convertToNewFormatBAK(self, completePath): # convert Name To New Format BAK "-" to "_" import os if os.path.exists(completePath): #print("exists, and convert") for i in os.listdir(completePath): #list of files in directory if "-" in i: new = i.replace("-","_") os.rename(completePath + "/" + i, completePath + "/" + new) def setListFilesBak(self, text): global takenBakFiles try: self.convertToNewFormatBAK(text) if ".FCMACRO" in text.upper(): text = text.split(".FCMacro")[0] text = text + ".FCMacro.BAK" elif ".PY" in text.upper(): text = text.split(".py")[0] text = text + ".py.BAK" text = text.replace("[*]","") try: self.ComboBox_Bak_Files.clear() except Exception: self.ComboBox_Bak_Files = QtWidgets.QComboBox() takenBakFiles = [] if os.path.exists(text): for i in enumerate(os.listdir(text)): #list of files in directory dummy = i[1].split("_##") convertName = dummy[0].split(".")[-1] if len(dummy) == 2: memo_Bak_Txt = dummy[1] else: memo_Bak_Txt = "" # if switchMemoBakUpDisplayOnComboBox: memo_Bak_Display = "_" + memo_Bak_Txt[:254] else: memo_Bak_Display = "" self.ComboBox_Bak_Files.addItem( str((i[0] + 1)) + " : " + convertName + memo_Bak_Display) # text in comboBox takenBakFiles.append([str(i[0]), convertName, text, i[1], memo_Bak_Txt]) self.setIconCurrentEditor(text) except Exception: None def on_ComboBox_Bak_Files_Clicked(self, text): global takenBakFiles global fileNameBAK # lenBackUpFile = len(os.listdir(fileNameBAK)) try: if len(takenBakFiles) != 0: filename = bakNickName = pathBak = nameBak = memo_Bak_Txt = "" itemFile = int(text.split(":")[0]) -1 ##itemFile = takenBakFiles[itemFile][0]) # 5 # index bakNickName = takenBakFiles[itemFile][1] # BAK_2023-09-04_174848 pathBak = takenBakFiles[itemFile][2] # C:/Users/Tyty/AppData/Roaming/FreeCAD/Macro/Tyty.py.BAK nameRealFile = pathBak.split("/")[-1] nameRealFile = nameRealFile[:-4] # Tyty.py nameBak = takenBakFiles[itemFile][3] # Tyty.py.BAK_2023-09-04_174848_memo_Bak_Txt memo_Bak_Txt = takenBakFiles[itemFile][4] # memo_Bak_Txt filename = pathBak + "/" + nameBak doc = FreeCAD.ActiveDocument if FreeCAD.ActiveDocument else FreeCAD.newDocument() textDoc = doc.addObject("App::TextDocument", bakNickName) with open(filename, 'r') as file: data = file.read() file.close() #### include info begin switchFrameInfoBackUpOnFile = pg.GetBool("switchFrameInfoBackUpOnFile") switchFrameInfoOnBeginOrEnd = pg.GetBool("switchFrameInfoOnBeginOrEnd") if switchFrameInfoBackUpOnFile == True: curLine = self.getLineNumberAtCursor() bookmarkSaved = "Bookmark to line " + str(curLine) + " last line of work " lDataII = len(data) lDataI = len(str(lDataII)) aI = len(bakNickName) bI = len(nameBak.split('.BAK_')[0]) cI = len(nameBak.split('.BAK_')[1].split('_##')[0]) d = "(Info include by Editor_Assistant " + __version__ + ")" dI = len(d) e = pathBak.split('.BAK')[0] eI = len(e) f = memo_Bak_Txt fI = len(f) g = bookmarkSaved gI = len(bookmarkSaved) x = max(aI, bI, cI, dI, eI, lDataI, fI) + 2 a = bakNickName + " "*(x - aI) b = nameBak.split('.BAK_')[0] + " "*(x - bI) c = nameBak.split('.BAK_')[1].split('_##')[0] + " "*(x - cI) e = e + " "*(x - eI) f = " " + f + " "*(x - fI) lData = str(lDataII) + " byte(s)" + " "*(x - lDataI - 8) g = " " + g + " "*(x - gI) ## create frame info begin backInfo = """####""" + "#"*(x + 2) + """#### ######""" + d + '#'*(x - dI) + """#### #### This document : """ + ' '*(x - 15) + """#### #### """ + a + """#### #### Length : """ + ' '*(x - 8) + """#### #### """ + lData + """#### #### is one backUp of the file : """ + ' '*(x - 27) + """#### #### """ + b + """#### #### Date Time : """ + ' '*(x - 11) + """#### #### """ + c + """#### #### Original (without memo) : """ + ' '*(x - 25) +"""#### #### """ + e + """#### #### Memo : """ + ' '*(x - 6) + """#### #### """ + g + """#### #### """ + f + """#### ####""" + '#'*(x + 2) + """#### """ ## create frame info end if switchFrameInfoOnBeginOrEnd == True: data = backInfo + "\n" + data # info en haut else: data = data + "\n" + backInfo # info en bas #### include info end textDoc.Text = data self.toast("Back file reload " + "\n" + filename,"Message") # restablished after add : line 337 self.msgBtn.setFixedWidth(300) #self.toast("Back file reload " + "\n" + pathBak,"Message") textDoc.ViewObject.doubleClicked() doc.recompute() except Exception: try: self.toast("Back file reload Error " + "\n" + filename,"Error") except Exception: self.toast("Back file reload Error " + "\n" + "XXXX", "Error") def on_Header_Bak_File_Info(self, text): global takenBakFiles global fileNameBAK # lenBackUpFile = len(os.listdir(fileNameBAK)) try: if len(takenBakFiles) != 0: itemFile = int(text.split(":")[0]) -1 ##itemFile = takenBakFiles[itemFile][0]) # 5 # index bakNickName = takenBakFiles[itemFile][1] # BAK_2023-09-04_174848 pathBak = takenBakFiles[itemFile][2] # C:/Users/Tyty/AppData/Roaming/FreeCAD/Macro/Tyty.py.BAK nameRealFile = pathBak.split("/")[-1] nameRealFile = nameRealFile[:-4] # Tyty.py nameBak = takenBakFiles[itemFile][3] # Tyty.py.BAK_2023-09-04_174848_##memo_Bak_Txt memo_Bak_Txt = takenBakFiles[itemFile][4] # memo_Bak_Txt filename = pathBak + "/" + nameBak if memo_Bak_Txt == "" : memo_Bak_Txt = "?" toolTipComboBox = "\n" + nameRealFile + "\n\n" + bakNickName + "\n\n" + pathBak + "\n\n" + memo_Bak_Txt + "\n" self.ComboBox_Bak_Files.setItemData(itemFile, toolTipComboBox, QtCore.Qt.ToolTipRole) except Exception: try: self.toast("Back file reload Error " + "\n" + filename,"Error") except Exception: self.toast("Back file reload Error " + "\n" + "XXXX", "Error") def on_Clear_FindReplaceCB_Clicked(self): self.findEdit.clear() self.ComboBox_Find.clear() self.replaceEdit.clear() self.ComboBox_replace.clear() def onFindEditTextChanged(self, arg1): matchCase = self.matchCaseCheckBox.isChecked() if shiboken and not shiboken.isValid(self.currentEditor) or not self.currentEditor: self.toast("current editor is invalid", "Error") return plainText = self.currentEditor.toPlainText() txt = self.filterBackSlashes(self.findEdit.text()) if not matchCase: plainText = plainText.lower() txt = txt.lower() name = self.editorList.currentItem().text() if self.editorList.currentItem() else "" count = plainText.count(txt) if name and txt: self.toast(f"{txt} count in {name}: {count}","Message") if self.lastHighlightMode == "find": self.highlightFromFind() def onFindBtnClicked(self, arg1=True): self.onRefreshBtnClicked(True) if shiboken and not shiboken.isValid(self.currentEditor) or not self.currentEditor: self.toast("current editor is invalid","Error") return self.currentEditor.setFocus() name = self.editorList.currentItem().text() self.highlight(name) txt = self.findEdit.text() matchCase = self.matchCaseCheckBox.isChecked() modifiers = QtWidgets.QApplication.keyboardModifiers() if modifiers == QtCore.Qt.AltModifier: selText = self.currentEditor.textCursor().selectedText() self.findEdit.setText(selText if selText else txt) txt = self.findEdit.text() elif modifiers == QtCore.Qt.ControlModifier: self.gotoLine(1, silent=True) self.found = False self.find(name, txt) if not self.found: if self.loopCheckBox.isChecked(): self.toast(f"{txt} not found in {name} --Looping back to start","Warning") self.gotoLine(1, silent=True) self.on_ComboBox_Find_Clicked(txt) self.highlight(txt) def on_Refresh_Aqua_HighlightS_clicked(self): newTxt = self.findEdit.text() self.highlight(newTxt) def on_Refresh_Aqua_HighlightR_clicked(self): newTxt = self.replaceEdit.text() self.highlight(newTxt) def updateSnapBtns(self,refresh=True): if refresh: self.onRefreshBtnClicked(True) if not hasattr(self, "editorList"): return curName = self.editorList.currentItem().text() if self.editorList.count() else None snaps = [snap for snap in reversed(self.snaps) if snap["name"] == curName] if not snaps and hasattr(self, "popSnapBtn"): self.popSnapBtn.setEnabled(False) self.popSnapBtn.setText("Pop") self.popSnapBtn.setToolTip("Pop/restore and discard latest snap") self.discardSnapBtn.setEnabled(False) elif hasattr(self, "popSnapBtn"): self.popSnapBtn.setEnabled(True) self.popSnapBtn.setText(f"Pop {snaps[0]['reason']}") self.popSnapBtn.setToolTip(f"Pop/restore and discard {snaps[0]['reason']}") self.discardSnapBtn.setEnabled(True) def takeSnap(self, curName, curCursor=None, reason="", plainText=""): """takeSnap(curName, curCursor=None, reason="") if not curCursor it is taken from current editor if not reason it is Snap #NNN""" curText = self.getText(curName) if not plainText else plainText curCursor = self.currentEditor.textCursor() if not curCursor else curCursor tc = self.getTC(curCursor) count = 1 for snap in self.snaps: if snap["name"] == curName: count += 1 if reason: thisReason = reason else: thisReason = f"Snap #{count}" thisSnap = {"name":curName, "old_text":curText, "reason":thisReason, "tc":tc} self.snaps.append(thisSnap) self.toast(f"{thisSnap['reason']} taken of {curName}","Message") if len(self.snaps) > UNDO_QUEUE_MAX_SIZE: self.snaps.pop(0) self.toast("Snaps count exceeds {UNDO_QUEUE_MAX_SIZE}, discarding oldest snap","Warning") self.updateSnapBtns(refresh=False) def onTakeSnapBtnClicked(self, arg1): self.onRefreshBtnClicked(True) self.updateSnapBtns() curName = self.editorList.currentItem().text() if self.editorList.count() else "" if not curName: self.toast("No current editor","Error") return self.takeSnap(curName) def getSnaps(self): self.onRefreshBtnClicked(True) curName = self.editorList.currentItem().text() if self.editorList.currentItem() else "" snaps = [snap for snap in reversed(self.snaps) if snap["name"] == curName] return snaps def discardSnap(self,idx=0): """discard a snap, default=0 = latest snap""" snaps = self.getSnaps() if not snaps: self.toast("No snaps to discard for this editor","Error") self.updateSnapBtns() return else: self.snaps.remove(snaps[idx]) self.updateSnapBtns() def discardAllSnaps(self): self.onRefreshBtnClicked(True) self.snaps = [] self.updateSnapBtns() def onPopSnapBtnClicked(self, arg1): self.onRefreshBtnClicked(True) curName = self.editorList.currentItem().text() snaps = [snap for snap in reversed(self.snaps) if snap["name"] == curName] if not snaps: self.toast("No snaps to restore for this editor","Error") self.updateSnapBtns() return else: old_text = self.getText(curName) old_cursor = self.currentEditor.textCursor() self.currentEditor.setPlainText(snaps[0]["old_text"]) self.setTextCursor(self.editorList.currentItem().text(), snaps[0]['tc']) self.snaps.remove(snaps[0]) self.updateSnapBtns() self.toast(f"Popped and restored {snaps[0]['reason']} to {snaps[0]['name']}","Message") self.setModified(curName, old_text, f"Pop {snaps[0]['reason']}", self.getTC(old_cursor)) def showWidgets(self,groupName,show): showDict = { "ShowEditorList": [self.editorList], "ShowRefreshLine": [self.refreshBtn, self.gotoMenuBtn, self.gotoLineEdit], "ShowGotoLine": [self.gotoEndBtn, self.gotoHomeBtn, self.nextBookmarkBtn, \ self.previousBookmarkBtn, \ self.removeAllBookmarksBtn, self.toggleBookmarkBtn], "ShowRunMacroBtn": [self.runMacroBtn], "ShowRunBackUpAction": [self.fileBackupDelBtn], "ShowRunShowFilesBak": [self.ComboBox_Bak_Files], "ShowUndoLine": [self.undoBtn, self.undoClearBtn, self.redoBtn], "ShowFindLine": [self.findEdit, self.findBtn, self.findBackBtn, self.Clear_FindReplaceCB, self.Refresh_Aqua_HighlightS], "ShowFindLine2": [self.ComboBox_Find], "ShowReplaceLine": [self.replaceEdit, self.Refresh_Aqua_HighlightR, self.replaceBtn, self.replaceAllBtn, self.Reverse_FindReplaceCB], "ShowReplaceLine2": [self.ComboBox_replace], "ShowIndentLine": [self.indentBackBtn, self.indentBtn, self.ComboBox_Indent_Memo, self.matchCaseCheckBox, \ self.matchWholeCheckBox, self.loopCheckBox], "ShowSnapsLine": [self.takeSnapBtn, self.discardSnapBtn, self.snapCenterBtn, self.snapMenuBtn, self.popSnapBtn], "ShowConsoleLine": [self.consoleLabel, self.consoleEdit] } for widget in showDict[groupName]: widget.setVisible(show) def setBool(self, name, value): pg.SetBool(name,value) self.showWidgets(name,value) def onMainMenuBtnClicked(self, arg1): """general purpose menu for things not related to going to a line or managing snaps or diffs""" def makeToggler(name,value): return lambda: self.setBool(name,value) #begin settings menu showEditorList = pg.GetBool("ShowEditorList", True) showRefreshLine = pg.GetBool("ShowRefreshLine", True) showGotoLine = pg.GetBool("ShowGotoLine", True) ShowRunMacroBtn = pg.GetBool("ShowRunMacroBtn", True) ShowRunBackUpAction = pg.GetBool("ShowRunBackUpAction", True) ShowRunShowFilesBak = pg.GetBool("ShowRunShowFilesBak", True) showUndoLine = pg.GetBool("ShowUndoLine", True) showFindLine = pg.GetBool("ShowFindLine", True) showFindLine2 = pg.GetBool("ShowFindLine2", False) showReplaceLine = pg.GetBool("ShowReplaceLine", True) showReplaceLine2 = pg.GetBool("ShowReplaceLine2", False) showIndentLine = pg.GetBool("ShowIndentLine", True) showSnapsLine = pg.GetBool("ShowSnapsLine", True) showConsoleLine = pg.GetBool("ShowConsoleLine", True) allLines = ["ShowEditorList","ShowRefreshLine","ShowGotoLine","ShowUndoLine",\ "ShowRunMacroBtn","ShowRunBackUpAction","ShowRunShowFilesBak",\ "ShowFindLine","ShowFindLine2","ShowReplaceLine","ShowReplaceLine2",\ "ShowIndentLine","ShowSnapsLine","ShowConsoleLine"] defaultLines = ["ShowEditorList","ShowRefreshLine","ShowGotoLine", "ShowUndoLine","ShowFindLine",\ "ShowReplaceLine","ShowIndentLine","ShowSnapsLine","ShowConsoleLine"] minimalLines = ["ShowEditorList","ShowRefreshLine","ShowUndoLine","ShowFindLine",\ "ShowReplaceLine","ShowIndentLine"] def show(lines): for line in allLines: self.setBool(line, False) for line in lines: self.setBool(line, True) mainMenu = QtWidgets.QMenu("Main menu") settingsMenu = QtWidgets.QMenu("Settings") settingsMenu.setIcon(QIconFromXPMString(tools_icon)) layoutMenu = QtWidgets.QMenu("Layout lines") settingsMenu.addMenu(layoutMenu) togglers = [] #settings -> layout editorListAction = QtGui.QAction("Editor list", layoutMenu, checkable=True) editorListAction.setChecked(showEditorList) togglers.append(makeToggler("ShowEditorList",not editorListAction.isChecked())) editorListAction.toggled.connect(togglers[-1]) layoutMenu.addAction(editorListAction) refreshLineAction = QtGui.QAction("Refresh line/Run",layoutMenu, checkable=True) refreshLineAction.setChecked(showRefreshLine) togglers.append(makeToggler("ShowRefreshLine", not refreshLineAction.isChecked())) refreshLineAction.toggled.connect(togglers[-1]) layoutMenu.addAction(refreshLineAction) gotoLineAction = QtGui.QAction("Goto/Bookmark line",layoutMenu, checkable=True) gotoLineAction.setChecked(showGotoLine) togglers.append(makeToggler("ShowGotoLine", not gotoLineAction.isChecked())) gotoLineAction.toggled.connect(togglers[-1]) layoutMenu.addAction(gotoLineAction) runMacroAction = QtGui.QAction("Run Macro",layoutMenu, checkable=True) runMacroAction.setChecked(ShowRunMacroBtn) togglers.append(makeToggler("ShowRunMacroBtn", not runMacroAction.isChecked())) runMacroAction.toggled.connect(togglers[-1]) layoutMenu.addAction(runMacroAction) # runBackUpAction = QtGui.QAction("Backup",layoutMenu, checkable=True) runBackUpAction = QtGui.QAction("Run Backup",layoutMenu, checkable=True) runBackUpAction.setChecked(ShowRunBackUpAction) togglers.append(makeToggler("ShowRunBackUpAction", not runBackUpAction.isChecked())) runBackUpAction.toggled.connect(togglers[-1]) layoutMenu.addAction(runBackUpAction) # runShowFilesBak = QtGui.QAction("Show Bak files",layoutMenu, checkable=True) runShowFilesBak = QtGui.QAction("Run Show Bak files",layoutMenu, checkable=True) runShowFilesBak.setChecked(ShowRunShowFilesBak) togglers.append(makeToggler("ShowRunShowFilesBak", not runShowFilesBak.isChecked())) runShowFilesBak.toggled.connect(togglers[-1]) layoutMenu.addAction(runShowFilesBak) undoLineAction = QtGui.QAction("Undo line", layoutMenu, checkable=True) undoLineAction.setChecked(showUndoLine) togglers.append(makeToggler("ShowUndoLine", not undoLineAction.isChecked())) undoLineAction.toggled.connect(togglers[-1]) layoutMenu.addAction(undoLineAction) findLineAction = QtGui.QAction("Find line", layoutMenu, checkable=True) findLineAction.setChecked(showFindLine) togglers.append(makeToggler("ShowFindLine", not findLineAction.isChecked())) findLineAction.toggled.connect(togglers[-1]) layoutMenu.addAction(findLineAction) findLine2Action = QtGui.QAction("Find line2", layoutMenu, checkable=True) findLine2Action.setChecked(showFindLine2) togglers.append(makeToggler("ShowFindLine2", not findLine2Action.isChecked())) findLine2Action.toggled.connect(togglers[-1]) layoutMenu.addAction(findLine2Action) replaceLineAction = QtGui.QAction("Replace line", layoutMenu, checkable=True) replaceLineAction.setChecked(showReplaceLine) togglers.append(makeToggler("ShowReplaceLine", not replaceLineAction.isChecked())) replaceLineAction.toggled.connect(togglers[-1]) layoutMenu.addAction(replaceLineAction) replaceLine2Action = QtGui.QAction("Replace line2", layoutMenu, checkable=True) replaceLine2Action.setChecked(showReplaceLine2) togglers.append(makeToggler("ShowReplaceLine2", not replaceLine2Action.isChecked())) replaceLine2Action.toggled.connect(togglers[-1]) layoutMenu.addAction(replaceLine2Action) indentLineAction = QtGui.QAction("Indent line", layoutMenu, checkable=True) indentLineAction.setChecked(showIndentLine) togglers.append(makeToggler("ShowIndentLine", not indentLineAction.isChecked())) indentLineAction.toggled.connect(togglers[-1]) layoutMenu.addAction(indentLineAction) snapsLineAction = QtGui.QAction("Snaps line", layoutMenu, checkable=True) snapsLineAction.setChecked(showSnapsLine) togglers.append(makeToggler("ShowSnapsLine", not snapsLineAction.isChecked())) snapsLineAction.toggled.connect(togglers[-1]) layoutMenu.addAction(snapsLineAction) consoleLineAction = QtGui.QAction("Console line", layoutMenu, checkable=True) consoleLineAction.setChecked(showConsoleLine) togglers.append(makeToggler("ShowConsoleLine", not consoleLineAction.isChecked())) consoleLineAction.toggled.connect(togglers[-1]) layoutMenu.addAction(consoleLineAction) settingsMenu.addSeparator() showAllAction = QtGui.QAction("Show all", layoutMenu) showAllAction.triggered.connect(lambda: show(allLines)) settingsMenu.addAction(showAllAction) showDefaultsAction = QtGui.QAction("Show defaults", settingsMenu) showDefaultsAction.triggered.connect(lambda: show(defaultLines)) settingsMenu.addAction(showDefaultsAction) showMinimalAction = QtGui.QAction("Show Minimal", settingsMenu) showMinimalAction.triggered.connect(lambda: show(minimalLines)) settingsMenu.addAction(showMinimalAction) #end settings->layout settingsMenu.addSeparator() bHighlightActiveTab = pg.GetString("ColorActiveTab","#B3F88C") == "#B3F88C" highlightActiveTabAction = QtGui.QAction("Highlight active tab", settingsMenu, checkable = True) highlightActiveTabAction.setChecked(bHighlightActiveTab) highlightActiveTabAction.triggered.connect(self.toggleActiveTabHighlighting) settingsMenu.addAction(highlightActiveTabAction) mainMenu.addMenu(settingsMenu) #end of settings #start goto menu gotoMenu = self.makeGotoMenu() gotoMenu.setIcon(QIconFromXPMString(goto_To_Menu_icon)) mainMenu.addMenu(gotoMenu) #start snaps menu snapsMenu = self.makeSnapsMenu() snapsMenu.setIcon(QIconFromXPMString(snapshot_icon)) mainMenu.addMenu(snapsMenu) #start templates menu templatesMenu = QtWidgets.QMenu("Templates") templatesMenu.setIcon(QIconFromXPMString(template_icon)) insertFromTemplateAction = QtGui.QAction("Insert from dialog") insertFromTemplateAction.triggered.connect(self.setupInsertFromTemplate) templatesMenu.addAction(insertFromTemplateAction) insertMenu = QtWidgets.QMenu("Insert") templatesMenu.addMenu(insertMenu) insertSubmenus = [] templateDict = self.getTemplateString() def makeTemplateLambda(x): return lambda : self.testTemplateItem(key=x, execute=True) templateActions = [] templateLambdas = [makeTemplateLambda(k) for k in sorted(templateDict.keys())] for ii, k in enumerate(sorted(templateDict.keys())): if ii % 25 == 0: insertSubmenus.append(QtWidgets.QMenu(f"Start from -- {k}")) templateActions.append(QtGui.QAction(k)) templateActions[-1].triggered.connect(templateLambdas[ii]) insertSubmenus[-1].addAction(templateActions[-1]) for sub in insertSubmenus: insertMenu.addMenu(sub) editTemplateAction = QtGui.QAction("Edit templates") editTemplateAction.triggered.connect(self.editTemplates) templatesMenu.addAction(editTemplateAction) mainMenu.addMenu(templatesMenu) #start help menu helpMenu = QtWidgets.QMenu("Help") helpMenu.setIcon(QIconFromXPMString(help_To_Web_icon)) mainMenu.addMenu(helpMenu) #start help -> reference menu helpReferenceMenu = QtWidgets.QMenu("Reference") helpMenu.addMenu(helpReferenceMenu) #start help -> reference -> moduleMenu = QtWidgets.QMenu("FreeCAD Modules") helpReferenceMenu.addMenu(moduleMenu) def makeModule(x): return lambda : self.makeReferenceMenu(x) packagesDict = { "Draft":"Draft", "DraftUtils":"DraftUtils", "Fem":" Fem", "FemGui":" FemGui", "Image":" Image", "ImageGui":" ImageGui", "Measure":" Measure", "Mesh":" Mesh", "MeshGui":" MeshGui", "MeshPart":" MeshPart", "MeshPartGui":"MeshPartGui", "PartDesign":" PartDesign", "PartDesignGui":"PartDesignGui", "Part":"Part", "PartGui":"PartGui", "Path":"Path", "PathGui":"PathGui", "PathSimulator":"PathSimulator", "Points":"Points", "PointsGui":"PointsGui", "Sketcher":"Sketcher", "SketcherGui":"SketcherGui", "Spreadsheet":"Spreadsheet", "SpreadsheetGui":"SpreadsheetGui", "TechDraw":"TechDraw", "TechDrawGui":"TechDrawGui", "Web":"Web", "WebGui":"WebGui" } moduleActions = [] modules = [] for k,v in packagesDict.items(): moduleActions.append(QtGui.QAction(k)) modules.append(makeModule(v)) moduleActions[-1].triggered.connect(modules[-1]) moduleMenu.addAction(moduleActions[-1]) FreeCADAction = QtGui.QAction("FreeCAD/App") FreeCADAction.triggered.connect(lambda :self.makeReferenceMenu(FreeCAD)) helpReferenceMenu.addAction(FreeCADAction) FreeCADGuiAction = QtGui.QAction("FreeCADGui/Gui") FreeCADGuiAction.triggered.connect(lambda :self.makeReferenceMenu(FreeCADGui)) helpReferenceMenu.addAction(FreeCADGuiAction) qtMenu = QtWidgets.QMenu("Qt/PySide") helpReferenceMenu.addMenu(qtMenu) QtCoreAction = QtGui.QAction("QtCore") QtCoreAction.triggered.connect(lambda :self.makeReferenceMenu(QtCore)) qtMenu.addAction(QtCoreAction) QtCore_QtAction = QtGui.QAction("QtCore.Qt") QtCore_QtAction.triggered.connect(lambda :self.makeReferenceMenu(QtCore.Qt)) qtMenu.addAction(QtCore_QtAction) QtGuiAction = QtGui.QAction("QtGui") QtGuiAction.triggered.connect(lambda :self.makeReferenceMenu(QtGui)) qtMenu.addAction(QtGuiAction) QtWidgetsAction = QtGui.QAction("QtWidgets") QtWidgetsAction.triggered.connect(lambda :self.makeReferenceMenu(QtWidgets)) qtMenu.addAction(QtWidgetsAction) QtNetworkAction = QtGui.QAction("QtNetwork") if hasQtNetwork else QtGui.QAction("QtNetwork (not installed)") QtNetworkAction.triggered.connect(lambda :self.makeReferenceMenu(QtNetwork)) qtMenu.addAction(QtNetworkAction) if not hasQtNetwork: QtNetWorkAction.setEnabled(False) QtHelpAction = QtGui.QAction("QtHelp") if hasQtHelp else QtGui.QAction("QtHelp (not installed)") QtHelpAction.triggered.connect(lambda :self.makeReferenceMenu(QtHelp)) qtMenu.addAction(QtHelpAction) if not hasQtHelp: QtHelpAction.setEnabled(False) QtMultimediaAction = QtGui.QAction("QtMultimedia") if hasQtMultimedia else QtGui.QAction("QtMultimedia (not installed)") QtMultimediaAction.triggered.connect(lambda :self.makeReferenceMenu(QtMultimedia)) qtMenu.addAction(QtMultimediaAction) if not hasQtMultimedia: QtMultimediaAction.setEnabled(False) QtOpenGLAction = QtGui.QAction("QtOpenGL") if hasQtOpenGL else QtGui.QAction("QtOpenGL (not installed)") QtOpenGLAction.triggered.connect(lambda :self.makeReferenceMenu(QtOpenGL)) qtMenu.addAction(QtOpenGLAction) if not hasQtOpenGL: QtOpenGLAction.setEnabled(False) QtPrintSupportAction = QtGui.QAction("QtPrintSupport") if hasQtPrintSupport else QtGui.QAction("QtPrintSupport (not installed)") QtPrintSupportAction.triggered.connect(lambda :self.makeReferenceMenu(QtPrintSupport)) qtMenu.addAction(QtPrintSupportAction) if not hasQtPrintSupport: QtPrintSupportAction.setEnabled(False) QtSqlAction = QtGui.QAction("QtSql") if hasQtSql else QtGui.QAction("QtSql (not installed)") QtSqlAction.triggered.connect(lambda :self.makeReferenceMenu(QtSql)) qtMenu.addAction(QtSqlAction) if not hasQtSql: QtSqlAction.setEnabled(False) QtSvgAction = QtGui.QAction("QtSvg") if hasQtSvg else QtGui.QAction("QtSvg (not installed)") QtSvgAction.triggered.connect(lambda :self.makeReferenceMenu(QtSvg)) qtMenu.addAction(QtSvgAction) if not hasQtSvg: QtSvgAction.setEnabled(False) QtTestAction = QtGui.QAction("QtTest") if hasQtTest else QtGui.QAction("QtTest (not installed)") QtTestAction.triggered.connect(lambda :self.makeReferenceMenu(QtTest)) qtMenu.addAction(QtTestAction) if not hasQtTest: QtTestAction.setEnabled(False) QtWidgetsAction = QtGui.QAction("QtWidgets") if hasQtWidgets else QtGui.QAction("QtWidgets (not installed)") QtWidgetsAction.triggered.connect(lambda :self.makeReferenceMenu(QtWidgets)) qtMenu.addAction(QtWidgetsAction) if not hasQtWidgets: QtWidgetsAction.setEnabled(False) QtXmlAction = QtGui.QAction("QtXml") if hasQtXml else QtGui.QAction("QtXml (not installed)") QtXmlAction.triggered.connect(lambda :self.makeReferenceMenu(QtXml)) qtMenu.addAction(QtXmlAction) if not hasQtXml: QtXmlAction.setEnabled(False) QtXmlPatternsAction = QtGui.QAction("QtXmlPatterns") if hasQtXmlPatterns else QtGui.QAction("QtXmlPatterns (not installed)") QtXmlPatternsAction.triggered.connect(lambda :self.makeReferenceMenu(QtXmlPatterns)) qtMenu.addAction(QtXmlPatternsAction) if not hasQtXmlPatterns: QtXmlPatternsAction.setEnabled(False) searchMenu = QtWidgets.QMenu("Search source code") searchAction = QtGui.QAction("Use find edit text") searchAction.triggered.connect(self.makeSearchFromFindEdit) searchMenu.addAction(searchAction) searchSelAction = QtGui.QAction("Use selected text") searchSelAction.triggered.connect(self.makeSearchFromSelection) searchMenu.addAction(searchSelAction) searchAskAction = QtGui.QAction("Ask for query") searchAskAction.triggered.connect(self.makeSearchFromImmediate) searchMenu.addAction(searchAskAction) helpMenu.addMenu(searchMenu) qSearchMenu = QtWidgets.QMenu("Search Qt") qSearchAction = QtGui.QAction("Use find edit text") qSearchAction.triggered.connect(self.makeqSearchFromFindEdit) qSearchMenu.addAction(qSearchAction) qSearchSelAction = QtGui.QAction("Use selected text") qSearchSelAction.triggered.connect(self.makeqSearchFromSelection) qSearchMenu.addAction(qSearchSelAction) qSearchAskAction = QtGui.QAction("Ask for query") qSearchAskAction.triggered.connect(self.makeqSearchFromImmediate) qSearchMenu.addAction(qSearchAskAction) helpMenu.addMenu(qSearchMenu) wSearchMenu = QtWidgets.QMenu("Search wiki") wSearchAction = QtGui.QAction("Use find edit text") wSearchAction.triggered.connect(self.makewSearchFromFindEdit) wSearchMenu.addAction(wSearchAction) wSearchSelAction = QtGui.QAction("Use selected text") wSearchSelAction.triggered.connect(self.makewSearchFromSelection) wSearchMenu.addAction(wSearchSelAction) wSearchAskAction = QtGui.QAction("Ask for query") wSearchAskAction.triggered.connect(self.makewSearchFromImmediate) wSearchMenu.addAction(wSearchAskAction) helpMenu.addMenu(wSearchMenu) #highlight menu highlightMenu = QtWidgets.QMenu("Highlight", mw) highlightMenu.setIcon(QIconFromXPMString(high_Light_icon)) highlightFromSelectionAction = QtGui.QAction("From selection") highlightFromSelectionAction.triggered.connect(self.highlightFromSelection) highlightMenu.addAction(highlightFromSelectionAction) highlightFromFindAction = QtGui.QAction("From find") highlightFromFindAction.triggered.connect(self.highlightFromFind) highlightMenu.addAction(highlightFromFindAction) mainMenu.addMenu(highlightMenu) highlightFromReplaceAction = QtGui.QAction("From replace") highlightFromReplaceAction.triggered.connect(self.on_Refresh_Aqua_HighlightR_clicked) highlightMenu.addAction(highlightFromReplaceAction) mainMenu.addMenu(highlightMenu) mainMenu.addSeparator() #drag to forum dragToForumAction = QtGui.QAction("Drag to forum") dragToForumAction.setIcon(QIconFromXPMString(pythonToForum_icon)) dragToForumEnabled = hasattr(self.editorList.currentItem(),"text") dragToForumAction.setEnabled(dragToForumEnabled) dragToForumAction.triggered.connect(lambda: self.dragToForum(self.editorList.currentItem())) mainMenu.addAction(dragToForumAction) #close menu if self.isTabbed: closeAction = QtGui.QAction("Close") closeAction.setIcon(QIconFromXPMString(Btn_Quit_icon)) closeAction.triggered.connect(self.close) mainMenu.addAction(closeAction) mainMenu.exec(self.mainMenuBtn.mapToGlobal(QtCore.QPoint())) def toggleActiveTabHighlighting(self): COLOR_ACTIVE_TAB = pg.GetString("ColorActiveTab","#B3F88C") bHighlightActiveTab = bool(COLOR_ACTIVE_TAB != "" and COLOR_ACTIVE_TAB != "0") if bHighlightActiveTab: #is active, so toggle it false by setting parameter to "0" pg.SetString("ColorActiveTab","0") mw.findChild(QtWidgets.QMdiArea).setStyleSheet("QTabBar::tab:selected, QTabBar::tab:hover {background-color: QPalette.Base;}") else: pg.SetString("ColorActiveTab","#B3F88C") COLOR_ACTIVE_TAB = pg.GetString("ColorActiveTab","#B3F88C") mw.findChild(QtWidgets.QMdiArea).setStyleSheet("QTabBar::tab:selected, QTabBar::tab:only-one {background-color: " + COLOR_ACTIVE_TAB + ";}") #credit Amartel at stackoverflow for this bit of code def getLineNumberAtCursor(self): cursor = self.currentEditor.textCursor() cursor.movePosition(QtGui.QTextCursor.StartOfLine) lines = 1 lines_text = cursor.block().text().splitlines() lines_pos = 0 for line_text in lines_text: lines_pos += len(line_text) + 1 if lines_pos > cursor.position() - cursor.block().position(): break lines += 1 block = cursor.block().previous() while block.isValid(): lines += block.lineCount() block = block.previous() return lines def setupInsertFromTemplate(self): templateDict = self.getTemplateString() items=[] for k,v in templateDict.items(): items.append(k) if not items: self.toast("No keys in template","Error") return item,ok = QtWidgets.QInputDialog.getItem(mw, "Select template","Select which template to insert", sorted(items)) if ok: self.testTemplateItem(key=item, execute=True) def testTemplateItem(self, key, testText="", execute=False): """test template from editor, but also can execute""" def inp(title="Input",label="Enter a value:"): return lambda:QtWidgets.QInputDialog.getMultiLineText(Gui.getMainWindow(), title, label) def inp1(title="Input",label="Enter a value:"): return lambda:QtWidgets.QInputDialog.getText(Gui.getMainWindow(), title, label) if not testText: templateDict = self.getTemplateString() rawDict = templateDict[key] else: rawDict = json.loads(testText, strict=False) if not "output" in rawDict: self.toast("Test failed: no key named 'output'","Error") return "" if rawDict["output"] == "input": retval,ok = inp(f"Input for {key}",f"Enter a value for {replacement[0]}")() rawOutString = retval if ok else None elif rawDict["output"] == 'input1': retval,ok = inp1Line(f"Input for {key}",f"Enter a value for {replacement[0]}")() rawOutString = retval if ok else None elif rawDict["output"] == "clipboard": rawOutString = QtGui.QClipboard().text() elif rawDict["output"] == "selection": rawOutString = self.currentEditor.textCursor().selectedText() else: rawOutString = rawDict["output"] if not rawOutString: self.toast("Empty output value","Error") return "" replacements = [(k,v) for k,v in rawDict.items() if k != "output" and k!= "goto"] for replacement in replacements: if replacement[1] == 'input': retval,ok = inp(f"Input for {key}",f"Enter a value for {replacement[0]}")() rawDict[replacement[0]] = retval if ok else None elif replacement[1] == 'input1': retval,ok = inp1Line(f"Input for {key}",f"Enter a value for {replacement[0]}")() rawDict[replacement[0]] = retval if ok else None elif replacement[1] == "selection": rawDict[replacement[0]] = self.currentEditor.textCursor().selectedText() elif replacement[1] == 'clipboard': clipTxt = QtGui.QClipboard().text() rawDict[replacement[0]] = clipTxt if not clipTxt: self.toast("Clipboard is empty","Warning") elif replacement[1] == 'selection': selTxt = self.currentEditor.textCursor().selectedText() rawDict[replacement[0]] = selTxt if not selTxt: self.toast("Selection is empty","Warning") elif replacement[1] == 'find': findTxt = self.findEdit.text() rawDict[replacement[0]] = findTxt if not findTxt: self.toast("Find edit is empty","Warning") elif replacement[1] == 'replace': replaceTxt = self.replaceEdit.text() rawDict[replacement[0]] = replaceTxt if not replaceTxt: self.toast("Replace edit is empty","Warning") for replacement in replacements: rawOutString = rawOutString.replace(replacement[0],rawDict[replacement[0]]) if not execute: return rawOutString if self.currentEditor: old_cursor = self.getTC(self.currentEditor.textCursor()) self.setModified(self.editorList.currentItem().text(), \ self.currentEditor.toPlainText(), f"Insert template: {key}", old_cursor) if "goto" in rawDict: if rawDict["goto"] == "home": self.gotoLine(1) elif rawDict["goto"] == '' or rawDict["goto"] == "current": pass elif rawDict["goto"] == "end": self.gotoLine(-1, eol=True) elif rawDict["goto"] == "input" or rawDict["goto"] == "input1": line,ok = inp1("Line number","Input line number for goto\nCancel for current cursor position: ")() if ok and line != "": self.gotoLine(self.parseLine(line)) elif rawDict["goto"].startswith("relative:"): relativeMove = rawDict["goto"][len("relative:"):] relativeLine = self.parseLine(relativeMove) curLine = self.getLineNumberAtCursor() self.gotoLine(curLine + relativeLine) else: lineNumber = self.parseLine(rawDict["goto"]) if lineNumber != 0: self.gotoLine(lineNumber) self.currentEditor.insertPlainText(rawOutString) else: self.toast("No editor to insert template into","Error") def getTemplateString(self): """updates self.templateDictString from templates file, returns dict""" import os real_path = os.path.realpath(__file__) dir_path = os.path.dirname(real_path) template_file = real_path.replace(".FCMacro","_Templates.txt") bHasFile = os.path.exists(template_file) if not bHasFile: dictString = pg.GetString("TemplateDictString","{}") if dictString == "{}": #no parameter templateDict = { "button":{"label":"input", "name":"input","output":"name = QtWidgets.QPushButton('label')"}, "import QtGui, QtWidgets, QtCore":{"output":"from PySide import QtGui, QtWidgets, QtCore"} } else: templateDict = json.loads(dictString) #preserve existing templates from parameters pg.RemString("TemplateDictString") self.setTemplateString(templateDict) #make the file with default samples else: #file already exists with open(template_file, 'r') as infile: self.templateDictString = infile.read() templateDict = json.loads(self.templateDictString, strict=False) return templateDict def setTemplateString(self, new_dict): """saves to text file in json format""" formatted = json.dumps(new_dict,indent=0,separators=(','+chr(10),':'+chr(10))) formatted = formatted.replace('\\n',chr(10)) import os real_path = os.path.realpath(__file__) dir_path = os.path.dirname(real_path) template_file = real_path.replace(".FCMacro","_Templates.txt") with open(template_file, 'w') as outfile: outfile.write(formatted) #pg.SetString("TemplateDictString", dumped) def editTemplates(self): dlg = TemplateEditor(form=self) #dlg.exec() dlg.show() def makeSearchFromFindEdit(self): findTxt = self.findEdit.text() if not findTxt: self.toast("Nothing in Find edit","Error") return self.search(findTxt) def makeSearchFromSelection(self): self.onRefreshBtnClicked(True) if not self.currentEditor: self.toast("No current editor","Error") return tc = self.currentEditor.textCursor() findTxt = tc.selectedText() if not findTxt: self.toast("Nothing in selection","Error") return self.search(findTxt) def makeSearchFromImmediate(self): findTxt, ok = QtWidgets.QInputDialog.getText(mw, "Search source","Enter search query:") if ok: self.search(findTxt) def makewSearchFromFindEdit(self): findTxt = self.findEdit.text() if not findTxt: self.toast("Nothing in Find edit","Error") return self.wSearch(findTxt) def makewSearchFromSelection(self): self.onRefreshBtnClicked(True) if not self.currentEditor: self.toast("No current editor","Error") return tc = self.currentEditor.textCursor() findTxt = tc.selectedText() if not findTxt: self.toast("Nothing in selection","Error") return self.wSearch(findTxt) def makewSearchFromImmediate(self): findTxt, ok = QtWidgets.QInputDialog.getText(mw, "Search wiki","Enter search query:") if ok: self.wSearch(findTxt) def makeqSearchFromFindEdit(self): findTxt = self.findEdit.text() if not findTxt: self.toast("Nothing in Find edit","Error") return self.qSearch(findTxt) def makeqSearchFromSelection(self): self.onRefreshBtnClicked(True) if not self.currentEditor: self.toast("No current editor","Error") return tc = self.currentEditor.textCursor() findTxt = tc.selectedText() if not findTxt: self.toast("Nothing in selection","Error") return self.qSearch(findTxt) def makeqSearchFromImmediate(self): findTxt, ok = QtWidgets.QInputDialog.getText(mw, "Search Qt","Enter qSearch query:") if ok: self.qSearch(findTxt) def makeReferenceMenu(self, mod): def makeReference(name): return lambda: self.showHelp(name) if isinstance(mod, str): mod = __import__(mod.strip()) refMenu = QtWidgets.QMenu(mod.__name__) subMenus = [] attributeStrings = [att for att in dir(mod) if not "__" in att] attrActions = [] attrActions.append(QtGui.QAction(f"{mod.__name__}")) attrActions[-1].triggered.connect(makeReference(f"{mod.__name__}")) refMenu.addAction(attrActions[-1]) if not attributeStrings: self.showHelp(mod) ii = 0 for attr in attributeStrings: if ii % 50 == 0: subMenus.append(QtWidgets.QMenu(f"Start from -- {mod.__name__}.{attr}")) ii += 1 if not hasattr(mod, "__name__"): continue attrActions.append(QtGui.QAction(f"{mod.__name__}.{attr}")) attrActions[-1].triggered.connect(makeReference(f"{mod.__name__}.{attr}")) subMenus[-1].addAction(attrActions[-1]) ii += 1 for sub in subMenus: refMenu.addMenu(sub) if exec: refMenu.exec(QtCore.QPoint()) else: return refMenu def showHelp(self, name): if isinstance(name, str) and name[:3] == "Qt.": name = "PySide.QtCore." + name from contextlib import redirect_stdout import io f = io.StringIO() with redirect_stdout(f): print(f"help({name}):") help(f"{name}") #self.print(f.getvalue()) self.makeWindow(name, f.getvalue()) def dir(self, name): from PySide import QtCore, QtGui Qt = QtCore.Qt if isinstance(name, str) and name[:3] == "Qt.": name = getattr(Qt,name[3:]) elif isinstance(name,str): try: name = __import__(name.strip()) except ModuleNotFoundError as ex: pass text = f"dir({name}):" text += f"{dir(name)}" #self.print(f.getvalue()) title = f"dir({name})".replace("'","") self.makeWindow(name, text, title=title) def makeWindow(self, name, txt, title=""): """make a window to show some text""" dlg = QtWidgets.QDockWidget() dlg.setObjectName("Editor assistant dockwidget") edit = QtWidgets.QPlainTextEdit() edit.setPlainText(txt) layout = QtWidgets.QVBoxLayout() layout.addWidget(edit) dlg.setLayout(layout) # dlg.resize(800,600) dlg.setWindowTitle(f"help on {name}" if not title else title) # dlg.setAttribute(QtCore.Qt.WA_DeleteOnClose, True) # self.mdi.addSubWindow(dlg) dlg.show() def close(self): mw.findChild(QtWidgets.QMdiArea).setStyleSheet("QTabBar::tab:selected, QTabBar::tab:hover {background-color: QPalette.Base;}") self.mdi.subWindowActivated.disconnect(self.onSubWindowActivated) self.form.close() def onSnapMenuBtnClicked(self, arg1): qp = QtCore.QPoint() self.snapMenuBtnContextMenu(qp) def makeSnapsMenu(self): snapsMenu = QtWidgets.QMenu("Snaps") self.onRefreshBtnClicked(True) curName = self.editorList.currentItem().text() if self.editorList.count() else "" if not curName: self.toast("No current editor","Error") snaps = [snap for snap in reversed(self.snaps) if snap["name"] == curName] takeSnapshotAction = QtGui.QAction("Take snapshot", mw) takeSnapshotAction.triggered.connect(lambda: self.onTakeSnapBtnClicked(True)) snapsMenu.addAction(takeSnapshotAction) takeSnapshotAction.setEnabled(curName != "") restoreMenu = QtWidgets.QMenu("Restore last snap") restoreToCurrentEditorAction = QtGui.QAction("Restore to current editor", mw) restoreToCurrentEditorAction.triggered.connect(self.doRestoreToCurrentEditor) restoreToCurrentEditorAction.setEnabled(len(snaps) > 0) restoreMenu.addAction(restoreToCurrentEditorAction) restoreToClipboardAction = QtGui.QAction("Restore to clipboard", mw) restoreToClipboardAction.triggered.connect(self.doRestoreToClipboard) restoreToClipboardAction.setEnabled(len(snaps) > 0) restoreMenu.addAction(restoreToClipboardAction) restoreToTextDocumentAction = QtGui.QAction("Restore to new Text document", mw) restoreToTextDocumentAction.triggered.connect(self.doRestoreToTextDocument) restoreToTextDocumentAction.setEnabled(len(snaps) > 0) restoreMenu.addAction(restoreToTextDocumentAction) snapsMenu.addMenu(restoreMenu) if not len(self.getSnaps()): restoreMenu.setEnabled(False) def makeRestoreAnyLambda(name,reason,idx): return lambda: self.restoreAny(name,reason,idx) restoreAnys = self.getRestoreAnys() restoreAnysMenu = QtWidgets.QMenu("Restore Any") restoreAnyActions = [] restoreAnyLambdas = [makeRestoreAnyLambda(tup[0],tup[1],ii) for ii,tup in enumerate(restoreAnys)] for ii,tup in enumerate(restoreAnys): restoreAnyActions.append(QtGui.QAction(f"Restore {tup[0]}: {tup[1]}", mw)) restoreAnyActions[-1].triggered.connect(restoreAnyLambdas[ii]) restoreAnysMenu.addAction(restoreAnyActions[-1]) snapsMenu.addMenu(restoreAnysMenu) if not restoreAnys: restoreAnysMenu.setEnabled(False) saveMenu = QtWidgets.QMenu("Save") saveSnapshotAsAction = QtGui.QAction("Save snapshot as...", mw) saveSnapshotAsAction.triggered.connect(self.doSaveSnapshotAs) saveSnapshotAsAction.setEnabled(len(snaps) > 0) saveMenu.addAction(saveSnapshotAsAction) saveAllSnapshotAsAction = QtGui.QAction("Save all snaps to JSON file...", mw) saveAllSnapshotAsAction.triggered.connect(self.saveSnapsToJSON) saveAllSnapshotAsAction.setEnabled(len(snaps) > 0) saveMenu.addAction(saveAllSnapshotAsAction) snapsMenu.addMenu(saveMenu) if not len(self.getSnaps()): saveMenu.setEnabled(False) loadMenu = QtWidgets.QMenu("Load") loadSnapshotAction = QtGui.QAction("Load snapshots from JSON...", mw) loadSnapshotAction.triggered.connect(self.loadSnapsFromJSON) loadMenu.addAction(loadSnapshotAction) snapsMenu.addMenu(loadMenu) discardMenu = QtWidgets.QMenu("Discard") def makeDiscardSnapLambda(x): return lambda: self.discardSnap(x) discardAction = QtGui.QAction("Discard latest snap", mw) discardAction.setToolTip("Discards most recent snap for the current editor") discardAction.triggered.connect(self.discardSnap) discardAction.setEnabled(len(snaps) > 0) discardMenu.addAction(discardAction) discardAllAction = QtGui.QAction("Discard all snaps", mw) discardAllAction.setToolTip("Disards all snaps for all editors") discardAllAction.triggered.connect(self.discardAllSnaps) discardAllAction.setEnabled(len(snaps) > 0) discardMenu.addAction(discardAllAction) discardSnaps = self.getSnaps() discardSnapActions = [] discardSnapLambdas = [makeDiscardSnapLambda(ii) for ii,snap in enumerate(discardSnaps)] for ii,snap in enumerate(discardSnaps): discardSnapActions.append(QtGui.QAction(f"Discard {snap['reason']}", mw)) discardSnapActions[-1].triggered.connect(discardSnapLambdas[ii]) discardMenu.addAction(discardSnapActions[-1]) if not discardSnaps: discardMenu.setEnabled(False) snapsMenu.addMenu(discardMenu) def makeDiffLambda(x,y,xlab="",ylab=""): return lambda: self.showDiff(x,y,xlab,ylab) diffSnaps = self.getDiffSnaps(curName) diffSnapsMenu = QtWidgets.QMenu("Diff current editor") diffSnapActions = [] diffSnapLambdas = [makeDiffLambda(snap['name'],ii) for ii,snap in enumerate(diffSnaps)] for ii,snap in enumerate(diffSnaps): diffSnapActions.append(QtGui.QAction(f"Diff {snap['reason']}", mw)) diffSnapActions[-1].triggered.connect(diffSnapLambdas[ii]) diffSnapsMenu.addAction(diffSnapActions[-1]) for edName in self.editorDict.keys(): if edName == curName: continue diffSnapActions.append(QtGui.QAction(f"Diff {edName}", mw)) diffSnapLambdas.append(makeDiffLambda(self.getText(edName), self.getText(curName), curName, edName)) diffSnapActions[-1].triggered.connect(diffSnapLambdas[-1]) diffSnapsMenu.addAction(diffSnapActions[-1]) clipText = QtGui.QClipboard().text() diffSnapActions.append(QtGui.QAction(f"Diff clipboard text", mw)) diffSnapLambdas.append(makeDiffLambda(clipText, self.getText(curName),curName, "Clipboard text")) diffSnapActions[-1].triggered.connect(diffSnapLambdas[-1]) diffSnapsMenu.addAction(diffSnapActions[-1]) if not clipText: diffSnapActions[-1].setEnabled(False) snapsMenu.addMenu(diffSnapsMenu) if not diffSnapActions: diffSnapsMenu.setEnabled(False) def makeEditReasonLambda(name,reason,idx): return lambda: self.editReason(name,reason,idx) editReasons = self.getEditReasons(curName) editReasonsMenu = QtWidgets.QMenu("Edit reason") editReasonActions = [] editReasonLambdas = [makeEditReasonLambda(tup[0],tup[1],ii) for ii,tup in enumerate(editReasons)] for ii,tup in enumerate(editReasons): editReasonActions.append(QtGui.QAction(f"Edit reason {tup[0]}: {tup[1]}", mw)) editReasonActions[-1].triggered.connect(editReasonLambdas[ii]) editReasonsMenu.addAction(editReasonActions[-1]) snapsMenu.addMenu(editReasonsMenu) if not editReasons: editReasonsMenu.setEnabled(False) return snapsMenu def snapMenuBtnContextMenu(self, point): snapsMenu = self.makeSnapsMenu() snapsMenu.exec(self.snapMenuBtn.mapToGlobal(point)) def editReason(self, name, reason, idx): snap = self.snaps[idx] new_reason,ok = QtWidgets.QInputDialog.getText(mw,"Edit reason",f"Enter a new reason in place of:\n\ {reason}\n", text=reason) if not ok: return snap['reason'] = new_reason self.snaps[idx] = snap self.toast(f"snap of {name}:{reason} updated to {new_reason}","Information") return def getEditReasons(self,curName): """list of tuple(name, reason, idx)""" editReasons = [tuple([snap['name'],snap['reason'],ii]) for ii,snap in enumerate(self.snaps)] return editReasons def doRestoreToCurrentEditor(self): snaps = self.getSnaps() if not snaps: self.toast("No snaps to restore", "Error") return self.restoreAny(snaps[0]['name'], snaps[0]['reason'],0) def restoreAny(self, name, reason, idx): """restore any snap to current document""" snap = self.snaps[idx] curName = self.editorList.currentItem().text() if self.editorList.currentItem() else "" if not curName: self.toast("Invalid current editor","Error") return if curName != name: items = ["Oops, wrong document -- cancel",f"I confirm: overwrite {curName} with this snap"] item,ok = QtWidgets.QInputDialog.getItem(mw,f"Restore",f"You are about to restore:{name}: {reason} to a different document: {curName}.\n",items) if not bool (ok and item == items[1]): return old_text = self.getText(curName) old_cursor = self.currentEditor.textCursor() self.currentEditor.setPlainText(snap["old_text"]) self.setTextCursor(self.editorList.currentItem().text(), snap['tc']) self.setModified(curName, old_text, f"Restore {snap['reason']}", self.getTC(old_cursor)) self.toast(f"snap of {name}:{reason} updated to {curName}: {snap['reason']}","Information") return def getRestoreAnys(self): """list of tuple(name, reason, idx)""" restoreAnys = [tuple([snap['name'],snap['reason'],ii]) for ii,snap in enumerate(self.snaps)] return restoreAnys def saveSnapsToJSON(self): """save all snaps to a JSON text file""" global setPathLatestDirectory if platform.node() == "mint": fname, filter = QtWidgets.QFileDialog.getSaveFileName(None, "Save all snaps to a JSON file", setPathLatestDirectory, "(*.json);; (*.*);; (*)")#PySide Mint filter = filter[filter.find("."):filter.find(")")] if filter[-2:] == ".*": filter = filter[:-2] fname = fname + filter else: fname, filter = QtWidgets.QFileDialog.getSaveFileName(None, "Save all snaps to a JSON file", setPathLatestDirectory, "json (*.json);; Any (*.*);; Any (*)") if not fname: return pathFile = os.path.dirname(fname) + "/" #1# = C:/Tmp/ setPathLatestDirectory = pathFile pg.SetString("setPathLatestDirectory",setPathLatestDirectory) with open(fname, "w") as outfile: json.dump(self.snaps, outfile) self.toast(f"All snaps saved to {outfile}", "Information") def loadSnapsFromJSON(self): """load previously saved snaps from a JSON file""" global setPathLatestDirectory if platform.node() == "mint": fname, filter = QtWidgets.QFileDialog.getOpenFileName(None, "Open a JSON file", setPathLatestDirectory, " (*.*);; (*)")#PySide Mint else: fname, filter = QtWidgets.QFileDialog.getOpenFileName(None, "Open a JSON file", setPathLatestDirectory, "Any (*.*);; Any (*)") if not fname: return pathFile = os.path.dirname(fname) + "/" #1# = C:/Tmp/ setPathLatestDirectory = pathFile pg.SetString("setPathLatestDirectory",setPathLatestDirectory) try: f = open(fname) except Exception as ex: self.toast(f"{ex}","Error") return try: self.snaps = json.load(f) except Exception as ex: self.toast(f"{ex}","Error") f.close() return self.updateSnapBtns() self.toast(f"Snaps loaded and restored from {fname}","Message") def getDiffSnaps(self, name): self.onRefreshBtnClicked(True) curName = name snaps = [snap for snap in reversed(self.snaps) if snap["name"] == curName] return snaps def showDiff(self, name, idx, firstLabel = "", secondLabel = ""): """make a diff of the snap and the text in the current editor""" if isinstance(idx, int): snaps = self.getDiffSnaps(name) plainText = self.getText(name).splitlines() plainLabel = name snapText = snaps[idx]['old_text'].splitlines() snapLabel = snaps[idx]['reason'] else: #presume to be strings passed in to be diffed snapText = name.splitlines() plainText = idx.splitlines() plainLabel = firstLabel snapLabel = secondLabel d = difflib.HtmlDiff(tabsize=4) ds = DiffSaver(form=self, snapText=snapText, plainText=plainText, label2=plainLabel, label1=snapLabel) ds.setWindowFlag(QtCore.Qt.WindowMinimizeButtonHint, True) ds.setWindowFlag(QtCore.Qt.WindowMaximizeButtonHint, True) ds.resizeEvent = ds.onResize self.mdi.addSubWindow(ds) layout = QtWidgets.QVBoxLayout() ds.setLayout(layout) ds.setWindowIcon(QIconFromXPMString(__icon__)) try: from PySide import QtWebEngineWidgets as Web ds.webView = Web.QWebEngineView() except: ds.webView = QtWidgets.QTextBrowser() #ds.webView.setHtml(ds.diff) saveBtn = QtWidgets.QPushButton("Save to html...") saveBtn.clicked.connect(ds.saveDiffToHtml) sliderLayout=QtWidgets.QHBoxLayout() sliderLayout.addWidget(saveBtn) ds.numlinesSpinBox = QtWidgets.QSpinBox() ds.numlinesSpinBox.setValue(5) ds.contextCheckBox = QtWidgets.QCheckBox() ds.contextCheckBox.setCheckState(QtCore.Qt.Checked) sliderLayout.addWidget(QtWidgets.QLabel("Context:")) sliderLayout.addWidget(ds.contextCheckBox) sliderLayout.addWidget(QtWidgets.QLabel("Context lines:")) sliderLayout.addWidget(ds.numlinesSpinBox) ds.contextCheckBox.stateChanged.connect(ds.onContextCheckBoxStateChanged) ds.numlinesSpinBox.valueChanged.connect(ds.onNumlinesSpinBoxValueChanged) sliderLayout.addWidget(QtWidgets.QLabel("Zoom:")) ds.slider = QtWidgets.QSlider(QtCore.Qt.Horizontal) ds.slider.setRange(25, 500) ds.slider.valueChanged.connect(ds.onSliderValueChanged) ds.slider.setMinimum(25) ds.slider.setMaximum(500) ds.slider.setTickPosition(QtWidgets.QSlider.TicksBelow) ds.slider.setTickInterval(25) ds.slider.setValue(100) sliderLayout.addWidget(ds.slider) sliderLayout.addWidget(QtWidgets.QLabel("Col width:")) ds.widthSlider = QtWidgets.QSlider(QtCore.Qt.Horizontal) ds.widthSlider.setRange(25, 2000) ds.widthSlider.valueChanged.connect(ds.onWidthSliderValueChanged) ds.widthSlider.setMinimum(25) ds.widthSlider.setMaximum(2000) ds.widthSlider.setTickPosition(QtWidgets.QSlider.TicksBelow) ds.widthSlider.setTickInterval(25) ds.widthSlider.setValue(500) sliderLayout.addWidget(ds.widthSlider) layout.addLayout(sliderLayout) layout.addWidget(ds.webView) ds.show() ds.resize(640,480) self.onRefreshBtnClicked(True) #self.toast(f"make diff of snap = {idx}","Message") def doSaveSnapshotAs(self): global setPathLatestDirectory self.onRefreshBtnClicked(True) curName = self.editorList.currentItem().text() snaps = [snap for snap in reversed(self.snaps) if snap["name"] == curName] if not snaps: self.toast("No saved snapshot to save as","Error") self.updateSnapBtns() return else: if platform.node() == "mint": fname, filter = QtWidgets.QFileDialog.getSaveFileName(None, "Save snapshot to text file", setPathLatestDirectory, " (*.FCMacro);; (*.py);; (*.txt);; (*.*);; (*)")#PySide Mint filter = filter[filter.find("."):filter.find(")")] if filter[-2:] == ".*": filter = filter[:-2] fname = fname + filter else: fname, filter = QtWidgets.QFileDialog.getSaveFileName(None, "Save snapshot to text file", setPathLatestDirectory, "Macro (*.FCMacro *.py);;Text file (*.txt);;Any (*.*);;Any (*)") if not fname: return pathFile = os.path.dirname(fname) + "/" #1# = C:/Tmp/ setPathLatestDirectory = pathFile pg.SetString("setPathLatestDirectory",setPathLatestDirectory) with open(fname,"w") as outfile: outfile.write(snaps[0]['old_text']) self.toast(f"Snapshot: {snaps[0]['reason']} saved to {fname}","Message") def doRestoreToClipboard(self): self.onRefreshBtnClicked(True) curName = self.editorList.currentItem().text() snaps = [snap for snap in reversed(self.snaps) if snap["name"] == curName] if not snaps: self.toast("No saved snapshot to send to clipboard","Error") self.updateSnapBtns() return else: clipboard = QtGui.QClipboard() clipboard.setText(snaps[0]["old_text"]) self.toast(f"Snapshot: {snaps[0]['reason']} sent to clipboard","Message") def doRestoreToTextDocument(self): self.onRefreshBtnClicked(True) curName = self.editorList.currentItem().text() snaps = [snap for snap in reversed(self.snaps) if snap["name"] == curName] if not snaps: self.toast("No saved snapshot to restore to text document","Error") self.updateSnapBtns() return else: doc = FreeCAD.ActiveDocument if FreeCAD.ActiveDocument else FreeCAD.newDocument() textDoc = doc.addObject("App::TextDocument","Text document") textDoc.Text = snaps[0]['old_text'] self.toast(f"Snapshot: {snaps[0]['reason']} sent to {textDoc.Name}","Message") textDoc.ViewObject.doubleClicked() doc.recompute() def onUndoBtnClicked(self, arg1): self.onRefreshBtnClicked(True) self.updateUndoBtn() curName = self.editorList.currentItem().text() curCursor = self.editorDict[curName].textCursor() for queue in reversed(self.undoQueue): if curName == queue["name"]: redo = {"name":curName, "reason":queue["reason"], "old_text":self.getText(curName), "tc":self.getTC(curCursor)} self.currentEditor.setPlainText(queue["old_text"]) self.setTextCursor(curName, queue['tc']) self.redoQueue.append(redo) self.undoQueue.pop() self.updateUndoBtn() break def onUndoClearBtnClicked(self, arg1): count = len(self.undoQueue) + len(self.redoQueue) self.undoQueue = [] self.redoQueue = [] self.updateUndoBtn() self.toast(f"Undo/redo queues purged ({count} items)","Message") def onRedoBtnClicked(self, arg1): self.onRefreshBtnClicked(True) self.updateUndoBtn() curName = self.editorList.currentItem().text() for queue in reversed(self.redoQueue): if curName == queue["name"]: undo = {"name":curName, "reason":queue["reason"], "old_text":self.getText(curName), "tc":self.getTC(self.currentEditor.textCursor())} self.currentEditor.setPlainText(queue["old_text"]) self.setTextCursor(curName, queue['tc']) self.undoQueue.append(undo) self.redoQueue.pop() self.updateUndoBtn() break def updateUndoBtn(self): self.undoBtn.setText("") if not self.editorList.currentItem(): return curName = self.editorList.currentItem().text() self.undoBtn.setEnabled(False) for queue in reversed(self.undoQueue): if curName == queue["name"]: self.undoBtn.setText(f"Undo {queue['reason']}") self.undoBtn.setEnabled(True) break self.redoBtn.setText("") self.redoBtn.setEnabled(False) for queue in reversed(self.redoQueue): if curName == queue["name"]: self.redoBtn.setText(f"Redo {queue['reason']}") self.redoBtn.setEnabled(True) break self.undoClearBtn.setEnabled(len(self.undoQueue)+len(self.redoQueue)) def onFindBackBtnClicked(self, arg1): self.onRefreshBtnClicked(True) if shiboken and not shiboken.isValid(self.currentEditor) or not self.currentEditor: self.toast("current editor is invalid","Error") return self.currentEditor.setFocus() name = self.editorList.currentItem().text() txt = self.findEdit.text() modifiers = QtWidgets.QApplication.keyboardModifiers() if modifiers == QtCore.Qt.AltModifier: selText = self.currentEditor.textCursor().selectedText() self.findEdit.setText(selText if selText else txt) txt = self.findEdit.text() elif modifiers == QtCore.Qt.ControlModifier: self.gotoLine(-1, silent=True, eol=True) self.found = False self.find(name, txt, True) if not self.found: if self.loopCheckBox.isChecked(): self.toast(f"{txt} not found in {name} --Looping back to end","Warning") self.gotoLine(-1, silent=True, eol=True) else: self.toast(f"{txt} not found backwards in {name}","Message") self.on_ComboBox_Find_Clicked(txt) self.highlight(txt) def setModified(self, name, old_text, reason, tc): self.undoQueue.append({"name":name, "old_text": old_text, "reason":reason, "tc":tc}) if len(self.undoQueue) > UNDO_QUEUE_MAX_SIZE: self.toast(f"undo queue reached max size {UNDO_QUEUE_MAX_SIZE}\ndiscarding {self.undoQueue[0]['reason']}","Warning") self.undoQueue.pop(0) self.updateUndoBtn() self.currentEditor.document().setModified(True) self.currentEditor.centerCursor() def onIndentBtnClicked(self, arg1): self.onRefreshBtnClicked(True) if shiboken and not shiboken.isValid(self.currentEditor) or not self.currentEditor: self.toast("current editor is invalid", "Error") return self.currentEditor.setFocus() old_text = self.getText() tc = self.currentEditor.textCursor() txt = tc.selectedText() if not txt: self.toast("nothing selected to indent") return lines = txt.splitlines() if len(self.ComboBox_Indent_Memo.currentText()) == 0: self.Indent_Memo = "" else: self.Indent_Memo = self.ComboBox_Indent_Memo.currentText() self.on_ComboBox_Indent_Memo_Clicked(self.Indent_Memo) if self.Indent_Memo == "": lines2 = [' ' + line for line in lines] else: lines2 = [self.Indent_Memo + line for line in lines] joined = '\u2029'.join(lines2) tc.insertText(joined) self.setModified(self.editorList.currentItem().text(), old_text, "Indent >>", self.getTC(tc)) tc.movePosition(QtGui.QTextCursor.Up, QtGui.QTextCursor.KeepAnchor, len(lines2)-1) tc.movePosition(QtGui.QTextCursor.StartOfLine, QtGui.QTextCursor.KeepAnchor) self.currentEditor.setTextCursor(tc) def on_ComboBox_Indent_Memo_Changed_Clicked(self, text): # change indentBtn icon self.Indent_Memo = "" if text == "": self.indentBtn.setIcon(QIconFromXPMString(indent_icon)) else: self.indentBtn.setIcon(QIconFromXPMString(indent_Memo_icon)) def on_ComboBox_Indent_Memo_Clicked(self, text): global duplicate_Indent_Memo global duplicate_Find if text not in duplicate_Indent_Memo: duplicate_Indent_Memo.append(text) duplicate_Indent_Memo = sorted(list(set(duplicate_Indent_Memo))) # sort duplicate duplicate_Find.append(text) duplicate_Find = sorted(list(set(duplicate_Find))) # sort duplicate self.ComboBox_Indent_Memo.setCurrentText(text) self.ComboBox_Find.addItem(text) self.ComboBox_Find.setCurrentText(text) self.findEdit.setText(text) self.Indent_Memo = self.ComboBox_Indent_Memo.currentText() def onIndentBackBtnClicked(self, arg1): self.onRefreshBtnClicked(True) if shiboken and not shiboken.isValid(self.currentEditor) or not self.currentEditor: self.toast("current editor is invalid", "Error") return self.currentEditor.setFocus() old_text = self.getText() old_cursor = self.currentEditor.textCursor() name = self.editorList.currentItem().text() tc = self.currentEditor.textCursor() txt = tc.selectedText() if not txt: self.toast("nothing selected to unindent") return lines = txt.splitlines() hasLeading = True for line in lines: if not line[:4] == ' ': hasLeading = False if not hasLeading: self.toast("Editor assistant: Cannot unindent selected block","Error") return lines2 = [line[4:] for line in lines] joined = '\u2029'.join(lines2) tc.insertText(joined) self.setModified(self.editorList.currentItem().text(), old_text, "<< Unindent", self.getTC(old_cursor)) tc.movePosition(QtGui.QTextCursor.Up, QtGui.QTextCursor.KeepAnchor, len(lines2)-1) tc.movePosition(QtGui.QTextCursor.StartOfLine, QtGui.QTextCursor.KeepAnchor) self.currentEditor.setTextCursor(tc) def onReplaceAllBtnClicked(self, arg1): self.onRefreshBtnClicked(True) if shiboken and not shiboken.isValid(self.currentEditor) or not self.currentEditor: self.toast("current editor is invalid", "Error") return self.currentEditor.setFocus() name = self.editorList.currentItem().text() txt = self.findEdit.text() newTxt = self.replaceEdit.text() self.on_ComboBox_Replace_Clicked(newTxt) self.replace(name, txt, newTxt) def onReplaceBtnClicked(self, arg1): self.onRefreshBtnClicked(True) if shiboken and not shiboken.isValid(self.currentEditor) or not self.currentEditor: self.toast("current editor is invalid", "Error") return self.currentEditor.setFocus() document = self.currentEditor.document() name = self.editorList.currentItem().text() text_cursor = self.currentEditor.textCursor() txt = self.getText(name) start = text_cursor.selectionStart() end = text_cursor.selectionEnd() if start == end: self.toast("Nothing selected, press Find and try again") return txt1 = txt[:start] txt2 = txt[end:] newtxt = self.replaceEdit.text() self.on_ComboBox_Replace_Clicked(newtxt) newText = txt1 + newtxt + txt2 self.setText(name,newText,f"replace {txt[start:end]}") text_cursor.setPosition(end) self.currentEditor.setTextCursor(text_cursor) self.onFindBtnClicked(True) def on_ComboBox_Replace_Clicked(self, text): global duplicate_Replace if text not in duplicate_Replace: duplicate_Replace.append(text) duplicate_Replace = sorted(list(set(duplicate_Replace))) # sort self.ComboBox_replace.addItem(text) self.ComboBox_replace.setCurrentText(text) self.replaceEdit.setText(text) def on_Reverse_FindReplaceCB_Clicked(self): txtf = self.findEdit.text() txtr = self.replaceEdit.text() self.replaceEdit.setText(txtf) self.on_ComboBox_Replace_Clicked(txtf) self.findEdit.setText(txtr) self.on_ComboBox_Find_Clicked(txtr) def onRefreshBtnClicked(self, arg1): self.getEditors() self.toast(f"Refreshed","Information",1000,priority="low",log=False) self.editorDict = {} for zz in zip(self.editors, self.parents, self.grandparents): self.editorDict [zz[2].windowTitle()] = zz[0] self.populateList() self.setCurrentEditor() def onGotoHomeBtnClicked(self, arg1): self.gotoLine(1) def onGotoEndBtnClicked(self, arg1): self.gotoLine(-1, eol=True) def gotoLineActionTriggered(self): line = self.getFirstLine() self.gotoLine(line) def parseLine(self, line_as_string): try: parsed = int(line_as_string) return parsed except ValueError as ve: self.print(f"{ve}","Error") return 0 def getFirstLine(self): """gets first line in the Goto line edit""" if not self.gotoLineEdit.text(): return 0 else: lines = self.gotoLineEdit.text().split(',') if lines: return self.parseLine(lines[0]) else: self.toast("Unable to parse lines","Error") return 0 def getGotoLines(self): if not self.gotoLineEdit.text(): return [] lines = self.gotoLineEdit.text().split(',') parsed = [self.parseLine(line) for line in lines if self.parseLine(line)] return parsed def onGotoLineEditTextChanged(self, arg1): """save the goto line edit text for each editor""" name = self.editorList.currentItem().text() if self.editorList.currentItem() else "" if not name: return self.gotoLineDict[name] = arg1 def makeGotoMenu(self): gotoMenu = QtWidgets.QMenu("Goto") self.onRefreshBtnClicked(True) curName = self.editorList.currentItem().text() if self.editorList.count() else "" if not curName: self.toast("No current editor","Error") lineNumsMenu = QtWidgets.QMenu("Line numbers") lineNums = self.getGotoLines() def makeLambda(x): return lambda: self.gotoLine(x) gotoLineLambdas = [makeLambda(lineNum) for lineNum in lineNums] gotoLineActions = [] for ii,lineNum in enumerate(lineNums): gotoLineActions.append(QtGui.QAction(f"Go to line {lineNum}", mw)) gotoLineActions[-1].triggered.connect(gotoLineLambdas[ii]) gotoLineActions[-1].setEnabled(len(self.gotoLineEdit.text()) > 0) lineNumsMenu.addAction(gotoLineActions[-1]) gotoMenu.addMenu(lineNumsMenu) if not gotoLineLambdas: lineNumsMenu.setEnabled(False) #classDefLines = (class name, def/class text, line number) classDefLinesMenu = QtWidgets.QMenu("Class/Def lines") classDefLines = sorted(self.getClassDefLines()) classDefLineActions = [] classDefSubmenus = [] classDefLineLambdas = [makeLambda(cl[2]) for cl in classDefLines] for ii,classDefLine in enumerate(classDefLines): if ii % 25 == 0: classDefSubmenus.append(QtWidgets.QMenu(f"Start from -- {classDefLine[2]}")) if "class" in classDefLine[1]: classDefLineActions.append(QtGui.QAction(f"{classDefLine[2]}..{classDefLine[1]}", mw)) else: #def line classDefLineActions.append(QtGui.QAction(f"{classDefLine[2]}..({classDefLine[0]}) {classDefLine[1]}", mw)) classDefLineActions[-1].triggered.connect(classDefLineLambdas[ii]) classDefSubmenus[-1].addAction(classDefLineActions[-1]) for sub in classDefSubmenus: classDefLinesMenu.addMenu(sub) gotoMenu.addMenu(classDefLinesMenu) if not classDefLineLambdas: classDefLinesMenu.setEnabled(False) bookmarks = sorted(self.getBookmarks()) bookmarksMenu = QtWidgets.QMenu("Bookmarks") toggleBookmarkAction = QtGui.QAction("Toggle Bookmark current line", mw) toggleBookmarkAction.triggered.connect(self.toggleBookmark) toggleBookmarkAction.setEnabled(curName != "") bookmarksMenu.addAction(toggleBookmarkAction) removeAllBookmarksAction = QtGui.QAction("Remove all bookmarks", mw) removeAllBookmarksAction.triggered.connect(self.removeAllBookmarks) removeAllBookmarksAction.setEnabled(bool(bookmarks)) bookmarksMenu.addAction(removeAllBookmarksAction) nextBookmarkAction = QtGui.QAction("Goto next bookmark", mw) nextBookmarkAction.triggered.connect(self.nextBookmark) nextBookmarkAction.setEnabled(bool(bookmarks)) bookmarksMenu.addAction(nextBookmarkAction) previousBookmarkAction = QtGui.QAction("Goto previous bookmark", mw) previousBookmarkAction.triggered.connect(self.previousBookmark) previousBookmarkAction.setEnabled(bool(bookmarks)) bookmarksMenu.addAction(previousBookmarkAction) bookmarksMenu.addSeparator() bookmarkActions = [] bookmarkLambdas = [makeLambda(bm[1]) for bm in bookmarks] for ii,bm in enumerate(bookmarks): bookmarkActions.append(QtGui.QAction(f"{bm[0]} ({bm[1]})", mw)) bookmarkActions[-1].triggered.connect(bookmarkLambdas[ii]) bookmarksMenu.addAction(bookmarkActions[-1]) gotoMenu.addMenu(bookmarksMenu) findResults = sorted(self.getFindResults()) findResultsMenu = QtWidgets.QMenu("Find results") findResultsSubmenus = [] findResultActions = [] findResultLambdas = [makeLambda(fr[0]) for fr in findResults] for ii,fr in enumerate(findResults): if ii % 25 == 0: findResultsSubmenus.append(QtWidgets.QMenu(f"Start from -- {fr[0]}")) findResultActions.append(QtGui.QAction(f"{fr[0]}..{fr[1]}{fr[2]}{fr[3]}..", mw)) findResultActions[-1].triggered.connect(findResultLambdas[ii]) findResultsSubmenus[-1].addAction(findResultActions[-1]) for sub in findResultsSubmenus: findResultsMenu.addMenu(sub) gotoMenu.addMenu(findResultsMenu) if not findResults: findResultsMenu.setEnabled(False) else: if self.matchWholeCheckBox.isChecked(): self.toast("Whole words checkbox ignored in Find results menu","Warning") findSelResults = sorted(self.getFindResults(useSelection=True)) findSelResultsMenu = QtWidgets.QMenu("Find selection results") findSelResultsSubmenus = [] findSelResultActions = [] findSelResultLambdas = [makeLambda(fsr[0]) for fsr in findSelResults] for ii,fsr in enumerate(findSelResults): if ii % 25 == 0: findSelResultsSubmenus.append(QtWidgets.QMenu(f"Start from --{fsr[0]}")) findSelResultActions.append(QtGui.QAction(f"{fsr[0]}..{fsr[1]}{fsr[2]}{fsr[3]}..", mw)) findSelResultActions[-1].triggered.connect(findSelResultLambdas[ii]) findSelResultsSubmenus[-1].addAction(findSelResultActions[-1]) for sub in findSelResultsSubmenus: findSelResultsMenu.addMenu(sub) gotoMenu.addMenu(findSelResultsMenu) if not findSelResults: findSelResultsMenu.setEnabled(False) else: if self.matchWholeCheckBox.isChecked(): self.toast("Whole words checkbox ignored in Find selection results menu","Warning") gotoHomeAction = QtGui.QAction("Home", mw) gotoHomeAction.triggered.connect(lambda: self.onGotoHomeBtnClicked(True)) gotoHomeAction.setEnabled(curName != "") gotoMenu.addAction(gotoHomeAction) gotoEndAction = QtGui.QAction("End", mw) gotoEndAction.triggered.connect(lambda: self.onGotoEndBtnClicked(True)) gotoEndAction.setEnabled(curName != "") gotoMenu.addAction(gotoEndAction) return gotoMenu def onGotoMenuBtnClicked(self, arg1): gotoMenu = self.makeGotoMenu() gotoMenu.exec(self.gotoMenuBtn.mapToGlobal(QtCore.QPoint())) def removeAllBookmarks(self): if not self.currentEditor: return curName = self.editorList.currentItem().text() if self.editorList.currentItem() else "" if not curName: self.toast("No editor to remove bookmarks from","Error") return bookmarks = self.getBookmarks() self.setModified(curName, self.currentEditor.toPlainText(),\ "Remove all bookmarks", self.getTC(self.currentEditor.textCursor())) for bookmark in bookmarks: self.removeBookmark(bookmark, setModified=False) def removeBookmark(self, bookmark, setModified=True): """bookmark is a tuple (desc, line)""" curName = self.editorList.currentItem().text() if self.editorList.currentItem() else "" if not curName: self.toast("No current editor for bookmarking","Error") return lines = self.getLines() curLine = bookmark[1] idx = lines[curLine-1].index(BOOKMARK_MARKER) lines[curLine-1] = lines[curLine-1][:idx] plainText = '\n'.join(lines) if lines[-1] == '': plainText += "\n" if setModified: self.setModified(curName, self.currentEditor.toPlainText(),"toggle " + bookmark[0], self.getTC(self.currentEditor.textCursor())) self.currentEditor.setPlainText(plainText) self.gotoLine(curLine) def addBookmark(self, bookmark): """bookmark is a tuple (desc, line)""" curName = self.editorList.currentItem().text() if self.editorList.currentItem() else "" if not curName: self.toast("No current editor for bookmarking","Error") return lines = self.getLines() curLine = bookmark[1] recul = 1 while True: try: lines[curLine-recul] = lines[curLine-recul] + BOOKMARK_MARKER + bookmark[0] break except Exception: recul += 1 plainText = '\n'.join(lines) if lines[-1] == '': plainText += "\n" self.setModified(curName, self.currentEditor.toPlainText(),"toggle " + bookmark[0], self.getTC(self.currentEditor.textCursor())) self.currentEditor.setPlainText(plainText) self.gotoLine(curLine) def toggleBookmark(self): if not self.currentEditor: return bookmarks = self.getBookmarks() curLine = self.getLineNumberAtCursor() hasBookmark = False for bookmark in bookmarks: if curLine == bookmark[1]: hasBookmark = True self.removeBookmark(bookmark) return #no bookmark on curLine if we get here self.addBookmark(tuple([f"Bookmark line {curLine}", curLine])) def nextBookmark(self): curName = self.editorList.currentItem().text() if self.editorList.currentItem() else "" if not curName: self.toast("No current editor for bookmarking","Error") return curLine = self.getLineNumberAtCursor() bookmarks = self.getBookmarks() for bookmark in bookmarks: if bookmark[1] > curLine: self.gotoLine(bookmark[1]) return self.toast(f"No next bookmark found from {curLine}","Warning") def previousBookmark(self): curName = self.editorList.currentItem().text() if self.editorList.currentItem() else "" if not curName: self.toast("No current editor for bookmarking","Error") return curLine = self.getLineNumberAtCursor() bookmarks = reversed(self.getBookmarks()) for bookmark in bookmarks: if bookmark[1] < curLine: self.gotoLine(bookmark[1]) return self.toast(f"No previous bookmark found from {curLine}","Warning") def onGotoLineEditReturnPressed(self): lines = self.getGotoLines() if len(lines) == 1: self.gotoLine(lines[0]) else: self.onGotoMenuBtnClicked(True) def gotoLine(self,line,silent=False,eol=False): self.onRefreshBtnClicked(True) if shiboken and not shiboken.isValid(self.currentEditor): self.toast("No valid current editor","Error") return document = self.currentEditor.document() if line < 0: txt = self.getText() txt_lines = txt.splitlines() txt_len = len(txt_lines) line = txt_len + 1 + line text_block = document.findBlockByLineNumber(line-1) if not text_block.isValid(): self.toast(f"Cannot goto Line# {line} of {self.editorList.currentItem().text()}") return text_cursor = self.currentEditor.textCursor() text_cursor.setPosition(text_block.position()) if eol: text_cursor.movePosition(QtGui.QTextCursor.EndOfLine) self.currentEditor.setTextCursor(text_cursor) self.currentEditor.centerCursor() if not silent: self.toast(f"Goto Line #{line} of {self.editorList.currentItem().text()}","Message") def getLines(self,name=None): """get plain text as string list""" txt = self.getText(name) return txt.splitlines() def getTrimmedLines(self, name=None): """remove all leading whitespace""" lines = self.getLines(name) lines2 = [] for line in lines: lines2.append(line.strip()) return lines2 def getFindResults(self, useSelection=False): lines = self.getTrimmedLines() findResults = [] if shiboken and not shiboken.isValid(self.currentEditor): return [] selTxt = self.currentEditor.textCursor().selectedText() if self.currentEditor else "" find = self.findEdit.text() if not useSelection else selTxt description_range = 35 preContext = 10 if not find: return [] matchCase = self.matchCaseCheckBox.isChecked() if not matchCase: find = find.lower() for ii,line in enumerate(lines): if find in line or bool(not matchCase and find in line.lower()): idx = line.find(find) if matchCase else line.lower().find(find) preDesc = line[:idx]# what comes before the find text desc = line[idx:] if len(preDesc) > preContext: preDesc = preDesc[-preContext:] if len(desc) > description_range: desc = desc[:description_range] desc = line[idx:idx+description_range] findResults.append(tuple([ii+1, preDesc, find, desc[len(find):]])) return findResults def getBookmarks(self, trimmed=True): if trimmed: lines = self.getTrimmedLines() else: lines = self.getLines() bookmarks = [] for ii,line in enumerate(lines): if BOOKMARK_MARKER in line: descIdx = line.find(BOOKMARK_MARKER) + len(BOOKMARK_MARKER) desc = line[descIdx:].strip() if trimmed else line[descIdx:] if desc: bookmarks.append(tuple([desc, ii+1])) return bookmarks def getClassDefLines(self): """tuple(class name, class/def line, line number)""" lines = self.getTrimmedLines() classDefLines = [] curClass = "" prevClass = "" for ii,line in enumerate(lines): if "class " in line and ":" in line: prevClass = curClass idx = line.find("class ") pretext = line[:idx].replace(' ','').replace('#','') idx2 = line.find(":", idx) curClass = line[idx + len("class "):idx2] if not pretext else prevClass if "(" in curClass and ")" in curClass: idx3 = curClass.find("(") idx4 = curClass.find(")",idx3) if idx4 > idx3: curClass = curClass[:idx3] else: curClass = "" classDefLines.append(tuple([curClass, line[idx:idx2], ii+1])) elif "def " in line and ":" in line: idx = line.find("def ") idx2 = line.find(":", idx) classDefLines.append(tuple([curClass, line[idx:idx2], ii+1])) return classDefLines def dragToForum(self, item): """make it easier to drag/drop files to the forum""" macroDir = FreeCAD.getUserMacroDir(True) filename = item.text() if item else "" if not filename: return if "[*]" in filename: filename = filename[:filename.find("[*]")] path = os.path.join(macroDir, filename) dlg = QtWidgets.QFileDialog(mw) dlg.setAttribute(QtCore.Qt.WA_DeleteOnClose, True) dlg.setOption(QtWidgets.QFileDialog.DontUseNativeDialog) dlg.setWindowTitle("Drag file to forum") dlg.setFileMode(QtWidgets.QFileDialog.ExistingFile) dlg.setNameFilter(os.path.basename(path)) model = FileFilterProxyModel(path) dlg.setProxyModel(model) if os.path.exists(path): dlg.setDirectory(os.path.dirname(path)) dlg.selectFile(os.path.basename(path)) dlg.exec() def populateList(self): self.blockSignals = True current = None if shiboken and not shiboken.isValid(self.editorList): return if self.editorList.count() != 0: current = self.editorList.currentItem().text() if self.editorList.currentItem() else "" self.editorList.clear() for k in sorted(self.editorDict.keys()): # line original self.editorList.addItem(k) # commented for display icon : .py, .FCMacro, .txt file if (k[-8:].upper() == ".FCMACRO") or (k[-11:].upper() == ".FCMACRO[*]") or (".FCMACRO[*] -" in k.upper()): iconItem = pythonFC_icon # Icon FreeCAD (.FCMacro) elif (k[-3:].upper() == ".PY") or (k[-6:].upper() == ".PY[*]") or (".PY[*] -" in k.upper()): iconItem = pythonPY_icon # Icon Python (.py) else: iconItem = file_Txt_icon # Icon file_Txt() or other self.editorList.addItem(QtWidgets.QListWidgetItem(QtGui.QIcon(QIconFromXPMString(iconItem)),k)) if current and current in self.editorDict: items = self.editorList.findItems(current, QtCore.Qt.MatchExactly) self.editorList.setCurrentItem(items[0] if items else self.editorList.item(0)) pass else: self.editorList.setCurrentRow(0) self.setCurrentEditor() self.blockSignals = False def print(self,message,type="Message"): if type == "Message" or type == "Information": FreeCAD.Console.PrintMessage(message+"\n") elif type == "Error": FreeCAD.Console.PrintError(message+"\n") elif type == "Warning": FreeCAD.Console.PrintWarning(message+"\n") def getStandardButtons(self): return int(QtWidgets.QDialogButtonBox.Close) def reject(self): FreeCADGui.Control.closeDialog() if FreeCADGui.activeDocument(): FreeCADGui.activeDocument().resetEdit() class TemplateEditor(QtWidgets.QWidget): def __init__(self, parent=mw, form=None): super(TemplateEditor, self).__init__(parent, QtCore.Qt.Tool) self.form=form self.blockSignals = False self.setWindowTitle(f"Template editor v{__version__}") self.setAttribute(QtCore.Qt.WA_DeleteOnClose, True) self.layout = QtWidgets.QVBoxLayout() self.setLayout(self.layout) self.templateList = QtWidgets.QListWidget() self.templateList.currentItemChanged.connect(self.onTemplateListCurrentItemChanged) self.templateDict = {} filterLine = QtWidgets.QHBoxLayout() self.layout.addLayout(filterLine) self.useFilterCheckBox = QtWidgets.QCheckBox("Filter") self.useFilterCheckBox.setCheckState(QtCore.Qt.Checked) self.useFilterCheckBox.stateChanged.connect(self.onUseFilterCheckBoxStateChanged) filterLine.addWidget(self.useFilterCheckBox) self.filterEdit = QtWidgets.QLineEdit() filterLine.addWidget(self.filterEdit) self.filterEdit.setPlaceholderText("Filter text goes here") self.filterEdit.textChanged.connect(self.onFilterEditTextChanged) self.matchCaseCheckBox = QtWidgets.QCheckBox() self.matchCaseCheckBox.setIcon(QIconFromXPMString(match_case_icon)) self.matchCaseCheckBox.stateChanged.connect(self.onMatchCaseCheckBoxStateChanged) filterLine.addWidget(self.matchCaseCheckBox) topLine = QtWidgets.QHBoxLayout() topLine.addWidget(self.templateList) buttonBox = QtWidgets.QVBoxLayout() buttonBox.setAlignment(QtCore.Qt.AlignTop) topLine.addLayout(buttonBox) self.plusBtn = QtWidgets.QPushButton()#"+" self.plusBtn.setToolTip("Adding") self.plusBtn.setIcon(QIconFromXPMString(plus_Template_icon)) self.plusBtn.setMaximumWidth(MAX_ICONIZED_BUTTON_WIDTH) buttonBox.addWidget(self.plusBtn) self.plusBtn.clicked.connect(self.onPlusBtnClicked) self.minusBtn = QtWidgets.QPushButton()#"-" self.minusBtn.setToolTip("Delete") self.minusBtn.setIcon(QIconFromXPMString(moins_Template_icon)) self.minusBtn.setMaximumWidth(MAX_ICONIZED_BUTTON_WIDTH) buttonBox.addWidget(self.minusBtn) self.minusBtn.clicked.connect(self.onMinusBtnClicked) self.renameBtn = QtWidgets.QPushButton()#"Rename" self.renameBtn.setToolTip("Rename") self.renameBtn.setIcon(QIconFromXPMString(rename_Template_icon)) self.renameBtn.setMaximumWidth(MAX_ICONIZED_BUTTON_WIDTH) buttonBox.addWidget(self.renameBtn) self.renameBtn.clicked.connect(self.onRenameBtnClicked) editLine = QtWidgets.QHBoxLayout() self.edit = QtWidgets.QPlainTextEdit() editLine.addWidget(self.edit) bottomButtonBox = QtWidgets.QVBoxLayout() bottomButtonBox.setAlignment(QtCore.Qt.AlignTop) editLine.addLayout(bottomButtonBox) self.testBtn = QtWidgets.QPushButton()#"Test" self.testBtn.setToolTip("Test") self.testBtn.setIcon(QIconFromXPMString(test_Template_icon)) self.testBtn.setMaximumWidth(MAX_ICONIZED_BUTTON_WIDTH) self.testBtn.clicked.connect(self.onTestBtnClicked) bottomButtonBox.addWidget(self.testBtn) self.executeBtn = QtWidgets.QPushButton()#"Execute" self.executeBtn.setToolTip("Execute") self.executeBtn.setIcon(QIconFromXPMString(execute_Template_icon)) self.executeBtn.setMaximumWidth(MAX_ICONIZED_BUTTON_WIDTH) self.executeBtn.clicked.connect(self.onExecuteBtnClicked) bottomButtonBox.addWidget(self.executeBtn) self.executeToClipboardBtn = QtWidgets.QPushButton()#"Execute to\nclipboard" self.executeToClipboardBtn.setToolTip("Execute current template, but send text to clipboard") self.executeToClipboardBtn.setIcon(QIconFromXPMString(execute_Clipboard_Template_icon)) self.executeToClipboardBtn.setMaximumWidth(MAX_ICONIZED_BUTTON_WIDTH) self.executeToClipboardBtn.clicked.connect(self.onExecuteToClipboardBtnClicked) bottomButtonBox.addWidget(self.executeToClipboardBtn) self.helpBtn = QtWidgets.QPushButton()#"Help" self.helpBtn.setToolTip("Help") self.helpBtn.setIcon(QIconFromXPMString(File_Dialog_Info_View_icon)) self.helpBtn.setMaximumWidth(MAX_ICONIZED_BUTTON_WIDTH) self.helpBtn.clicked.connect(self.onHelpBtnClicked) bottomButtonBox.addWidget(self.helpBtn) self.applyBtn = QtWidgets.QPushButton()#"Apply" self.applyBtn.setToolTip("Apply changes, saves to templates file") self.applyBtn.setIcon(QIconFromXPMString(save_Template_icon)) self.applyBtn.setMaximumWidth(MAX_ICONIZED_BUTTON_WIDTH) self.applyBtn.clicked.connect(self.onApplyBtnClicked) self.acceptBtn = QtWidgets.QPushButton()#"Accept" self.acceptBtn.setToolTip("Accept and quit") self.acceptBtn.setIcon(QIconFromXPMString(accept_Template_icon)) self.acceptBtn.setMaximumWidth(MAX_ICONIZED_BUTTON_WIDTH) self.acceptBtn.clicked.connect(self.accept) self.rejectBtn = QtWidgets.QPushButton()#"Reject" self.rejectBtn.setToolTip("Reject and quit") self.rejectBtn.setIcon(QIconFromXPMString(reject_Template_icon)) self.rejectBtn.setMaximumWidth(MAX_ICONIZED_BUTTON_WIDTH) self.rejectBtn.clicked.connect(self.reject) self.layout.addLayout(topLine) self.layout.addLayout(editLine) dlgButtonBox = QtWidgets.QHBoxLayout() self.layout.addLayout(dlgButtonBox) self.layout.setAlignment(dlgButtonBox, QtCore.Qt.AlignBottom) self.layout.setAlignment(dlgButtonBox, QtCore.Qt.AlignCenter) dlgButtonBox.addWidget(self.applyBtn) dlgButtonBox.addWidget(self.acceptBtn) dlgButtonBox.addWidget(self.rejectBtn) self.resize(800,600) self.updateList() def onFilterEditTextChanged(self, arg1): self.updateList(fetch=False) def onMatchCaseCheckBoxStateChanged(self, arg1): self.updateList(fetch=False) def onUseFilterCheckBoxStateChanged(self, arg1): self.updateList(fetch=False) def updateList(self, fetch=True): self.templateList.clear() if fetch: self.templateDict = self.form.getTemplateString() self.blockSignals = True items=[] filter = self.filterEdit.text() for k,v in self.templateDict.items(): if self.useFilterCheckBox.isChecked(): if self.matchCaseCheckBox.isChecked(): if filter == "" or filter in k: items.append(k) else: if filter == "" or filter.lower() in k.lower(): items.append(k) else: items.append(k) self.templateList.addItems(sorted(items)) self.blockSignals = False if self.templateList.count(): self.templateList.setCurrentRow(0) def setCurrentByName(self, name): if self.templateList.count() == 0: return match = 0 for ii in range(self.templateList.count()): if self.templateList.item(ii).text() == name: match = ii break idx = self.templateList.setCurrentRow(match) def setCurrentByRow(self, row): if self.templateList.count() == 0: return if self.templateList.count() <= row: self.templateList.setCurrentRow(self.templateList.count()-1) else: self.templateList.setCurrentRow(row) def onExecuteToClipboardBtnClicked(self, arg1): """test current template""" curName = self.templateList.currentItem().text() if self.templateList.currentItem() else "" if not curName: return txt = self.edit.toPlainText() if not txt: return clipTxt = self.form.testTemplateItem(curName, txt) QtGui.QClipboard().setText(clipTxt) self.form.toast(f"{curName} to clipboard","Message") def onTestBtnClicked(self,arg1): """test current template""" curName = self.templateList.currentItem().text() if self.templateList.currentItem() else "" if not curName: return txt = self.edit.toPlainText() if not txt: return testTxt = "
" + self.form.testTemplateItem(curName, txt) + "
" QtWidgets.QMessageBox.information(self, f"{curName}", testTxt) def onExecuteBtnClicked(self, arg1): """execute current template""" curName = self.templateList.currentItem().text() if self.templateList.currentItem() else "" if not curName: return txt = self.edit.toPlainText() if not txt: return self.form.testTemplateItem(curName, txt, execute=True) def shallowCopy(self, fromDict): toDict = {} for k,v in fromDict.items(): toDict[k] = v return toDict def onPlusBtnClicked(self, arg1): """add a new template item""" curName = self.templateList.currentItem().text() if self.templateList.currentItem() else "" curDict = {} if curName: curDict = self.shallowCopy(self.templateDict[curName]) newTemplateName,ok = QtWidgets.QInputDialog.getText(self, "Add template","Enter name for new template:") if ok and newTemplateName: if newTemplateName in self.templateDict: self.form.print(f"{newTemplateName} already exists","Error") return if not curName: self.templateDict[newTemplateName] = {"label" : "input","name" : "input","output" : "name = QtGui.QPushButton('label') #QtWidgets.QPushButton('label') for PySide"} else: self.templateDict[newTemplateName] = curDict self.updateList(fetch=False) self.setCurrentByName(newTemplateName) def onMinusBtnClicked(self, arg1): curName = self.templateList.currentItem().text() if self.templateList.currentItem() else "" if not curName: return curRow = self.templateList.currentRow() self.templateDict.pop(curName) self.blockSignals = True self.updateList(fetch=False) self.blockSignals = False self.setCurrentByRow(curRow) if self.templateList.count() == 0: self.blockSignals = True self.templateList.addItem("template") self.edit.setPlainText("{}") self.templateDict = {"template":{"label":"input","name":"input","output":"name = QtGui.QPushButton('label') # QtWidgets.QPushButton('label') for PySide"}} self.blockSignals = False self.setCurrentByRow(0) def onHelpBtnClicked(self, arg1): helpText = """
Templates are a way to insert text into the current editor
at the current cursor position.  The templates are stored
in memory as a python dictionary of dictionaries.  In the
simplest case the text is copied directly into the editor,
but some text may also be replaced during execution.

The template item dictionary must contain a key named
"output".  This key contains the text to be inserted.
It can also hold some special values:

"input" -- user types in value for output in dialog.
"input1" -- like "input", but a single line edit.
"clipboard" -- output text comes from clipboard.
"selection" -- output text comes from current selection.
Any other value means use that value as the output text.

If "output" contains text matching the name of one of
the other keys, then that text gets replaced, depending
on the key's value:

'input' -- replacement text from multiple line QInputDialog
'input1' -- like input, but use single line dialog
'selection' -- taken from selection in current editor
'clipboard' -- replacement text is from the system clipboard
'find' -- replacement text is from the Find QLineEdit
'replace' -- replacement text is from the Replace QLineEdit
Any other value means use that value as the replacement text.

The "goto" key, if it exists, positions the cursor before the
text is inserted.  The "goto" key can have these values:

'input' (or 'input1') -- line is from single line QInputDialog
'home' -- position cursor at start of line 1
'end' -- position cursor at end of document
'current' or '' -- ignore and use current cursor position
'42' -- example, go to line 42 and insert output there
'relative:7' -- example, go 7 lines down from current
'relative:-3' -- example, go 3 lines up from current
""" QtWidgets.QMessageBox.information(self, "", helpText)#Help def onRenameBtnClicked(self, arg1): curName = self.templateList.currentItem().text() if self.templateList.currentItem() else "" if not curName: return newName,ok = QtWidgets.QInputDialog.getText(self, "Editor assisant", f"Enter new name for {curName}",text=curName) if ok: if newName in self.templateDict: self.form.toast(f"{newName} already in dictionary","Error") return self.templateDict[newName] = {} for k,v in self.templateDict[curName].items(): self.templateDict[newName][k] = v self.templateDict.pop(curName) self.blockSignals = True self.updateList(fetch=False) self.blockSignals = False self.setCurrentByName(newName) def updateParameters(self): """update parameter string""" self.form.setTemplateString(self.templateDict) def updateDict(self, name, templateItemText): templateItem = json.loads(templateItemText,strict=False) self.templateDict[name] = templateItem def onTemplateListCurrentItemChanged(self, current, previous): if not self.templateList.count(): return if self.blockSignals: return if previous: self.updateDict(previous.text(), self.edit.toPlainText()) if current: self.updateEdit(current.text()) def updateEdit(self, name): txt = self.formatTemplate(self.templateDict[name]) self.edit.setPlainText(txt) def formatTemplate(self,template): """formats a single dictionary template, returns formatted string""" formatted = json.dumps(template,indent=0,separators=(','+chr(10),':'+chr(10))) formatted = formatted.replace('\\n',chr(10)) return formatted def onApplyBtnClicked(self, arg1): self.updateDict(self.templateList.currentItem().text(),self.edit.toPlainText()) self.updateParameters() def accept(self): self.updateDict(self.templateList.currentItem().text(),self.edit.toPlainText()) self.updateParameters() self.close() def reject(self): self.close() class DiffSaver (QtWidgets.QDialog): def __init__(self, parent=mw, form=None, plainText=None, snapText=None, label1=None, label2=None): super(DiffSaver, self).__init__(parent, QtCore.Qt.Tool) self.form=form self.slider=None self.webView=None self.widthSlider=None self.contextCheckBox = None self.numlinesSpinBox = None self.plainText = plainText self.snapText = snapText self.label1 = label1 self.label2 = label2 self.diff = "" self.makeDiff() self.blockSignals = False def setMaxWidthString(self, width=None): if not self.webView: return colWidth = width if width else self.width()/2-70 MAXWIDTH=f"{colWidth}" #chr(123) = {, 125 = } width_string= f"" new_diff = self.diff.replace("",width_string) self.webView.setHtml(new_diff) def onContextCheckBoxStateChanged(self, arg1): self.makeDiff() self.setMaxWidthString() def onNumlinesSpinBoxValueChanged(self, val): self.makeDiff() self.setMaxWidthString() def makeDiff(self): """make the diff, expensive operation should only be done when necessary""" d = difflib.HtmlDiff(tabsize=4) numlines2 = 5 if not self.numlinesSpinBox else self.numlinesSpinBox.value() context2 = self.contextCheckBox.isChecked() if self.contextCheckBox else True self.diff = d.make_file(fromlines = self.snapText, tolines = self.plainText, fromdesc = self.label1, todesc = self.label2, context=context2, numlines=numlines2) def updateTitle(self): if self.widthSlider and self.slider: self.setWindowTitle(f"Ea v{__version__} Diff Saver zoom:{self.slider.value()}%; Col width: {self.widthSlider.value()}px") def onResize(self, event): if not self.widthSlider: return self.blockSignals = True width = self.width()/2-70 self.widthSlider.setValue(width) self.setColWidth(width) def onSliderValueChanged(self, value): if self.blockSignals: self.blockSignals = False return if hasattr(self.webView,"setZoomFactor"): self.webView.setZoomFactor(value/100.0) self.updateTitle() def saveDiffToHtml(self): global setPathLatestDirectory if platform.node() == "mint": fname, filter = PySide.QtWidgets.QFileDialog.getSaveFileName(None, "Save diff to html file", setPathLatestDirectory, "*.html")#PySide Mint filter = filter[filter.find("."):filter.find(")")] if filter[-2:] == ".*": filter = filter[:-2] fname = fname + filter else: fname, filter = PySide.QtWidgets.QFileDialog.getSaveFileName(None, "Save diff to html file", setPathLatestDirectory, "*.html") if not fname: return pathFile = os.path.dirname(fname) + "/" #1# = C:/Tmp/ setPathLatestDirectory = pathFile pg.SetString("setPathLatestDirectory",setPathLatestDirectory) with open(fname,"w") as outfile: outfile.write(self.diff) self.form.toast(f"Diff saved to {fname}","Message") def setColWidth(self, value): self.setMaxWidthString(value) self.updateTitle() def onWidthSliderValueChanged(self, value): self.setColWidth(value) def QIconFromXPMString(xpm_string): xpm = xpm_string.replace("\"","").replace(',','').splitlines()[4:-1] for line in reversed(xpm): if line.startswith("/*") and line.endswith("*/"): xpm.pop(xpm.index(line)) pixmap = QtGui.QPixmap(xpm) icon = QtGui.QIcon(pixmap) return icon def QIconFromStandard(name): ##self.xxxx.setIcon(QIconFromStandard("xxxx")) pixmap = getattr(QtWidgets.QStyle,name) icon = QtWidgets.QPushButton().style().standardIcon(pixmap) return icon def showEditorAssistantAsDockWidget(floating = False): dockWidget = mw.findChild(QtGui.QDockWidget,"Editor assistant dockwidget") if not dockWidget: dockWidget = QtWidgets.QDockWidget() dockWidget.setAttribute(QtCore.Qt.WA_DeleteOnClose, True) dockWidget.setWindowTitle(f"Editor assistant v{__version__}") dockWidget.setObjectName("Editor assistant dockwidget") edit = QtWidgets.QPlainTextEdit() edit.setPlainText("Plain Text") layout = QtWidgets.QVBoxLayout() layout.addWidget(edit) dockWidget.setLayout(layout) mw.addDockWidget(QtCore.Qt.LeftDockWidgetArea, dockWidget) dockWidget.setFloating(floating) dlg = TaskEditorAssistant() dockWidget.setWidget(dlg.form) modelView = mw.findChild(QtGui.QDockWidget,'Model') # taskspanel = mw.findChild(QtGui.QDockWidget,"Tasks") if dockWidget and modelView: # dock = mw.tabifyDockWidget(modelView, taskspanel) dock2 = mw.tabifyDockWidget(modelView, dockWidget) modelView.raise_() dockWidget.raise_() def showEditorAssistantDialog(): '''show the editor assistant dialog''' dlg = TaskEditorAssistant() #ori comboView = mw.findChild(QtGui.QDockWidget,"Combo View") comboView = mw.findChild(QtWidgets.QDockWidget,"Combo View") tabWidget = None if comboView: tabWidget = comboView.findChild(QtWidgets.QTabWidget) else: #no combo view, so show as a tabbed dock widget showEditorAssistantAsDockWidget(floating=False) return if tabWidget: tabWidget.addTab(dlg.form,f"Editor assistant v{__version__}") dlg.isTabbed = True tabWidget.setCurrentWidget(dlg.form) if not comboView.isVisible(): FreeCAD.Console.PrintWarning("Editor assistant: Making Combo View visible\n") FreeCAD.Console.PrintMessage("Tip: press Alt while executing to open as dockable widget\n") comboView.setVisible(True) elif not FreeCADGui.Control.activeDialog(): FreeCADGui.Control.showDialog(dlg.form) else: FreeCAD.Console.PrintError("Another task dialog is active. Showing as dockable widget instead.\n") showEditorAssistantAsDockWidget() __icon__=""" /* XPM */ static char *_647719150564[] = { /* columns rows colors chars-per-pixel */ "64 64 7 1 ", " c black", ". c #EDED1C1C2424", "X c #2222B1B14C4C", "o c #FFFFC9C90E0E", "O c #3F3F4848CCCC", "+ c #DFDFDFDFDFDF", "@ c None", /* pixels */ " @@@@@@@@@@@@@", " @@@@@@@@@@@@@", " @@@@@@@@@@@@", " @@@@@@@@@@@", " ++++++++++++++++++++++++++++++++++++++++++++ @@@@@@@@@@", " ++++++++++++++++++++++++++++++++++++++++++++ @@@@@@@@@", " ++++++++++++++++++++++++++++++++++++++++++++ @@@@@@@@", " ++++++++++++++++++++++++++++++++++++++++++++ + @@@@@@@", " ++++++++++++++++++++++++++++++++++++++++++++ ++ @@@@@@", " ++++++++++++++++++++++++++++++++++++++++++++ +++ @@@@@", " ++++++++++++++++++++++++++++++++++++++++++++ ++++ @@@@", " ++++++++++++++++++++++++++++++++++++++++++++ +++++ @@@", " ++++++++++++++++++++++++++++++++++++++++++++ ++++++ @@", " ++++++++++++++++++++++++++++++++++++++++++++ +++++++ @", " ++++++++++++++++++++++++++++++++++++++++++++ ++++++++ @", " +++++++OOOOOOOOOOOXXXXXXXXXX ++++++ ", " +++++++OOOOOOOOOOOXXXXXXXXXX ++++++ ", " +++++++OOOOOOOOOOOXXXXXXXXXX ++++++ ", " +++++++OOOOOOOOOOOXXXXXXXXXX ++++++++++++++++++ ", " +++++++OOOOOOOOOOOXXXXXXXXXX ++++++++++++++++++ ", " ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ", " ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ", " ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ", " ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ", " ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ", " ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ", " +++++++ooooo ............ XXXXX++++++++++ ", " +++++++ooooo ............ XXXXX++++++++++ ", " +++++++ooooo ............ XXXXX++++++++++ ", " +++++++ooooo ............ XXXXX++++++++++ ", " +++++++ooooo ............ XXXXX++++++++++ ", " ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ", " ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ", " ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ", " ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ", " ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ", " ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ", " +++++++ XXXXXXXXXXXXXXOOOOOXXXXXXXXX ++++++++++ ", " +++++++ XXXXXXXXXXXXXXOOOOOXXXXXXXXX ++++++++++ ", " +++++++ XXXXXXXXXXXXXXOOOOOXXXXXXXXX ++++++++++ ", " +++++++ XXXXXXXXXXXXXXOOOOOXXXXXXXXX ++++++++++ ", " +++++++ XXXXXXXXXXXXXXOOOOOXXXXXXXXX ++++++++++ ", " ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ", " ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ", " ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ", " ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ", " ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ", " ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ", " +++++++....... ooooooOOOOOOOOOOOOO++++++++++ ", " +++++++....... ooooooOOOOOOOOOOOOO++++++++++ ", " +++++++....... ooooooOOOOOOOOOOOOO++++++++++ ", " +++++++....... ooooooOOOOOOOOOOOOO++++++++++ ", " +++++++....... ooooooOOOOOOOOOOOOO++++++++++ ", " ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ", " ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ", " ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ", " ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ", " ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ", " ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ", " ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ", " ", " ", " ", " " };""" runSave_icon = """ /* XPM */ static char *runSave_icon_XPM[] = { /* columns rows colors chars-per-pixel */ "64 64 9 1", " c None", ". c #1A2A01", "+ c #2E6C9F", "@ c #3A76AA", "# c #3E84B7", "$ c #5BA900", "% c #84E033", "& c #FFD63E", "* c #FFDF58", " ", " ##############@@ ", " ##################@@@ ", " ################@#@@@@@ ", " ###############@@@##@@@@@ ", " ###################@@@@@@@@ ", " #### ###########@@@@@@@@@+ ", " #### #########@@@@@@@@@@+ ", " #### ########@@@@@@@@@@++ ", " #### #######@@@@@@@@@@++++ ", " ##### ####@@@@#@@@@@@@@+++++ ... ", " ###########@#@##@@@@@@@@++++++ ..... ", " ##############@@@@@@@@@+++++++ ..$$$.. ", " ############@@@@@@@@@@+++++++..$%%%$.. ", " ############@@@@@@@@+++++++..$%%%%%$.. ", " @@@@@@+++++++..$%%%$%%%$.. ", " ##################@@@@@@+++++++..$%%%$$$%%%$.. ", " ################@@@@#@@@@@@@@+++++++..$%%%$$$$$%%%$.. ", " ################@###@@@@@@@@@+++++++..$%%%$$$$$$$%%%$.. ", " ####################@@@@@@@@@+++++++..$%%%$$$$$$$$$%%%$.. ", " ###################@@@@@@@@@@++++++..$%%%$$$$$$$$$$$%%$.. ", " ###################@@@@@@@@@@++++++..$%%%$$$$$$$$$$$%%$.. ", " #########.#########@@@@@@@@@@++++++..$%%%$$$$$$$$$$$%%$.. ", " ########...#####@@@#@@@@@@@@++++++..$%%%$$$$$$$$$$$%%$..** ", " #######.....##@#@##@@@@@@@@++++++..$%%%$$$$$$$$$$$%%$..*** ", " #######..$$$..####@@@@@@@@@++++++..$%%%$$$$$$$$$$$%%$..**** ", " ######..$%%%$..##@@@@@@@@@@+++++..$%%%$$$$$$$$$$$%%$..****** ", " #####..$%%%%%$..@@@@@@@@@@+++++..$%%%$$$$$$$$$$$%%$..******* ", " ####..$%%%$$%%$..@@@@@@@@+++++..$%%%$$$$$$$$$$$%%$..******** ", " ###..$%%%$$$$%%$..@@@@@@+++++..$%%%$$$$$$$$$$$%%$..********* ", " ##..$%%%$$$$$$%%$..@@@@+++++..$%%%$$$$$$$$$$$%%$..********&& ", " #..$%%%$$$$$$$$%%$.. ..$%%%$$$$$$$$$$$%%$..********&&& ", " ..$%%%$$$$$$$$$$%%$..*****..$%%%$$$$$$$$$$$%%$..********&&&& ", " ..$%%$$$$$$$$$$$$%%$..***..$%%%$$$$$$$$$$$%%$..*******&&&&&& ", " #..$%%$$$$$$$$$$$$%%$..*..$%%%$$$$$$$$$$$%%$..*******&&&&&&& ", " ##..$%%$$$$$$$$$$$$%%$...$%%%$$$$$$$$$$$%%$..******&&&&&&&&& ", " ###..$%%$$$$$$$$$$$$%%$.$%%%$$$$$$$$$$$%%$..******&&&&&&&&&& ", " ####..$%%$$$$$$$$$$$$%%$%%%$$$$$$$$$$$%%$..******&&&&&&&&&&& ", " ####..$%%$$$$$$$$$$$$%%%%$$$$$$$$$$$%%$..*****&&&&&&&&&&&&& ", " #####..$%%$$$$$$$$$$$$%%$$$$$$$$$$$%%$..*****&&&&&&&&&&&&& ", " ###@@..$%%$$$$$$$$$$$$$$$$$$$$$$$%%$..****&&&&&&&&&&&&&&& ", " ##@@@@..$%%$$$$$$$$$$$$$$$$$$$$$%%$..****&&&&&&&&&&&&&&&& ", " @@@@@@..$%%$$$$$$$$$$$$$$$$$$$%%$..****&&&&&&&&&&&&&&&& ", " #@@@@@@..$%%$$$$$$$$$$$$$$$$$%%$..***&&&&&&&&&&&&&&&&& ", " @@@@@@..$%%$$$$$$$$$$$$$$$%%$..***&&&&&&&&&&&&&&&&& ", " @@@@++..$%%$$$$$$$$$$$$$%%$..**&&&&&&&&&&&&&&&&&& ", " ..$%%$$$$$$$$$$$%%$.. ", " ..$%%$$$$$$$$$%%$.. ", " ..$%%$$$$$$$%%$..*&&&&&&&&&& ", " *..$%%$$$$$%%$..*&&&&&&&&&&&& ", " **..$%%$$$%%$..&&&&&&&&&&&&&&& ", " ***..$%%$%%$..&&&&&&&&&&&&&&&& ", " ****..$%%%$..&&&&&&&&& &&&&& ", " *****..$%$..&&&&&&&&& &&&& ", " ******.....&&&&&&&&&& &&&& ", " *******...&&&&&&&&&&& &&& ", " ******&.&&&&&&&&&&&&& &&&& ", " *****&&&&&&&&&&&&&&&&&&&&&& ", " *&&&&&&&&&&&&&&&&&&&&&&& ", " &&&&&&&&&&&&&&&&&&&&& ", " &&&&&&&&&&&&&&&&& ", " &&&&&&&&&&&&& ", " ", " "} """ undo_icon = """ /* XPM */ static char *edit_undo_XPM[] = { /* columns rows colors chars-per-pixel */ "64 64 7 1", " c None", ". c #FF8000", "+ c #FFFF80", "@ c #666666", "# c #FFFF00", "$ c #FF8080", "% c None", /* pixels */ " ", " ", " .. ", " ... ", " ..... ", " ...... ", " ...+... ", " ..++... ", " ...+++... ", " ...++++... ", " ...+++++... ", " ..++++++... ", " ...+++++++... ", " ....++++++++... ", " ...++++++++++... ", " ...+++++++++++.@. ", " ...++++++++++++........... ", " ...+++++++++++++.+++++++..... ", " ...++++++++++++++++++++++++++.... ", " ...+++++++++++++++++++#+++++++.... ", " ...++++++++++++++++++########+++++... ", " ...++++++++++++++++++##########+++++... ", " ...+++++++++++++++++##############++++... ", " ....++++++++++++++++################++++.. ", " ...+++++++++++++++####################+++... ", " ....++++++++++++++####################++++... ", " ....++++++++++++######################+++#... ", " ...+++++++++++#######################++##.. ", " ...+++++++++##########################++.. ", " ...+++++++#######++++++++############++.. ", " ...++++#########++++++++++++########++.. ", " ....+++########++....++++++########+++. ", " ..++++######++.. .....++++#######++... ", " ...++++#####++.. .....++++######++... ", " ...++++####++.. ...++++#####++... ", " ...+++####++.. ...+++#####++... ", " ...++++##++.. ..$+++###++... ", " ...++++#++.. ...+++###++... ", " ...++++++.. ..#++###++... ", " ...+++++.. ...++###++... ", " ..++++.. ..++###++... ", " %$.++#.$% % % ..+++##++.. ", " % %% %%$.##.$%%%%%%%% +.+++#+++. ", " %% %%% %%%....$%%%%%%%% %%.+++#+++. ", " %% %%%%%%%%%%%%....%%%%%%%%%%%.++##++.. ", " %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%.++#++#.. %% ", " %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%.++++++...%%% ", " %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%..++++...%%%%% ", " %%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%..+++++..%%%%% ", " %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%..++++++.%%%%%%%%%% %% ", " %%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%..++++++..%%%%%%%%%%%%% ", " %%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%...++++++..%%%%%%% %%%% ", " %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%..+++++++..%%%%%%%%% %% ", " %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%..++++++...%%%%%%%%% %% ", " %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%..+++++...%%%%%%%%%%%%%%% ", " %%%% %%%%%%%%%%%%%%%%%%%%%%%%..++++...%%%%%%%%% %%%%%% ", " %%%%%%%%%%%%%%%%%%%%%%%%.......%%%%%%%%%%%%%%% %% ", " %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % ", " %% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % ", " %% %%%%%%%%%%%%%%%%%%%%%%%%%%% %%% ", " %% %%%% %%%%%%%% %%% ", " %% %%%% %%%%%%%% %% ", " %% % ", " " };""" redo_icon = """ /* XPM */ static char *edit_redo_XPM[] = { /* format */ "64 64 7 1", " c None", ". c #FF8000", "+ c #FFFF80", "@ c #666666", "# c #FFFF00", "$ c #FF8080", "% c None", /* pixels */ " ", " ", " .. ", " ... ", " ..... ", " ...... ", " ...+... ", " ...++.. ", " ...+++... ", " ...++++... ", " ...+++++... ", " ...++++++.. ", " ...+++++++... ", " ...++++++++.... ", " ...++++++++++... ", " .@.+++++++++++... ", " ...........++++++++++++... ", " .....+++++++.+++++++++++++... ", " ....++++++++++++++++++++++++++... ", " ....+++++++#+++++++++++++++++++... ", " ...+++++########++++++++++++++++++... ", " ...+++++##########++++++++++++++++++... ", " ...++++##############+++++++++++++++++... ", " ..++++################++++++++++++++++.... ", " ...+++####################+++++++++++++++... ", " ...++++####################++++++++++++++.... ", " ...#+++######################++++++++++++.... ", " ..##++#######################+++++++++++... ", " ..++##########################+++++++++... ", " ..++############++++++++#######+++++++... ", " ..++########++++++++++++#########++++... ", " .+++########++++++....++########+++.... ", " ...++#######++++..... ..++######++++.. ", " ...++######++++..... ..++#####++++... ", " ...++#####++++... ..++####++++... ", " ...++#####+++... ..++####+++... ", " ...++###+++$.. ..++##++++... ", " ...++###+++... ..++#++++... ", " ...++###++#.. ..++++++... ", " ...++###++... ..+++++... ", " ...++###++.. ..++++.. ", " ..++##+++.. % % %$.#++.$% ", " .+++#+++.+ %%%%%%%%$.##.$%% %% % ", " .+++#+++.%% %%%%%%%%$....%%% %%% %% ", " ..++##++.%%%%%%%%%%%....%%%%%%%%%%%% %% ", " %% ..#++#++.%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% ", " %%%...++++++.%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% ", " %%%%%...++++..%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% ", " %%%%%..+++++..%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%% ", " %% %%%%%%%%%%.++++++..%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% ", " %%%%%%%%%%%%%..++++++..%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%% ", " %%%% %%%%%%%..++++++...%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%% ", " %% %%%%%%%%%..+++++++..%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% ", " %% %%%%%%%%%...++++++..%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% ", " %%%%%%%%%%%%%%%...+++++..%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% ", " %%%%%% %%%%%%%%%...++++..%%%%%%%%%%%%%%%%%%%%%%%% %%%% ", " %% %%%%%%%%%%%%%%%.......%%%%%%%%%%%%%%%%%%%%%%%% ", " % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% ", " % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% ", " %%% %%%%%%%%%%%%%%%%%%%%%%%%%%% %% ", " %%% %%%%%%%% %%%% %% ", " %% %%%%%%%% %%%% %% ", " % %% ", " " };""" indent_icon = """ /* XPM */ static char *indent_xpm[] = { /* format */ "64 64 9 1", " c None", ". c black", "+ c #DFDFDF", "@ c #3F48CC", "# c green", "$ c red", "% c black", "& c #ED1C24", "* c #E2D9D6", /* pixels */ "................................................... ", "................................................... ", ".................................................... ", "..................................................... ", "....++++++++++++++++++++++++++++++++++++++++++++...... ", "....++++++++++++++++++++++++++++++++++++++++++++....... ", "....++++++++++++++++++++++++++++++++++++++++++++........ ", "....++++++++++++++++++++++++++++++++++++++++++++...+..... ", "....++++++++++++++++++++++++++++++++++++++++++++...++..... ", "....++++++++++++++++++++++++++++++++++++++++++++...+++..... ", "....++++++++++++++++++++++++++++++++++++++++++++...++++..... ", "....++++++++++++++++++++++++++++++++++++++++++++...+++++..... ", "....++++++++++++++++++++++++++++++++++++++++++++...++++++..... ", "....++++++++++++++++++++++++++++++++++++++++++++...+++++++..... ", "....++++++++++++++++++++++++++++++++++++++++++++...++++++++.... ", "....+++++++%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%++++++................", "....+++++++%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%++++++................", "....+++++++%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%++++++................", "....+++++++%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%++++++++++++++++++....", "....+++++++%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%++++++++++++++++++....", "....++++++++++++++++++++++++++++++++++++++++++++++++++++++++....", "....++++++++++++++++++++++++++++++++++++++++++++++++++++++++....", "....++++++++++++++++++++++++++++++++++++++++++++++++++++++++....", "....++++++++++++++++++++++++++++++++++++++++++++++++++++++++....", "....+++....+++++++++++++++++++++++++++++++++++++++++++++++++....", "....+++.....++++++++++++++++++++++++++++++++++++++++++++++++....", "....+++..$$..++++++++++++++++++++%%%%%%%%%%%%%%%%%%%%%%%%%++....", "....+++..$$$...++++++++++++++++++%%%%%%%%%%%%%%%%%%%%%%%%%++....", "....+++..$$$$$...++++++++++++++++%%%%%%%%%%%%%%%%%%%%%%%%%++....", "....++++..$$$$$$...++++++++++++++%%%%%%%%%%%%%%%%%%%%%%%%%++....", "....+++++..$$$$$$$...++++++++++++%%%%%%%%%%%%%%%%%%%%%%%%%++....", "....+++++++..$$$$$$$...+++++++++++++++++++++++++++++++++++++....", "....+++++++++..$$$$$$...++++++++++++++++++++++++++++++++++++....", "....+++++++++++..$$$$$$..+++++++++++++++++++++++++++++++++++....", "....+++++++++++++..$$$$$$..+++++++++++++++++++++++++++++++++....", "....+++++++++++++++..$$$$$..++++++++++++++++++++++++++++++++....", "....+++++++++++++++++..$$$$..+++++++++++++++++++++++++++++++....", "....++++++++++++++++++..$$$$..+++%%%%%%%%%%%%%%%%%%%%%%%%%++....", "....++++++++++++++++++..$$$$..+++%%%%%%%%%%%%%%%%%%%%%%%%%++....", "....++++++++++++++++++..$$$$..+++%%%%%%%%%%%%%%%%%%%%%%%%%++....", "....++++++++++++++++..$$$$$..++++%%%%%%%%%%%%%%%%%%%%%%%%%++....", "....+++++++++++++++..$$$$$..+++++%%%%%%%%%%%%%%%%%%%%%%%%%++....", "....+++++++++++++..$$$$$$..+++++++++++++++++++++++++++++++++....", "....+++++++++++..$$$$$$$..++++++++++++++++++++++++++++++++++....", "....+++++++++..$$$$$$$..++++++++++++++++++++++++++++++++++++....", "....+++++++..$$$$$$$$..+++++++++++++++++++++++++++++++++++++....", "....+++++..$$$$$$$$..+++++++++++++++++++++++++++++++++++++++....", "....++++..$$$$$$$..+++++++++++++++++++++++++++++++++++++++++....", "....+++..$$$$$$..++++++++++++++++%%%%%%%%%%%%%%%%%%%%%%%%%++....", "....+++..$$$$..++++++++++++++++++%%%%%%%%%%%%%%%%%%%%%%%%%++....", "....+++..$$$..+++++++++++++++++++%%%%%%%%%%%%%%%%%%%%%%%%%++....", "....+++.....+++++++++++++++++++++%%%%%%%%%%%%%%%%%%%%%%%%%++....", "....++++...++++++++++++++++++++++%%%%%%%%%%%%%%%%%%%%%%%%%++....", "....++++++++++++++++++++++++++++++++++++++++++++++++++++++++....", "....++++++++++++++++++++++++++++++++++++++++++++++++++++++++....", "....++++++++++++++++++++++++++++++++++++++++++++++++++++++++....", "....++++++++++++++++++++++++++++++++++++++++++++++++++++++++....", "....++++++++++++++++++++++++++++++++++++++++++++++++++++++++....", "....++++++++++++++++++++++++++++++++++++++++++++++++++++++++....", "....++++++++++++++++++++++++++++++++++++++++++++++++++++++++....", "................................................................", "................................................................", "................................................................", "................................................................" };""" indent_Memo_icon = """ /* XPM */ static char *indent_xpm[] = { /* format */ "64 64 9 1", " c None", ". c black", "+ c #DFDFDF", "@ c #3F48CC", "# c green", "$ c red", "% c black", "& c #ED1C24", "* c #E2D9D6", /* pixels */ "................................................... ", "................................................... ", ".................................................... ", "..................................................... ", "....++++++++++++++++++++++++++++++++++++++++++++...... ", "....++++++++++++++++++++++++++++++++++++++++++++....... ", "....++++++++++++++++++++++++++++++++++++++++++++........ ", "....++++++++++++++++++++++++++++++++++++++++++++...+..... ", "....++++++++++++++++++++++++++++++++++++++++++++...++..... ", "....++++++++++++++++++++++++++++++++++++++++++++...+++..... ", "....++++++++++++++++++++++++++++++++++++++++++++...++++..... ", "....++++++++++++++++++++++++++++++++++++++++++++...+++++..... ", "....++++++++++++++++++++++++++++++++++++++++++++...++++++..... ", "....++++++++++++++++++++++++++++++++++++++++++++...+++++++..... ", "....++++++++++++++++++++++++++++++++++++++++++++...++++++++.... ", "....+++++++%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%++++++................", "....+++++++%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%++++++................", "....+++++++%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%++++++................", "....+++++++%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%++++++++++++++++++....", "....+++++++%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%++++++++++++++++++....", "....++++++++++++++++++++++++++++++++++++++++++++++++++++++++....", "....+++..$$$$$$..+++++++++++++++++++++++++++++++++++++++++++....", "....+++..$$$$$$..+++++++++++++++++++++++++++++++++++++++++++....", "....+++..$$$$$$..+++++++++++++++++++++++++++++++++++++++++++....", "....+++..$$$$$$..+++++++++++++++++++++++++++++++++++++++++++....", "....+++..$$$$$$..+++++++++++++++++++++++++++++++++++++++++++....", "....+++..$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$%%%%%%%%%%%%%%%%%%%++....", "....+++..$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$%%%%%%%%%%%%%%%%%%%++....", "....+++..$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$%%%%%%%%%%%%%%%%%%%++....", "....+++..$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$%%%%%%%%%%%%%%%%%%%++....", "....+++..$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$%%%%%%%%%%%%%%%%%%%++....", "....+++..$$$$$$..+++++++++++++++++++++++++++++++++++++++++++....", "....+++..$$$$$$..+++++++++++++++++++++++++++++++++++++++++++....", "....+++..$$$$$$..+++++++++++++++++++++++++++++++++++++++++++....", "....+++..$$$$$$..+++++++++++++++++++++++++++++++++++++++++++....", "....+++..$$$$$$..+++++++++++++++++++++++++++++++++++++++++++....", "....+++..$$$$$$..+++++++++++++++++++++++++++++++++++++++++++....", "....+++..$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$%%%%%%%%%%%%%%%%%%%++....", "....+++..$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$%%%%%%%%%%%%%%%%%%%++....", "....+++..$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$%%%%%%%%%%%%%%%%%%%++....", "....+++..$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$%%%%%%%%%%%%%%%%%%%++....", "....+++..$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$%%%%%%%%%%%%%%%%%%%++....", "....+++..$$$$$$..+++++++++++++++++++++++++++++++++++++++++++....", "....+++..$$$$$$..+++++++++++++++++++++++++++++++++++++++++++....", "....+++..$$$$$$..+++++++++++++++++++++++++++++++++++++++++++....", "....+++..$$$$$$..+++++++++++++++++++++++++++++++++++++++++++....", "....+++..$$$$$$..+++++++++++++++++++++++++++++++++++++++++++....", "....+++..$$$$$$..+++++++++++++++++++++++++++++++++++++++++++....", "....+++..$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$%%%%%%%%%%%%%%%%%%%++....", "....+++..$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$%%%%%%%%%%%%%%%%%%%++....", "....+++..$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$%%%%%%%%%%%%%%%%%%%++....", "....+++..$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$%%%%%%%%%%%%%%%%%%%++....", "....+++..$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$%%%%%%%%%%%%%%%%%%%++....", "....+++..$$$$$$..+++++++++++++++++++++++++++++++++++++++++++....", "....+++..$$$$$$..+++++++++++++++++++++++++++++++++++++++++++....", "....+++..$$$$$$..+++++++++++++++++++++++++++++++++++++++++++....", "....+++..$$$$$$..+++++++++++++++++++++++++++++++++++++++++++....", "....+++..$$$$$$..+++++++++++++++++++++++++++++++++++++++++++....", "....+++..$$$$$$..++++++++++++++++++++++++++++++++++++++++++++...", "....+++..$$$$$$..+++++++++++++++++++++++++++++++++++++++++++....", "................................................................", "................................................................", "................................................................", "................................................................" };""" replace_icon = """ /* XPM */ static char *_647894170722[] = { /* columns rows colors chars-per-pixel */ "64 64 9 1 ", " c black", ". c #2B0000", "X c #2B2B00", "o c gray17", "O c #552B2B", "+ c #3F48CC", "@ c #C3C3C3", "# c #FFFFD4", "$ c None", "$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$", "$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$", "$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$@@@@@@@@$$$$$$$$$$$$$$", "$$$$@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@$$@@@@@@@@$$$$$$$$$$$$$$", "$$$$@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@$$@@ @@$$$$$$$$$$$$$$", "$$$$@@@@@@@@@@@+++++++++++++++++++++++@@$$@@ @@$$$$$$$$$$$$$$", "$$$$@@@@@@@@@@++++++++++++++++++++++++@@$$@@ @@$$$$$$$$$$$$$$", "$$$$@@@@@@@@@+++++++++++++++++++++++++@@$$@@ @@$$$$$$$$$$$$$$", "$$$$@@@@@@@@++++++++++++++++++++++++++@@$$@@ @@$$$$$$$$$$$$$$", "$$$$@@@@@@@@++++++++++++++++++++++++++@@$$@@ @@@@@@@@@@@@@$$$", "$$$$@@@@@@@+++++++++++++++++++++++++++@@$$@@ @@@@@@@@@@@@@$$$", "$$$$@@@@@@++++++++++++++++++++++++++++@@$$@@ @@$$$", "$$$$@@@@@+++++++++++@@@@@@@@@@@@@@@@@@@@$$@@ @@$$$", "$$$$@@@@@++++++++++@@@@@@@@@@@@@@@@@@@@@$$@@ @@$$$", "$$$$@@@@@+++++++++@@@@@@$$$$$$$$$$$$$$$$$$@@ @@@@@@@@ @@$$$", "$$$$@@@@@++++++++@@@@@@@$$$$$$$$$$$$$$$$$$@@ @@@@@@@@ @@$$$", "$$$$@@@@@++++++++@@@@@@@$$$$$$$$$$$$$$$$$$@@ @@@@@@@@ @@#$$", "$$$$@@@@++++++++++@@@@@@$$$$$$$$$$$$$$$$$$@@ @@@@@@@@ @@#$$", "$$$$@@@++++++++++++@@@@@$$$$$$$$$$$$$$$$$$@@ @@@@@@@@ @@#$$", "$$$$@++++++++++++++++@@@$$$$$$$$$$$$$$$$$$@@ @@@@@@@@ @@$$$", "$$$$@+++++++++++++++++@@$$$$$$$$$$$$$$$$$$@@ @@@@@@@@ @@$$$", "$$$$@+++++++++++++++++@@$$$$$$$$$$$$$$$$$$@@ @@@@@@@@ @@$$$", "$$$$@@@++++++++++++@@@@@$$$$$$$$$$$$$$$$$$@@ @@$$$", "$$$$@@@++++++++++++@@@@@$$$$$$$$$$$$$$$$$$@@ @@$$$", "$$$$@@@++++++++++++@@@@@$$$$$$$$$$$$$$$$$$@@ @@$$$", "$$$$@@@@+++++++++++@@@@@$$$$$$$$$$$$$$$$$$@@@@@@@@@@@@@@@@@@@$$$", "$$$$@@@@++++++++++@@@@@@$$$$$$$$$$$$$$$$$$@@@@@@@@@@@@@@@@@@@$$$", "$$$$@@@@++++++++++@@@@@@$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$", "$$$$@@@@++++++++++@@@@@@$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$", "$$$$@@@@@++++++++@@@@@@@$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$", "$$$$@@@@@++++++++@@@@@@@$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$", "$$$$@@@@@++++++++@@@@@@@$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$", "$$$$@@@@@@++++++@@@@@@@@$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$", "$$$$@@@@@@++++++@@@@@@@@$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$", "$$$$@@@@@@++++++@@@@@@@@$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$", "$$$$@@@@@@@++++@@@@@@@@@$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$", "$$$$@@@@@@@++++@@@@@@@@@$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$", "$$$$@@@@@@@@++@@@@@@@@@@$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$", "$$$$@@@@@@@@@@@@@@@@@@@@$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$", "$$@@@@@@@@@@@@@@@@@@@@@@@@$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$", "$$@@@@@@@@@ XO@@@@@@@@@$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$", "$$@@@@@@ .@@@@@@@$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$", "$$@@@@@ @@@@@@$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$", "$$@@@@ @@@@@$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$", "$$@@@ @@@@@ .@@@@$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$", "$$@@ @@@@@@ @@@@$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$", "$$@@ .@@@@@@@ @@@@$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$", "$$@@ @@@@@@@@@@@@@@@@@$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$", "$$@@ @@@@@@@@@@@@@@@@@$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$", "$$@@ @@@@@@@@@@@@@@@@@$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$", "$$@@ @@@@@@@@@@@@@@@@@$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$", "$$@@ @@@@@@@@@@@@@@@@@$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$", "$$@@ @@@@@@@ @@@@$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$", "$$@@@ @@@@@ @@@@$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$", "$$@@@ @@@@@$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$", "$$@@@@ @@@@@@$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$", "$$@@@@@@ @@@@@@@$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$", "$$@@@@@@@@o .o@@@@@@@@@$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$", "$$@@@@@@@@@@@@@@@@@@@@@@@@$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$", "$$@@@@@@@@@@@@@@@@@@@@@@@@$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$", "$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$", "$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$", "$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$", "$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$" };""" find_previous_icon = """ /* XPM */ static char *_647896432515[] = { /* columns rows colors chars-per-pixel */ "64 64 8 1 ", " c black", ". c #ED1C24", "X c #22B14C", "o c #FFC90E", "O c #3F48CC", "+ c #7A82DC", "@ c #DFDFDF", "# c None", "################################################################", "################################################################", "####### #############################", "###### ###########################", "##### @@@@@@@@@@@@@@@@ ##########################", "#### @ @@@@@@@@@@@@@@@ ########################", "### @@ @@@@@@@@@@@@@@ #######################", "## @@@ @@@@@@@@@@@@@@ +++++ #######################", "# @@@@ @@@@@@@@@@@@@ +++++++ ######################", " @@@ XXXXX ++++++++++ ######################", " @@@ XXXX +++++++++++ #####################", " @@@@@@@@@ XXXX +++++++++++++ #####################", " @@@@@@@@@@@@@@@@@ +++++++++++++ ####################", " @@@@@@@@@@@@@@@@@ +++++++++++++++ ####################", " @@@@@@@@@@@@@@@@@ +++++++++++++++ ####################", " @@@@@XXX .... +++++++++++++++++ ###################", " @@@@@XXX .... +++++++++++++++++ ###################", " @@@@@@@@@@@@@@@@ +++++++++++++++++ ###################", " @@@@@@@@@@@@@@@@ +++++++++++++++++ ###################", " @@@@@@@@@@@@@@@@ +++++++++++++++++ ###################", " @@@@@ XXXXXOOX +++++++++++++++++ ###################", " @@@@@ XXXXXOOX +++++++++++++++++ ###################", " @@@@@ XXXXXOOX +++++++++++++++++ ###################", " @@@@@@@@@@@@@@@@@ +++++++++++++++ ###############OOO##", " @@@@@@@@@@@@@@@@@ +++++++++++++++ ##############OOOOO#", " @@@@@@@@@@@@@@@@@ +++++++++++++++ ##############OOOOO#", " @@@@@OOOOOOOooo +++++++++++++ ############OOOOOOO#", " @@@@@OOOOOOOooo +++++++++++ ############OOOOOOOO#", " @@@@@@@@@@@@@@@@@@ +++++++++++ ############OOOOOOO##", " @@@@@@@@@@@@@@@@@@@ +++++++++ #############OOOOOOO##", " @@@@@@@@@@@@@@@@@@@ +++++ ##############OOOOOOO##", " @@@@@@@@@@@@@@@@@@@@ ##############OOOOOOO##", " ##############OOOOOOOO##", " ################OOOOOOOO##", "########################## #################OOOOOOO###", "############################ ###################OOOOOOO###", "############################# ####################OOOOOOO###", "############################# ###################OOOOOOOO###", "############################# ###################OOOOOOOO###", "############################# ###################OOOOOOOO###", "############################# ###################OOOOOOOO###", "############################# ##################OOOOOOOO####", "############################# #################OOOOOOOOO####", "############################# #################OOOOOOOOO####", "############################# ###############OOOOOOOOOOO####", "############################# #############OOOOOOOOOOOO#####", "#####################OOO######################OOOOOOOOOOOOO#####", "##################OOOOOOO####################OOOOOOOOOOOOO######", "##############OOOOOOOOOOOO##################OOOOOOOOOOOOOO######", "###########OOOOOOOOOOOOOOO##################OOOOOOOOOOOOO#######", "########OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO########", "####OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO########", "###OOOOOOOOOOOOOOO###OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO#########", "##OOOOOOOOOOOOO#######OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO##########", "##OOOOOOOOOOOOO#######OOOOOOOOOOOOOOOOOOOOOOOOOOOOOO############", "###OOOOOOOOOOOOOOO###OOOOOOOOOOOOOOOOOOOOOOOOOOOOOO#############", "####OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO##############", "#######OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO################", "###########OOOOOOOOOOOOOOOO#####################################", "##############OOOOOOOOOOOO######################################", "#################OOOOOOOO#######################################", "#####################OOO########################################", "################################################################", "################################################################" };""" find_next_icon = """ /* XPM */ static char *_647896407113[] = { /* columns rows colors chars-per-pixel */ "64 64 8 1 ", " c black", ". c #ED1C24", "X c #22B14C", "o c #FFC90E", "O c #3F48CC", "+ c #7A82DC", "@ c #DFDFDF", "# c None", "################################################################", "################################################################", "############################# ########################", "########################### ######", "########################## @@@@@@@@@@@@@@@@ #####", "######################## @@@@@@@@@@@@@@@ @ ####", "####################### @@@@@@@@@@@@@@ @@ ###", "####################### +++++ @@@@@@@@@@@@@@ @@@ ##", "###################### +++++++ @@@@@@@@@@@@@ @@@@ #", "###################### ++++++++++ XXXXX @@@ ", "##################### +++++++++++ XXXX @@@ ", "##################### +++++++++++++ XXXX @@@@@@@@@ ", "#################### +++++++++++++ @@@@@@@@@@@@@@@@@ ", "#################### +++++++++++++++ @@@@@@@@@@@@@@@@@ ", "#################### +++++++++++++++ @@@@@@@@@@@@@@@@@ ", "################### +++++++++++++++++ .... XXX@@@@@ ", "################### +++++++++++++++++ .... XXX@@@@@ ", "################### +++++++++++++++++ @@@@@@@@@@@@@@@@ ", "################### +++++++++++++++++ @@@@@@@@@@@@@@@@ ", "################### +++++++++++++++++ @@@@@@@@@@@@@@@@ ", "################### +++++++++++++++++ XOOXXXXX @@@@@ ", "################### +++++++++++++++++ XOOXXXXX @@@@@ ", "################### +++++++++++++++++ XOOXXXXX @@@@@ ", "##OOO############### +++++++++++++++ @@@@@@@@@@@@@@@@@ ", "#OOOOO############## +++++++++++++++ @@@@@@@@@@@@@@@@@ ", "#OOOOO############## +++++++++++++++ @@@@@@@@@@@@@@@@@ ", "#OOOOOOO############ +++++++++++++ oooOOOOOOO@@@@@ ", "#OOOOOOOO############ +++++++++++ oooOOOOOOO@@@@@ ", "##OOOOOOO############ +++++++++++ @@@@@@@@@@@@@@@@@@ ", "##OOOOOOO############# +++++++++ @@@@@@@@@@@@@@@@@@@ ", "##OOOOOOO############## +++++ @@@@@@@@@@@@@@@@@@@ ", "##OOOOOOO############## @@@@@@@@@@@@@@@@@@@@ ", "##OOOOOOOO############## ", "##OOOOOOOO################ ", "###OOOOOOO################# ##########################", "###OOOOOOO################### ############################", "###OOOOOOO#################### #############################", "###OOOOOOOO################### #############################", "###OOOOOOOO################### #############################", "###OOOOOOOO################### #############################", "###OOOOOOOO################### #############################", "####OOOOOOOO################## #############################", "####OOOOOOOOO################# #############################", "####OOOOOOOOO################# #############################", "####OOOOOOOOOOO############### #############################", "#####OOOOOOOOOOOO############# #####OOOO####################", "#####OOOOOOOOOOOOO######################OOOO####################", "######OOOOOOOOOOOOO####################OOOOOOOO#################", "######OOOOOOOOOOOOOO##################OOOOOOOOOOOOO#############", "#######OOOOOOOOOOOOOOO##############OOOOOOOOOOOOOOOOOO##########", "########OOOOOOOOOOOOOOO###########OOOOOOOOOOOOOOOOOOOOOOO#######", "########OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO####", "#########OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO###OOOOOOOOOOOOOOO###", "##########OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO#######OOOOOOOOOOOOO##", "############OOOOOOOOOOOOOOOOOOOOOOOOOOOOOO#######OOOOOOOOOOOOO##", "#############OOOOOOOOOOOOOOOOOOOOOOOOOOOOOO###OOOOOOOOOOOOOOO###", "##############OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO####", "################OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO#######", "##################OOOOO############OOOOOOOOOOOOOOOOOO###########", "######################################OOOOOOOOOOOOO#############", "#######################################OOOOOOOOO################", "########################################OOOO####################", "########################################OOOO####################", "################################################################" };""" replace_all_icon = """ /* XPM */ static char *_647894950477[] = { /* columns rows colors chars-per-pixel */ "64 64 9 1 ", " c black", ". c #2B0000", "X c #2B2B00", "o c gray17", "O c #552B2B", "+ c #3F48CC", "@ c #C3C3C3", "# c #FFFFD4", "$ c None", "$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$", "$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$", "$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$@@@@@@@@@$$$$$$$$$$$$$$", "$$$$@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@$$$$$$$$$$$$$$", "$$$$@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@$$$$$$$$$$$$$$", "$$$$@@@@@@@@@@@+++++++++++++++++++++++@@@@@@ @@$$$$$$$$$$$$$$", "$$$$@@@@@@@@@@++++++++++++++++++++++++@@@@@@ @@$$$$$$$$$$$$$$", "$$$$@@@@@@@@@+++++++++++++++++++++++++@@@@@@ @@$$$$$$$$$$$$$$", "$$$$@@@@@@@@++++++++++++++++++++++++++@ @@ @@$$$$$$$$$$$$$$", "$$$$@@@@@@@@++++++++++++++++++++++++++@ @@ @@@@@@@@@@@@@$$$", "$$$$@@@@@@@++++++++++++@@@@@@@@@@@@@@@@ @@ @@@@@@@@@@@@@$$$", "$$$$@@@@@@+++++++++++++@@@@@ @@ @@$$$", "$$$$@@@@@+++++++++++@@@@@@@@ @@ @@$$$", "$$$$@@@@@++++++++++@@@@@@@@@ @@ @@$$$", "$$$$@@@@@+++++++++@@@@@@@@@@ @@@@@@@@ @@ @@@@@@@@ @@$$$", "$$$$@@@@@++++++++@@@@@@@@@@@ @@@@@@@@ @@ @@@@@@@@ @@$$$", "$$$$@@@@@++++++++@@@@@@@@@@@ @@@@@@@@ @@ @@@@@@@@ @@#$$", "$$$$@@@@++++++++++@@@@@@@@@@ @@@@@@@@ @@ @@@@@@@@ @@#$$", "$$$$@@@++++++++++++@@@@@@@@@ @@@@@@@@ @@ @@@@@@@@ @@#$$", "$$$$@++++++++++++++++@@@@@@@ @@@@@@@@ @@ @@@@@@@@ @@$$$", "$$$$@+++++++++++++++++@@@@@@ @@@@@@@@ @@ @@@@@@@@ @@$$$", "$$$$@+++++++++++++++++@@@@@@ @@@@@@@@ @@ @@@@@@@@ @@$$$", "$$$$@@@++++++++++++@@@@@@@@@ @@ @@$$$", "$$$$@@@++++++++++++@@@@@@@@@ @@ @@$$$", "$$$$@@@++++++++++++@@@@@@@@@ @@ @@$$$", "$$$$@@@@+++++++++++@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@$$$", "$$$$@@@@++++++++++@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@$$$", "$$$$@@@@++++++++++@@@@@@@$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$", "$$$$@@@@++++++++++@@@@@@@$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$", "$$$$@@@@@++++++++@@@@@@@@$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$", "$$$$@@@@@++++++++@@@@@@@@$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$", "$$$$@@@@@++++++++@@@@@@@@$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$", "$$$$@@@@@@++++++@@@@@@@@@$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$", "$$$$@@@@@@++++++@@@@@@@@@$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$", "$$$$@@@@@@++++++@@@@@@@@@$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$", "$$$$@@@@@@@++++@@@@@@@@@@$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$", "$$$$@@@@@@@++++@@@@@@@@@@$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$", "$$$$@@@@@@@@++@@@@@@@@@@@$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$", "$$$$@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@$$$$$$$$$$$$$$$$$$", "$$@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@$$$$$$$$$$$$$$$$$$", "$$@@@@@@@@@ @ @@@@@@@@@@ XO@@@@@@@$$$$$$$$$$$$$$$$$$", "$$@@@@@@ @@@@@@@ .@@@@@$$$$$$$$$$$$$$$$$$", "$$@@@@@ @@@@@@ @@@@$$$$$$$$$$$$$$$$$$", "$$@@@@ @@@@@ @@@$$$$$$$$$$$$$$$$$$", "$$@@@ @@@@@ @@@@ @@@@@ .@@$$$$$$$$$$$$$$$$$$", "$$@@ @@@@@@ @@@ @@@@@@ @@$$$$$$$$$$$$$$$$$$", "$$@@ .@@@@@@@ @@@ .@@@@@@@ @@$$$$$$$$$$$$$$$$$$", "$$@@ @@@@@@@@@ @@@ @@@@@@@@@@@@@@@$$$$$$$$$$$$$$$$$$", "$$@@ @@@@@@@@@ @@@ @@@@@@@@@@@@@@@$$$$$$$$$$$$$$$$$$", "$$@@ @@@@@@@@@ @@@ @@@@@@@@@@@@@@@$$$$$$$$$$$$$$$$$$", "$$@@ @@@@@@@@@ @@@ @@@@@@@@@@@@@@@$$$$$$$$$$$$$$$$$$", "$$@@ @@@@@@@@@ @@@ @@@@@@@@@@@@@@@$$$$$$$$$$$$$$$$$$", "$$@@ @@@@@@@ @@@ @@@@@@@ @@$$$$$$$$$$$$$$$$$$", "$$@@@ @@@@@ @@@@ @@@@@ @@$$$$$$$$$$$$$$$$$$", "$$@@@ @@@@ @@@$$$$$$$$$$$$$$$$$$", "$$@@@@ @@@@@ @@@@$$$$$$$$$$$$$$$$$$", "$$@@@@@@ @@@@@@@ @@@@@$$$$$$$$$$$$$$$$$$", "$$@@@@@@@@ . @ @@@@@@@@@o .o@@@@@@@$$$$$$$$$$$$$$$$$$", "$$@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@$$$$$$$$$$$$$$$$$$", "$$@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@$$$$$$$$$$$$$$$$$$", "$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$", "$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$", "$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$", "$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$" };""" unindent_icon = """ /* XPM */ static char * unindent_xpm[] = { /* format */ "64 64 9 1", " c None", "z c #000000", "+ c #DFDFDF", "@ c #3F48CC", "# c #22B14C", "x c red", "% c black", "& c #ED1C24", "* c #E2D9D6", /* pixels */ "zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz ", "zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz ", "zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz ", "zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz ", "zzzz++++++++++++++++++++++++++++++++++++++++++++zzzzzz ", "zzzz++++++++++++++++++++++++++++++++++++++++++++zzzzzzz ", "zzzz++++++++++++++++++++++++++++++++++++++++++++zzzzzzzz ", "zzzz++++++++++++++++++++++++++++++++++++++++++++zzz+zzzzz ", "zzzz++++++++++++++++++++++++++++++++++++++++++++zzz++zzzzz ", "zzzz++++++++++++++++++++++++++++++++++++++++++++zzz+++zzzzz ", "zzzz++++++++++++++++++++++++++++++++++++++++++++zzz++++zzzzz ", "zzzz++++++++++++++++++++++++++++++++++++++++++++zzz+++++zzzzz ", "zzzz++++++++++++++++++++++++++++++++++++++++++++zzz++++++zzzzz ", "zzzz++++++++++++++++++++++++++++++++++++++++++++zzz+++++++zzzzz ", "zzzz++++++++++++++++++++++++++++++++++++++++++++zzz++++++++zzzz ", "zzzz+++++++%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%++++++zzzzzzzzzzzzzzzz", "zzzz+++++++%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%++++++zzzzzzzzzzzzzzzz", "zzzz+++++++%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%++++++zzzzzzzzzzzzzzzz", "zzzz+++++++%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%++++++++++++++++++zzzz", "zzzz+++++++%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%++++++++++++++++++zzzz", "zzzz++++++++++++++++++++++++++++++++++++++++++++++++++++++++zzzz", "zzzz++++++++++++++++++++++++++++++++++++++++++++++++++++++++zzzz", "zzzz++++++++++++++++++++++++++++++++++++++++++++++++++++++++zzzz", "zzzz++++++++++++++++++++++++++++++++++++++++++++++++++++++++zzzz", "zzzz++++++++++++++++++++++++++++++++++++++++++++++++++++++++zzzz", "zzzz+++++++++++++++++++++++++++++++++++++++++++++++++zz+++++zzzz", "zzzz++++%%%%%%%%%%%%%%%%%%%%%%%%%+++++++++++++++++++zzzzz+++zzzz", "zzzz++++%%%%%%%%%%%%%%%%%%%%%%%%%++++++++++++++++++zzxxzz+++zzzz", "zzzz++++%%%%%%%%%%%%%%%%%%%%%%%%%++++++++++++++++zzxxxxzz+++zzzz", "zzzz++++%%%%%%%%%%%%%%%%%%%%%%%%%++++++++++++++zzxxxxxxzz+++zzzz", "zzzz++++%%%%%%%%%%%%%%%%%%%%%%%%%++++++++++++zzxxxxxxxzz++++zzzz", "zzzz+++++++++++++++++++++++++++++++++++++++zzxxxxxxxxzz+++++zzzz", "zzzz++++++++++++++++++++++++++++++++++++++zzxxxxxxxxzz++++++zzzz", "zzzz++++++++++++++++++++++++++++++++++++zzxxxxxxxxzz++++++++zzzz", "zzzz+++++++++++++++++++++++++++++++++++zzxxxxxxxzz++++++++++zzzz", "zzzz+++++++++++++++++++++++++++++++++zzxxxxxxxzz++++++++++++zzzz", "zzzz++++++++++++++++++++++++++++++++zzxxxxxxzz++++++++++++++zzzz", "zzzz++++%%%%%%%%%%%%%%%%%%%%%%%%%++zzxxxxxxzz+++++++++++++++zzzz", "zzzz++++%%%%%%%%%%%%%%%%%%%%%%%%%++zzxxxxzz+++++++++++++++++zzzz", "zzzz++++%%%%%%%%%%%%%%%%%%%%%%%%%++zzxxxxxzz++++++++++++++++zzzz", "zzzz++++%%%%%%%%%%%%%%%%%%%%%%%%%+++zzxxxxxzzz++++++++++++++zzzz", "zzzz++++%%%%%%%%%%%%%%%%%%%%%%%%%++++zzxxxxxxzz+++++++++++++zzzz", "zzzz++++++++++++++++++++++++++++++++++zzxxxxxxxzz+++++++++++zzzz", "zzzz+++++++++++++++++++++++++++++++++++zzzxxxxxxzzz+++++++++zzzz", "zzzz+++++++++++++++++++++++++++++++++++++zzzxxxxxxzz++++++++zzzz", "zzzz++++++++++++++++++++++++++++++++++++++zzzxxxxxxzz+++++++zzzz", "zzzz+++++++++++++++++++++++++++++++++++++++zzzzxxxxxxzz+++++zzzz", "zzzz+++++++++++++++++++++++++++++++++++++++++zzzzxxxxxxzz+++zzzz", "zzzz++++%%%%%%%%%%%%%%%%%%%%%%%%%++++++++++++++zzzzxxxxzz+++zzzz", "zzzz++++%%%%%%%%%%%%%%%%%%%%%%%%%+++++++++++++++++zzxxxxzz++zzzz", "zzzz++++%%%%%%%%%%%%%%%%%%%%%%%%%++++++++++++++++++zzxxxzz++zzzz", "zzzz++++%%%%%%%%%%%%%%%%%%%%%%%%%+++++++++++++++++++zzxxzz++zzzz", "zzzz++++%%%%%%%%%%%%%%%%%%%%%%%%%++++++++++++++++++++zzzzz++zzzz", "zzzz++++++++++++++++++++++++++++++++++++++++++++++++++zzz+++zzzz", "zzzz++++++++++++++++++++++++++++++++++++++++++++++++++++++++zzzz", "zzzz++++++++++++++++++++++++++++++++++++++++++++++++++++++++zzzz", "zzzz++++++++++++++++++++++++++++++++++++++++++++++++++++++++zzzz", "zzzz++++++++++++++++++++++++++++++++++++++++++++++++++++++++zzzz", "zzzz++++++++++++++++++++++++++++++++++++++++++++++++++++++++zzzz", "zzzz++++++++++++++++++++++++++++++++++++++++++++++++++++++++zzzz", "zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz", "zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz", "zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz", "zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz" };""" snapshot_icon = """ /* XPM */ static char *_647898900207[] = { /* columns rows colors chars-per-pixel */ "64 64 8 1", " c None", ". c #000000", "+ c #0A0A0A", "@ c #302B01", "# c #CC0000", "$ c #888A85", "% c #FCE94F", "& c #FFFFFF", " ", " ", " ", " ", " ", " ", " ............ ", " ..##########.. ", " ..############.. ", " .###........###. ", " ..##..........##.. ", " +.##..%%%%%%%%..##.+ ", " ...... ..###.%%%%%%%%%%.###.. ", " .&&&&. ..###+.%%%&&&&%%%.+###.. ", " .&&&&. ..###++.%%%&&&&%%%.++###.. ", " .........###+++.%%%%%%%%%%.+++###......... ", " ...##########++++++%%%%%%%%++++++##########.... ", " ...###########++++++++++++++++++++++############.. ", " ..#####++++++++++++++++++++++++++++++++++++++#####.. ", " ..####+++++++++++++++++++++++++++++++++++++++++++###.. ", " .###++++++++++++++++++++++++++++++++++++++++++++++###.. ", " ..##++++++++++++++++++++++++++++++++++++++++++++++++###. ", " .###+++++++++++++++++++++++++++++++++++++++++++++++++##.. ", " .##++++++++++++++++++++++++++++++++++++++++++++++++++###. ", " .##++++++++++++++++++++++#######+++++++++++$$$+$$$++++##. ", " .##++++++++++++++++++++###@@@@@###+++++++++$$$+$$+++++##. ", " .##++++++++++++++++++###@@@@@@@@@###+++++++$$$+$++++++##. ", " .##+++++++++++++++++##@@@@@@@@@@@@@##+++++++++++++++++##. ", " .##++++++++++++++++##@@@@@@@@@@@@@@@##++++++++++++++++##. ", " .##++++++++++++++++#@@@@@@@@@@@@@@@@@##+++++++++++++++##. ", " .##+++++++++++++++##@@@@@@@@@@@@@@@@@@#+++++++++++++++##. ", " .##+++++++++++++++#@@@@@@@@+++@@@@@@@@#+++++++++++++++##. ", " .##++++++++++++++##@@@@@@+++++++@@@@@@##++++++++++++++##. ", " .##++++++++++++++#@@@@@@@+++++++@@@@@@@#++++++++++++++##. ", " .##++++++++++++++#@@@@@@+++++++++@@@@@@#++++++++++++++##. ", " .##++++++++++++++#@@@@@@+++++++++@@@@@@#++++++++++++++##. ", " .##++++++++++++++#@@@@@@+++++++++@@@@@@#++++++++++++++##. ", " .##++++++++++++++##@@@@@@+++++++@@@@@@@#++++++++++++++##. ", " .##+++++++++++++++#@@@@@@+++++++@@@@@@##++++++++++++++##. ", " .##+++++++++++++++##@@@@@@@+++@@@@@@@@#+++++++++++++++##. ", " .##++++++++++++++++#@@@@@@@@@@@@@@@@@##+++++++++++++++##. ", " .##++++++++++++++++##@@@@@@@@@@@@@@@##++++++++++++++++##. ", " .##+++++++++++++++++##@@@@@@@@@@@@@##+++++++++++++++++##. ", " .##++++++++++++++++++###@@@@@@@@@###++++++++++++++++++##. ", " .##++++++++++++++++++++###@@@@@###++++++++++++++++++++##. ", " .##++++++++++++++++++++++#######++++++++++++++++++++++##. ", " .##++++++++++++++++++++++++++++++++++++++++++++++++++###. ", " .##++++++++++++++++++++++++++++++++++++++++++++++++++##.. ", " .###+++++++++++++++++++++++++++++++++++++++++++++++++##. ", " ..###+++++++++++++++++++++++++++++++++++++++++++++++###. ", " ..###+++++++++++++++++++++++++++++++++++++++++++++###.. ", " ..###++++++++++++++++++++++++++++++++++++++++++####.. ", " ..######+++++++++++++++++++++++++++++++++++######.. ", " ..############################################... ", " .....#####################################.... ", " ....................................... ", " ", " ", " ", " ", " ", " ", " ", " " };""" match_case_icon = """ /* XPM */ static char *_647901377770[] = { /* columns rows colors chars-per-pixel */ "64 64 3 1 ", " c black", "z c #C3C3C3", "x c None", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", "xxxxxxxxxxxxzzzzzzzzzzzzzzxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", "xxxxxxxxxxxxzzzzzzzzzzzzzzxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", "xxxxxxxxxxxxzz zzxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", "xxxxxxxxxxxzz zzxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", "xxxxxxxxxxxzz zzxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", "xxxxxxxxxxzz zzxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", "xxxxxxxxxxzz zzxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", "xxxxxxxxxxzz zzxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", "xxxxxxxxxzz zzxxxxxxxxxxxzzzzzzzzzzzzzzzzzzzzxxxxx", "xxxxxxxxxzz zzxxxxxxxxxxxxzzzzzzzzzzzzzzzzzxxxxxxx", "xxxxxxxxxzz z zzxxxxxxxxxxxzz zzzzzxxxxxx", "xxxxxxxxzz z zzxxxxxxxxzz zzzzxxxx", "xxxxxxxxzz zzz zzxxxxxxxzz zzzxxxx", "xxxxxxxxzz zzz zzxxxxxzz zzzxxxx", "xxxxxxxzz zzz zzxxxxxzz zzxxxx", "xxxxxxxzz zzzz zzxxxxzz zzzzz zzxxxx", "xxxxxxzz zzzzz zzxxxxxzzzz zzzzzzz zzxxxx", "xxxxxxzz zzzzz zzxxxxxzzzzzzzzzzzzzz zzxxxx", "xxxxxxzz zzzzzz zzxxxxxxxzzzzzz zzxxxx", "xxxxxzz zzxxxxxxzzz zzxxxx", "xxxxxzz zzxxxxzz zzxxxx", "xxxxxzz zzxxzz zz zzxxxx", "xxxxzz zzxzz zzzzzz zzxxxx", "xxxxzz zzxzz zzzzzzz zzxxxx", "xxxxzz zzzz zzzzzzz zzxxxx", "xxxzz zzzz zzzzz zzxxxx", "xxxzz zzzzzzzzzzz zzzz zzxxxx", "xxxzz zzzzzzzzzzz zzz zzxxxx", "xxxzz zzxxxxxxxzz zzzz z zzxxx", "xxxzz zzxxxxxxxxxzz zzzz zzz zzxxx", "xxxzz zzxxxxxxxxxzz zzxxzz zzzzz zzxxx", "xxzzzzzzzzzzzzxxxxxxxxxzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzxx", "xxzzzzzzzzzzzzxxxxxxxxxzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzxx", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" };""" match_whole_word_icon = """ /* XPM */ static char *_647901969918[] = { /* columns rows colors chars-per-pixel */ "64 64 3 1 ", " c black", "z c #C3C3C3", "x c None", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", "zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz", "zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz", "zz zz", "zz zz", "zz zz", "zz zz", "zz zz", "zz zz", "zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz", "zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", "xxxxxxxxxxxxzzzzzzzzzzzzzzxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", "xxxxxxxxxxxxzzzzzzzzzzzzzzxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", "xxxxxxxxxxxxzz zzxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", "xxxxxxxxxxxzz zzxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", "xxxxxxxxxxxzz zzxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", "xxxxxxxxxxzz zzxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", "xxxxxxxxxxzz zzxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", "xxxxxxxxxxzz zzxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", "xxxxxxxxxzz zzxxxxxxxxxxxzzzzzzzzzzzzzzzzzzzzxxxxx", "xxxxxxxxxzz zzxxxxxxxxxxxxzzzzzzzzzzzzzzzzzxxxxxxx", "xxxxxxxxxzz z zzxxxxxxxxxxxzz zzzzzxxxxxx", "xxxxxxxxzz z zzxxxxxxxxzz zzzzxxxx", "xxxxxxxxzz zzz zzxxxxxxxzz zzzxxxx", "xxxxxxxxzz zzz zzxxxxxzz zzzxxxx", "xxxxxxxzz zzz zzxxxxxzz zzxxxx", "xxxxxxxzz zzzz zzxxxxzz zzzzz zzxxxx", "xxxxxxzz zzzzz zzxxxxxzzzz zzzzzzz zzxxxx", "xxxxxxzz zzzzz zzxxxxxzzzzzzzzzzzzzz zzxxxx", "xxxxxxzz zzzzzz zzxxxxxxxzzzzzz zzxxxx", "xxxxxzz zzxxxxxxzzz zzxxxx", "xxxxxzz zzxxxxzz zzxxxx", "xxxxxzz zzxxzz zz zzxxxx", "xxxxzz zzxzz zzzzzz zzxxxx", "xxxxzz zzxzz zzzzzzz zzxxxx", "xxxxzz zzzz zzzzzzz zzxxxx", "xxxzz zzzz zzzzz zzxxxx", "xxxzz zzzzzzzzzzz zzzz zzxxxx", "xxxzz zzzzzzzzzzz zzz zzxxxx", "xxxzz zzxxxxxxxzz zzzz z zzxxx", "xxxzz zzxxxxxxxxxzz zzzz zzz zzxxx", "xxxzz zzxxxxxxxxxzz zzxxzz zzzzz zzxxx", "xxzzzzzzzzzzzzxxxxxxxxxzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzxx", "xxzzzzzzzzzzzzxxxxxxxxxzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzxx", "xxzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz", "zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz", "zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz", "zz zz", "zz zz", "zz zz", "zz zz", "zz zz", "zz zz", "zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz", "zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" };""" home_icon = """ /* XPM */ static char *_649035328466[] = { /* columns rows colors chars-per-pixel */ "64 64 3 1 ", " c black", ". c #C3C3C3", "X c None", "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", "XXXXXXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXXXXXXX", "XXXXXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXXXXXX", "XXXXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXXXXX", "XXXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXXXX", "XXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXXX", "XXXXXXXXXXXXXXXXXXXXXXXX .. XXXXXXXXXXXXXXXXXXXXXXXX", "XXXXXXXXXXXXXXXXXXXXXX .... XXXXXXXXXXXXXXXXXXXXXX", "XXXXXXXXXXXXXXXXXXXXX ...... XXXXXXXXXXXXXXXXXXXXX", "XXXXXXXXXXXXXXXXXXXX ........ XXXXXXXXXXXXXXXXXXXX", "XXXXXXXXXXXXXXXXXXX .......... XXXXXXXXXXXXXXXXXXX", "XXXXXXXXXXXXXXXXXX ............ XXXXXXXXXXXXXXXXXX", "XXXXXXXXXXXXXXXXX ................ XXXXXXXXXXXXXXXXX", "XXXXXXXXXXXXXXXX .................. XXXXXXXXXXXXXXXX", "XXXXXXXXXXXXXX .................... XXXXXXXXXXXXXX", "XXXXXXXXXXXXX ...................... XXXXXXXXXXXXX", "XXXXXXXXXXXX ........................ XXXXXXXXXXXX", "XXXXXXXXXXX .......................... XXXXXXXXXXX", "XXXXXXXXXX ............................ XXXXXXXXXX", "XXXXXXXXX ................................ XXXXXXXXX", "XXXXXXXX .................................. XXXXXXXX", "XXXXXX .................................... XXXXXX", "XXXXX ...................................... XXXXX", "XXXX ........................................ XXXX", "XXX XXX", "XX XX", "XX XX", "XX XX", "XXX XXX", "XXXXXXXXXXXXX ........................... XXXXXXXXXXXXXX", "XXXXXXXXXXXXX ........................... XXXXXXXXXXXXXX", "XXXXXXXXXXXXX ........................... XXXXXXXXXXXXXX", "XXXXXXXXXXXXX ........................... XXXXXXXXXXXXXX", "XXXXXXXXXXXXX ........................... XXXXXXXXXXXXXX", "XXXXXXXXXXXXX ........................... XXXXXXXXXXXXXX", "XXXXXXXXXXXXX ........................... XXXXXXXXXXXXXX", "XXXXXXXXXXXXX ........................... XXXXXXXXXXXXXX", "XXXXXXXXXXXXX ........................... XXXXXXXXXXXXXX", "XXXXXXXXXXXXX ........................... XXXXXXXXXXXXXX", "XXXXXXXXXXXXX ........................... XXXXXXXXXXXXXX", "XXXXXXXXXXXXX ........................... XXXXXXXXXXXXXX", "XXXXXXXXXXXXX ........................... XXXXXXXXXXXXXX", "XXXXXXXXXXXXX ........................... XXXXXXXXXXXXXX", "XXXXXXXXXXXXX ........................... XXXXXXXXXXXXXX", "XXXXXXXXXXXXX ........................... XXXXXXXXXXXXXX", "XXXXXXXXXXXXX ........................... XXXXXXXXXXXXXX", "XXXXXXXXXXXXX ........................... XXXXXXXXXXXXXX", "XXXXXXXXXXXXX ........................... XXXXXXXXXXXXXX", "XXXXXXXXXXXXX ........................... XXXXXXXXXXXXXX", "XXXXXXXXXXXXX ........................... XXXXXXXXXXXXXX", "XXXXXXXXXXXXX ........................... XXXXXXXXXXXXXX", "XXXXXXXXXXXXX ........................... XXXXXXXXXXXXXX", "XXXXXXXXXXXXX ........................... XXXXXXXXXXXXXX", "XXXXXXXXXXXXX XXXXXXXXXXXXXX", "XXXXXXXXXXXXX XXXXXXXXXXXXXX", "XXXXXXXXXXXXX XXXXXXXXXXXXXX", "XXXXXXXXXXXXX XXXXXXXXXXXXXX", "XXXXXXXXXXXXX XXXXXXXXXXXXXX", "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" };""" end_icon = """ /* XPM */ static char *_649036163438[] = { /* columns rows colors chars-per-pixel */ "64 64 8 1 ", " c black", ". c #ED1C24", "X c #22B14C", "o c #FFC90E", "O c #3F48CC", "+ c red", "@ c #DFDFDF", "# c None", "################################################################", "################################################################", "#####++++++++++++++++++++++++++++++++++++++++++++++++++++#######", "####++++++++++++++++++++++++++++++++++++++++++++++++++++++######", "####+++++++++++++++++++++++++++++++++++++++++++++++++++++++#####", "####++++++++++++++++++++++++++++++++++++++++++++++++++++++++####", "#####+++++++++++++++++++++++++++++++++++++++++++++++++++++++####", "#####+++++++++++++++++++++++++++++++++++++++++++++++++++++++####", "#####################################################+++++++####", "#####################################################+++++++####", "#####################################################+++++++####", "### ############+++++++####", "### ###########+++++++####", "### ##########+++++++####", "### @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ ##########+++++++####", "### @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ ########+++++++####", "### @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @ #######+++++++####", "### @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@ #######+++++++####", "### @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@ #####+++++++####", "### @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@ ####+++++++####", "### @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@ ####+++++++####", "### @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@ ###+++++++####", "### @@@@@OOOOOOOOXXXXXXXX @@@@@ ##+++++++####", "### @@@@@OOOOOOOOXXXXXXXX @@@@@ ##+++++++####", "### @@@@@OOOOOOOOXXXXXXXX @@@@@@@@@@@@@@ ##+++++++####", "### @@@@@OOOOOOOOXXXXXXXX @@@@@@@@@@@@@@ ##+++++++####", "### @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ ##+++++++####", "### @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ ##+++++++####", "### @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ ##+++++++####", "### @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ ##+++++++####", "### @@@@@oooo ......... XXX@@@@@@@@ ##+++++++####", "### @@@@@oooo ......... XXX@@@@@@@@ ##+++++++####", "### @@@@@oooo ......... XXX@@@@@@@@ ##+++++++####", "### @@@@@oooo ......... XXX@@@@@@@@ ##+++++++####", "### @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ ##+++++++####", "### @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ ##+++++++####", "### @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ ##+++++++####", "### @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ ##+++++++####", "### @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ ##+++++++####", "### @@@@@ XXXXXXXXXXOOOOXXXXXXX @@@@@@@@ ##+++++++####", "### @@@@@ XXXXXXXXXXOOOOXXXXXXX @@@@@@@@ ##+++++++####", "### @@@@@ XXXXXXXXXXOOOOXXXXXXX @@@@@@@@ ##+++++++####", "### @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ ##+++++++####", "### @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@++++@ ##+++++++####", "### @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@+++++@ ##+++++++####", "### @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@+++++@@ ##+++++++####", "### @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@+++++@@@ ##+++++++####", "### @@@@@..... oooooOOOOOOOO+++++@@@@ ##+++++++####", "### @@@@@..... oooooOOOOOOO++++++++++++++++++++++####", "### @@@@@..... oooooOOOOOO+++++++++++++++++++++++####", "### @@@@@..... oooooOOOOOO+++++++++++++++++++++++####", "### @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@+++++++++++++++++++++++####", "### @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@++++++++++++++++++++++####", "### @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@+++++@@@@ #############", "### @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@+++++@@@ #############", "### @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@+++++@@ #############", "### ++++ #############", "### +++ #############", "### #############", "################################################################", "################################################################", "################################################################", "################################################################", "################################################################" };""" toggle_bookmark_icon = """ /* XPM */ static char *_649037028270[] = { /* columns rows colors chars-per-pixel */ "64 64 3 1 ", " c black", ". c #C3C3C3", "X c None", "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", "XXXXXXXXXX............................................XXXXXXXXXX", "XXXXXXXXXX............................................XXXXXXXXXX", "XXXXXXXXXX............................................XXXXXXXXXX", "XXXXXXXXXX... ...XXXXXXXXXX", "XXXXXXXXXX... ...XXXXXXXXXX", "XXXXXXXXXX... ...XXXXXXXXXX", "XXXXXXXXXX... ...XXXXXXXXXX", "XXXXXXXXXX... ...XXXXXXXXXX", "XXXXXXXXXX... ...XXXXXXXXXX", "XXXXXXXXXX... ...XXXXXXXXXX", "XXXXXXXXXX... ...XXXXXXXXXX", "XXXXXXXXXX... ...XXXXXXXXXX", "XXXXXXXXXX... ...XXXXXXXXXX", "XXXXXXXXXX... ...XXXXXXXXXX", "XXXXXXXXXX... ...XXXXXXXXXX", "XXXXXXXXXX... ...XXXXXXXXXX", "XXXXXXXXXX... ...XXXXXXXXXX", "XXXXXXXXXX... ...XXXXXXXXXX", "XXXXXXXXXX... ...XXXXXXXXXX", "XXXXXXXXXX... ...XXXXXXXXXX", "XXXXXXXXXX... ...XXXXXXXXXX", "XXXXXXXXXX... ...XXXXXXXXXX", "XXXXXXXXXX... ...XXXXXXXXXX", "XXXXXXXXXX... ...XXXXXXXXXX", "XXXXXXXXXX... ...XXXXXXXXXX", "XXXXXXXXXX... ...XXXXXXXXXX", "XXXXXXXXXX... ...XXXXXXXXXX", "XXXXXXXXXX... ...XXXXXXXXXX", "XXXXXXXXXX... ...XXXXXXXXXX", "XXXXXXXXXX... ...XXXXXXXXXX", "XXXXXXXXXX... ...XXXXXXXXXX", "XXXXXXXXXX... ...XXXXXXXXXX", "XXXXXXXXXX... . ...XXXXXXXXXX", "XXXXXXXXXX... ... ...XXXXXXXXXX", "XXXXXXXXXX... ..... ...XXXXXXXXXX", "XXXXXXXXXX... ..... ...XXXXXXXXXX", "XXXXXXXXXX... ...X... ...XXXXXXXXXX", "XXXXXXXXXX... ....X.... ...XXXXXXXXXX", "XXXXXXXXXX... ...XXX... ...XXXXXXXXXX", "XXXXXXXXXX... ....XXX.... ...XXXXXXXXXX", "XXXXXXXXXX... ...XXXXX... ...XXXXXXXXXX", "XXXXXXXXXX... ...XXXXXXX... ...XXXXXXXXXX", "XXXXXXXXXX... ....XXXXXXX.... ...XXXXXXXXXX", "XXXXXXXXXX... ....XXXXXXXXX... ...XXXXXXXXXX", "XXXXXXXXXX... ....XXXXXXXXX.... ...XXXXXXXXXX", "XXXXXXXXXX... ....XXXXXXXXXXX................XXXXXXXXXX", "XXXXXXXXXX................XXXXXXXXXXXX................XXXXXXXXXX", "XXXXXXXXXX................XXXXXXXXXXXXX...............XXXXXXXXXX", "XXXXXXXXXX...............XXXXXXXXXXXXXXX..............XXXXXXXXXX", "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" };""" next_bookmark_icon = """ /* XPM */ static char *_649037522124[] = { /* columns rows colors chars-per-pixel */ "64 64 5 1 ", " c black", ". c red", "X c darkorange", "o c #C3C3C3", "O c None", "OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO", "OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO", "OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO", "OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO", "OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO", "OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO", "OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO", "OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO", "OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO", "OOOOOOOOOOooooooooooooooooooooooooooooooooooooooooooooOOOOOOOOOO", "OOOOOOOOOOooooooooooooooooooooooooooooooooooooooooooooOOOOOOOOOO", "OOOOOOOOOOooooooooooooooooooooooooooooooooooooooooooooOOOOOOOOOO", "OOOOOOOOOOooo oooOOOOOOOOOO", "OOOOOOOOOOooo oooOOOOOOOOOO", "OOOOOOOOOOooo oooOOOOOOOOOO", "OOOOOOOOOOooo oooOOOOOOOOOO", "OOOOOOOOOOooo oooOOOOOOOOOO", "OOOOOOOOOOooo oooOOOOOOOOOO", "OOOOOOOOOOooo oooOOOOOOOOOO", "OOOOOOOOOOooo oooOOOOO", "OOOOOOOOOOooo ... oooOOOOO", "OOOOOOOOOOooo ...... oooOOOOO", "OOOOOOOOOOooo ......... oooOOOOO", "OOOOOOOOOOooo ................................OOOOO", "OOOOOOOOOOooo ......................XXX.........OOOO", "OOOOOOOOOOooo ......................XXXXXX.........O", "OOOOOOOOOOooo ...XXXXXXXXXXXXXXXXXXXXXXXXXXX........", "OOOOOOOOOOooo ...XXXXXXXXXXXXXXXXXXXXXXXXXXX........", "OOOOOOOOOOooo ...XXXXXXXXXXXXXXXXXXXXXXXXXXX........", "OOOOOOOOOOooo ...XXXXXXXXXXXXXXXXXXXXXXXXXXX........", "OOOOOOOOOOooo ......................XXXXXX.........O", "OOOOOOOOOOooo ......................XXX.........OOOO", "OOOOOOOOOOooo ................................OOOOO", "OOOOOOOOOOooo ......... oooOOOOO", "OOOOOOOOOOooo ...... oooOOOOO", "OOOOOOOOOOooo .. oooOOOOO", "OOOOOOOOOOooo oooOOOOO", "OOOOOOOOOOooo oooOOOOOOOOOO", "OOOOOOOOOOooo oooOOOOOOOOOO", "OOOOOOOOOOooo oooOOOOOOOOOO", "OOOOOOOOOOooo oooOOOOOOOOOO", "OOOOOOOOOOooo o oooOOOOOOOOOO", "OOOOOOOOOOooo ooo oooOOOOOOOOOO", "OOOOOOOOOOooo ooooo oooOOOOOOOOOO", "OOOOOOOOOOooo ooooo oooOOOOOOOOOO", "OOOOOOOOOOooo oooOooo oooOOOOOOOOOO", "OOOOOOOOOOooo ooooOoooo oooOOOOOOOOOO", "OOOOOOOOOOooo oooOOOooo oooOOOOOOOOOO", "OOOOOOOOOOooo ooooOOOoooo oooOOOOOOOOOO", "OOOOOOOOOOooo oooOOOOOooo oooOOOOOOOOOO", "OOOOOOOOOOooo oooOOOOOOOooo oooOOOOOOOOOO", "OOOOOOOOOOooo ooooOOOOOOOoooo oooOOOOOOOOOO", "OOOOOOOOOOooo ooooOOOOOOOOOooo oooOOOOOOOOOO", "OOOOOOOOOOooo ooooOOOOOOOOOoooo oooOOOOOOOOOO", "OOOOOOOOOOooo ooooOOOOOOOOOOOooooooooooooooooOOOOOOOOOO", "OOOOOOOOOOooooooooooooooooOOOOOOOOOOOOooooooooooooooooOOOOOOOOOO", "OOOOOOOOOOooooooooooooooooOOOOOOOOOOOOOoooooooooooooooOOOOOOOOOO", "OOOOOOOOOOoooooooooooooooOOOOOOOOOOOOOOOooooooooooooooOOOOOOOOOO", "OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO", "OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO", "OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO", "OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO", "OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO", "OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO" };""" remove_all_bookmarks_icon = """ /* XPM */ static char *_649039201346[] = { /* columns rows colors chars-per-pixel */ "64 64 4 1 ", " c black", ". c #ED1C24", "X c #C3C3C3", "o c None", "oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo", "oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo", "oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo", "oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo", "oooo...ooooooooooooooooooooooooooooooooooooooooooooooooo.....ooo", "oooo....ooooooooooooooooooooooooooooooooooooooooooooooo......ooo", "oooo.....ooooooooooooooooooooooooooooooooooooooooooooo.......ooo", "oooo......ooooooooooooooooooooooooooooooooooooooooooo.......oooo", "oooo.......ooooooooooooooooooooooooooooooooooooooooo.......ooooo", "ooooo.......XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX.......oooooo", "oooooo.......XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX.......ooooooo", "ooooooo.......XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX.......oooooooo", "oooooooo....... .......ooooooooo", "ooooooooo....... .......oooooooooo", "oooooooooo....... .......Xoooooooooo", "ooooooooooX....... .......XXoooooooooo", "ooooooooooXX....... .......XXXoooooooooo", "ooooooooooXXX....... ....... XXXoooooooooo", "ooooooooooXXX ....... ....... XXXoooooooooo", "ooooooooooXXX ....... ....... XXXoooooooooo", "ooooooooooXXX ....... ....... XXXoooooooooo", "ooooooooooXXX ....... ....... XXXoooooooooo", "ooooooooooXXX ....... ....... XXXoooooooooo", "ooooooooooXXX ....... ....... XXXoooooooooo", "ooooooooooXXX ....... ....... XXXoooooooooo", "ooooooooooXXX ....... ....... XXXoooooooooo", "ooooooooooXXX ....... ....... XXXoooooooooo", "ooooooooooXXX ....... ....... XXXoooooooooo", "ooooooooooXXX ....... ....... XXXoooooooooo", "ooooooooooXXX ............. XXXoooooooooo", "ooooooooooXXX ........... XXXoooooooooo", "ooooooooooXXX ......... XXXoooooooooo", "ooooooooooXXX ....... XXXoooooooooo", "ooooooooooXXX ......... XXXoooooooooo", "ooooooooooXXX ........... XXXoooooooooo", "ooooooooooXXX ............. XXXoooooooooo", "ooooooooooXXX ....... ....... XXXoooooooooo", "ooooooooooXXX ....... ....... XXXoooooooooo", "ooooooooooXXX ....... ....... XXXoooooooooo", "ooooooooooXXX ....... ....... XXXoooooooooo", "ooooooooooXXX ....... ....... XXXoooooooooo", "ooooooooooXXX ....... X ....... XXXoooooooooo", "ooooooooooXXX ....... XXX ....... XXXoooooooooo", "ooooooooooXXX ....... XXXXX ....... XXXoooooooooo", "ooooooooooXXX ....... XXXXX ....... XXXoooooooooo", "ooooooooooXXX ....... XXXoXXX ....... XXXoooooooooo", "ooooooooooXXX ....... XXXXoXXXX ....... XXXoooooooooo", "ooooooooooXXX....... XXXoooXXX ....... XXXoooooooooo", "ooooooooooXX....... XXXXoooXXXX .......XXXoooooooooo", "ooooooooooX....... XXXoooooXXX .......XXoooooooooo", "oooooooooo....... XXXoooooooXXX .......Xoooooooooo", "ooooooooo....... XXXXoooooooXXXX .......oooooooooo", "oooooooo....... XXXXoooooooooXXX .......ooooooooo", "ooooooo....... XXXXoooooooooXXXX .......oooooooo", "oooooo....... XXXXoooooooooooXXXXXXXXXXXX.......ooooooo", "ooooo.......XXXXXXXXXXXXXXooooooooooooXXXXXXXXXXXXX.......oooooo", "oooo.......XXXXXXXXXXXXXXXoooooooooooooXXXXXXXXXXXXX.......ooooo", "oooo......XXXXXXXXXXXXXXXoooooooooooooooXXXXXXXXXXXXX.......oooo", "oooo.....ooooooooooooooooooooooooooooooooooooooooooooo.......ooo", "oooo....ooooooooooooooooooooooooooooooooooooooooooooooo......ooo", "oooo...ooooooooooooooooooooooooooooooooooooooooooooooooo.....ooo", "oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo", "oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo", "oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo" };""" reverse_find_replace_icon = """ /* XPM */ static char * reverse_find_replace_icon_xpm[] = { /* columns rows colors chars-per-pixel */ "64 64 5 1", " c None", ". c #A70002", "+ c #EF2B29", "@ c #4E990D", "# c #8AE138", " ", " ", " ......... ", " ............. ", " ..+++++++++++.... ", " ..+++++++++++++++.. ", " ..+++++++++++++++++.. ", " ..+++++++++++++++++++.. ", " ..+++++++++++++++++++++.. ", " ..+++++++++++++++++++++++.. ", " ..+++........++++++++++++++.. ", " ..++.. ..+++++++++++++.. ", " ..++.. ..+++++++++++++.. ", " .++.. ..+++++++++++++. ", " .++.. ..++++++++++++.. ", " .++. ..+++++++++++.. ", " .... ..++++++++++++. ", " .++++++++++++. ", " .++++++++++++. ", " ..........++++++++++++. ", " .+++++++++++++++++++++........... ", " .+++++++++++++++++++++........... ", " ..+++++++++++++++++++++++++++++.. ", " ..+++++++++++++++++++++++++++.. ", " ..+++++++++++++++++++++++++.. ", " ..+++++++++++++++++++++++.. ", " @@ ..+++++++++++++++++++++.. ", " @@@@ ..+++++++++++++++++++.. ", " @@##@@ ..+++++++++++++++++.. ", " @@####@@ ..+++++++++++++++.. ", " @@######@@ ..+++++++++++++.. ", " @@########@ ..+++++++++++.. ", " @@#########@@ ..+++++++++.. ", " @@###########@@ .++++++++.. ", " @@#############@@ ..++++++.. ", " @@###############@@ ..++++.. ", " @@#################@@ ..++.. ", " @@###################@@ .... ", " @@#####################@@ .. ", " @@#######################@@ ", " @@#########################@@ ", " @@###########################@@ ", " @@#############################@@ ", " @@@@@@@@@@@#####################@ ", " @@@@@@@@@@@#####################@ ", " @############@@@@@@@@@@ ", " @############@ ", " @############@ ", " @############@@ @@@@ ", " @@###########@@ @##@ ", " @@############@@ @@##@ ", " @#############@@ @@##@ ", " @@#############@@ @@##@@ ", " @@#############@@ @@##@@ ", " @@##############@@@@@@@@###@@ ", " @@#######################@@ ", " @@#####################@@ ", " @@###################@@ ", " @@#################@@ ", " @@###############@@ ", " @@@@###########@@ ", " @@@@@@@@@@@@@ ", " @@@@@@@@@ ", " " };""" execute_Template_icon = """ /* XPM */ static char * execute_Template_icon_xpm[] = { /* columns rows colors chars-per-pixel */ "64 64 5 1", " c None", ". c #192A02", "+ c #5AA909", "@ c #7CD124", "# c #85E033", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ... ", " ..... ", " ..+++.. ", " ..+###+.. ", " ..+#####+.. ", " ..+###+###+.. ", " ..+###+++###+.. ", " ..+###+++++###+.. ", " ..+###+++++++###+.. ", " ..+###+++++++++###+.. ", " ..+###+++++++++++##+.. ", " ..+###+++++++++++##+.. ", " . ..+###+++++++++++##+.. ", " ... ..+###+++++++++++##+.. ", " ..... ..+###+++++++++++##+.. ", " ..+++.. ..+###+++++++++++##+.. ", " ..+###+.. ..+###+++++++++++##+.. ", " ..+#####+.. ..+###+++++++++++##+.. ", " ..+###++##+.. ..+###+++++++++++##+.. ", " ..+###++++##+.. ..+###+++++++++++##+.. ", " ..+###++++++##+.. ..+###+++++++++++##+.. ", " ..+###++++++++##+.. ..+###+++++++++++##+.. ", " ..+###++++++++++##+.. ..+###+++++++++++##+.. ", " ..+##++++++++++++##+.. ..+###+++++++++++##+.. ", " ..+##++++++++++++##+.. ..+###+++++++++++##+.. ", " ..+##++++++++++++##+...+###+++++++++++##+.. ", " ..+##++++++++++++##+.+###+++++++++++##+.. ", " ..+##++++++++++++##+###+++++++++++##+.. ", " ..+##++++++++++++####+++++++++++##+.. ", " ..+##++++++++++++##+++++++++++##+.. ", " ..+##+++++++++++++++++++++++##+.. ", " ..+##+++++++++++++++++++++##+.. ", " ..+##+++++++++++++++++++##+.. ", " ..+##+++++++++++++++++##+.. ", " ..+##+++++++++++++++##+.. ", " ..+##+++++++++++++##+.. ", " ..+##+++++++++++##+.. ", " ..+##+++++++++##+.. ", " ..+##+++++++##+.. ", " ..+##+++++##+.. ", " ..+##+++##+.. ", " ..+##+##+.. ", " ..+###+.. ", " ..+#+.. ", " ..... ", " ... ", " . ", " ", " ", " ", " ", " ", " " };""" plus_Template_icon = """ /* XPM */ static char * plus_Template_icon_xpm[] = { /* columns rows colors chars-per-pixel */ "64 64 9 1", " c None", ". c #1B2B03", "+ c #365712", "@ c #56A506", "# c #66BA15", "$ c #6EC21B", "% c #7ACD22", "& c #7DD728", "* c #86E235", " ", " ", " ", " ", " ................ ", " ................ ", " ..************.. ", " ..************.. ", " ..**@@@@@@@@**.. ", " ..**@@@@@@@@**.. ", " ..**@@@@@@@@**.. ", " ..**@@@@@@@@**.. ", " ..**@@@@@@@@**.. ", " ..**@@@@@@@@**.. ", " ..**@@@@@@@@**.. ", " ..**@@@@@@@@**.. ", " ..**@@@@@@@@**.. ", " ..**@@@@@@@@**.. ", " ..**@@@@@@@@**.. ", " ..**@@@@@@@@**.. ", " ..**@@@@@@@@**.. ", " ..**@@@@@@@@**.. ", " ..**@@@@@@@@**.. ", " ..**@@@@@@@@**.. ", " ......................**@@@@@@@@**...................... ", " ......................**@@@@@@@@**...................... ", " ..**********************@@@@@@@@**********************.. ", " ..**********************@@@@@@@@**********************.. ", " ..**@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@**.. ", " ..**@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@**.. ", " ..**@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@**.. ", " ..**@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@**.. ", " ..**@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@**.. ", " ..**@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@**.. ", " ..**@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@**.. ", " ..**@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@**.. ", " ..**********************@@@@@@@@**********************.. ", " ..**********************@@@@@@@@**********************.. ", " ......................**@@@@@@@@**...................... ", " ......................**@@@@@@@@**...................... ", " ..**@@@@@@@@**.. ", " ..**@@@@@@@@**.. ", " ..**@@@@@@@@**.. ", " ..**@@@@@@@@**.. ", " ..**@@@@@@@@**.. ", " ..**@@@@@@@@**.. ", " ..**@@@@@@@@**.. ", " ..**@@@@@@@@**.. ", " ..**@@@@@@@@**.. ", " ..**@@@@@@@@**.. ", " ..**@@@@@@@@**.. ", " ..**@@@@@@@@**.. ", " ..**@@@@@@@@**.. ", " ..**@@@@@@@@**.. ", " ..**@@@@@@@@**.. ", " ..**@@@@@@@@**.. ", " ..************.. ", " ..************.. ", " ................ ", " ................ ", " ", " ", " ", " " };""" moins_Template_icon = """ /* XPM */ static char * moins_Template_icon_xpm[] = { /* columns rows colors chars-per-pixel */ "64 64 9 1", " c None", ". c #290000", "+ c #2C0001", "@ c #AA0004", "# c #B60008", "$ c #C30D0D", "% c #D61819", "& c #E51E22", "* c #EE2A28", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ........................................................ ", " ..++++++++++++++++++++++++++++++++++++++++++++++++++++.. ", " .+****************************************************+. ", " .+****************************************************+. ", " .+**@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@**+. ", " .+**@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@**+. ", " .+**@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@**+. ", " .+**@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@**+. ", " .+**@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@**+. ", " .+**@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@**+. ", " .+**@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@**+. ", " .+**@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@**+. ", " .+****************************************************+. ", " .+****************************************************+. ", " ..++++++++++++++++++++++++++++++++++++++++++++++++++++.. ", " ........................................................ ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " " };""" rename_Template_icon = """ /* XPM */ static char * rename_Template_icon_xpm[] = { /* columns rows colors chars-per-pixel */ "64 64 9 1", " c None", ". c #000000", "+ c #A70002", "@ c #154A89", "# c #3167A7", "$ c #4B9A00", "% c #499B1C", "& c #898B88", "* c #C3A000", " ", " ", " ", " @@@@@@@ ", " @@@@@@@@@@@@@@@@ ", " @@@@#############@@@@@ @ ", " @@####################@@@ @@ ", " @@########################@@@ @@@ ", " @@###########################@@@ @@#@ ", " @@##############################@@@ @##@ ", " @@#################################@@ @@##@ ", " @###################################@@@ @@###@ ", " @@####################################@@@@####@ ", " @@########@@@@@@@@@######################@##@##@ ", " @@#####@@@@@@@@@@@@@@@@####################@@##@ ", " @####@@@@@@@@@ @@@#################@@@##@ ", " @@###@@@ @@@@ @@@@#############@@@@##@ ", " @@##@@ @@@ @@@##########@@@@@##@ ", " @##@@ @@@ @@@#######@@@@@@##@ ", " @#@@ @@ @@@#####@@@@@@@##@ ", " @#@ @@ @@@##@@@@@@@@##@ ", " @@@ @@@ @@#@@@@@@@@@##@ ", " @@ @@@ @@#@@@@@@@@@@##@ ", " @@ @@ @@#@@@@@@@@@@@##@ ", " @@........* @@#@@@@@@@@@@@@##@ ", " @@.++++++.* @#@@@@@@@@@@@@@##@ ", " @@.++++++.* @@################@ ", " @.+++++++.* @@#################@ ", " .+++*++++.* @@@@@@@@@@@@@@@@@@@@@ ", " .+++*++++.* ", " .++++*+++++.* ......... ", " .+++* .++++.* .&&&&&&&. ", " .+++* .++++.* .&&&&&&&. ", " .+++* .++++.* ...&&&... .................* ", " .+++* .++++.* .&&&. .$$$$$$$$$$$$$%%.* ", " .++++* .+++++.* .&&&. .$$$$$$$$$$$$$$$%.* ", " .+++* .++++.* .&&&. .$$$$$$$$$$$$$$$$%.* ", " .+++* .++++.* .&&&. .$$$%*.......$$$$%.* ", " .+++* .++++.* .&&&. .$$$%* .$$$$%.* ", " .++++++++++++++++.* .&&&. .$$$%* .$$$%.* ", " .+++++++++++++++++.* .&&&. .$$$%* .$$$%.* ", " .++++++++++++++++++.* .&&&. .$$$%* .$$$%.* ", " .+++***********++++.* .&&&. .$$$%*********$$$%.* ", " .++++* .++++.* .&&&. .$$$%%%%%%%%%$$$$%.* ", " .+++* .++++.* .&&&. .$$$$$$$$$$$$$$$%.* ", " .+++* .++++.* .&&&. .$$$$$$$$$$$$$$$%.* ", " .+++* .++++.* .&&&. .$$$$$$$$$$$$$$$$%.* ", " .+++* .++++.* .&&&. .$$$%*.......$$$$$%.* ", " .++++* .+++++.* .&&&. .$$$%* ..$$$%.* ", " .+++* .++++.* .&&&. .$$$%* .$$$%.* ", " ***** ......* .&&&. .$$$%* .$$$%.* ", " ****** .&&&. .$$$%* .$$$%.* ", " .&&&. .$$$%* .$$$%.* ", " .&&&. .$$$%* .$$$%.* ", " .&&&. .$$$%**********$$$%.* ", " ...&&&... .$$$%%%%%%%%%%$$$$%.* ", " .&&&&&&&. .$$$$$$$$$$$$$$$$%.* ", " .&&&&&&&. .$$$$$$$$$$$$$$$%.* ", " ......... .$$$$$$$$$$$$$%%.* ", " .%%%%%%%%%%%%%..* ", " ..............** ", " ************** ", " ", " " };""" test_Template_icon = """ /* XPM */ static char * test_Template_icon_xpm[] = { /* columns rows colors chars-per-pixel */ "64 64 9 1", " c None", ". c #1A2A01", "+ c #313436", "@ c #184C8A", "# c #565855", "$ c #616360", "% c #5BA900", "& c #84E033", "* c #D3DAE2", " +###+ ", " ++***#+ ", " ++#****+ ", " ++####*#+ ", " ++######++ ", " ++######++ ", " ++######++ ", " ++#######++ ", " ++#######++ ", " +++++++++++++ ++#######++ ", " +#############+++#######++ ", " +###*************########+ ... ", " +##***@@@@@@@@@****######++ ..... ", " +##***@@@@@@@@@@@@***####++ ..%%%.. ", " +##**@@@@@******@@@@****#++ ..%&&&%.. ", " +##***@@@**********@@@***#+ ..%&&&&&%.. ", " +##**@@@************@@@***#+ ..%&&&%&&&%.. ", " +#**@@@*************@@@***#+ ..%&&&%%%&&&%.. ", " +#**@@************@@@@@@**#+ ..%&&&%%%%%&&&%.. ", " +#*@@@************@@@@@@**#+ ..%&&&%%%%%%%&&&%.. ", " +#*@@@***********@@@@@@@**#+ ..%&&&%%%%%%%%%&&&%.. ", " +#*@@************@@@@@@@**#+ ..%&&&%%%%%%%%%%%&&%.. ", " +#*@@***********@@@@@@@@**#+ ..%&&&%%%%%%%%%%%&&%.. ", " +#*@@@*********@@@@@@@@@**#+ ..%&&&%%%%%%%%%%%&&%.. ", " +#*@@@*********@@@@@@@@@**#+ ..%&&&%%%%%%%%%%%&&%.. ", " +#*@@@********@@@@@@@@@@**#+ ..%&&&%%%%%%%%%%%&&%.. ", " +#**@@@*****@@@@@@@@@@@@**#+ ..%&&&%%%%%%%%%%%&&%.. ", " +#**@@@@**@@@@@@@@@@@@@***#+ ..%&&&%%%%%%%%%%%&&%.. ", " +##**@@@@@@@@@@@@@@@@@@**##+..%&&&%%%%%%%%%%%&&%.. ", " +##**@@@@@@@@@@@@@@@@**##+..%&&&%%%%%%%%%%%&&%.. ", " ..+##**@@@@@@@@@@@@@@**##+..%&&&%%%%%%%%%%%&&%.. ", " ..%&+##**@@@@@@@@@@@@**##+..%&&&%%%%%%%%%%%&&%.. ", " ..%&&&+##**@@@@@@@@@***##+..%&&&%%%%%%%%%%%&&%.. ", " ..%&&&%%+##************##+..%&&&%%%%%%%%%%%&&%.. ", " ..%&&%%%%+##############+..%&&&%%%%%%%%%%%&&%.. ", " ..%&&%%%%++++++++++++++..%&&&%%%%%%%%%%%&&%.. ", " ..%&&%%%%%%%%%%%%&&%...%&&&%%%%%%%%%%%&&%.. ", " ..%&&%%%%%%%%%%%%&&%.%&&&%%%%%%%%%%%&&%.. ", " ..%&&%%%%%%%%%%%%&&%&&&%%%%%%%%%%%&&%.. ", " ..%&&%%%%%%%%%%%%&&&&%%%%%%%%%%%&&%.. ", " ..%&&%%%%%%%%%%%%&&%%%%%%%%%%%&&%.. ", " ..%&&%%%%%%%%%%%%%%%%%%%%%%%&&%.. ", " ..%&&%%%%%%%%%%%%%%%%%%%%%&&%.. ", " ..%&&%%%%%%%%%%%%%%%%%%%&&%.. ", " ..%&&%%%%%%%%%%%%%%%%%&&%.. ", " ..%&&%%%%%%%%%%%%%%%&&%.. ", " ..%&&%%%%%%%%%%%%%&&%.. ", " ..%&&%%%%%%%%%%%&&%.. ", " ..%&&%%%%%%%%%&&%.. ", " ..%&&%%%%%%%&&%.. ", " ..%&&%%%%%&&%.. ", " ..%&&%%%&&%.. ", " ..%&&%&&%.. ", " ..%&&&%.. ", " ..%&%.. ", " ..... ", " ... ", " . ", " ", " ", " ", " ", " ", " " };""" execute_Clipboard_Template_icon = """ /* XPM */ static char * execute_Clipboard_Template_icon_xpm[] = { /* columns rows colors chars-per-pixel */ "64 64 9 1", " c None", ". c #1A2A01", "+ c #303436", "@ c #56A506", "# c #898B88", "$ c #949693", "% c #A9ABA8", "& c #86E235", "* c #FFFFFF", " +++++++++ ", " +++++++%+++ ", " ++%*****+++%++ ", " +********+++%++ ", " ++++++++++********+++++%++ ", " ++#######++%*******++++++++++++++ ", " ++#********%*******++++++++%$%%%%$++ ", " +#********+********+++++++++++++++++ ", " +#********+++******+++++++++*****++++++ ", " +********+++++********+++++*****++++++++ ", " +#******+++++++**********++*****+++++++++ ", " +#****+++$++$+%*********+++****+++++++++... ", " +*****$$%****+..*******+++++**+++++++++..... ", " +****$%******++..******+++++++++++++++..@@@.. ", " +#####********++.%%%%++++++++++++++++..@&&&@.. ", " +######********++%.......++++++++++++..@&&&&&@.. ", " +++*****#*******+++++%+++++..%+%$.....%..@&&&@&&&@.. ", " +#**************++++++****++%.$...**%%..@&&&@@@&&&@.. ", " +#******##*********+++*****+++$.#*****..@&&&@@@@@&&&@.. ", " +******+***********++*****+++++.#****..@&&&@@@@@@@&&&@.. ", " ++*****++**********++++**+++++++.#***..@&&&@@@@@@@@@&&&@.. ", " +*****++**********++++++++++++++.#**..@&&&@@@@@@@@@@@&&@.. ", " ++***+++********++++++++++++++++.#*..@&&&@@@@@@@@@@@&&@.. ", " +**+++********++++**+++++++++++.%..@&&&@@@@@@@@@@@&&@.. ", " ++**+++*******++++**+++++++++++....@&&&@@@@@@@@@@@&&@.. ", " ++*****+*****+++++**+++++++++++....@&&&@@@@@@@@@@@&&@.. ", " ++******+****++++++*+++++++++++++..@&&&@@@@@@@@@@@&&@.. ", " +******++***++++++++++++++++++++..@&&&@@@@@@@@@@@&&@.... ", " +*****++++*++++++++++++++++++++..@&&&@@@@@@@@@@@&&@..%. ", " +****+++++++++++++++++++++++++..@&&&@@@@@@@@@@@&&@..%... ", " +#**+++++++++++++++++++++++++..@&&&@@@@@@@@@@@&&@..%%.... ", " +#*+++++++++++++++++++++++++..@&&&@@@@@@@@@@@&&@..%%.%%%.. ", " +.#*+++++++++++++++++++++++..@&&&@@@@@@@@@@@&&@..%%%%%%%.. ", " +..#*****+++++++++++++++++..@&&&@@@@@@@@@@@&&@..%%%%%%%%.. ", " ......+++++++++++++........@&&&@@@@@@@@@@@&&@..%%%%%%%%%%.. ", " ..@&.....................@&&&@@@@@@@@@@@&&@..%%%%%%%%%%.. ", " ..@&&@@@@@@@@@@@@&&@...@&&&@@@@@@@@@@@&&@..%%%%%%%%%%%.. ", " ..@&&@@@@@@@@@@@@&&@.@&&&@@@@@@@@@@@&&@..%%%%%%%%%%%%.. ", " ..@&&@@@@@@@@@@@@&&@&&&@@@@@@@@@@@&&@..%%%%%%%%%%%... ", " ..@&&@@@@@@@@@@@@&&&&@@@@@@@@@@@&&@................ ", " ..@&&@@@@@@@@@@@@&&@@@@@@@@@@@&&@................ ", " ..@&&@@@@@@@@@@@@@@@@@@@@@@@&&@.. ", " ..@&&@@@@@@@@@@@@@@@@@@@@@&&@.. ", " ..@&&@@@@@@@@@@@@@@@@@@@&&@.. ", " ..@&&@@@@@@@@@@@@@@@@@&&@.. ", " ..@&&@@@@@@@@@@@@@@@&&@.. ", " ..@&&@@@@@@@@@@@@@&&@.. ", " ..@&&@@@@@@@@@@@&&@.. ", " ..@&&@@@@@@@@@&&@.. ", " ..@&&@@@@@@@&&@.. ", " ..@&&@@@@@&&@.. ", " ..@&&@@@&&@.. ", " ..@&&@&&@.. ", " ..@&&&@.. ", " ..@&@.. ", " ..... ", " ... ", " . ", " ", " ", " ", " ", " ", " " };""" annuler_Template_icon = """ /* XPM */ static char * annuler_Template_icon_xpm[] = { /* columns rows colors chars-per-pixel */ "64 64 9 1", " c None", ". c #290000", "+ c #1A2A01", "@ c #A30500", "# c #C41015", "$ c #DE2221", "% c #EE2A28", "& c #5BA900", "* c #84E033", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " . . +++ ", " ... ... +++++ ", " ..#.. ..#.. ++&&&++ ", " ..#%#.. ..#%#.. ++&***&++ ", " ..#%%%#.. ..#%%%#..++&*****&++ ", " ..#%%#%%#.. ..#%%#%%#..&***&***&++ ", " ..#%%###%%#.. ..#%%###%%#..**&&&***&++ ", " ..#%%#####%%#.. ..#%%#####%%#..&&&&&***&++ ", " ..#%%#######%%#.. ..#%%#######%%#..&&&&&***&++ ", " ..#%%#########%%#.. ..#%%#########%%#..&&&&&***&++ ", " ..#%%#########%%#...#%%#########%%#..&&&&&&&**&++ ", " ..#%%#########%%#.#%%#########%%#..&&&&&&&**&++ ", " + ..#%%#########%%#%%#########%%#..&&&&&&&**&++ ", " +++ ..#%%#########%%%#########%%#..&&&&&&&**&++ ", " +++++ ..#%%#########%#########%%#..&&&&&&&**&++ ", " ++&&&++ ..#%%#################%%#..&&&&&&&**&++ ", " ++&***&++ ..#%%###############%%#..&&&&&&&**&++ ", " ++&*****&++ ..#%%#############%%#..&&&&&&&**&++ ", " ++&***&&**&++ ..#%%###########%%#..&&&&&&&**&++ ", " ++&***&&&&**&++ ..#%%#########%%#..&&&&&&&**&++ ", " ++&***&&&&&&**&++..#%%###########%%#..&&&&&**&++ ", " ++&***&&&&&&&&**&..#%%#############%%#..&&&**&++ ", " ++&***&&&&&&&&&&*..#%%###############%%#..&**&++ ", " ++&**&&&&&&&&&&&..#%%#################%%#..*&++ ", " ++&**&&&&&&&&&..#%%#########%#########%%#..++ ", " ++&**&&&&&&&..#%%#########%%%#########%%#.. ", " ++&**&&&&&..#%%#########%%#%%#########%%#.. ", " ++&**&&&..#%%#########%%#.#%%#########%%#.. ", " ++&**&..#%%#########%%#...#%%#########%%#.. ", " ++&*..#%%#########%%#..&..#%%#########%%#.. ", " ++&*..#%%#######%%#..&&&..#%%#######%%#.. ", " ++&*..#%%#####%%#..&&&&&..#%%#####%%#.. ", " ++&*..#%%###%%#..&&&&&&&..#%%###%%#.. ", " ++&*..#%%#%%#..&&&&&&&**..#%%#%%#.. ", " ++&*..#%%%#..&&&&&&&**&+..#%%%#.. ", " ++&*..#%#..&&&&&&&**&++ ..#%#.. ", " ++&*..#..&&&&&&&**&++ ..#.. ", " ++&*...&&&&&&&**&++ ... ", " ++&*.&&&&&&&**&++ . ", " ++&**&&&&&**&++ ", " ++&**&&&**&++ ", " ++&**&**&++ ", " ++&***&++ ", " ++&*&++ ", " +++++ ", " +++ ", " + ", " ", " ", " ", " ", " ", " " };""" help_Template_icon = """ /* XPM */ static char * help_Template_icon_xpm[] = { /* columns rows colors chars-per-pixel */ "64 64 9 1", " c None", ". c #5D5F5C", "+ c #7A7C78", "@ c #867D44", "# c #DDC91B", "$ c #F4E135", "% c #ECDF6D", "& c #FEF8C7", "* c #FDFEF9", " ", " ", " ", " ", " ", " ", " # # # # # ", " # # ## # # ", " # # # # # # ", " # # # # # # # # ", " # # # # # # ", " # # ", " # ## # # # # # # # # # # # # # ", " # # # ##$ $ $ $$$ # # # ", " # # # ### ##$$$$$$$$$$$$# # # # ", " # #$$$$$$$$$$$$$# # # ", " ## # ##$$$$$$$$$$$$$$$$### # ", " # # # # ###$$$$$$$$$$$$$$$$$# # # ", " # # #$#$$$$$$$$$$$$$$$$$$$### # ", " ##$$$$$$$$$%%%%%%$$$$$$$$# # ", " ## # ##$$$$$$$$$%&&&&&%$$$$$$$$### # ", " # # # ###$$$$$$$$%&****&%$$$$$$$$$# # # ", " ##$$$$$$$$%%&&****&&%%$$$$$$$$# # ", " # ###$$$$$$$$%&&*******&&$$$$$$$$ # # ", " # ##$$$$$$$$%%&&*********&%%$$$$$$$$$## # ", " # # $$$$$$$$$%&&**********&&&%$$$$$$$$# ", " # #$$$$$$$$$&&*************&%$$$$$$$$## # ", " ## $$$$$$$$$&**************&%$$$$$$$$# ", " #$$$$$$$$$&**************&%$$$$$$$$ # ", " # $$$$$$$$$&**************&%$$$$$$$ # # ", " # #$$$$$$$$$&**************&%$$$$$$$$## ", " # $$$$$$$$$&**************&%$$$$$$$$# ", " # #$$$$$$$$$%&&***********&&%$$$$$$$$## ", " # # $$$$$$$$$%%&&*********&&%%$$$$$$$$# ", " ####$$$$$$$$%&********&&%$$$$$$$$#### # ", " # #$$$$$$$$%&&&*****&&%$$$$$$$$ # # ", " # ###$$$$$$$$%%&****&&%$$$$$$$$$# # # ", " # # #$$$$$$$$%%&&&&&%$$$$$$$$## # ", " # #$$$$$$$$%%&&%%%$$$$$$$$# # ", " # $ $$$$$$$%%%%$$$$$$$$ # # ", " # ## # # ##$$$$$$$$$$$$$$$$$#### # # ", " # #$#$$$$$$$$$$$$$$$# # ", " ######$$$$$$$$####### ", " # # @%##$$$$$$$##%% # # ", " @.@%#########%@@@ # # ", " # .@@%%%%%%%%%@.... ", " ...@@@@@@@@@@..... ", " .................. ", " ...++++++++++..... ", " ...+++++++++++.... ", " ...++++++++++..... ", " .................. ", " .................. ", " ...++++++++++..... ", " ...+++++++++++.... ", " ...++++++++++..... ", " .................. ", " ................. ", " +++++++++++++++++ ", " ++++++++++++++ ", " ++++++++++++++ ", " +++++++++++ ", " ", " " };""" save_Template_icon = """ /* XPM */ static char * save_Template_icon_xpm[] = { /* columns rows colors chars-per-pixel */ "64 64 10 1", " c None", ". c #4E9A06", "+ c #FFFFFF", "@ c #345F9A", "# c #7495BF", "$ c #545653", "% c #BABDB6", "& c #555754", "* c #D6D8D5", "= c #888A85", " ", " . ", " .+. ", " .+.+. ", " .+...+. ", " @@@@@@@@@ .+.....+. ", " @@@@#######@@@@ . .+.......+. ", " @@#############@@ .+. .+.......+. ", " @@###############@@ .+.+. .+.......+. ", " @#################@@ .+...+. .+.......+. ", " @@###################@@ .+.....+.+.......+. ", " @###@@@@@@@###########@@ .+.......+.......+. ", " @@##@@ @@###########@@ .+.............+. ", " @@#@@ @@##########@@ .+...........+. ", " @#@ @@@#########@ .+.........+. ", " @@ @#########@ .+.......+. ", " @@ $$$$$$$$$$@#########@@$$$$$$$.+.....+. ", " @ $$%%%%%%%%%@@#########@%%%%%%%%.+...+. ", " $$$%%%%%%%%%%@#########@%%%%%%%%%.+.+. ", " $$%@@@@@@@@@@@#########@@@@@@@@@@@.+. ", " $$%@@############################@@.$ ", " $%%%@@##########################@@%%$ ", " $$%%%%@@#############@@@@@@@@@##@@%%%$$ ", " $$%%%%%%@@##########@@@@@@@@@@##@@%%%%$$ ", " $$%%%%%%%@@#######@@@@@@@@@@@##@@%%%%%%$$ ", " $$%%%%%%%%%@@####@@@@@@@@@@@@##@@%%%%%%%$$ ", " $$%%%%%%%%%%@@##@@@@@@@@@@@@##@@%%%%%%%%%$ ", " $$%%%%%%%%%%%@@##@@@@@@@@@@##@@%%%%%%%%%%$$ ", " $$%%%%%%%%%%%%%@@##@@@@@@@@##@@%%%%%%%%%%%$$ ", " $$%%%%%%%%%%%%%%@@##@@@@@@##@@%%%%%%%%%%%%%$ ", " $$%%%%%%%%%%%%%%%%@@##@@@@##@@%%%%%%%%%%%%%%$$ ", " $$%%%%%%%%%%%%%%%%%@@##@@##@@%%%%%%%%%%%%%%%%$ ", " $$%%%%%%%%%%%%%%%%%%%@@#@##@@%%%%%%%%%%%%%%%%%$$ ", " $$%%%%%%%%%%%%%%%%%%%%@@##@@%%%%%%%%%%%%%%%%%%$$ ", " $$%%%%%%%%%%%%%%%%%%%%%@@@@%%%%%%%%%%%%%%%%%%%%$$ ", " $%%%%%%%%%%%%%%%%%%%%%%%@@%%%%%%%%%%%%%%%%%%%%%$$ ", " $$%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%$ ", " $$%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%$$ ", " $$%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%$$$ ", " $$%%%%%%%%%%%%%%%&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&$$ ", " $$%%%%%%%%%%%%%%%&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&$$ ", " $$%&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&$$ ", " $$%&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&$$ ", " $$%&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&$$ ", " $$%&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&***&***&***&***&&&$$ ", " $$%&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&***&***&***&***&&&$$ ", " $$%&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&***&***&***&***&&&$$ ", " $$%&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&***&***&***&***&&&$$ ", " $$%&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&***&***&***&***&&&$$ ", " $$%&&&&*************&&&&&&&&&&&&&***&***&***&***&&&$$ ", " $$%&&&&*************&&&&&&&&&&&&&***&***&***&***&&&$$ ", " $$%&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&$$ ", " $$=**********************&&&&&&&&&&&&&&&&&&&&&&&&&$$$ ", " $$&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&$$ ", " $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ ", " ", " ", " ", " ", " ", " ", " ", " ", " " };""" accept_Template_icon = """ /* XPM */ static char * accept_Template_icon_xpm[] = { /* columns rows colors chars-per-pixel */ "64 64 5 1", " c None", ". c #192A02", "+ c #5AA909", "@ c #7CD124", "# c #85E033", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ... ", " ..... ", " ..+++.. ", " ..+###+.. ", " ..+#####+.. ", " ..+###+###+.. ", " ..+###+++###+.. ", " ..+###+++++###+.. ", " ..+###+++++++###+.. ", " ..+###+++++++++###+.. ", " ..+###+++++++++++##+.. ", " ..+###+++++++++++##+.. ", " . ..+###+++++++++++##+.. ", " ... ..+###+++++++++++##+.. ", " ..... ..+###+++++++++++##+.. ", " ..+++.. ..+###+++++++++++##+.. ", " ..+###+.. ..+###+++++++++++##+.. ", " ..+#####+.. ..+###+++++++++++##+.. ", " ..+###++##+.. ..+###+++++++++++##+.. ", " ..+###++++##+.. ..+###+++++++++++##+.. ", " ..+###++++++##+.. ..+###+++++++++++##+.. ", " ..+###++++++++##+.. ..+###+++++++++++##+.. ", " ..+###++++++++++##+.. ..+###+++++++++++##+.. ", " ..+##++++++++++++##+.. ..+###+++++++++++##+.. ", " ..+##++++++++++++##+.. ..+###+++++++++++##+.. ", " ..+##++++++++++++##+...+###+++++++++++##+.. ", " ..+##++++++++++++##+.+###+++++++++++##+.. ", " ..+##++++++++++++##+###+++++++++++##+.. ", " ..+##++++++++++++####+++++++++++##+.. ", " ..+##++++++++++++##+++++++++++##+.. ", " ..+##+++++++++++++++++++++++##+.. ", " ..+##+++++++++++++++++++++##+.. ", " ..+##+++++++++++++++++++##+.. ", " ..+##+++++++++++++++++##+.. ", " ..+##+++++++++++++++##+.. ", " ..+##+++++++++++++##+.. ", " ..+##+++++++++++##+.. ", " ..+##+++++++++##+.. ", " ..+##+++++++##+.. ", " ..+##+++++##+.. ", " ..+##+++##+.. ", " ..+##+##+.. ", " ..+###+.. ", " ..+#+.. ", " ..... ", " ... ", " . ", " ", " ", " ", " ", " ", " " };""" reject_Template_icon = """ /* XPM */ static char * reject_Template_icon_xpm[] = { /* columns rows colors chars-per-pixel */ "64 64 9 1", " c None", ". c #000000", "+ c #860002", "@ c #BF0001", "# c #FA1F1F", "$ c #CA3432", "% c #DF4846", "& c #F99B9B", "* c #EBE9E6", " @@@@@@@@@@@@@@@@@@@@@@@@ ", " @@@@@@@@@@@@@@@@@@@@@@@@@@ ", " @@************************@@ ", " @@**@@@@@@@@@@@@@@@@@@@@@@**@@ ", " @@**@@@@@@@@@@@@@@@@@@@@@@@@**@@ ", " @@**@@@@@@@@@@@@@@@@@@@@@@@@@@**@@ ", " @@**@@@@@@@@@@@@@@@@@@@@@@@@@@@@**@@ ", " @@**@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@**@@ ", " @@**@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@**@@ ", " @@**@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@**@@ ", " @@**@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@**@@ ", " @@**@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@**@@ ", " @@**@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@**@@ ", " @@**@@@@@@@@@@...@@@@@@@@@@@@@@@@@@...@@@@@@@@**@@ ", " @@**@@@@@@@@@@..*..@@@@@@@@@@@@@@@@..*..@@@@@@@@**@@ ", " @@**@@@@@@@@@@..***..@@@@@@@@@@@@@@..***..@@@@@@@@**@@ ", " @@**@@@@@@@@@@..*****..@@@@@@@@@@@@..*****..@@@@@@@@**@@ ", " @@**@@@@@@@@@@..*******..@@@@@@@@@@..*******..@@@@@@@@**@@ ", " @@*@@@@@@@@@@..*********..@@@@@@@@..*********..@@@@@@@@*@@ ", " @@*@@@@@@@@@@.***********..@@@@@@..***********.@@@@@@@@*@@ ", " @@*@@@@@@@@@@..***********..@@@@..***********..@@@@@@@@*@@ ", " @@*@@@@@@@@@@@..***********..@@..***********..@@@@@@@@@*@@ ", " @@*@@@@@@@@@@@@..***********....***********..@@@@@@@@@@*@@ ", " @@*@@@@@@@@@@@@@..***********..***********..@@@@@@@@@@@*@@ ", " @@*@@@@@@@@@@@@@@..**********************..@@@@@@@@@@@@*@@ ", " @@*@@@@@@@@@@@@@@@..********************..@@@@@@@@@@@@@*@@ ", " @@*@@@@@@@@@@@@@@@@..******************..@@@@@@@@@@@@@@*@@ ", " @@*@@@@@@@@@@@@@@@@@..****************..@@@@@@@@@@@@@@@*@@ ", " @@*@@@@@@@@@@@@@@@@@@..**************..@@@@@@@@@@@@@@@@*@@ ", " @@*@@@@@@@@@@@@@@@@@@@..************..@@@@@@@@@@@@@@@@@*@@ ", " @@*@@@@@@@@@@@@@@@@@@@..************..@@@@@@@@@@@@@@@@@*@@ ", " @@*@@@@@@@@@@@@@@@@@@..**************..@@@@@@@@@@@@@@@@*@@ ", " @@*@@@@@@@@@@@@@@@@@..****************..@@@@@@@@@@@@@@@*@@ ", " @@*@@@@@@@@@@@@@@@@..******************..@@@@@@@@@@@@@@*@@ ", " @@*@@@@@@@@@@@@@@@..********************..@@@@@@@@@@@@@*@@ ", " @@*@@@@@@@@@@@@@@..**********************..@@@@@@@@@@@@*@@ ", " @@*@@@@@@@@@@@@@..***********..***********..@@@@@@@@@@@*@@ ", " @@*@@@@@@@@@@@@..***********....***********..@@@@@@@@@@*@@ ", " @@*@@@@@@@@@@@..***********..@@..***********..@@@@@@@@@*@@ ", " @@*@@@@@@@@@@..***********..@@@@..***********.@@@@@@@@@*@@ ", " @@*@@@@@@@@@@.***********..@@@@@@..*********..@@@@@@@@@*@@ ", " @@**@@@@@@@@@..*********..@@@@@@@@..*******..@@@@@@@@@@*@@ ", " @@**@@@@@@@@@..*******..@@@@@@@@@@..*****..@@@@@@@@@@**@@ ", " @@**@@@@@@@@@..*****..@@@@@@@@@@@@..***..@@@@@@@@@@**@@ ", " @@**@@@@@@@@@..***..@@@@@@@@@@@@@@..*..@@@@@@@@@@**@@ ", " @@**@@@@@@@@@..*..@@@@@@@@@@@@@@@@...@@@@@@@@@@**@@ ", " @@**@@@@@@@@@...@@@@@@@@@@@@@@@@@@@@@@@@@@@@@**@@ ", " @@**@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@**@@ ", " @@**@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@**@@ ", " @@**@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@**@@ ", " @@**@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@**@@ ", " @@**@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@**@@ ", " @@**@@@@@@@@@@@@@@@@@@@@@@@@@@@@@**@@ ", " @@**@@@@@@@@@@@@@@@@@@@@@@@@@@@**@@ ", " @@**@@@@@@@@@@@@@@@@@@@@@@@@@**@@ ", " @@**@@@@@@@@@@@@@@@@@@@@@@@**@@ ", " @@*************************@@ ", " @@@@@@@@@@@@@@@@@@@@@@@@@@@ ", " @@@@@@@@@@@@@@@@@@@@@@@@@ ", " ", " ", " ", " ", " " };""" Reset_Button_icon = """ /* XPM */ static char * Reset_Button_icon_xpm[] = { /* columns rows colors chars-per-pixel */ "64 64 7 1", " c None", ". c #6E4600", "+ c #957311", "@ c #E6CB34", "# c #C2AC17", "$ c #710808", "% c #D31515", " ", " ... ", " ....... ", " ..+@+@@.. ", " .++...+@.. ", " ..@.. ..@+. ", " ..@.. ..+@. ", " ..@....++@+. ", " ..+++.+++++.. ", " ..@++++++@.. ", " .+@+++++++. ", " .++++++++.. ", " ..@+++++++.. ", " ..+++++++.. ", " ..+++...+.. ", " ..++....... ++ ", " ..++...... ++#+ ", " ..+.....+++@@#+ ", " .....+++@@@@#+ ", " ..+++#@@@@@#+ ", " .++#@@@@@@@@.$$$ ", " ++#@@@@@@@@$$$$$ ", " +++#@@@@@@@@.$$%%%$$ ", " ++######@@@.$$%%%%%$$+ ", " ++#######+$$$%%%%%$$$++ ", " +####+$$$%%%%%%$$$++++ ", " ++#.$$%%%%%%$$$@@@@#++ ", " .$$$%%%%%$$$.@###@@#++ ", " $$$%%%%%%$$.@@######@#+++ ", " $$%%%%%$$$@@@########@@#+ ", " $$$%%$$$@@@@###########@#++ ", " $$$$$.@################@#++ ", " $$$+#@#################@@++ ", " ++@###################@@++ ", " ++@####################@@++ ", " ++@@####################@@++ ", " +#@#####################@@#+ ", " +#@######################@@@+ ", " +#@#######################@@@+ ", " +#@########################@@@+ ", " +@###########.##########.###@@#++ ", " +@#######################.###@@@++ ", " +#@###########.###.#######..##@@@#++ ", " +#@############.###.#######..##@@@++ ", " ++@############.####.########.#@@++ ", " +#@##########@..####.#######@.+++ ", " #@######.###@#.####..#####@@.++ ", " +@#############.####.####@@#.+ ", " +#@######.######.####.#@@#++. ", " ++@######.######.####.+##++ ", " .+#@#.####.######.#@@@.++ ", " .++@@######.#####.#@@++. ", " +#@#.#####.##@@.+++ ", " +#@#.###@.#@@#.++ ", " +@@.@@@@.++++. ", " +@.@##+.+ ", " ++.++++. ", " .+ ", " ", " ", " ", " ", " ", " " };""" BrowserReload_icon = """ /* XPM */ static char * BrowserReload_icon_xpm[] = { /* columns rows colors chars-per-pixel */ "64 64 9 1", " c None", ". c #2B5B93", "+ c #3368A7", "@ c #5082BD", "# c #6196CA", "$ c #7499C5", "% c #80A9D3", "& c #A1BEDE", "* c #B9CFE7", " ", " ", " ", " ....... ", " ....+@@@@@+..... ", " ...@%&&&&&&&&&&%%@+... . ", " ..#&&&&&&&&&&&&&&&&&%#+.. .. ", " ..#&&&&&&&&&&&&&&&&&&&&&&%@.. ... ", " ..%&&&&&&&&&&&&&&&&&&%%%%&&&%@.. ..#. ", " .+&&&&&&&&&&&&&&&&&&&&%%%%%%&&&%+.. .#&. ", " .+&&&&&&&&&&&&&&&&&&&&&%%%%%%%%%&&%.. .@%&. ", " .%&&&&&&&&&&&&&&&&&&&&%%%%%%%%%%%&&&@.. .@%%&. ", " .@&&&&&&&&&&&&&&&&&&&&&%%%%%%%%%%%%%%%@..@%##&. ", " ..&&&&&&%#@......+@%%&&&&%%%%%%%%%%@@@@%%@%#@#&. ", " .@&&&&#+..............@%&&&%%%%%%@@@@@@@%%%@@#&. ", " .&&&%+........ ...#&&&%%@@@@@@@@@@@@@@#&. ", " .+&&%...&&&.. ...@#%%@@@@@@@@@@@@@@#&. ", " .@&#..&&&&.. ..@%%@@@@@@@@@@@@@#&. ", " .%%..&&&&&. ..@%%@@@@@@@@@@@#&. ", " .%+.&&&&&&. ..+%%@@@@@@@@@@#&. ", " .#.+@&&&&&. ..@%%@@@@@@@@#&. ", " .+.@@@&&&.. .+%%@@@@@@@@#&. ", " ..+@@@@&&. ..%%@@@@@@@@@#&. ", " ..+@ . ..%%@@@@@@@@@@#&. ", " ..@ ..#%@@@@@@@@@@@#&. ", " .. .#%@@@@@@@@@@@@#&. ", " .. .@%%@@@@@@@@@@@@#&. ", " .. .@&&&&&&&&&&&&&&&&&. ", " ..................... ", " ..................... ", " .+@@@@@@@@@@@@@@@@+.. ", " .%&&&&&&&&&&&&&&&&.. . ", " .%&%%%%%%%%%%%%&&+. . ", " .%&%%%%%%%%%%%%&@. .. ", " .%&%%%%%%%%%%%&@. ... ", " .%&%%%%%%%%%%&#. @ ... ", " .%&%%%%%%%%%&%.. @& ... ", " .%&%%%%%%%%&&@.. @& .... ", " .%&%%%%%%%%%%&#.. @&&& .@.. ", " .%&%%%%%%%%%%%&%+.. @&&&& ..@. ", " .%&%%%%%%%%%%%%&&#.. +#&&&&&..@@. ", " .%&%%%%%%%%%%%%%%%#+... .+&&&&%..@@@. ", " .%&%%%%%%%%%%%%#@@###+... ..%&&&@..@@@@. ", " .%&%%%&%%%%%%#@@@@@@###@..... ...+%%@+...@@@@. ", " .%&%%&&&&%%%#@@@@@@@@@###@++............++@@@@@. ", " .%&%%&++%&%#@@@@@@@@@@@@@@##@@@@@@@@@@@@@@@@@@.. ", " .%&%&@...#&#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@. ", " .%&&#. ..+#%#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@. ", " .%&%.. ..@##@@@@@@@@@@@@@@@@@@@@@@@@@@@@@.. ", " .%%.. ..+@##@@@@@@@@@@@@@@@@@@@@@@@@@@.. ", " .@.. ..+@##@@@@@@@@@@@@@@@@@@@@@@@.. ", " ... ....@###@@@@@@@@@@@@@@@@@@... ", " .. ...+@@@@@@@@@@@@@@@@@... ", " . .....@@@@@@@@@@@.... ", " .............. ", " ", " ", " ", " ", " ", " ", " ", " ", " " };""" snap_Menu_Btn_icon = """ /* XPM */ static char * snap_Menu_Btn_icon_xpm[] = { /* columns rows colors chars-per-pixel */ "64 64 4 1", " c None", ". c #060706", "+ c #011515", "@ c #CB0808", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " +++++++++++++++++++++++++++++ ", " +@@@@@@@@@@@@@@@@@@@@@@@@@@@+ ", " +@@@@@@@@@@@@@@@@@@@@@@@@@@@+ ", " +@@+++++++++++++++++++++++@@+ ", " +@@+++++++++++++++++++++++@@+ ", " +@@+++++++++++++++++++++++@@+ ", " +@@+++++++++++++++++++++++@@+ ", " +@@+++++++++++++++++++++++@@+ ", " +++++++++++@@+++++++++++++++++++++++@@+++++++++.+ ", " +@@@@@@@@@@@@+++++++++++++++++++++++@@@@@@@@@@@@+ ", " +@@@@@@@@@@@@+++++++++++++++++++++++@@@@@@@@@@@@+ ", " ++@@@+++++++++++++++++++++++++++++++++++++++@@@++ ", " ++@@@+++++++++++++++++++++++++++++++++++++@@@++ ", " ++@@@+++++++++++++++++++++++++++++++++++@@@++ ", " ++@@@+++++++++++++++++++++++++++++++++@@@++ ", " ++@@@+++++++++++++++++++++++++++++++@@@++ ", " ++@@@+++++++++++++++++++++++++++++@@@++ ", " ++@@@+++++++++++++++++++++++++++@@@++ ", " ++@@@+++++++++++++++++++++++++@@@++ ", " ++@@@+++++++++++++++++++++++@@@++ ", " ++@@@+++++++++++++++++++++@@@++ ", " ++@@@+++++++++++++++++++@@@++ ", " ++@@@+++++++++++++++++@@@++ ", " ++@@@+++++++++++++++@@@++ ", " ++@@@+++++++++++++@@@++ ", " ++@@@+++++++++++@@@++ ", " ++@@@+++++++++@@@++ ", " ++@@@+++++++@@@++ ", " ++@@@+++++@@@++ ", " ++@@@+++@@@++ ", " ++@@@+@@@++ ", " ++@@@@@++ ", " ++@@@++ ", " ++@++ ", " +++ ", " + ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " " };""" File_Dialog_Info_View_icon = """ /* XPM */ static char * File_Dialog_Info_View_icon_xpm[] = { /* columns rows colors chars-per-pixel */ "64 64 3 1", " c None", ". c #1E4C89", "+ c #F1F6F8", " ", " ", " ", " .............. ", " .................. ", " ...................... ", " ......++++++++++++...... ", " .....++++++++++++++++++..... ", " .....++++++++++++++++++++++..... ", " ....++++++..............++++++.... ", " ...++++++..................++++++... ", " ...+++++......................+++++... ", " ...++++..........................++++... ", " ...++++...........++++++...........++++... ", " ...++++...........++++++++...........++++... ", " ...++++...........++++++++++...........++++... ", " ...++++............++++++++++............++++... ", " ...++++.............++++++++++.............++++... ", " ...++++..............++++++++++..............++++... ", " ...+++...............++++++++++...............+++... ", " ..++++................++++++++................++++.. ", " ...+++..................++++++..................+++... ", " ...++++..........................................++++... ", " ...+++............................................+++... ", " ...+++............................................+++... ", " ....+++............................................+++.... ", " ...+++................++++++++++++..................+++... ", " ...+++................++++++++++++..................+++... ", " ...+++................++++++++++++..................+++... ", " ...+++....................++++++++..................+++... ", " ...+++....................++++++++..................+++... ", " ...+++....................++++++++..................+++... ", " ...+++....................++++++++..................+++... ", " ...+++....................++++++++..................+++... ", " ...+++....................++++++++..................+++... ", " ...+++....................++++++++..................+++... ", " ...+++....................++++++++..................+++... ", " ...+++....................++++++++..................+++... ", " ....+++...................++++++++.................+++.... ", " ...+++...................++++++++.................+++... ", " ...+++...................++++++++.................+++... ", " ...++++..................++++++++................++++... ", " ...+++..................++++++++................+++... ", " ..++++.................++++++++...............++++.. ", " ...+++.................++++++++...............+++... ", " ...++++................++++++++..............++++... ", " ...++++...............++++++++.............++++... ", " ...++++..............++++++++............++++... ", " ...++++..........++++++++++++++........++++... ", " ...++++.........++++++++++++++.......++++... ", " ...++++........++++++++++++++......++++... ", " ...++++..........................++++... ", " ...+++++......................+++++... ", " ...++++++..................++++++... ", " ....++++++..............++++++.... ", " .....++++++++++++++++++++++..... ", " .....++++++++++++++++++..... ", " ......++++++++++++...... ", " ...................... ", " .................. ", " .............. ", " ", " ", " " };""" msgBtn_Critical_icon = """ /* XPM */ static char * msgBtn_Critical_icon_xpm[] = { /* columns rows colors chars-per-pixel */ "64 64 6 1", " c None", ". c #000000", "+ c #BF0001", "@ c #BE0209", "# c #EBE9E6", "$ c #F1F6F8", " ", " ", " ", " @@@@@@@@@@@@@@ ", " @@@@@@@@@@@@@@@@@@ ", " @@@@@@@@@@@@@@@@@@@@@@ ", " @@@@@@$$$$$$$$$$$$@@@@@@ ", " @@@@@$$$$$$$$$$$$$$$$$$@@@@@ ", " @@@@@$$$$$$$$$$$$$$$$$$$$$$@@@@@ ", " @@@@$$$$$$++++++++++++++$$$$$$@@@@ ", " @@@$$$$$$++++++++++++++++++$$$$$$@@@ ", " @@@$$$$$++++++++++++++++++++++$$$$$@@@ ", " @@@$$$$++++++++++++++++++++++++++$$$$@@@ ", " @@@$$$$++++++++++++++++++++++++++++$$$$@@@ ", " @@@$$$$++++++++++++++++++++++++++++++$$$$@@@ ", " @@@$$$$+++++...++++++++++++++++++...+++$$$$@@@ ", " @@@$$$$+++++..#..++++++++++++++++..#..+++$$$$@@@ ", " @@@$$$$+++++..###..++++++++++++++..###..+++$$$$@@@ ", " @@@$$$$+++++..#####..++++++++++++..#####..+++$$$$@@@ ", " @@@$$$+++++..#######..++++++++++..#######..+++$$$@@@ ", " @@$$$$++++..#########..++++++++..#########..++$$$$@@ ", " @@@$$$+++++.###########..++++++..###########.+++$$$@@@ ", " @@@$$$$+++++..###########..++++..###########..+++$$$$@@@ ", " @@@$$$+++++++..###########..++..###########..+++++$$$@@@ ", " @@@$$$++++++++..###########....###########..++++++$$$@@@ ", " @@@@$$$+++++++++..###########..###########..+++++++$$$@@@@ ", " @@@$$$+++++++++++..######################..+++++++++$$$@@@ ", " @@@$$$++++++++++++..####################..++++++++++$$$@@@ ", " @@@$$$+++++++++++++..##################..+++++++++++$$$@@@ ", " @@@$$$++++++++++++++..################..++++++++++++$$$@@@ ", " @@@$$$+++++++++++++++..##############..+++++++++++++$$$@@@ ", " @@@$$$++++++++++++++++..############..++++++++++++++$$$@@@ ", " @@@$$$++++++++++++++++..############..++++++++++++++$$$@@@ ", " @@@$$$+++++++++++++++..##############..+++++++++++++$$$@@@ ", " @@@$$$++++++++++++++..################..++++++++++++$$$@@@ ", " @@@$$$+++++++++++++..##################..+++++++++++$$$@@@ ", " @@@$$$++++++++++++..####################..++++++++++$$$@@@ ", " @@@$$$+++++++++++..######################..+++++++++$$$@@@ ", " @@@@$$$+++++++++..###########..###########..+++++++$$$@@@@ ", " @@@$$$++++++++..###########....###########..++++++$$$@@@ ", " @@@$$$+++++++..###########..++..###########..+++++$$$@@@ ", " @@@$$$$+++++..###########..++++..###########.++++$$$$@@@ ", " @@@$$$+++++.###########..++++++..#########..++++$$$@@@ ", " @@$$$$++++..#########..++++++++..#######..++++$$$$@@ ", " @@@$$$+++++..#######..++++++++++..#####..+++++$$$@@@ ", " @@@$$$$+++++..#####..++++++++++++..###..+++++$$$$@@@ ", " @@@$$$$+++++..###..++++++++++++++..#..+++++$$$$@@@ ", " @@@$$$$+++++..#..++++++++++++++++...+++++$$$$@@@ ", " @@@$$$$+++++...++++++++++++++++++++++++$$$$@@@ ", " @@@$$$$++++++++++++++++++++++++++++++$$$$@@@ ", " @@@$$$$++++++++++++++++++++++++++++$$$$@@@ ", " @@@$$$$++++++++++++++++++++++++++$$$$@@@ ", " @@@$$$$$++++++++++++++++++++++$$$$$@@@ ", " @@@$$$$$$++++++++++++++++++$$$$$$@@@ ", " @@@@$$$$$$++++++++++++++$$$$$$@@@@ ", " @@@@@$$$$$$$$$$$$$$$$$$$$$$@@@@@ ", " @@@@@$$$$$$$$$$$$$$$$$$@@@@@ ", " @@@@@@$$$$$$$$$$$$@@@@@@ ", " @@@@@@@@@@@@@@@@@@@@@@ ", " @@@@@@@@@@@@@@@@@@ ", " @@@@@@@@@@@@@@ ", " ", " ", " " };""" msgBtn_Warning_icon = """ /* XPM */ static char * msgBtn_Warning_icon_xpm[] = { /* columns rows colors chars-per-pixel */ "64 64 6 1", " c None", ". c #000000", "+ c #BC9100", "@ c #FBE500", "# c #FCE500", "$ c #FCE600", " ", " ", " ", " ", " ", " ", " ", " ++++++ ", " ++++++++ ", " +++$$+++ ", " +++$$$$+++ ", " ++$$$$$$++ ", " ++$$$$$$$+++ ", " ++$$@$$$$$++ ", " ++$$@@@$$$$+++ ", " +++$$@@@$$$$$+++ ", " ++$$@@@@@$$$$+++ ", " +++$$@@@$$$$$$$+++ ", " ++$$@@@$$#$$$$$$++ ", " ++$$$@@@$$#$$$$$$+++ ", " ++$$@@@$$$$$$@$$$$++ ", " ++$$$@$@......@$$$$+++ ", " +++$$@@$@......@$$$$$+++ ", " ++$$$@@$@......@$$$$$+++ ", " +++$$@@$$@......@$$$$$$+++ ", " ++$$$@@$$@......@$$$$$$$++ ", " ++$$$@$$$$$......$$$$$$$$+++ ", " ++$$$@$$$$$......$$$$$$$$$++ ", " ++$$$@@$$$$$......$$$$$$$$$+++ ", " +++$$$@@$$$$$......$$$$$$$$$$+++ ", " ++$$$@@$$$#$$......$$$$$$$$$$$++ ", " +++$$$@@$$$#$$......$$$$$$$$$$$+++ ", " ++$$$@$$$$$$$$......$$$$$$$$$$$$++ ", " ++$$$@@$$$$$$$$......$$$$$$$$$$$$+++ ", " ++$$$@$$$$$$$$$......$$$$$$$$$$$$$++ ", " ++$$$@@@$$$###$$......$$$$$$$$$$$$$+++ ", " +++$$$$$$$$$$$$$$......$$$$$$$$$$$$$$+++ ", " ++$$$@@$$#$#####$......$$$$$$$$$$$$$$$++ ", " +++$$$@@$$$$$$$$$$......$$$$$$$$$$$$$$$+++ ", " ++$$$@@$$$$$$$$$$$$@@@@$$$$$$$$$$$$$$$$$++ ", " ++$$$$@$$$$$$$$$$$$@@@@@@$$$$$$$$$$$$$$$$+++ ", " ++$$$@$$$$$$$$$$$$$@@@@@@$$$$$$$$$$$$$$$$$++ ", " ++$$$$@$$$$$$$$$$$$$$....$$$$$$$$$$$$$$$$$$+++ ", " +++$$$@@$$$$$$$$$$$$$......$$$$$$$$$$$$$$$$$$+++ ", " ++$$$$@@$$$$$$$$$$$$$......$$$$$$$$$$$$$$$$$$$++ ", " +++$$$@@$$$$$$$$$$$$$$......$$$$$$$$$$$$$$$$$$$+++ ", " ++$$$$$@$$$$$$$$$$$$$$......$$$$$$$$$####$$$$$$$++ ", " +++$$$$$$$###$$$$####$$......$$####$$$$$$$$$$$$$$+++ ", " ++$$$$$$$$$$$$$$$$$$$$$$....$$$$$$$$$$$$$$$$$$$$$$++ ", " +++$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$+++ ", " ++$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$++ ", " ++$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$++ ", " ++$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$++ ", " ++++++++++++++++++++++++++++++++++++++++++++++++++++++ ", " ++++++++++++++++++++++++++++++++++++++++++++++++++++++ ", " ", " ", " ", " ", " ", " ", " ", " ", " " };""" Btn_Refresh_Aqua_Highlight_icon = """ /* XPM */ static char * Btn_Refresh_Aqua_Highlight_icon_xpm[] = { /* columns rows colors chars-per-pixel */ "64 64 5 1", " c None", ". c #191ED6", "+ c #19EED7", "@ c #1913D7", "# c #0FD902", " ", " ", " ......... ", " ............. ", " ..+++++++++++.... ", " ..+++++++++++++++.. ", " ..+++++++++++++++++.. ", " ..+++++++++++++++++++.. ", " ..+++++++++++++++++++++.. ", " ..+++++++++++++++++++++++.. ", " ..+++........++++++++++++++.. ", " ..++.. ..+++++++++++++.. ", " ..++.. ..+++++++++++++.. ", " .++.. ..+++++++++++++. ", " .++.. ..++++++++++++.. ", " .++. ..+++++++++++.. ", " .... ..++++++++++++. ", " .++++++++++++. ", " .++++++++++++. ", " ..........++++++++++++. ", " .+++++++++++++++++++++........... ", " .+++++++++++++++++++++........... ", " ..+++++++++++++++++++++++++++++.. ", " ..+++++++++++++++++++++++++++.. ", " ..+++++++++++++++++++++++++.. ", " ..+++++++++++++++++++++++.. ", " @@ ..+++++++++++++++++++++.. ", " @@@@ ..+++++++++++++++++++.. ", " @@##@@ ..+++++++++++++++++.. ", " @@####@@ ..+++++++++++++++.. ", " @@######@@ ..+++++++++++++.. ", " @@########@ ..+++++++++++.. ", " @@#########@@ ..+++++++++.. ", " @@###########@@ .++++++++.. ", " @@#############@@ ..++++++.. ", " @@###############@@ ..++++.. ", " @@#################@@ ..++.. ", " @@###################@@ .... ", " @@#####################@@ .. ", " @@#######################@@ ", " @@#########################@@ ", " @@###########################@@ ", " @@#############################@@ ", " @@@@@@@@@@@#####################@ ", " @@@@@@@@@@@#####################@ ", " @############@@@@@@@@@@ ", " @############@ ", " @############@ ", " @############@@ @@@@ ", " @@###########@@ @##@ ", " @@############@@ @@##@ ", " @#############@@ @@##@ ", " @@#############@@ @@##@@ ", " @@#############@@ @@##@@ ", " @@##############@@@@@@@@###@@ ", " @@#######################@@ ", " @@#####################@@ ", " @@###################@@ ", " @@#################@@ ", " @@###############@@ ", " @@@@###########@@ ", " @@@@@@@@@@@@@ ", " @@@@@@@@@ ", " " };""" Btn_Quit_icon = """ /* XPM */ static char * Btn_Quit_icon_xpm[] = { /* columns rows colors chars-per-pixel */ "64 64 6 1", " c None", ". c #000000", "+ c #BF0001", "@ c #BE0209", "# c #EBE9E6", "$ c #F1F6F8", " ", " ", " ........... ", " .....@@@@@@@@@..... ", " ....@@@@@@@@@@@@@@@@@.... ", " ...@@@@@@@@@@@@@@@@@@@@@@@... ", " ...@@@@@@@@@@@@@@@@@@@@@@@@@@@... ", " ..@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@.. ", " ..@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@.. ", " ..@@@@@@@@@@@+++++$$$++++++@@@@@@@@@@.. ", " ...@@@@@@@@@@++++++$$$$$+++++++@@@@@@@@@... ", " .@@@@@@@@@@+++++++$$$$$$$++++++++@@@@@@@@@. ", " ..@@@@@@@@+++++++@$$$$$$$$$+++++++++@@@@@@@.. ", " ..@@@@@@@@+++++@@+@$$$$$$$$$@+@+++++++@@@@@@@.. ", " ..@@@@@@@@++++++@@@@$$$$$$$$$@@@@+++++++@@@@@@@.. ", " ..@@@@@@@@+++++$$@@@@$$$$$$$$$@@@@$$++++++@@@@@@@.. ", " .@@@@@@@@+++++$$$@@@@$$$$$$$$$@@@@$$$++++++@@@@@@@. ", " ..@@@@@@@++++$$$$$@@@@$$$$$$$$$@@@@$$$$$+++++@@@@@@.. ", " .@@@@@@@++++$$$$$$@@+@$$$$$$$$$@+@@$$$$$$+++++@@@@@@. ", " ..@@@@@@+++++$$$$$$@@++$$$$$$$$$@+++$$$$$$++++++@@@@@.. ", " .@@@@@@@++++$$$$$@@@@@+$$$$$$$$$++++++$$$$$+++++@@@@@@. ", " .@@@@@@++++$$$$$@@@@@@+$$$$$$$$$+++++++$$$$$+++++@@@@@. ", " ..@@@@@@++++$$$$$+@@@@@@$$$$$$$$$+++++@@$$$$$+++++@@@@@.. ", " .@@@@@@++++$$$$$++++@@@@$$$$$$$$$++++@@@@$$$$$+++++@@@@@. ", " .@@@@@@++++$$$$++++++@@@$$$$$$$$$++@@@@@@+$$$$+++++@@@@@. ", " .@@@@@@++++$$$$+++++++@@$$$$$$$$$@@@@@@@++$$$$+++++@@@@@. ", " ..@@@@@++++$$$$+++++++++@$$$$$$$$$@@@@@@++++$$$$+++++@@@@.. ", " .@@@@@@+++$$$$$++++++++++$$$$$$$$$@@@@@+++++$$$$$++++@@@@@. ", " .@@@@@@+++$$$$$++++++++++$$$$$$$$$@@@@++++++$$$$$++++@@@@@. ", " .@@@@@@+++$$$$+++++++++++$$$$$$$$$@@@++++++++$$$$++++@@@@@. ", " .@@@@@@+++$$$$++++++++++++$$$$$$$@@@@++++++++$$$$++++@@@@@. ", " .@@@@@@+++$$$$+++++++++++++$$$$$@@@@+++++++++$$$$++++@@@@@. ", " .@@@@@@+++$$$$+++++++++++++@$$$@@@@@@++++++++$$$$++++@@@@@. ", " .@@@@@@+++$$$$+++++++++++++@@@@@@@@@@++++++++$$$$++++@@@@@. ", " .@@@@@@+++$$$$$++++++++++++@@@@@@@@@@@++++++$$$$$++++@@@@@. ", " .@@@@@@+++$$$$$++++++++++++@@@@@@@@@@@++++++$$$$$++++@@@@@. ", " ..@@@@@++++$$$$++++++++++++@@@@@@@@@@@++++++$$$$+++++@@@@.. ", " .@@@@@+++++$$$$++++++++++@@@@@@@@@@@@@++++$$$$++++++@@@@. ", " .@@@@@@++++$$$$++++++++@@@@@@++++@@@@@++++$$$$+++++@@@@@. ", " .@@@@@@++++$$$$$++++@@@@@+++++++++@@@@@++$$$$$+++++@@@@@. ", " ..@@@@@+++++$$$$$++@@@@+++++++++++@@@@@@$$$$$++++++@@@@.. ", " .@@@@@@++++$$$$$++@@@++++++++++++@@@@@@$$$$$+++++@@@@@. ", " .@@@@@@+++++$$$$$++@++++++++++++++++++$$$$$++++++@@@@@. ", " ..@@@@@@+++++$$$$$$+++++++++++++++++$$$$$$++++++@@@@@.. ", " .@@@@@@+++++$$$$$$$+++++++++++++++$$$$$$$++++++@@@@@. ", " ..@@@@@@+++++$$$$$$$$+++++++++++$$$$$$$$++++++@@@@@.. ", " .@@@@@@@++++++$$$$$$$$$+++++$$$$$$$$$+++++++@@@@@@. ", " ..@@@@@@@++++++$$$$$$$$$$$$$$$$$$$$$+++++++@@@@@@.. ", " ..@@@@@@@+++++++$$$$$$$$$$$$$$$$$++++++++@@@@@@.. ", " ..@@@@@@@+++++++++$$$$$$$$$$$++++++++++@@@@@@.. ", " ..@@@@@@@++++++++++$$$$$$$+++++++++++@@@@@@.. ", " .@@@@@@@@++++++++++++++++++++++++++@@@@@@@. ", " ...@@@@@@@@++++++++++++++++++++++@@@@@@@... ", " ..@@@@@@@@@++++++++++++++++++@@@@@@@@.. ", " ..@@@@@@@@@@++++++++++++++@@@@@@@@@.. ", " ..@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@.. ", " ...@@@@@@@@@@@@@@@@@@@@@@@@@@@... ", " ...@@@@@@@@@@@@@@@@@@@@@@@... ", " ....@@@@@@@@@@@@@@@@@.... ", " .....@@@@@@@@@..... ", " ........... ", " ", " ", " " };""" pythonFC_icon = """ /* XPM */ static char * Python_FC_xpm[] = { /* columns rows colors chars-per-pixel */ "64 64 7 1", " c None", ". c #390602", "+ c #630E02", "@ c #FF3302", "# c #366E9E", "$ c #3D74CC", "% c #FCE84F", " ", " ", " ", " ............................... ", " .+++++++++++++++++++++++++++++. ", " .+@@@@@@@@@@@@@@@@@@@@@@@@@@@+. ", " .+@@@@@@@@@@@@@@@@@@@@@@@@@@@+. ", " .+@@@@@@@@@@@@@@@@@@@@@@@@@@@+. ", " .+@@@@@@@@@@@@@@@@@@@@@@@@@@@+. ", " .+@@@@@@@@@@@@@@@@@@@@@@@@@@@+. ", " .+@@@@@@@@@@@@@@@@@@@@@@@@@@@+. ", " .+@@@@@@@@@@@@@@@@@@@@@@@@@@@+. ", " .+@@@@@@@@@@@@@@@@@@@@@@@@@@@+. ", " .+@@@@@@@@@@@@@@@@@@@@@@@@@@@+. ", " .+@@@@@@@@@@@@@@@@@@@@@@@@@@@+. ", " .+@@@@@@@@@@@@@@@@@@@@@@@@@@@+. ", " .+@@@@@@@@++++++++++++++++++++. ", " .+@@@@@@@@+.................... ", " .+@@@@@@@@+. ######## ", " .+@@@@@@@@+. ############## ", " .+@@@@@@@@+. ################ ", " .+@@@@@@@@+. ################## ", " .+@@@@@@@@+. ### ############## ", " .+@@@@@@@@+. ### ############## ", " .+@@@@@@@@+. ### ############## ", " .+@@@@@@@@+........ #################### ", " .+@@@@@@@@++++++++. #################### ", " .+@@@@@@@@@@@@@@@+. #################### ", " .+@@@@@@@@@@@@@@@+. ########## ", " .+@@@@@@@@@@@@@@@+. ########################### %%%%%% ", " .+@@@@@@@@@@@@@@@+.############################ %%%%%%%% ", " .+@@@@@@@@++++++++.############################ %%%%%%%% ", " .+@@@@@@@@+........############################ %%%%%%%%% ", " .+@@@@@@@@+. ############################## %%%%%%%%% ", " .+@@@@@@@@+. ############################## %%%%%%%%% ", " .+@@@@@@@@+. ############################## %%%%%%%%% ", " .+@@@@@@@@+. ############################## %%%%%%%%%% ", " .+@@@@@@@@+. ############################## %%%%%%%%%%% ", " .+@@@@@@@@+. ############################ %%%%%%%%%%%% ", " .+@@@@@@@@+. ############## %%%%%%%%%%%%%% ", " .+@@@@@@@@+. ############ %%%%%%%%%%%%%%%%%%%%%%%%%%%% ", " .+@@@@@@@@+. ########### %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% ", " .+@@@@@@@@+. ########## %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% ", " .+@@@@@@@@+. ######### %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% ", " .+@@@@@@@@+. ######### %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% ", " .+@@@@@@@@+. ######### %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% ", " .+@@@@@@@@+. ######### %%%%%%%%%%%%%%%%%%%%%%%%%%%%% ", " .+@@@@@@@@+. ######## %%%%%%%%%%%%%%%%%%%%%%%%%%%%% ", " .+@@@@@@@@+. ######## %%%%%%%%%%%%%%%%%%%%%%%%%%%% ", " .+@@@@@@@@+. ###### %%%%%%%%%%%%%%%%%%%%%%%%%%% ", " .++++++++++. %%%%%%%%%% ", " ............ %%%%%%%%%%%%%%%%%%%% ", " %%%%%%%%%%%%%%%%%%%% ", " %%%%%%%%%%%%%%%%%%%% ", " %%%%%%%%%%%%%% %%% ", " %%%%%%%%%%%%%% %%% ", " %%%%%%%%%%%%%% %%% ", " %%%%%%%%%%%%%%%%%% ", " %%%%%%%%%%%%%%%% ", " %%%%%%%%%%%%%% ", " %%%%%%%% ", " ", " ", " " };""" pythonPY_icon = """ /* XPM */ static char * python_xpm[] = { /* columns rows colors chars-per-pixel */ "64 64 6 1", " c None", ". c #2E6C9F", "+ c #3A76AA", "@ c #3E84B7", "# c #FFD63E", "$ c #FFDF58", " ", " @@@@@@@@@@@@@@++ ", " @@@@@@@@@@@@@@@@@@+++ ", " @@@@@@@@@@@@@@@@+@+++++ ", " @@@@@@@@@@@@@@@+++@@+++++ ", " @@@@@@@@@@@@@@@@@@@++++++++ ", " @@@@ @@@@@@@@@@@+++++++++. ", " @@@@ @@@@@@@@@++++++++++. ", " @@@@ @@@@@@@@++++++++++.. ", " @@@@ @@@@@@@++++++++++.... ", " @@@@@ @@@@++++@++++++++..... ", " @@@@@@@@@@@+@+@@++++++++...... ", " @@@@@@@@@@@@@@+++++++++....... ", " @@@@@@@@@@@@++++++++++....... ", " @@@@@@@@@@@@++++++++........ ", " ++++++......... ", " @@@@@@@@@@@@@@@@@@++++++.......... ", " @@@@@@@@@@@@@@@@++++@++++++++........... ", " @@@@@@@@@@@@@@@@+@@@+++++++++............ ", " @@@@@@@@@@@@@@@@@@@@+++++++++............. ", " @@@@@@@@@@@@@@@@@@@++++++++++............. ", " @@@@@@@@@@@@@@@@@@@++++++++++.............. ", " @@@@@@@@@@@@@@@@@@@++++++++++............... $$$$$$ ", " @@@@@@@@@@@@@@@@+++@++++++++................ $$$$$$$$$ ", " @@@@@@@@@@@@@@+@+@@++++++++................. $$$$$$$$$$$ ", " @@@@@@@@@@@@@@@@@@@@@++++++.................. $$$$$$$$$$$$ ", " @@@@@@@@@@@@@@@@@@@++++++++................. $$$$$$$$$$$$$ ", " @@@@@@@@@@@@@@@@++++++++++................. $$$$$$$$$$$$$ ", " @@@@@@@@@@@@@@@++++++++++................. $$$$$$$$$$$$$$ ", " @@@@@@@@@@@@@@++++++++++................. $$$$$$$$$$$$$$$ ", " @@@@@@@@@@@@@++++++++++................ $$$$$$$$$$$$$$## ", " @@@@@@@@@@@@@++++ $$$$$$$$$$$$$$### ", " @@@@@@@@@@@@++++ $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$#### ", " @@@@@@@@@@@++++ $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$###### ", " @@@@@@@@@@++++ $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$####### ", " @@@@@@@@@+++++ $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$######### ", " @@@@@@@@++++++ $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$########## ", " @@@@@@@@++++++ $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$########### ", " @@@@@@+++++++ $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$############# ", " @@@@@+++++++ $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$############# ", " @@@++++++++ $$$$$$$$$$$$$$$$$$$$$$$$$$$$############### ", " @@+++++++++ $$$$$$$$$$$$$$$$$$$$$$$$$$$################ ", " ++++++++++ $$$$$$$$$$$$$$$$$$$$$$$$$$$################ ", " @+++++++++ $$$$$$$$$$$$$$$$$$$$$$$$$################# ", " ++++++++ $$$$$$$$$$$$$$$$$$$$$$$$################# ", " ++++.+ $$$$$$$$$$$$$$$$$$$$$$################## ", " $$$$$$$$$$$$$$$$$$$ ", " $$$$$$$$$$$$$$$$$$ ", " $$$$$$$$$$$$$$$$$$########## ", " $$$$$$$$$$$$$$$$$############ ", " $$$$$$$$$$$$$$$############### ", " $$$$$$$$$$$$$$################ ", " $$$$$$$$$$$$$######### ##### ", " $$$$$$$$$$$$######### #### ", " $$$$$$$$$$$########## #### ", " $$$$$$$$$$########### ### ", " $$$$$$$$############# #### ", " $$$$$###################### ", " $####################### ", " ##################### ", " ################# ", " ############# ", " ", " " };""" tools_icon = """ /* XPM */ static char * tools_icon[] = { /* columns rows colors chars-per-pixel */ "64 64 8 1", " c None", ". c #000000", "+ c #11468A", "@ c #3167A7", "# c #6295D2", "$ c #ADB2B4", "% c #EDD400", "& c #D7DCDF", " ", " ", " ", " ", " ", " ", " ", " ....... ", " ..%%%%%%... ... ", " .%%%%%%%%%.. .$$. ", " .%%%%%%%%%.. ..&&$$.. ", " ..%%%%%%%%. ..&&&&$$.. ", " ..%%%%%%%. ..&&&&&&&$$.. ", " .%%%%%%%. ..&&&&&&&&&$.. ", " .%%%%%%%. ..&&&&&&&&&&&. ", " .%%%%%%%%. .&&&&&&&&&&&. ", " .%%%%%%%%. .&&$$&&&&&&.. ", " ... .%%%%%%%%. .&&$&&&&&&&. ", " ..%%. ..%%%%%%%%. .&&$&&$&&&. ", " .%%%%. .%%%%%%%%%. ..&&$$$$&&. ", " .%%%%%. ..%%%%%%%%%. ..&&$&&&&&.. ", " .%%%%%%......%%%%%%%%%%. ..&&$&&&&&&. ", " ..%%%%%%%%%%%%%%%%%%%%%.. ..&&$&&..... ", " .%%%%%%%%%%%%%%%%%%%%%%.. ..&&$&&.. ", " .%%%%%%%%%%%%%%%%%%%%%%%.. ..&&$&&.. ", " .%%%%%%%%%%%%%%%%%%%%%%%.. ..&&$&&.. ", " ..%%%%%%%%%%%%%%%%%%%%%%%...&&$&&.. ", " ..%%%%%%%%%%%%%%%%%%%%%%..&&$&&.. ", " ...%%%%%%%...%%%%%%%%%..&&$&&.. ", " ....... ..%%%%%%%..&&$&&.. ", " ..%%%%%..&&$&&.. ", " ..%%%..&&$&&.... ", " ..%..&&$&&..%%.. ", " +++@..&&$&&..%%%%.. ", " ++++++&&$&&..%%%%%%.. ", " ++#&##++&&&..%%%%%%%%.. ", " ++##&&##++&..%%%%%%%%%%.. ", " ++##&&&@##++.%%%%%%%%%%%%.. ", " ++#####@@@##+@%%%%%%%%%%%%%.. ", " ++######@@@@#@+.%%%%%%%%%%%%%.. ", " ++######@@@@@#++..%%%%%%%%%%%%%.. ", " ++######@@@@@#++ ..%%%%%%%%%%%%%.. ", " ++######@@@@@@#++ ..%%%%%%%%%%%%%.. ", " +++######@@@@@@#++ ..%%%%%%%%%%%%%.. ", " ++######&@@@@@@#++ ..%%%%%%%%%%%%%.. ", " ++#####&&@@@@@@#++ ..%%%%%%%%%%%%%.. ", " +++####&&#@@@@@@#++ ..%%%%%%%%%%%%%.. ", " ++####&&&#@@@@@@#++ ..%%%%%%%%%%%%%. ", " ++###&&&&#@@@@@@#++ ..%%%%%%%...%%.. ", " ++###&&&&#@@@@@@#++ ..%%%%%.. ..%%. ", " ++##&&&&&#@@@@@@#++ ..%%%%. .%%. ", " ++##&&&#@@@@@@@@#+ ..%%%.. ..%%. ", " ++#####@@@@@@@@#++ ..%%%...%%.. ", " +####@@@@@@@@##+ ..%%%%%%%. ", " ++##@@@@@@@@@#++ ..%%%%... ", " ++##@@@@@@@#++ ...... ", " +++##@@@@@##+ ", " +++##@@@##+ ", " ++++###+++ ", " ++++++ ", " +++ ", " ", " ", " " };""" high_Light_icon = """ /* XPM */ static char * high_Light_icon[] = { /* columns rows colors chars-per-pixel */ "64 64 9 1", " c None", ". c #000000", "+ c #05989A", "@ c #888A87", "# c #00EED5", "$ c #14EBD9", "% c #30E5E2", "& c #DDEFE8", "* c #ECEFEB", " @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ ", " @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ ", " @@**************************************************@@ ", " @@**************************************************@@ ", " @@**************************************************@@ ", " @@**************************************************@@ ", " @@**************************************************@@ ", " @@**************************************************@@ ", " @@**************************************************@@ ", " @@***##########################################*****@@ ", " @@***##########################################*****@@ ", " @@***##########################################*****@@ ", " @@***##+++++++++++++++##+++++++++++++++++++++##*****@@ ", " @@***##+++++++++++++++##+++++++++++++++++++++##*****@@ ", " @@***##+++++++++++++++##+++++++++++++++++++++##*****@@ ", " @@***##+++++++++++++++#########################*****@@ ", " @@***##+++++++++++++++#########################*****@@ ", " @@***##+++++++++++++++******************************@@ ", " @@***##+++++++++++++++######################********@@ ", " @@***##+++++++++++++++######################********@@ ", " @@***##+++++++++++++++##++++++++++++++++++##********@@ ", " @@***##+++++++++++++++##++++++++++++++++++##********@@ ", " @@***##+++++++++++++++##++++++++++++++++++##********@@ ", " @@***##+++++++++++++++######################********@@ ", " @@***##+++++++++++++++######################********@@ ", " @@***##+++++++++++++++******************************@@ ", " @@***##################################*************@@ ", " @@***##################################*************@@ ", " @@***##++++++++++++++++++++++++++++++##*************@@ ", " @@***##++++++++++++++++++++++++++++++##*************@@ ", " @@***##++++++++++++++++++++++++++++++##*************@@ ", " @@***##################################*************@@ ", " @@***##################################*************@@ ", " @@***##*********************************************@@ ", " @@***########################################*******@@ ", " @@***########################################*******@@ ", " @@***##++++++++++++++++++++++++++++++++++++##*******@@ ", " @@***##++++++++++++++++++++++++++++++++++++##*******@@ ", " @@***##++++++++++++++++++++++++++++++++++++##*******@@ ", " @@***########################################*******@@ ", " @@***##########################....##########*******@@ ", " @@***##************************....*&&&&&&&&&*******@@ ", " @@***##########################*..*##$$$$######*****@@ ", " @@***##########################*..*#######$$$$#*****@@ ", " @@***##++++++++++++++++++++++##*..*$$++++++++%%*****@@ ", " @@***##++++++++++++++++++++++##*..*$$++++++++##*****@@ ", " @@***##++++++++++++++++++++++##*..*$$++++++++#%*****@@ ", " @@***##########################*..*$#%%%%%%%%##*****@@ ", " @@***##########################*..*$#%%%%%%%%%%*****@@ ", " @@******************************..******************@@ ", " @@*****************************....*****************@@ ", " @@*****************************....*****************@@ ", " @@**************************************************@@ ", " @@**************************************************@@ ", " @@**************************************************@@ ", " @@**************************************************@@ ", " @@**************************************************@@ ", " @@**************************************************@@ ", " @@**************************************************@@ ", " @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ ", " @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ ", " ", " ", " " };""" goto_To_Menu_icon = """ /* XPM */ static char * goto_To_Menu_icon[] = { /* columns rows colors chars-per-pixel */ "64 64 7 1", " c None", ". c #000000", "+ c #2E3436", "@ c #234A88", "# c #555753", "$ c #888A85", "% c #F6F9F6", " ", " ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ", " ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ", " ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ", " +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%+++ ", " +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%+++ ", " +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%+++ ", " +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%+++ ", " +%%%%%...........................................%%%%+++ ", " +%%%%%$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$%%%%+++ ", " +%%%%%$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$%%%%+++ ", " +%%%%%$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$%%%%+++ ", " +%%%%%$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$%%%%+++ ", " +%%%%%$$$$$$$$$$$$$$$$$..$$$$$$$$$$$$$$$$$$$$$$$$%%%%+++ ", " +%%%%%%%%%%%%%%%%%%%%%.@@.%%%%%%%%%%%%%%%%%%%%%%%%%%%+++ ", " +%%%%%%%%%%%%%%%%%%%%.@@@@.%%%%%%%%%%%%%%%%%%%%%%%%%%+++ ", " +%%%%%%%%%%%%%%%%%%%.@@@@@@.%%%%%%%%%%%%%%%%%%%%%%%%%+++ ", " +%%%%%%%%%%%%%%%%%%.@@@@@@@@.%%%%%%%%%%%%%%%%%%%%%%%%+++ ", " +%%%%%.............@@@@@@@@@@....................%%%%+++ ", " +%%%%%%%%%%%%%%%%.@@@@@@@@@@@@.%%%%%%%%%%%%%%%%%%%%%%+++ ", " +%%%%%%%%%%%%%%%.@@@@@@@@@@@@@.%%%%%%%%%%%%%%%%%%%%%%+++ ", " +%%%%%%%%%%%%%%.@@@@@@@@@@@@@@@.%%%%%%%%%%%%%%%%%%%%%+++ ", " +%%%%%%%%%%%%%.@@@@@@@@@@@@@@@@@.%%%%%%%%%%%%%%%%%%%%+++ ", " +%%%%%%%%%%%%.@@@@@@@@@@@@@@@@@@@.%%%%%%%%%%%%%%%%%%%+++ ", " +%%%%%%%%%%%.@@@@@@@@@@@@@@@@@@@@@.%%%%%%%%%%%%%%%%%%+++ ", " +%%%%%%%%%%.@@@@@@@@@@@@@@@@@@@@@@@.%%%%%%%%%%%%%%%%%+++ ", " +%%%%%%%%%.@@@@@@@@@@@@@@@@@@@@@@@@@.%%%%%%%%%%%%%%%%+++ ", " +%%%%%%%%.@@@@@@@@@@@@@@@@@@@@@@@@@@@.%%%%%%%%%%%%%%%+++ ", " +%%%%%%..@@@@@@@@@@@@@@@@@@@@@@@@@@@@@...........%%%%+++ ", " +%%%%%..@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@.%%%%%%%%%%%%%+++ ", " +%%%%%.@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@.%%%%%%%%%%%%+++ ", " +%%%%%.@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@.%%%%%%%%%%%%+++ ", " +%%%%%.@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@.%%%%%%%%%%%%+++ ", " +%%%%%...........@@@@@@@@@@@@@@@@@@@@@@@.%%%%%%%%%%%%+++ ", " +%%%%%%%%%%%%%%%.@@@@@@@@@@@@@@..........%%%%%%%%%%%%+++ ", " +%%%%%%%%%%%%%%%.@@@@@@@@@@@@@@..%%%%%%%%%%%......%%%+++ ", " +%%%%%%%%%%%%%%%.@@@@@@@@@@@@@@@.%%%%%%%%%%%.@@@@.%%%+++ ", " +%%%%%%%%%%%%%%%.@@@@@@@@@@@@@@@.%%%%%%%%%%%.@@@@.%%%+++ ", " +%%%%%...........@@@@@@@@@@@@@@@@...........@@@@@.%%%+++ ", " +%%%%%%%%%%%%%%%..@@@@@@@@@@@@@@@@.%%%%%%%%.@@@@@.%%%+++ ", " +%%%%%%%%%%%%%%%%.@@@@@@@@@@@@@@@@@.%%%%%%.@@@@@@.%%%+++ ", " +%%%%%%%%%%%%%%%%..@@@@@@@@@@@@@@@@@......@@@@@@..%%%+++ ", " +%%%%%%%%%%%%%%%%%.@@@@@@@@@@@@@@@@@@@@@@@@@@@@@.%%%%+++ ", " +%%%%%%%%%%%%%%%%%%.@@@@@@@@@@@@@@@@@@@@@@@@@@@.%%%%%+++ ", " +%%%%%%%%%%%%%%%%%%%.@@@@@@@@@@@@@@@@@@@@@@@@@.%%%%%%+++ ", " +%%%%%%%%%%%%%%%%%%%%.@@@@@@@@@@@@@@@@@@@@@@@.%%%%%%%+++ ", " +%%%%%%%%%%%%%%%%%%%%%.@@@@@@@@@@@@@@@@@@@@@.%%%%%%%%+++ ", " +%%%%%%%%%%%%%%%%%%%%%%.@@@@@@@@@@@@@@@@@@@.%%%%%%%%%+++ ", " +%%%%%...................@@@@@@@@@@@@@@@@@.......%%%%+++ ", " +%%%%%%%%%%%%%%%%%%%%%%%%...@@@@@@@@@@@@@.%%%%%%%%%%%+++ ", " +%%%%%%%%%%%%%%%%%%%%%%%%%%%..@@@@@@@@@..%%%%%%%%%%%%+++ ", " +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%.........%%%%%%%%%%%%%%+++ ", " +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%+++ ", " +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%+++ ", " +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%+++ ", " +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%+++ ", " +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%+++ ", " +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%+++ ", " +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%+++ ", " +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%+++ ", " +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%+++ ", " ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ", " ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ", " " };""" pythonToForum_icon = """ /* XPM */ static char * pythonToForum_icon[] = { /* columns rows colors chars-per-pixel */ "64 64 9 1", " c None", ". c #000000", "+ c #1A1B4D", "@ c #284F84", "# c #FF3000", "$ c #6B8CB4", "% c #94999E", "& c #D2D7D9", "* c #FEE849", " ", " ..................... ", " .###################. ", " .###################. ", " .###################. ++++++++ ", " .###################. ++++++++++++ ", " .###################.+++++$%%%&&&%%$$@++++ ", " .###################.+@&&&&&&&&&&&&&&&&$@++ ", " .###################.&&&&&&&&&&&&&$$$$$&&&$+++ ", " .###################.&&&$%&&&&&&&%&%%$$$$$&%@++ ", " .###################.&&%&&&&&&&&&%&&%%$$$$$&&%++ ", " .######..............%@@@@@&&&%%%&&&&%$$%&&&&&&@+ ", " .######. +$&&&&$@@@@@@@@@%&&&&%&&%%%&&%%&&%&%+ ", " .######. +$&&%$%@@@@@@@@@@@&&&%%&&&%&&&$&&&&&&%+ ", " .######. +@&&%&&@@@&@@@@@@@@@&&&&&&%%&%&$%&&&&&&%+ ", " .######. ++&&&%&&@@&&&@@@@@@@@@&&&&&%%%%%$&&&&&&&&@+ ", " .######......&&&&&@@@&@@@@@@@@@@&&&&%&%&&&&&&&&&&&&&@+ ", " .###########.&&&&&@@@@@@@@@@@@@@&&&&%&&&&&&&&&&&&&&&&+ ", " .###########.&&&&&&&%&&&&@@@@@@@....&&&&&&&&&&&&&&&&&%+ ", " .###########.@@@@@@@@@@@@@@@@@@@****.&&&&&&&&&&&&&&&&&+ ", " .###########.@@@@@@@@@@@@@@@@@@@*****.&%%&%&&&&&&&&&&&%+ ", " .######......@@@@@@@@@@@@@@@@@@@******.%$%%&%&&&&&&&&&&++ ", " .######.&&&&@@@@@@@@@@@@@@@@@@@@******.%$$$%$%&&&&&&&&&@+ ", " .######.&&&@@@@@@@@@@@@@@@@@@@@@******.&&%$$$$@@&&&&&%&%+ ", " .######.&&&@@@@@@@@@@@@@@@@@@@@@*******.&&%&%$$%&&&&&%&&++ ", " .######.&&&@@@@@@@@@@@@@@@@@@@@********.&&&&&&&&&&&&%%%&@+ ", " .######.&&$@@@@@@@@............********.&&&&&&&&%&&&$%%&%+ ", " .######.&$$@@@@@@@@********************.&&&&&&&&@%&&%@@%%+ ", " .######.&$$@@@@@@@@********************.&&&&&&&&%$&&&%%$$+ ", " .######.&$$@@@@@@@********************.&&&&&&&&&&@%&%%%$$+ ", " .######.&&&@@@@@@@********************.&&&&&&&&&&%$&%%@@$+ ", " .######.%&&&@@@@@@*******************.&&&&&&&&&&&&@%%@@@$+ ", " .######.$$%&&@@@@@*******************.&&&&&&&&&&&&$%@@@$$+ ", " ........$$$$&%%&&.********...........&&&&&&&&&&&&&&%%@@$$+ ", " ++&$$$$$%%&&.**************.$&&&&&&&&&&&&&&&&%%%@@$@+ ", " ++&$$$$$$&&&.**********.***.$$&%%$%%&&&&&&&&&%%@@@$@+ ", " ++&$$$$$$&&&.*********...**.$$$$$$$$&&&&&&&&%%%@@@$@+ ", " +$%$$$$$&&&&.*********.***.$$$$$$$$&&&&&&&%%%@@@@$++ ", " +@&$$$$%&&&&&.***********.$$$$$$$$$%&&&&&&%%%@@@$$++ ", " ++&$$$$&&&&&&&.********..$$$$$$$$$@%&&&&&%%%@@@@$@+ ", " +$$$$$%&&&&&&&..*****.$$$$$$$$$$@@$&&&&%%%%@@@@$++ ", " +@&$$$$&&&&&&&&&.....$$$$$$$$$$@@@@&&&%%%%%@@@$$+ ", " ++$$$$$$&&&&&&&&&&&%$$$$$$$$$@@@@@$&&%%%%%%@@@$++ ", " +@%$@$$%&&&&&&&&&&$$$$$$$$$@@@@@@$%%%%%%%%@@$@+ ", " +$$@@@$$&&&&&&&&&$$$$$$@@@@@@@@@$%%%%%%%@@@$++ ", " +$$@@@@%&&&&&&&&@$@@@@@@@@@@@@@$%%%%%%@@@$@+ ", " +@$$@@@%&&&&&&%%@@@@@@@@@@@@@@@@%%%%%%@@$@++ ", " +@$$@@%&&&&&%@@@@@@@@@@@@@@@@@@%%%%%%@$$++ ", " ++$$$@$&&&&&%@@@@@@@@@@@@@@@@@@@%%%%%$$++ ", " ++$$$$%%%%%%@@@@@@@@@@@@@@@@@@@%%%%$$++ ", " ++@$%%%%%%@@@@@@@@@@@@@@@@@@@@%%@$$++ ", " ++@%&%%%@@@@@@@@@@@@@@@@@@@@@%@$@++ ", " +++%&%@@@@@@@@@@@@@@@@@@@@@@$$@++ ", " ++++%$$@@@@@@@@@@@@@@@@@@$$@+++ ", " ++@$$$$@@@@@@@@@@@@$$$@++ ", " ++++@$$$$$$$$$$$$$@ +++ ", " +++++@@@@@++++++++ ", " +++++++++++++++++ ", " ", " ", " ", " ", " ", " " };""" help_To_Web_icon = """ /* XPM */ static char * help_To_Web_icon[] = { /* columns rows colors chars-per-pixel */ "64 64 9 1", " c None", ". c #020A4A", "+ c #144893", "@ c #4E5D73", "# c #4F6EA7", "$ c #7A9ECE", "% c #A5A9AC", "& c #CBDCEA", "* c #FFFFFF", " +++++++++++ ", " +++########+++ ", " ++&**********&+++ ", " ++$**************$++ ", " +$***%#++++++++#%***$+........ ", " +%**&++++++++++++++&**%+......... ", " +$**#+++++#****&#++++#**$+&&&&%$$+.... ", " +%**$+++++&********++++$**%+&&&&&&&&$+.. ", " ++$**$+++++&**********++++$**$+&&$$$$&&&&$... ", " +$**#+++++&***********#++++#**$+%&&&&$$$$&&+.. ", " +&*&++++++*****#+&*****+++++&*&+%&&&&&$$$$&&%.. ", " +#**+++++++****++++&****++++++**#+&&&&&&&*****&@. ", "++**%+++++++$**#++++&****++++++%**+$&&&&&&*%%*&$*%. ", "++**#++++++++++++++$*****++++++#**++&&&&***@&**&**%. ", "+#**++++++++++++++$*****++++++++**#+&&&&&&*@%******%. ", "+#**+++++++++++++%****&+++++++++**#+&&&&%%%$********@. ", "+#**++++++++++++$*****++++++++++**#+&%*%&*&*******&&&.. ", "+#**+++++++++++%****&+++++++++++**#+&%&&***********&&&. ", "+#**+++++++++++&****&+++++++++++**#+&&*************&&&@. ", "+#**+++++++++++&****&+++++++++++**#+&&&************&&&&. ", "+#**+++++++++++&****&+++++++++++**#+&***%%*%*******&&&&@. ", "+#**++++++++++++****++++++++++++**#+***@&&$%&%*****&&&&&.. ", "++**#++++++++++++++++++++++++++#**++&*%&&&$$$@$****&&&&&@. ", "++**%++++++++++++++++++++++++++%**+$&&&**&%$$$$+@&*&&&&&%. ", "++#**+++++++++++****+++++++++++**#+&&******$&&$$%**&&&%&&.. ", " +&*&+++++++++******+++++++++&*&+&&***************&&%%%&@. ", " +$**#++++++++******++++++++#**$+&*************&%*&&@@%&@. ", " +$**$+++++++******+++++++$**$+&&**************+%&&%++%@. ", " +%**$++++++******++++++$**%+&&***************%$&&&%%@@. ", " +$**#+++++#****#+++++#**$+&&&****************@%&%%%@$. ", " +%**&++++++++++++++&**%+&&&&****************@@&%%@+$. ", " .+$***%#++++++++#%***$+&&&&&***************&&+%%@++$. ", " .@++$**************$++&&&&$&***************&&@%@+++$. ", " .+$#++&**********&++#$$$$$$$&*************&&&&%%@+@@. ", " ..$$$+++########+++$$$$$$$$$$&************&&&%%%++$@. ", " .$$$$$#++++++++$$$$$$$$$$$$$$&@%@@%*****&&&&%%@++$@. ", " .$$$$$$$********%$$$$$$$$$$$$$$$$$$****&&&&%%%+++$+. ", " .$$$$$$$*********&$$$$$$$$$$$$$$$$$***&&&&&%%++++$. ", " .+$$$$$&***********&$$$$$$$$$$$$$$$%*&&&&&%%@+++@@. ", " ..$$$$$&*************%$$$$$$$$$$$++$&&&&&%%%@+++$+. ", " .$$$$$%*************%$$$$$$$$$$+++$&&&&%%%%@+++$.. ", " .+$$$$$&************@$$$$$$$$$+++++&&&%%%%%@++@@. ", " ..$$+$$$***********@$$$$$$$$++++++$&&%%%%%%@++$.. ", " .+$$++$%**********@$$$$$$++++++++$&%%%%%%%@+@@. ", " .$$++++$*********@$$$+++++++++++$%%%%%%%@++$.. ", " .$$++++%********@++++++++++++++@%%%%%%@++$@. ", " .+$$+++%&&&&&&%@++++++++++++++++%%%%%%@+@@.. ", " .+$$++%&&&&&%++++++++++++++++++@%%%%@@@@.. ", " ..$$$+@&&&&&%++++++++++++++++++@%%%%@@@.. ", " ..$$$$%%%%%@+++++++++++++++++++%%%@@@.. ", " ..+$%%%%%%++++++++++++++++++++%@@@@.. ", " .+%%%%@+++++++++++++++++++++.@@@.. ", " ..%%%@++++++++++++++++++++@@@+.. ", " ..@$$+++++++++++++++++@@@+... ", " ..+$$$$+++++++++++@@$@+.. ", " ...+$$$$$$$$$$$$@++... ", " .....+++++...... ", " ............. ", " ", " ", " ", " ", " ", " " };""" template_icon = """ /* XPM */ static char * template_icon[] = { /* columns rows colors chars-per-pixel */ "64 64 9 1", " c None", ". c #000000", "+ c #862122", "@ c #3C5A3B", "# c #884E4C", "$ c #5D5F5C", "% c #A1A09D", "& c #CEC9C8", "* c #FFFFFF", " %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%$$$$$$$$$$$$$$$$$$$$ ", " $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ ", " $%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%$ ", " $%***************************************************%$ ", " $%*%%%%%%******************@%************************%$ ", " $%*%%%%%%*$*$%%$&***********@%************$****&&****%$ ", " $%*%%%%%%*$&$%@$@@@@@@@@@&&$@$@@@@@@&@@@%%@@$@@@@@&&*%$ ", " $%*%%%%%%*&$%&@%$@@$%@@@@@$$@$@$@@@@%@@@@@@@@@@@@$$$*%$ ", " $%*%%%%%%**&&*&*&&&&*&&&&&&&&&&&&&&&*&&&&&&&&&&&&&&&*%$ ", " $%*%%%%%%*%%%%&***%%&****%****&*****%&**&%%%%%%%%*&%*%$ ", " $%*%%%%%%*@@@@$%%%@@@%%%%@%%%$$%%%%%$@&**%$@$$@@@&%@*%$ ", " $%*%%%%%%*@$@$@@@@@@..@@$@@@@@@@@@@@$@&*&$@@@@@@@@@@*%$ ", " $%*%%%%%%********************************************%$ ", " $%*%%%%%%********************************************%$ ", " $%*%%%%%%********************************************%$ ", " $%*%%%%%%********************************************%$ ", " $%*%%%%%%********************************************%$ ", " $%*%%%%%%********************************************%$ ", " $%*%%%%%%********************************************%$ ", " $%*%%%%%%********************************************%$ ", " $%*%%%%%%********************************************%$ ", " $%*%%%%%%********************************************%$ ", " $%*%% %%***********&&***#++#%%&%*#&&&&&&**##&&&&&%#*%$ ", " $%*%% %%***********%%&**&&++#+##&#+#+++%**+##+++++#*%$ ", " $%*%%%%%%*&&&&*************&&&&&&&&&&&&&&&&&&&&&&&&&*%$ ", " $%*%%%%%%*&&&************&&**&&**********%&**********%$ ", " $%*%%%%%%*%*********%%&**#+%###%%%%%%%%%%#%%%%%%%%%%*%$ ", " $%*%%%%%%*$*********$$&****&##+++++++++#&%##+###+++#*%$ ", " $%*%%%%%%*$****************$########+###%#+##$######*%$ ", " $%*%%%%%%**$$$$%*************************************%$ ", " $%*%%%%%%************&***#+#&&%&$&&&*&&&**#*#%+%&&&&*%$ ", " $%*%%%%%%***********$$&**&%++++#+#++#+##&%$&#*+#++++*%$ ", " $%*%%%%%%***********&&&****&&&&&&&+&&&&&&%%#&*&&&&&&*%$ ", " $%*%%%%%%*************************&******&%&*&**&****%$ ", " $%*%%%%%%*%*********%%&**%%%&&%%%%%%*%%%&&#*%%%%#&%%*%$ ", " $%*%%%%%%*$%********$$&****+###$#$+##+##&%&%+#+##&#$*%$ ", " $%*%%%%%%*$****************+#++%##++#+####*+%*+#+##+*%$ ", " $%*%%%%%%**$$$$$******************%***********%&*****%$ ", " $%*%%%%%%****************####%***********************%$ ", " $%*%% %%***********$$&**&%%%&***********************%$ ", " $%*%% %%***********&&&******************************%$ ", " $%*%%%%%%*%&*****************************************%$ ", " $%*%%%%%%*&**************%%%&**&%%%%*%&**************%$ ", " $%*%%%%%%*$$$&******%$&**%#%#**&#+$#*#&**************%$ ", " $%*%%%%%%*.$@%*************#+######+*****************%$ ", " $%*%%%%%%****$$$$$***********************************%$ ", " $%*%%%%%%****************%#&%&#&%&%#*&%&&*&*$%%*%&%#*%$ ", " $%*%%%%%%***********$$&**&%#+#+###+#*#%+#++&#*###+%%*%$ ", " $%*%%%%%%***********&&&****###+#####&%&#%#+#&*###%***%$ ", " $%*%%%%%%*%&***************&&&&&&&&&&&*&*&&&**&&&****%$ ", " $%*%%%%%%*&******************************************%$ ", " $%*%%%%%%********************************************%$ ", " $%*%%%%%%********************************************%$ ", " $%*%%%%%%********************************************%$ ", " $%*%%%%%%********************************************%$ ", " $%*%%%%%%*$&%%$$.$.$%*&.$$$$$$$$$$..$$$$&%$%#%+#####*%$ ", " $%*%%%%%%*.$..$$$..$$&%.$..$.$......$..$%%$*&&++++++*%$ ", " $%*%%%%%%*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&***&&&&&&*%$ ", " $%*%%%%%%********************************************%$ ", " $%*%%%%%%********************************************%$ ", " $%*%%%%%%********************************************%$ ", " $%***************************************************%$ ", " $%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%$ ", " $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ " };""" directory_Backup_Empty_icon = """ /* XPM */ static char * directory_Backup_Empty_icon[] = { /* columns rows colors chars-per-pixel */ "64 64 8 1", " c None", ". c #4F514F", "+ c #315E97", "@ c #808381", "# c #5C90C6", "$ c #73A3D2", "% c #ADB1AF", "& c #A1BDDE", " ", " ", " ", " ", " ", " ", " ................................................. ", " .@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@. ", " .@%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%@. ", " .@%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%@. ", " .@%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%@. ", " .@%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%@. ", " .@%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%@. ", " .@%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%@. ", " .@%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%. ", " .@%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%. ", " .@%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%. ", " .@%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%. ", " .@%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%. ", " .@%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%. ", " .@%%%%%++++++++++++++++++++++++++++++++++++++++++++++++ ", " .@%%%%%+&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&+ ", " .@%%%%%+&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&+ ", " .@%%%%%+&&$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$+ ", " .@%%%%++&&$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$++ ", " ..%%%%+&&&$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$+ ", " ..%%%%+&&$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$+ ", " ..%%%%+&&$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$+ ", " ..%%%%+&&$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$+ ", " ..%%%%+&&$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$+ ", " ..%%%%+&&$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$+ ", " ..%%%%+&&$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$+ ", " ..%%%%+&&$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$+ ", " ..%%%%+&&$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$+ ", " ..%%%%+&&$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$+ ", " ..%%%++&&$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$++ ", " ..%%%++&&$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$++ ", " .%%%+&&$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$++ ", " .%%%+&&$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$+ ", " .%%%+&&$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$+ ", " .%%%+&&$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$+ ", " .%%%+&&$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$+ ", " .%%%+&&$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$#+ ", " .%%%+&&$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$#+ ", " .%%%+&&$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$#+ ", " ..%%+&&$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$#+ ", " ..%%+&&############################################+ ", " ..%%+&&###########################################++ ", " ..%++&############################################++ ", " .%++&############################################++ ", " .%+##############################################++ ", " .%+##############################################+ ", " .+++++++++++++++++++++++++++++++++++++++++++++++++ ", " .+++++++++++++++++++++++++++++++++++++++++++++++++ ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " " };""" directory_Backup_Taken_icon = """ /* XPM */ static char * directory_Backup_Taken_icon[] = { /* columns rows colors chars-per-pixel */ "64 64 9 1", " c None", ". c #290000", "+ c #C60916", "@ c #ED2928", "# c #2C5C96", "$ c #5D5F5C", "% c #70A2D4", "& c #FEE849", "* c #FFFFFF", " ", " ######## ", " ############## ", " ################ ", " ################## ", " ### ############## ", " ### ############## ", " ### ############## ", " $$$$$$$$$$$$$$$$$####################$$$$$$$$ ", " $$$$$$$$$$$$$$$$$####################$$$$$$$$ ", " $$***************####################*******$ ", " $$*************************##########*******$ ", " $$$$$$$$$$$$$$$********###########################*&&&&&&$ ", " $$$$$$$$$$$$$$$*******############################*&&&&&&&& ", " $$************$*******############################*&&&&&&&& ", " $$************$*******############################*&&&&&&&&& ", " $**$$$$$$$$$$$*****##############################*&&&&&&&&& ", " $***********$$*****##############################$&&&&&&&&& ", " $**$$$$$$$$$$******##############################*&&&&&&&&& ", " $**$$$$$$$$$$*****##############################**&&&&&&&&&& ", " $**$$$$$$$$$$*****##############################*&&&&&&&&&&& ", " $**$$$$$$$$$$*****############################**&&&&&&&&&&&& ", " $**********$******##############**************&&&&&&&&&&&&&& ", " $$*$$$$$$$$$******############**&&&&&&&&&&&&&&&&&&&&&&&&&&&& ", " $$**$$$$$$$*******###########*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& ", " $$*******$$******$##########$$&&.&&&&&&&&&&&&&&&&&&&.&&&&&&& ", " $$**$$$$$$$********#########*&&...&&&&&&&&&&&&&&&&&...&&&&& ", " $$**$$$$$$*********#########*&..+..&&&&&&&&&&&&&&&..+..&&&& ", " $$**$$$$$$*********#########*..+@+..&&&&&&&&&&&&&..+@+..&&& ", " $**$$$$$$*********#########..+@@@+..&&&&&&&&&&&..+@@@+..$$$$$", " $**$$$$$****##############..+@@+@@+..#########..+@@+@@+..###$", " $**$$$$$***$#%%%%%%%%%%%%..+@@+++@@+..%%%%%%%..+@@+++@@+..%#$", " $$*$$$$$***$#***********..+@@+++++@@+..*****..+@@+++++@@+..#$", " $$*$$$$****$#*%%%%%%%%%..+@@+++++++@@+..%%%..+@@+++++++@@+..$", " $$*$$$$****##*%%%%%%%%..+@@+++++++++@@+..%..+@@+++++++++@@+..", " $$*$$$$****#%*%%%%%%%%%..+@@+++++++++@@+...+@@+++++++++@@+..$", " $$*$$$*****#%*%%%%%%%%%%..+@@+++++++++@@+.+@@+++++++++@@+..#$", " $$*$$$*****#*%%%%%%%%%%%%..+@@+++++++++@@+@@+++++++++@@+..#$ ", " $**$$*****#*%%%%%%%%%%%%%..+@@+++++++++@@@+++++++++@@+..%#$ ", " $*$$$****$#*%%%%%%%%%%%%%%..+@@+++++++++@+++++++++@@+..%##$ ", " $**$$****##%%%%%%%%%%%%%%%%..+@@+++++++++++++++++@@+..%%#$ ", " $**$*****#%%%%%%%%%%%%%%%%%%..+@@+++++++++++++++@@+..%%%#$ ", " $$$$*****#%%%%%%%%%%%%%%%%%%%..+@@+++++++++++++@@+..%%%##$ ", " $$*$*****#%%%%%%%%%%%%%%%%%%%%..+@@+++++++++++@@+..%%%%#$ ", " $$*$*****#%%%%%%%%%%%%%%%%%%%%%..+@@+++++++++@@+..%%%%%#$ ", " $$$$****%#%%%%%%%%%%%%%%%%%%%%..+@@+++++++++++@@+..%%%%#$ ", " $$*$****#%%%%%%%%%%%%%%%%%%%%..+@@+++++++++++++@@+..%%#$ ", " $$*$$***#%%%%%%%%%%%%%%%%%%%..+@@+++++++++++++++@@+..%#$ ", " $$*$$$$$#%%%%%%%%%%%%%%%%%%..+@@+++++++++++++++++@@+..#$ ", " $$*$$$$$#%%%%%%%%%%%%%%%%%..+@@+++++++++@+++++++++@@+..$ ", " $$$$$$$##%%%%%%%%%%%%%%%%..+@@+++++++++@@@+++++++++@@+.. ", " $$$$$$#%%%%%%%%%%%%%%%%..+@@+++++++++@@+@@+++++++++@@+.. ", " $$$$$$#%%%%%%%%%%%%%%%..+@@+++++++++@@+.+@@+++++++++@@+.. ", " $$$$$##%%%%%%%%%%%%%%..+@@+++++++++@@+...+@@+++++++++@@+.. ", " $$$$$#%%%%%%%%%%%%%%..+@@+++++++++@@+..%..+@@+++++++++@@+..", " $$$$##%%%%%%%%%%%%%%%..+@@+++++++@@+..%%%..+@@+++++++@@+.. ", " $$$##%%%%%%%%%%%%%%%%%..+@@+++++@@+..%%%%%..+@@+++++@@+.. ", " $$##%%%%%%%%%%%%%%%%%%%..+@@+++@@+..%%%%%%%..+@@+++@@+.. ", " $######################..+@@+@@+..#########..+@@+@@+.. ", " $######################..+@@@+..###########..+@@@+.. ", " $$$$$$$$$$$$$$$$$$$$$$$..+@+..$$$$$$$$$$$$$..+@+.. ", " ..+.. ..+.. ", " ... ... ", " . . " };""" file_Txt_icon = """ /* XPM */ static char * directory_Backup_Taken_icon[] = { /* columns rows colors chars-per-pixel */ "64 64 9 1", " c None", ". c #C92415", "+ c #635E51", "@ c #7F6411", "# c #A7A8A3", "$ c #CCA735", "% c #D0A36C", "& c #D6D7D1", "* c #FFFFFF", " ", " ", " ", " @@@@ @@@@ @@@@ @@@@ @@@@ @@@@ @@@@ @@@@ ", " @$$@ @$$@ @$$@ @$$@ @$$@ @$$@ @$$@ @$$@ ", " #%@$$@%@$$@%@$$@%%@$$@%@$$@%@$$@%%@$$@%@$$@%% ", " ###@$$@#@$$@#@$$@##@$$@#@$$@#@$$@##@$$@#@$$@### ", " #&&#@$$@&@$$@&@$$@&&@$$@&@$$@&@$$@&&@$$@&@$$@#### ", " #&#%@$$@%@$$@%@$$@%%@$$@%@$$@%@$$@%%@$$@%@$$@%%%# ", " #&##@@@@#@@@@#@@@@##@@@@#@@@@#@@@@##@@@@#@@@@#### ", " #&###@@###@@###@@####@@###@@###@@####@@###@@##### ", " #&############################################### ", " #&**********************************************# ", " #***********************************************# ", " #***********************************************# ", " ##***********************************************# ", " ##****######################################&****# ", " ##****&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&****# ", " #&***********************************************# ", " #&***********************************************# ", " #&****######################################&****# ", " #&****&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&****## ", " #&***********************************************#@@@@@ ", " #&*********************************************&#@@...@@ ", " #*****#################&*********************&#@@......@@ ", " #*****&&&&&&&&&&&&&&&&&&*******************&#@@##.......@ ", " #****************************************&#@@%%###......@ ", " #**************************************&+@@%%%%####.....@ ", " #************************************&+@@%%%%%%%###....@ ", " #**********************************&+@@%%%%%%$$$###..@@@ ", " ##*****&&&&&&&&&&&&&&&&&&&&&&&&&&&#+@@%%%%%$$$$$$$##@@@ ", " ##*****##########################@@@%%%%%$$$$$$$@+@@@ ", " #&****************************#@@@%%%%%$$$$$$@@@@@## ", " #&**************************#@@@%%%%%$$$$$$@@@@@+&*# ", " #&*****&&&&&&&&&&&&&&&&&&&#@@@%%%%%$$$$$$@@@@@+&&&*# ", " #&*****##################@@@%%%%%$$$$$$@@@@@+#&&&&*#+ ", " #&*********************&@@%%%%%$$$$$$@@@@@+&&&&&&&*#+ ", " #&********************&@@%%%%$$$$$$@@@@+&&&&&&&&&&*#+ ", " #&*****&&&&&&&&&&&&&&&@@%%%%$$$$$@@@@+#&&&&&&&&&&&*&+ ", " #&*****##############@@%%%%%$$@@@@@+##########&&&&*&+ ", " #*****&&&&&&&&&&&&&&@@%%%%%%%@@@@+#&&&&&&&&&&&&&&&*&+ ", " #**&&&&&&&&&&&&&&&&@@+%%%%%%@@@+###&&&&&&&&&&&&&&&*&+ ", " #**&&&&&&&&&&&&&&#++++@@@@@@++######&&&&&&&&&&&&&&*&+ ", " #**&&&&##########++++#############&&&&&&&&&&&&&&&&&&+ ", " +#*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*+ ", " +#*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*+ ", " +#*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*+ ", " +#*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*+ ", " +#*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*+ ", " +&*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*#+ ", " +&*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*#+ ", " +&*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*#+ ", " +&***************************************************#+ ", " +&&#################################################&#+ ", " +&##################################################&#+ ", " +&##################################################&#+ ", " +#&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&#+ ", " ++++++++++++++++++++++++++++++++++++++++++++++++++++++ ", " +++++++++++++++++++++++++++++++++++++++++++++++++++ ", " ", " ", " ", " ", " " };""" children = mw.findChildren(QtWidgets.QWidget,"Editor assistant") if not children: modifiers = QtWidgets.QApplication.keyboardModifiers() if modifiers == QtCore.Qt.AltModifier: showEditorAssistantAsDockWidget(floating=True) else: showEditorAssistantDialog() else: FreeCAD.Console.PrintError("Editor assistant already running\n")