class Q7OptionContext(object): Q_VAR_NODE = 'NODE' Q_VAR_PARENT = 'PARENT' Q_VAR_NAME = 'NAME' Q_VAR_VALUE = 'VALUE' Q_VAR_CGNSTYPE = 'SIDSTYPE' Q_VAR_CHILDREN = 'CHILDREN' Q_VAR_TREE = 'TREE' Q_VAR_PATH = 'PATH' Q_VAR_LINKS = 'LINKS' Q_VAR_SKIPS = 'SKIPS' Q_VAR_RESULT = 'RESULT' Q_VAR_USER = '******' Q_VAR_SELECTED = 'SELECTED' Q_VAR_RESULT_LIST = '__Q7_QUERY_RESULT__' Q_SCRIPT_PRE = """ import CGNS.PAT.cgnskeywords as CGK import CGNS.PAT.cgnsutils as CGU import CGNS.PAT.cgnslib as CGL import numpy """ Q_FILE_PRE = """ import CGNS.PAT.cgnskeywords as CGK import CGNS.PAT.cgnsutils as CGU import CGNS.PAT.cgnslib as CGL import CGNS.NAV.moption as CGO import numpy """ Q_SCRIPT_POST = """ try: %s[0]=%s except NameError: %s[0]=None """ % (Q_VAR_RESULT_LIST, Q_VAR_RESULT, Q_VAR_RESULT_LIST) _depends = { 'MaxDisplayDataSize': ['DoNotDisplayLargeData'], 'MaxLoadDataSize': ['DoNotLoadLargeArrays'], 'MaxRecursionLevel': ['RecursiveTreeDisplay'], } _HasProPackage = True CHLoneTrace = False QueryNoException = False ActivateMultiThreading = False NAVTrace = False AutoExpand = False RecursiveTreeDisplay = False OneViewPerTreeNode = False ShowTableIndex = True RecursiveSIDSPatternsLoad = True DoNotDisplayLargeData = False CheckOnTheFly = False FollowLinksAtLoad = True DoNotFollowLinksAtSave = True AddCurrentDirInSearch = True AddRootDirInSearch = True DoNotLoadLargeArrays = True ShowSIDSStatusColumn = True ForceSIDSLegacyMapping = False ForceFortranFlag = True FilterCGNSFiles = True FilterHDFFiles = True FilterOwnFiles = True FileUpdateRemovesChildren = True TransposeArrayForView = True Show1DAsPlain = True ShowSIDSColumn = True ShowLinkColumn = True ShowSelectColumn = True ShowUserColumn = True ShowCheckColumn = True ShowShapeColumn = True ShowDataTypeColumn = True UserCSS = "" SelectionListDirectory = op.normpath(op.join(conf_path, 'selections')) QueriesDirectory = op.normpath(op.join(conf_path, 'queries')) FunctionsDirectory = op.normpath(op.join(conf_path, 'functions')) SnapShotDirectory = op.normpath(op.join(conf_path, 'snapshots')) _HistoryFileName = op.normpath(op.join(conf_path, 'historyfile.py')) _OptionsFileName = op.normpath(op.join(conf_path, 'optionsfile.py')) _QueriesDefaultFile = 'default.py' _FunctionsDefaultFile = 'default.py' IgnoredMessages = [] LinkSearchPathList = [] ProfileSearchPathList = [] GrammarSearchPathList = [] ValKeyList = ['sample'] CGNSFileExtension = ['.cgns', '.adf'] HDFFileExtension = ['.hdf', '.hdf5'] OwnFileExtension = ['.cgh'] MaxLoadDataSize = 1000 MaxDisplayDataSize = 1000 MaxRecursionLevel = 7 ADFConversionCom = 'cgnsconvert' TemporaryDirectory = op.normpath(tmp_path) _ConvertADFFiles = True _ToolName = 'CGNS.NAV' _ToolVersion = '%s' % __vid__ _CopyrightNotice = u""" Copyright (c) Marc Poinot <br> Copyright (c) Onera - The French Aerospace Labs<br><br> <b>all other copyrights and used versions listed below</b> <hr> <h3>Contributors (alphabetic order)</h3> <table> <tr><td>Florent Cayré</td><td>-SNECMA, France</td></tr> <tr><td>Alexandre Fayolle</td><td>-LOGILAB, France</td></tr> <tr><td>Loic Hauchard</td><td>-ONERA (Student INSA Rouen, France)</td></tr> <tr><td>Elise Hénaux</td><td>-ONERA (Student FIIFO Orsay, France)</td></tr> <tr><td>Grégory Laheurte</td><td>-ONERA (DSNA/CS2A), France</td></tr> <tr><td>Pierre-Jacques Legay</td><td>-BERTIN, France</td></tr> <tr><td>Bill Perkins</td><td>-Pacific Northwest Ntl Lab, U.S.A.</td></tr> <tr><td>Jérôme Regis</td><td>-STILOG, France</td></tr> <tr><td>Benoit Rodriguez</td><td>-ONERA (DAAP/H2T), France</td></tr> <tr><td>Tristan Soubrié</td><td>-ANDHEO, France</td></tr> <tr><td>Francois Thirifays</td><td>-CENAERO, Belgique</td></tr> <tr><td>Simon Verley</td><td>-ONERA (DADS/MSAE), France</td></tr> <tr><td>Ching-Yang Wang</td><td>-U.S.A.</td></tr> </table> <h2>Copyrights & Versions</h2> <hr> %(pycgnsversion)s<br> All <b>pyCGNS</b> rights reserved in accordance with GPL v2 <br><br> <b>NO WARRANTY :</b><br> Check GPL v2 sections 15 and 16 about <font color=red>loss of data or corrupted data</font><br> <hr> %(pyqtversion)s<br> PyQt Copyright (c) Riverbank Computing Limited. <br> Usage within the terms of the GPL v2.<br> All Rights Reserved.<br> <hr> %(qtversion)s<br> Qt Copyright (c)<br> The Qt4 Library is (c) 2011 Nokia Corporation and/or its subsidiary(-ies), and is licensed under the GNU Lesser General Public License version 2.1 with Nokia Qt LGPL exception version 1.1. <br> <hr> %(pythonversion)s<br> Python Copyright (c)<br> Copyright (c) 2001-2011 Python Software Foundation.<br> All Rights Reserved.<br> <br> Copyright (c) 2000 BeOpen.com.<br> All Rights Reserved.<br> <br> Copyright (c) 1995-2001 Corporation for National Research Initiatives.<br> All Rights Reserved.<br> <br> Copyright (c) 1991-1995 Stichting Mathematisch Centrum, Amsterdam.<br> All Rights Reserved.<br> <br> <hr> %(numpyversion)s<br> Numpy Copyright (c)<br> Copyright (c) 2005, NumPy Developers<br> <hr> %(hdf5version)s<br> HDF5 Copyright (c)<br> HDF5 (Hierarchical Data Format 5) Software Library and Utilities<br> Copyright 2006-2013 by The HDF Group.<br> NCSA HDF5 (Hierarchical Data Format 5) Software Library and Utilities<br> Copyright 1998-2006 by the Board of Trustees of the University of Illinois.<br> <hr> %(vtkversion)s<br> VTK Copyright (c)<br> Copyright (c) 1993-2008 Ken Martin, Will Schroeder, Bill Lorensen <br> All rights reserved.<br> <hr> %(cythonversion)s<br> Cython Copyright (c)<br> (c) Copyright 2012, Stefan Behnel, Robert Bradshaw, Dag Sverre Seljebotn, Greg Ewing, William Stein, Gabriel Gellner, et al. <hr> Icons Copyright (c)<br> All these nice icons are provided or are modified versions of original icons provided by Mark James (Birmingham, UK).<br> Please visit his web site: http://www.famfamfam.com/<br> """ #__fv = QFont(QFontDatabase().families()[0]) # Spyder-like but needs a QApplication __fv = QFont('Courier new') __fc = QFont('Courier new') _Label_Font = QFont(__fv) _Button_Font = QFont(__fv) _Table_Font = QFont(__fc) _Edit_Font = QFont(__fc) _RName_Font = QFont(__fc) _NName_Font = QFont(__fc) _NName_Font.setBold(True) _Default_Fonts = { 'Label_Family': _Label_Font.family(), 'Label_Size': _Label_Font.pointSize(), 'Label_Bold': False, 'Label_Italic': False, 'Table_Family': _Table_Font.family(), 'Table_Size': _Table_Font.pointSize(), 'Table_Bold': False, 'Table_Italic': False, 'Edit_Family': _Edit_Font.family(), 'Edit_Size': _Edit_Font.pointSize(), 'Edit_Bold': False, 'Edit_Italic': False, 'Button_Family': _Button_Font.family(), 'Button_Size': _Button_Font.pointSize(), 'Button_Bold': False, 'Button_Italic': False, 'RName_Family': _RName_Font.family(), 'RName_Size': _RName_Font.pointSize(), 'RName_Bold': False, 'RName_Italic': False, 'NName_Family': _NName_Font.family(), 'NName_Size': _NName_Font.pointSize(), 'NName_Bold': False, 'NName_Italic': True, } UserColors = [ 'gray', 'red', 'green', 'blue', 'orange', None, None, None, None, None, ] _ColorList = { 'cold_grey': (0.5000, 0.5400, 0.5300), 'dim_grey': (0.4118, 0.4118, 0.4118), 'grey': (0.7529, 0.7529, 0.7529), 'light_grey': (0.8275, 0.8275, 0.8275), 'slate_grey': (0.4392, 0.5020, 0.5647), 'slate_grey_dark': (0.1843, 0.3098, 0.3098), 'slate_grey_light': (0.4667, 0.5333, 0.6000), 'warm_grey': (0.5000, 0.5000, 0.4100), 'black': (0.0000, 0.0000, 0.0000), 'ivory_black': (0.1600, 0.1400, 0.1300), 'lamp_black': (0.1800, 0.2800, 0.2300), 'alizarin_crimson': (0.8900, 0.1500, 0.2100), 'brick': (0.6100, 0.4000, 0.1200), 'coral': (1.0000, 0.4980, 0.3137), 'coral_light': (0.9412, 0.5020, 0.5020), 'deep_pink': (1.0000, 0.0784, 0.5765), 'firebrick': (0.6980, 0.1333, 0.1333), 'geranium_lake': (0.8900, 0.0700, 0.1900), 'hot_pink': (1.0000, 0.4118, 0.7059), 'light_salmon': (1.0000, 0.6275, 0.4784), 'madder_lake_deep': (0.8900, 0.1800, 0.1900), 'maroon': (0.6902, 0.1882, 0.3765), 'pink': (1.0000, 0.7529, 0.7961), 'pink_light': (1.0000, 0.7137, 0.7569), 'raspberry': (0.5300, 0.1500, 0.3400), 'rose_madder': (0.8900, 0.2100, 0.2200), 'salmon': (0.9804, 0.5020, 0.4471), 'tomato': (1.0000, 0.3882, 0.2784), 'beige': (0.6400, 0.5800, 0.5000), 'brown': (0.5000, 0.1647, 0.1647), 'brown_madder': (0.8600, 0.1600, 0.1600), 'brown_ochre': (0.5300, 0.2600, 0.1200), 'burlywood': (0.8706, 0.7216, 0.5294), 'burnt_sienna': (0.5400, 0.2100, 0.0600), 'burnt_umber': (0.5400, 0.2000, 0.1400), 'chocolate': (0.8235, 0.4118, 0.1176), 'deep_ochre': (0.4500, 0.2400, 0.1000), 'flesh': (1.0000, 0.4900, 0.2500), 'flesh_ochre': (1.0000, 0.3400, 0.1300), 'gold_ochre': (0.7800, 0.4700, 0.1500), 'greenish_umber': (1.0000, 0.2400, 0.0500), 'khaki': (0.9412, 0.9020, 0.5490), 'khaki_dark': (0.7412, 0.7176, 0.4196), 'light_beige': (0.9608, 0.9608, 0.8627), 'peru': (0.8039, 0.5216, 0.2471), 'rosy_brown': (0.7373, 0.5608, 0.5608), 'raw_sienna': (0.7800, 0.3800, 0.0800), 'raw_umber': (0.4500, 0.2900, 0.0700), 'sepia': (0.3700, 0.1500, 0.0700), 'sienna': (0.6275, 0.3216, 0.1765), 'saddle_brown': (0.5451, 0.2706, 0.0745), 'sandy_brown': (0.9569, 0.6431, 0.3765), 'tan': (0.8235, 0.7059, 0.5490), 'van_dyke_brown': (0.3700, 0.1500, 0.0200), 'cadmium_orange': (1.0000, 0.3800, 0.0100), 'carrot': (0.9300, 0.5700, 0.1300), 'dark_orange': (1.0000, 0.5490, 0.0000), 'mars_orange': (0.5900, 0.2700, 0.0800), 'mars_yellow': (0.8900, 0.4400, 0.1000), 'orange': (1.0000, 0.5000, 0.0000), 'orange_red': (1.0000, 0.2706, 0.0000), 'yellow_ochre': (0.8900, 0.5100, 0.0900), 'aureoline_yellow': (1.0000, 0.6600, 0.1400), 'banana': (0.8900, 0.8100, 0.3400), 'cadmium_lemon': (1.0000, 0.8900, 0.0100), 'cadmium_yellow': (1.0000, 0.6000, 0.0700), 'cadmium_yellow_light': (1.0000, 0.6900, 0.0600), 'gold': (1.0000, 0.8431, 0.0000), 'goldenrod': (0.8549, 0.6471, 0.1255), 'goldenrod_dark': (0.7216, 0.5255, 0.0431), 'goldenrod_light': (0.9804, 0.9804, 0.8235), 'goldenrod_pale': (0.9333, 0.9098, 0.6667), 'light_goldenrod': (0.9333, 0.8667, 0.5098), 'melon': (0.8900, 0.6600, 0.4100), 'naples_yellow_deep': (1.0000, 0.6600, 0.0700), 'yellow': (1.0000, 1.0000, 0.0000), 'yellow_light': (1.0000, 1.0000, 0.8784), 'chartreuse': (0.4980, 1.0000, 0.0000), 'chrome_oxide_green': (0.4000, 0.5000, 0.0800), 'cinnabar_green': (0.3800, 0.7000, 0.1600), 'cobalt_green': (0.2400, 0.5700, 0.2500), 'emerald_green': (0.0000, 0.7900, 0.3400), 'forest_green': (0.1333, 0.5451, 0.1333), 'green': (0.0000, 1.0000, 0.0000), 'green_dark': (0.0000, 0.3922, 0.0000), 'green_pale': (0.5961, 0.9843, 0.5961), 'green_yellow': (0.6784, 1.0000, 0.1843), 'lawn_green': (0.4863, 0.9882, 0.0000), 'lime_green': (0.1961, 0.8039, 0.1961), 'mint': (0.7400, 0.9900, 0.7900), 'olive': (0.2300, 0.3700, 0.1700), 'olive_drab': (0.4196, 0.5569, 0.1373), 'olive_green_dark': (0.3333, 0.4196, 0.1843), 'permanent_green': (0.0400, 0.7900, 0.1700), 'sap_green': (0.1900, 0.5000, 0.0800), 'sea_green': (0.1804, 0.5451, 0.3412), 'sea_green_dark': (0.5608, 0.7373, 0.5608), 'sea_green_medium': (0.2353, 0.7020, 0.4431), 'sea_green_light': (0.1255, 0.6980, 0.6667), 'spring_green': (0.0000, 1.0000, 0.4980), 'spring_green_medium': (0.0000, 0.9804, 0.6039), 'terre_verte': (0.2200, 0.3700, 0.0600), 'viridian_light': (0.4300, 1.0000, 0.4400), 'yellow_green': (0.6039, 0.8039, 0.1961), 'aquamarine': (0.4980, 1.0000, 0.8314), 'aquamarine_medium': (0.4000, 0.8039, 0.6667), 'cyan': (0.0000, 1.0000, 1.0000), 'cyan_white': (0.8784, 1.0000, 1.0000), 'turquoise': (0.2510, 0.8784, 0.8157), 'turquoise_dark': (0.0000, 0.8078, 0.8196), 'turquoise_medium': (0.2824, 0.8196, 0.8000), 'turquoise_pale': (0.6863, 0.9333, 0.9333), 'alice_blue': (0.9412, 0.9725, 1.0000), 'blue': (0.0000, 0.0000, 1.0000), 'blue_light': (0.6784, 0.8471, 0.9020), 'blue_medium': (0.0000, 0.0000, 0.8039), 'cadet': (0.3725, 0.6196, 0.6275), 'cobalt': (0.2400, 0.3500, 0.6700), 'cornflower': (0.3922, 0.5843, 0.9294), 'cerulean': (0.0200, 0.7200, 0.8000), 'dodger_blue': (0.1176, 0.5647, 1.0000), 'indigo': (0.0300, 0.1800, 0.3300), 'manganese_blue': (0.0100, 0.6600, 0.6200), 'midnight_blue': (0.0980, 0.0980, 0.4392), 'navy': (0.0000, 0.0000, 0.5020), 'peacock': (0.2000, 0.6300, 0.7900), 'powder_blue': (0.6902, 0.8784, 0.9020), 'royal_blue': (0.2549, 0.4118, 0.8824), 'slate_blue': (0.4157, 0.3529, 0.8039), 'slate_blue_dark': (0.2824, 0.2392, 0.5451), 'slate_blue_light': (0.5176, 0.4392, 1.0000), 'slate_blue_medium': (0.4824, 0.4078, 0.9333), 'sky_blue': (0.5294, 0.8078, 0.9216), 'sky_blue_deep': (0.0000, 0.7490, 1.0000), 'sky_blue_light': (0.5294, 0.8078, 0.9804), 'steel_blue': (0.2745, 0.5098, 0.7059), 'steel_blue_light': (0.6902, 0.7686, 0.8706), 'turquoise_blue': (0.0000, 0.7800, 0.5500), 'ultramarine': (0.0700, 0.0400, 0.5600), 'blue_violet': (0.5412, 0.1686, 0.8863), 'cobalt_violet_deep': (0.5700, 0.1300, 0.6200), 'magenta': (1.0000, 0.0000, 1.0000), 'orchid': (0.8549, 0.4392, 0.8392), 'orchid_dark': (0.6000, 0.1961, 0.8000), 'orchid_medium': (0.7294, 0.3333, 0.8275), 'permanent_red_violet': (0.8600, 0.1500, 0.2700), 'plum': (0.8667, 0.6275, 0.8667), 'purple': (0.6275, 0.1255, 0.9412), 'purple_medium': (0.5765, 0.4392, 0.8588), 'ultramarine_violet': (0.3600, 0.1400, 0.4300), 'violet': (0.5600, 0.3700, 0.6000), 'violet_dark': (0.5804, 0.0000, 0.8275), 'violet_red': (0.8157, 0.1255, 0.5647), 'violet_red_medium': (0.7804, 0.0824, 0.5216), 'violet_red_pale': (0.8588, 0.4392, 0.5765), } _ReservedNames = CGK.cgnsnames _ReservedTypes = CGK.cgnstypes _SortedTypeList = CGK.sortedtypelist _UsualQueries = [ # --------------------------------------------------------------------------- # INDENTATION IS SIGNIFICANT # --------------------------------------------------------------------------- # --- Search ----------------------------------------------------------- # last two booleans: Update tree, has args ('001. Node name', 'Search by', 'RESULT=(NAME==ARGS[0])', """ Search by Node name Search all nodes with the exact NAME as argument. The argument name need not to be a tuple or to have quotes, all the following values are ok and would match the NAME <i>ZoneType</i>: ZoneType 'ZoneType' ('ZoneType',) """, False, True), ('002. Wildcard node name', 'Search by', """import fnmatch RESULT=fnmatch.fnmatchcase(NAME,ARGS[0]) """, """ Search by Wildcard node name Search all nodes with the wildcard NAME as argument. Warning: the <b>argument name</b> should be quoted: 'BC*' is ok BC* would fail """, False, True), ('003. Node type', 'Search by', 'RESULT=(SIDSTYPE==ARGS[0])', """search all nodes with argument SIDS type.""", False, True), ('005. Node value', 'Search by', """ from numpy import * target=eval(ARGS[0]) if (VALUE is None and target is None): RESULT=True elif (VALUE is None) : RESULT=False elif (target.dtype!=VALUE.dtype): RESULT=False elif (target.size!=VALUE.size): RESULT=False elif (target.shape!=VALUE.shape): RESULT=False elif (target.tolist()==VALUE.tolist()): RESULT=True else: RESULT=False """, """search all nodes with argument value. The compare is performed using a straightforward '==' and then relies on the Python/Numpy comparison operator.""", False, True), ('010. Node with truncated data', 'Search by', 'if (PATH in SKIPS): RESULT=PATH', """search all nodes with truncated or unread data, for example if you have set the maximum data argument for the load, or if you release the memory of a node.""", False, False), ('004. Wildcard node type', 'Search by', """ import fnmatch RESULT=fnmatch.fnmatchcase(SIDSTYPE,ARGS[0]) """, """ Search by Wildcard node type Search all nodes with wildcard argument SIDS type. Warning: the <b>argument type</b> should be quoted: 'Turb*' is ok Turb* would fail """, False, True), ('011. Non-MT UserDefinedData', 'Search by', """ if ( (SIDSTYPE==CGK.UserDefinedData_ts) and (CGU.getValueDataType(NODE)!=CGK.MT)): RESULT=True """, """ Search by Valued UserDefinedData Search all <b>UserDefinedData_t</b> nodes with a non-<b>MT</b> data type. No argument. """, False, False), # ----------------------------------------------------------------------------- ('012. FamilyName', 'Search by', """ if (SIDSTYPE in [CGK.FamilyName_ts, CGK.AdditionalFamilyName_ts]): RESULT=True """, """ Search by All <b>FamilyName_t</b> and <b>AdditionalFamilyname_t</b> nodes. """, False, False), # ----------------------------------------------------------------------------- ('013. FamilyName reference', 'Search by', """ if ((SIDSTYPE in [CGK.FamilyName_ts, CGK.AdditionalFamilyName_ts]) and (VALUE.tostring().decode('ascii')==ARGS[0])): RESULT=True """, """ Search by<br> Reference to a FamilyName<br> Search all <b>FamilyName</b> nodes with the arg string (plain).<br> The string arg should be a valid Python string such as:<br> 'BLADE(1)'<br> 'Surface ext 1A'<br> 'Left/Wing/Flap'<br> """, False, True), # ----------------------------------------------------------------------------- ('014. Zones', 'Search by', """ if (SIDSTYPE in [CGK.Zone_ts]): RESULT=True """, """ Search by All <b>Zone_t</b> nodes. """, False, False), # ----------------------------------------------------------------------------- ('015. Zones Structured', 'Search by', """ if (SIDSTYPE in [CGK.Zone_ts]): t=CGU.hasChildName(NODE,CGK.ZoneType_s) if (t is None or CGU.stringValueMatches(t,CGK.Structured_s)): RESULT=True """, """ Search by All <b>Zone_t</b> with Structured <b>ZoneType</b> nodes. """, False, False), # ----------------------------------------------------------------------------- ('016. Zones Unstructured', 'Search by', """ if (SIDSTYPE in [CGK.Zone_ts]): t=CGU.hasChildName(NODE,CGK.ZoneType_s) if (t is not None and CGU.stringValueMatches(t,CGK.Unstructured_s)): RESULT=True """, """ Search by All <b>Zone_t</b> with Unstructured <b>ZoneType</b> nodes. """, False, False), # ----------------------------------------------------------------------------- ('017. BCs', 'Search by', """ if (SIDSTYPE in [CGK.BC_ts]): RESULT=True """, """ Search by All <b>BC_t</b> nodes. """, False, False), # --- Replace # ----------------------------------------------------------------------------- ('050. Valued UserDefinedData', 'Replace', """ if ( (SIDSTYPE==CGK.UserDefinedData_ts) and (CGU.getValueDataType(NODE)!=CGK.MT)): NODE[3]=CGK.DataArray_ts RESULT=True """, """ Replace Valued UserDefinedData Search all <b>UserDefinedData_t</b> nodes with a non-<b>MT</b> data type and replace them as <b>DataArray_t</b>.""", False, False), ('051. Substitute Zone name', 'Replace', """ l1=len(ARGS[0]) if ((SIDSTYPE==CGK.Zone_ts) and (NAME[:l1]==ARGS[0])): NODE[0]=ARGS[1]+NODE[0][l1:] RESULT=True if (CGU.getValueDataType(NODE)==CGK.C1): v=VALUE.tostring().decode('ascii') if (v[:l1]==ARGS[0]): v=ARGS[1]+v[l1:] NODE[1]=CGU.setStringAsArray(v) RESULT=True """, """ <h1>Replace</h1> <h2>Substitute Zone name</h2> <p> Search all <b>Zone_t</b> nodes with a name pattern, then rename the zone with the substitution pattern. Any other reference in the tree, as a connectivity value for example, is subsitued as well. <p> Argument is a tuple with the first pattern to find and the second as the subsitution pattern. For example: <pre> ('domain.','zone#') </pre> """, True, True), # ----------------------------------------------------------------------------- ('052. FamilySpecified BC type rewrite', 'Replace', """ if ((SIDSTYPE in [CGK.FamilyName_ts, CGK.AdditionalFamilyName_ts]) and (VALUE.tostring().decode('ascii')==ARGS[0]) and (PARENT[3]==CGK.BC_ts)): PARENT[1]=CGU.setStringAsArray(CGK.FamilySpecified_s) RESULT=True """, """ <h1>Replace</h1> <h2>FamilySpecified BC type rewrite</h2> <p> Search all <b>FamilyName BC</b> nodes with the arg string (plain).<br> The string arg should be a valid Python string such as:<br> 'BLADE(1)'<br> 'Surface ext 1A'<br> 'Left/Wing/Flap'<br> <p> Once found, the parent <b>BC_t</b> value is forced to <b>FamilySpecified</b> """, True, True), # --- Find Elements_t ('020. Elements', 'Find Elements_t', """if (SIDSTYPE==CGK.Elements_ts): RESULT=True """, """Find all <b>Elements_t</b> nodes """, False, False), ('021. Elements QUAD', 'Find Elements_t', """if (SIDSTYPE==CGK.Elements_ts): RESULT=VALUE[0] in (CGK.QUAD_4, CGK.QUAD_8, CGK.QUAD_9) """, """Find all <b>Elements_t</b> nodes of type <b>QUAD</b>""", False, False), ('022. Elements TRI', 'Find Elements_t', """if (SIDSTYPE==CGK.Elements_ts): RESULT=VALUE[0] in (CGK.TRI_3, CGK.TRI_6) """, """Find all <b>Elements_t</b> nodes of type <b>TRI</b>""", False, False), ('023. Elements NGON', 'Find Elements_t', """if (SIDSTYPE==CGK.Elements_ts): RESULT=VALUE[0] in (CGK.NGON_n,) """, """Find all <b>Elements_t</b> nodes of type <b>NGON_n</b>""", False, False), ('024. Elements HEXA', 'Find Elements_t', """if (SIDSTYPE==CGK.Elements_ts): RESULT=VALUE[0] in (CGK.HEXA_8, CGK.HEXA_20, CGK.HEXA_27) """, """Find all <b>Elements_t</b> nodes of type <b>HEXA</b>""", False, False), ('025. Elements TETRA', 'Find Elements_t', """if (SIDSTYPE==CGK.Elements_ts): RESULT=VALUE[0] in (CGK.TETRA_4, CGK.TETRA_10) """, """Find all <b>Elements_t</b> nodes of type <b>TETRA</b>""", False, False), # --- External Tools ('030. Create Cartesian Zone', 'External Tools', """ if (SIDSTYPE==CGK.CGNSTree_ts): import Generator.PyTree as G z=G.cart((0.,0.,0.), (0.1,0.1,0.2), (10,11,12)) b=None base='BASE' if (len(ARGS)>0): base=ARGS[0] b=CGU.hasChildName(NODE,base) if (b is None): base=CGU.checkUniqueChildName(NODE,base) b=CGL.newCGNSBase(NODE,base,3,3) CGU.addChild(b,z) """, """Example of Cartesian zone creation using Cassiopee. The first argument is the base name, if ommitted a name is generated.""", True, True), ('031. Bounding boxes', 'External Tools', """ if (SIDSTYPE==CGK.Zone_ts): import Generator as G RESULT=G.bbox(NODE) """, """Example of Bounding box computation using Cassiopee"""), ('100. .Solver#Compute children', 'Edit filters', """ if (PARENT[0]=='.Solver#Compute'): RESULT=PATH """, """Selects all children nodes of the .Solver#Compute elsA userdefined node""", False, False), ('101. ReferenceState children', 'Edit filters', """ if (PARENT[0]=='ReferenceState'): RESULT=PATH """, """Selects all children nodes of the ReferenceState node""", False, False), ('102. .Solver#Param children', 'Edit filters', """ if (PARENT[0]=='.Solver#Param'): RESULT=PATH """, """Selects all children nodes of the .Solver#Param elsA userdefined node""", False, False), ] # ----------------------------------------------------------------- @classmethod def _setOption(cls, name, value): setattr(cls, name, value) @classmethod def _writeFile(cls, tag, name, udata, filename, prefix=""): gdate = strftime("%Y-%m-%d %H:%M:%S", gmtime()) s = u"""# %s - %s - Generated %s\n# coding: utf-8\n%s\nimport PyQt5\n%s=""" % \ (cls._ToolName, tag, gdate, prefix, name) if isinstance(udata, dict): s += u"""{\n""" for k in udata: # print 'K',k,'V',udata[k],'T',type(udata[k]) if k[0] != '_': val = '%s' % str(udata[k]) if isinstance(udata[k], str): val = u'u"""%s"""' % repr( udata[k]).lstrip("u'").lstrip("'").rstrip( "'") # Error elif isinstance(udata[k], bytes): val = u'u"""%s"""' % repr(udata[k].decode( 'utf-8')).lstrip("u'").lstrip("'").rstrip("'") if not isinstance(k, str): uk = u"u'%s'" % repr(k.decode('utf-8')).lstrip( "u'").lstrip("'").rstrip("'") else: uk = u"u'%s'" % repr(k).lstrip("u'").lstrip( "'").rstrip("'") s += """%s:%s,\n""" % (uk, val) s += u"""}\n\n# --- last line\n""" elif isinstance(udata, list): s += u"""[\n""" for k in udata: s += u"""%s,\n""" % (k) s += u"""]\n\n# --- last line\n""" cls._crpath(filename) with open(filename, 'w+') as f: f.write(s) @classmethod def _readFile(cls, name, filename): dpath = tempfile.mkdtemp() if not op.exists(filename): return None try: copyOneFile(filename, '%s/%s.py' % (dpath, name)) except IOError: removeSubDirAndFiles(dpath) return None sprev = sys.path sys.path = [dpath] + sys.path try: fp, pathname, description = imp.find_module(name) except IndexError: # ImportError: return None try: mod = imp.load_module(name, fp, pathname, description) finally: if fp: fp.close() removeSubDirAndFiles(dpath) sys.path = sprev return mod @classmethod def _crpath(cls, path): p = op.dirname(path) if op.exists(p): return True os.makedirs(p) @classmethod def _trpath(cls, path): return op.normpath(op.expanduser(op.expandvars(path))) @classmethod def _writeHistory(cls, control): filename = cls._trpath(cls._HistoryFileName) cls._writeFile('History', 'history', control._history, filename) @classmethod def _readHistory(cls, control): filename = cls._trpath(cls._HistoryFileName) m = cls._readFile('history', filename) if m is None: return None try: return m.history except: return None @classmethod def _writeOptions(cls, control): filename = cls._trpath(cls._OptionsFileName) cls._writeFile('User options', 'options', control._options, filename) @classmethod def _readOptions(cls, control): filename = cls._trpath(cls._OptionsFileName) m = cls._readFile('options', filename) if m is None: return None try: return m.options except: return None @classmethod def _writeQueries(cls, control, q): filename = cls._trpath( op.join(cls.QueriesDirectory, cls._QueriesDefaultFile)) cls._writeFile('User queries', 'queries', q, filename, cls.Q_FILE_PRE) @classmethod def _readQueries(cls, control): filename = cls._trpath( op.join(cls.QueriesDirectory, cls._QueriesDefaultFile)) m = cls._readFile('queries', filename) if m is None: return None try: return m.queries except: return None @classmethod def _writeFunctions(cls, control, f): filename = cls._trpath( op.join(cls.FunctionsDirectory, cls._FunctionsDefaultFile)) cls._writeFile('User functions', 'functions', f, filename, cls.Q_FILE_PRE) @classmethod def _readFunctions(cls, control): filename = cls._trpath( op.join(cls.FunctionsDirectory, cls._FunctionsDefaultFile)) m = cls._readFile('functions', filename) if m is None: return None try: return m.Q7UserFunction except: return None def __init__(self): pass def __getitem__(self, name): if name[0] != '_': return Q7OptionContext.__dict__[name] return None def __setitem__(self, name, value): if name[0] != '_': setattr(Q7OptionContext, name, value) return None def __iter__(self): for o in dir(self): if o[0] != '_': yield o def _nextName(self): for o in dir(self): if o[0] != '_': yield o
def get_font(font_family, point_size): font_family = font_asst.resolve_alias(font_family, font_family) font = QFont(font_family, point_size) return font
def __init__(self, parent: QWidget): super(_ScriptBrowser, self).__init__(parent) self.setLineWrapMode(QTextEdit.NoWrap) self.setFont(QFont("Consolas")) self.setReadOnly(True) self.zoomIn(3)
def get_font(font_family, point_size): font = QFont(font_family, point_size) return font
def paintEvent(self, event: QPaintEvent) -> None: """Drawing functions.""" width = self.width() height = self.height() if self.width_old is None: self.width_old = width if self.height_old is None: self.height_old = height if self.width_old != width or self.height_old != height: self.ox += (width - self.width_old) / 2 self.oy += (height - self.height_old) / 2 # 'self' is the instance of 'DynamicCanvas'. BaseCanvas.paintEvent(self, event) # Draw links except ground brush = color_qt('dark-gray') if self.monochrome else LINK_COLOR brush.setAlphaF(self.transparency) self.painter.setBrush(brush) for vlink in self.vlinks[1:]: self.__draw_link(vlink) self.painter.setBrush(Qt.NoBrush) # Draw path if self.path.show != -2: self.__draw_path() # Draw solving path if self.show_target_path: self.painter.setFont(QFont("Arial", self.font_size + 5)) self.draw_ranges() self.draw_target_path() self.painter.setFont(QFont("Arial", self.font_size)) # Draw points for i, vpoint in enumerate(self.vpoints): self.__draw_point(i, vpoint) # Draw solutions if self.select_mode == SelectMode.SOLUTION: for i, expr in enumerate(self.exprs): func = expr[0] params = expr[1:-1] target = expr[-1] self.draw_solution(func, params, target, self.vpoints) if i in self.selections: pos, _ = self.solution_polygon(func, params, target, self.vpoints) pen = QPen() pen.setWidth(self.link_width + 3) pen.setColor(QColor(161, 16, 239)) self.painter.setPen(pen) self.painter.drawPolygon( QPolygonF([QPointF(x, y) for x, y in pos])) # Draw a colored frame for free move mode if self.free_move != FreeMode.NO_FREE_MOVE: pen = QPen() if self.free_move == FreeMode.TRANSLATE: pen.setColor(QColor(161, 16, 229)) elif self.free_move == FreeMode.ROTATE: pen.setColor(QColor(219, 162, 6)) elif self.free_move == FreeMode.REFLECT: pen.setColor(QColor(79, 249, 193)) pen.setWidth(8) self.painter.setPen(pen) self.__draw_frame() # Rectangular selection if self.selector.picking: pen = QPen(Qt.gray) pen.setWidth(1) self.painter.setPen(pen) self.painter.drawRect(self.selector.to_rect(self.zoom)) # Show FPS self.fps_updated.emit() self.painter.end() # Record the widget size self.width_old = width self.height_old = height
def __init__(self, parent=None): QDialog.__init__(self, parent=parent) self._shortcuts_summary_title = SHORTCUTS_SUMMARY_TITLE # Calculate font and amount of elements in each column # according screen size width, height = self.get_screen_resolution() font_size = int(round(height / 80)) font_size = max(min(font_size, MAX_FONT_SIZE), MIN_FONT_SIZE) shortcuts_column = (height - 8 * font_size) / (font_size + 16) # Widgets style = """ QDialog { margin:0px; padding:0px; border-radius: 2px; }""" self.setStyleSheet(style) font_names = QFont() font_names.setPointSize(font_size) font_names.setBold(True) font_keystr = QFont() font_keystr.setPointSize(font_size) font_title = QFont() font_title.setPointSize(font_size + 2) font_title.setBold(True) title_label = QLabel(self._shortcuts_summary_title) title_label.setAlignment(Qt.AlignCenter) title_label.setFont(font_title) # iter over shortcuts and create GroupBox for each context # with shortcuts in a grid columns_layout = QHBoxLayout() added_shortcuts = 0 group = None # group shortcuts by context shortcuts = groupby(sorted(CONF.iter_shortcuts()), key=itemgetter(0)) for __, group_shortcuts in shortcuts: for i, (context, name, keystr) in enumerate(group_shortcuts): # start of every column if added_shortcuts == 0: column_layout = QVBoxLayout() # at start of new context add previous context group if i == 0 and added_shortcuts > 0: column_layout.addWidget(group) # create group at start of column or context if added_shortcuts == 0 or i == 0: if context == '_': context = 'Global' group = QGroupBox(context.capitalize()) group.setFont(font_names) group_layout = QGridLayout() group.setLayout(group_layout) # Count space for titles added_shortcuts += 1 # Widgets label_name = QLabel(name.capitalize().replace('_', ' ')) label_name.setFont(font_names) keystr = QKeySequence(keystr).toString(QKeySequence.NativeText) label_keystr = QLabel(keystr) label_keystr.setFont(font_keystr) group_layout.addWidget(label_name, i, 0) group_layout.addWidget(label_keystr, i, 1) added_shortcuts += 1 if added_shortcuts >= shortcuts_column: column_layout.addWidget(group) columns_layout.addLayout(column_layout) added_shortcuts = 0 column_layout.addWidget(group) column_layout.addStretch() # avoid lasts sections to appear too big columns_layout.addLayout(column_layout) # Scroll widget self.scroll_widget = QWidget() self.scroll_widget.setLayout(columns_layout) self.scroll_area = QScrollArea() self.scroll_area.setWidget(self.scroll_widget) # widget setup self.setWindowFlags(Qt.FramelessWindowHint) self.setWindowOpacity(0.95) # layout self._layout = QVBoxLayout() self._layout.addWidget(title_label) self._layout.addWidget(self.scroll_area) self.setLayout(self._layout) self.setGeometry(0, 0, width, height)
def font(self): return QFont(self.rules['font']['family'], self.rules['font']['size'])
def drawContents(self, painter): """ @type painter: QPainter """ w = self.width() h = self.height() margin = 10 background = QColor(210, 211, 215) text_color = QColor(0, 0, 0) foreground = QColor(255, 255, 255) painter.setBrush(background) painter.fillRect(0, 0, w, h, background) pen = QPen() pen.setWidth(2) pen.setColor(foreground) painter.setPen(pen) painter.drawRect(0, 0, w - 1, h - 1) image_width = self.splash_image.width() image_height = self.splash_image.height() aspect = 1.0 if image_height: aspect = float(image_width) / float(image_height) scaled_height = h - 2 * margin scaled_width = round(scaled_height * aspect) painter.drawRect(margin, margin, scaled_width, scaled_height) painter.drawPixmap(margin, margin, scaled_width, scaled_height, self.splash_image) text_x = scaled_width + 2 * margin top_offset = margin text_area_width = w - scaled_width - 2 * margin painter.setPen(text_color) text_size = 150 font = QFont("Serif") font.setStyleHint(QFont.Serif) font.setPixelSize(text_size) painter.setFont(font) painter.drawText(text_x, margin + top_offset, text_area_width, text_size, int(Qt.AlignHCenter | Qt.AlignCenter), self.ert) top_offset += text_size + 2 * margin text_size = 25 font.setPixelSize(text_size) painter.setFont(font) painter.drawText(text_x, top_offset, text_area_width, text_size, int(Qt.AlignHCenter | Qt.AlignCenter), self.ert_title) top_offset += text_size + 4 * margin text_size = 20 font.setPixelSize(text_size) painter.setFont(font) painter.drawText(text_x, top_offset, text_area_width, text_size, int(Qt.AlignHCenter | Qt.AlignCenter), self.version)
def test_update_decorations_when_scrolling(qtbot): """ Test how many calls we're doing to update decorations when scrolling. """ # NOTE: Here we need to use `patch` from unittest.mock, instead of the # mocker fixture, to have the same results when running the test # alone and with the other tests in this file. patched_object = ('spyder.plugins.editor.utils.decoration.' 'TextDecorationsManager._update') with patch(patched_object) as _update: # NOTE: We can't use a fixture to build a CodeEditor instance here # because the testing results are not consistent. editor = CodeEditor(parent=None) editor.setup_editor( language='Python', color_scheme='spyder/dark', font=QFont("Monospace", 10), ) editor.resize(640, 480) editor.show() qtbot.addWidget(editor) # If there's no waiting after CodeEditor is created, there shouldn't # be a call to _update. assert _update.call_count == 0 with open(osp.join(PARENT, 'codeeditor.py'), 'r') as f: text = f.read() editor.set_text(text) # If there's no waiting after setting text, there shouldn't be a # call to _update either. assert _update.call_count == 0 # Simulate scrolling scrollbar = editor.verticalScrollBar() for i in range(6): scrollbar.setValue(i * 70) qtbot.wait(100) # A new call is done here due to __cursor_position_changed being # called, which in turn calls highlight_current_cell and # highlight_current_line assert _update.call_count == 1 # Wait for decorations to update qtbot.wait(editor.UPDATE_DECORATIONS_TIMEOUT + 100) # Assert a new call to _update was done assert _update.call_count == 2 # Simulate grabbing and moving the scrollbar with the mouse scrollbar = editor.verticalScrollBar() value = scrollbar.value() for __ in range(400): scrollbar.setValue(value + 1) value = scrollbar.value() # No calls should be done after this. assert _update.call_count == 2 # Wait for decorations to update qtbot.wait(editor.UPDATE_DECORATIONS_TIMEOUT + 100) # Assert a new call to _update was done assert _update.call_count == 3 # Move to the last visible line _, last = editor.get_visible_block_numbers() editor.go_to_line(last) # Simulate continuously pressing the down arrow key. for __ in range(200): qtbot.keyPress(editor, Qt.Key_Down) # Only one call to _update should be done, after releasing the key. qtbot.wait(editor.UPDATE_DECORATIONS_TIMEOUT + 100) assert _update.call_count == 4 # Simulate continuously pressing the up arrow key. for __ in range(200): qtbot.keyPress(editor, Qt.Key_Up) # Only one call to _update should be done, after releasing the key. qtbot.wait(editor.UPDATE_DECORATIONS_TIMEOUT + 100) assert _update.call_count == 5
def scan_devices_update_list_view(self): """ Scan for new devices; and update the list view :return: """ # self.devices_view.clear() device_exists_in_view = False paired_devices = [] for index in range(self.devices_view.count()): paired_devices.append(self.devices_view.item(index)) __devices = self.adb.devices_detailed() log(__devices) for i in __devices: device_is_wifi = i["identifier"].count(".") >= 3 and ( ":" in i["identifier"]) if i["identifier"] not in self.config["device"].keys(): device_paired_and_exists = False self.config["device"][i["identifier"]] = {"rotation": 0} else: device_paired_and_exists = True if device_is_wifi: _icon_suffix = "_wifi" else: _icon_suffix = "_usb" icon = ":/icons/icons/portrait_mobile_white{}.svg".format( _icon_suffix) if i["status"] == "offline": icon = ":/icons/icons/portrait_mobile_error.svg" elif i["status"] == "unauthorized": icon = ":/icons/icons/portrait_mobile_warning.svg" if i["status"] == "no_permission": log("pairfilter: 5") # https://stackoverflow.com/questions/ # 53887322/adb-devices-no-permissions-user-in- # plugdev-group-are-your-udev-rules-wrong udev_error = ( "Error connecting to device. Your udev rules are" " incorrect. See https://stackoverflow.com/questions" "/53887322/adb-devices-no-permissions-user-in-plugdev-" "group-are-your-udev-rules-wrong") self.display_public_message(udev_error) print(udev_error) return [] # Check if device is unauthorized elif i["status"] == "unauthorized": log("unauthorized device detected: Click Allow on your device") log("pairfilter: 4") # The device is connected; and might/might't paired in the past # And is connected to the same IP address # It is possibly a bug with the connection; # Temporarily create a new QListItem to display the # device with the error paired = False device_paired_and_exists = False self.display_public_message( f"{i['identifier']} is unauthorized. Please click allow " f"on your device.") # Remove other devices with the same id and offline and # unauthorized self.remove_device_device_view( i["identifier"], statuses=["offline", "unauthorized"]) # Unauthorized device cannot be considered as a paired device devices_view_list_item = QListWidgetItem() else: # check if device is paired # if yes, just update the list item if not device_paired_and_exists: paired = False devices_view_list_item = QListWidgetItem() else: for paired_device in paired_devices: if paired_device.text().split()[0] == i["model"]: log("pairfilter: 1") paired = True devices_view_list_item = paired_device # as we have found a paired device # we know by assumption; there cannot be two # devices with the same local IP address; # lets scan the devices_view once more in a loop # to check for any device with the same # identifier and remove them; based on this same # assumption self.remove_device_device_view( i["identifier"], statuses=["offline", "unauthorized"]) break elif paired_device.text().split( )[1] == i["identifier"]: log("pairfilter: 2") self.remove_device_device_view( i["identifier"], statuses=["offline", "unauthorized"]) devices_view_list_item = QListWidgetItem() paired = False break else: log("pairfilter: 3") paired = False devices_view_list_item = QListWidgetItem() devices_view_list_item.setIcon(QIcon(icon)) devices_view_list_item.setText("{device}\n{mode}\n{status}".format( device=i["model"], mode=i["identifier"], status=i["status"])) __sha_shift = self.config.get("sha_shift", 5) __sha = hashlib.sha256(str(i["identifier"]).encode()).hexdigest( )[__sha_shift:__sha_shift + 6] devices_view_list_item.setToolTip( "Device: " "<span style='color: #{inv_color};background-color: #{color}'>" "<b>{d}</b></span>\n" "<br>" "Model: {m}\n<br>" "Alias: {a}\n<br>" "Status: {s}\n<br>" "Transport ID: {t}\n<br>" "Paired: {p}".format( d=i["identifier"], m=i["model"], a=i["product"], s=i["status"], t=i["transport_id"], p=paired, color=__sha, inv_color=str(hex(0xFFFFFF - int(__sha, 16))[2:]), )) devices_view_list_item.setFont(QFont("Noto Sans", 8)) log(f"Pairing status: {device_paired_and_exists}") if device_paired_and_exists and device_is_wifi: # we need to only neglect wifi devices # paired usb device need to still show in the display continue elif device_exists_in_view: # devices exists in the list with the same status and # we should not add the new detected list item continue # If and only if the device doesn't exist; add it self.devices_view.addItem(devices_view_list_item) return __devices
class HistoryWidget(PluginMainWidget): """ History plugin main widget. """ DEFAULT_OPTIONS = { 'color_scheme_name': 'spyder/dark', 'font': QFont(), 'go_to_eof': True, 'line_numbers': True, 'max_entries': 100, 'wrap': True, } # Signals sig_focus_changed = Signal() """ This signal is emitted when the focus of the code editor storing history changes. """ def __init__(self, name, plugin, parent, options=DEFAULT_OPTIONS): super().__init__(name, plugin, parent, options) # Attributes self.editors = [] self.filenames = [] self.tabwidget = None self.dockviewer = None self.wrap_action = None self.linenumbers_action = None self.editors = [] self.filenames = [] # Widgets self.tabwidget = Tabs(self) self.find_widget = FindReplace(self) # Setup self.find_widget.hide() # Layout layout = QVBoxLayout() # TODO: Move this to the tab container directly if sys.platform == 'darwin': tab_container = QWidget(self) tab_container.setObjectName('tab-container') tab_layout = QVBoxLayout(tab_container) tab_layout.setContentsMargins(0, 0, 0, 0) tab_layout.addWidget(self.tabwidget) layout.addWidget(tab_container) else: layout.addWidget(self.tabwidget) layout.addWidget(self.find_widget) self.setLayout(layout) # Signals self.tabwidget.currentChanged.connect(self.refresh) self.tabwidget.move_data.connect(self.move_tab) # --- PluginMainWidget API # ------------------------------------------------------------------------ def get_title(self): return _('History') def get_focus_widget(self): return self.tabwidget.currentWidget() def setup(self, options): # Actions self.history_action = self.create_action( HistoryWidgetActions.MaximumHistoryEntries, text=_("History..."), tip=_("Set history maximum entries"), icon=self.create_icon('history'), triggered=self.change_history_depth, ) self.wrap_action = self.create_action( HistoryWidgetActions.ToggleWrap, text=_("Wrap lines"), toggled=lambda value: self.set_option('wrap', value), initial=self.get_option('wrap'), ) self.linenumbers_action = self.create_action( HistoryWidgetActions.ToggleLineNumbers, text=_("Show line numbers"), toggled=lambda value: self.set_option('line_numbers', value), initial=self.get_option('line_numbers'), ) # Menu menu = self.get_options_menu() for item in [ self.history_action, self.wrap_action, self.linenumbers_action ]: self.add_item_to_menu( item, menu=menu, section=HistoryWidgetOptionsMenuSections.Main, ) def update_actions(self): pass def on_option_update(self, option, value): if self.tabwidget is not None: if option == 'wrap': for editor in self.editors: editor.toggle_wrap_mode(value) elif option == 'line_numbers': for editor in self.editors: editor.toggle_line_numbers( linenumbers=value, markers=False, ) elif option == 'color_scheme_name': for editor in self.editors: editor.set_font(self.get_option('font'), value) # --- Public API # ------------------------------------------------------------------------ def update_font(self, font, color_scheme): """ Update font of the code editor. Parameters ---------- font: QFont Font object. color_scheme: str Name of the color scheme to use. """ self.font = font self.color_scheme = color_scheme for editor in self.editors: editor.set_font(font, color_scheme) def move_tab(self, index_from, index_to): """ Move tab. Parameters ---------- index_from: int Move tab from this index. index_to: int Move tab to this index. Notes ----- Tabs themselves have already been moved by the history.tabwidget. """ filename = self.filenames.pop(index_from) editor = self.editors.pop(index_from) self.filenames.insert(index_to, filename) self.editors.insert(index_to, editor) def get_filename_text(self, filename): """ Read and return content from filename. Parameters ---------- filename: str The file path to read. Returns ------- str Content of the filename. """ # Avoid a possible error when reading the history file try: text, _ = encoding.read(filename) except (IOError, OSError): text = "# Previous history could not be read from disk, sorry\n\n" text = normalize_eols(text) linebreaks = [m.start() for m in re.finditer('\n', text)] maxNline = self.get_option('max_entries') if len(linebreaks) > maxNline: text = text[linebreaks[-maxNline - 1] + 1:] # Avoid an error when trying to write the trimmed text to disk. # See spyder-ide/spyder#9093. try: encoding.write(text, filename) except (IOError, OSError): pass return text def add_history(self, filename): """ Create a history tab for `filename`. Parameters ---------- filename: str History filename. """ filename = encoding.to_unicode_from_fs(filename) if filename in self.filenames: return # Widgets editor = codeeditor.CodeEditor(self) # Setup language = 'py' if osp.splitext(filename)[1] == '.py' else 'bat' editor.setup_editor( linenumbers=self.get_option('line_numbers'), language=language, scrollflagarea=False, debug_panel=False, ) editor.setReadOnly(True) editor.toggle_wrap_mode(self.get_option('wrap')) editor.set_text(self.get_filename_text(filename)) editor.set_cursor_position('eof') editor.set_font( self.get_option('font'), self.get_option('color_scheme_name'), ) self.find_widget.set_editor(editor) index = self.tabwidget.addTab(editor, osp.basename(filename)) self.filenames.append(filename) self.editors.append(editor) self.tabwidget.setCurrentIndex(index) self.tabwidget.setTabToolTip(index, filename) # Signals editor.focus_changed.connect(lambda: self.sig_focus_changed.emit()) @Slot(str, str) def append_to_history(self, filename, command): """ Append command to history tab. Parameters ---------- filename: str History file. command: str Command to append to histroy file. """ if not is_text_string(filename): # filename is a QString filename = to_text_string(filename.toUtf8(), 'utf-8') index = self.filenames.index(filename) command = to_text_string(command) self.editors[index].append(command) if self.get_option('go_to_eof'): self.editors[index].set_cursor_position('eof') self.tabwidget.setCurrentIndex(index) @Slot() @Slot(int) def change_history_depth(self, depth=None): """ Change history max entries. Parameters ---------- depth: int, optional Number of entries to use for the history. If None, an input dialog will be used. Default is None. """ valid = True if depth is None: depth, valid = QInputDialog.getInt( self, _('History'), _('Maximum entries'), self.get_option('max_entries'), 10, 10000, ) if valid: self.set_option('max_entries', depth) def refresh(self): """Refresh widget and update find widget on current editor.""" if self.tabwidget.count(): editor = self.tabwidget.currentWidget() else: editor = None self.find_widget.set_editor(editor)
__email__ = "*****@*****.**" from typing import Mapping, Tuple, Optional from qtpy.QtCore import Qt, QSize, QPointF from qtpy.QtGui import QImage, QPainter, QBrush, QPen, QIcon, QPixmap, QFont from pyslvs import edges_view from pyslvs.graph import Graph, external_loop_layout from pyslvs_ui.info import logger from .color import color_qt, color_num from .canvas import convex_hull, LINK_COLOR _Pos = Mapping[int, Tuple[float, float]] engines = ("External Loop", ) _font = QFont("Monospace") _font.setBold(True) _font.setStyleHint(QFont.TypeWriter) def engine_picker(g: Graph, engine: str, node_mode: bool) -> _Pos: """Generate a position dict.""" if engine == "External Loop": try: layout: _Pos = external_loop_layout(g, node_mode, scale=30) except ValueError as error: logger.warn(error) return {} else: raise ValueError(f"engine {engine} is not exist")
def setup_ui(self, enabled=True): self.v_lay = QVBoxLayout(self) self.v_lay.setContentsMargins(-1, 6, -1, 6) self.v_lay.setSpacing(0) self.row1 = QHBoxLayout() self.row1.setSpacing(6) self.enabled_checkbox = QCheckBox(self) self.enabled_checkbox.setChecked(enabled) self.enabled_checkbox.stateChanged.connect(self._on_enabled_checkbox) self.enabled_checkbox.setToolTip(trans._("enable/disable")) sizePolicy = QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth( self.enabled_checkbox.sizePolicy().hasHeightForWidth()) self.enabled_checkbox.setSizePolicy(sizePolicy) self.enabled_checkbox.setMinimumSize(QSize(20, 0)) self.enabled_checkbox.setText("") self.row1.addWidget(self.enabled_checkbox) self.plugin_name = QLabel(self) sizePolicy = QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Minimum) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth( self.plugin_name.sizePolicy().hasHeightForWidth()) self.plugin_name.setSizePolicy(sizePolicy) font15 = QFont() font15.setPointSize(15) self.plugin_name.setFont(font15) self.row1.addWidget(self.plugin_name) icon = QColoredSVGIcon.from_resources("warning") self.warning_tooltip = QtToolTipLabel(self) # TODO: This color should come from the theme but the theme needs # to provide the right color. Default warning should be orange, not # red. Code example: # theme_name = get_settings().appearance.theme # napari.utils.theme.get_theme(theme_name, as_dict=False).warning.as_hex() self.warning_tooltip.setPixmap( icon.colored(color="#E3B617").pixmap(15, 15)) self.warning_tooltip.setVisible(False) self.row1.addWidget(self.warning_tooltip) self.item_status = QLabel(self) self.item_status.setObjectName("small_italic_text") self.item_status.setSizePolicy(sizePolicy) self.row1.addWidget(self.item_status) self.row1.addStretch() self.package_name = QLabel(self) self.package_name.setAlignment(Qt.AlignRight | Qt.AlignTrailing | Qt.AlignVCenter) self.row1.addWidget(self.package_name) self.cancel_btn = QPushButton("cancel", self) self.cancel_btn.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) self.cancel_btn.setObjectName("remove_button") self.row1.addWidget(self.cancel_btn) self.update_btn = QPushButton(self) self.update_btn.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) self.update_btn.setObjectName("install_button") self.row1.addWidget(self.update_btn) self.update_btn.setVisible(False) self.help_button = QPushButton(self) self.action_button = QPushButton(self) sizePolicy = QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth( self.action_button.sizePolicy().hasHeightForWidth()) self.help_button.setSizePolicy(sizePolicy) self.action_button.setSizePolicy(sizePolicy) self.row1.addWidget(self.help_button) self.row1.addWidget(self.action_button) self.v_lay.addLayout(self.row1) self.row2 = QHBoxLayout() self.error_indicator = QPushButton() self.error_indicator.setObjectName("warning_icon") self.error_indicator.setCursor(Qt.PointingHandCursor) self.error_indicator.hide() self.row2.addWidget(self.error_indicator) self.row2.setContentsMargins(-1, 4, 0, -1) self.summary = QElidingLabel(parent=self) sizePolicy = QSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.Preferred) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth( self.summary.sizePolicy().hasHeightForWidth()) self.summary.setSizePolicy(sizePolicy) self.summary.setObjectName("small_text") self.row2.addWidget(self.summary) self.package_author = QLabel(self) sizePolicy = QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth( self.package_author.sizePolicy().hasHeightForWidth()) self.package_author.setSizePolicy(sizePolicy) self.package_author.setObjectName("small_text") self.row2.addWidget(self.package_author) self.v_lay.addLayout(self.row2)
def _get_font(family, size, bold=False, italic=False): weight = QFont.Bold if bold else QFont.Normal font = QFont(family, size, weight) if italic: font.setItalic(True) return to_qvariant(font)
def set_visible(self, is_visible: bool) -> None: font = QFont() font.setBold(is_visible) font.setItalic(not is_visible) self.setFont(0, font)