예제 #1
0
    def send(self):

        self.tcpSocket.abort()

        # on some linux distros QHostAddress.LocalHost does not work

        # self.tcpSocket.connectToHost(QHostAddress.LocalHost,47405)

        self.tcpSocket.connectToHost(QHostAddress("127.0.0.1"), 47405)

        if self.tcpSocket.waitForConnected(3000):

            self.tcpSocket.writeData(self.fileName)

        else:

            dbgMsg("Connection timed out")

        # wait here for tcp server to read fileName

        if self.tcpSocket.waitForDisconnected(3000):

            pass

        else:

            dbgMsg("server busy - did not respond within 3 secs")
예제 #2
0
    def __init__(self, parent=None):

        super(CycleTabsPopup, self).__init__(parent)

        self.editorWindow = parent

        self.setText("THIS IS CYCLE WINDOWS TAB")

        # self.__text = unicode(text)

        self.setWindowFlags(Qt.Popup | Qt.FramelessWindowHint)

        # palette = QPalette()

        palette = self.palette()

        palette.setColor(self.backgroundRole(), QColor('#F5F6CE'))

        self.setPalette(palette)

        font = self.font()

        font.setPointSize(9)

        # on mac base size font has to be gibber than on linux or windows - otherwise letters are too small

        if sys.platform.startswith('darwin'):
            font.setPointSize(11)

        self.setFont(font)

        # self.setBackgroundRole(QtPalette.Light)

        # self.setWindowFlags(Qt.FramelessWindowHint)

        self.setTextFormat(Qt.RichText)

        # self.setupUi(self)

        self.ctrlTabShortcut = QShortcut(QKeySequence("Ctrl+Tab"), self)

        self.CtrlKeyEquivalent = Qt.Key_Control

        if sys.platform.startswith("darwin"):
            self.ctrlTabShortcut = QShortcut(QKeySequence("Alt+Tab"), self)

            self.CtrlKeyEquivalent = Qt.Key_Alt

        self.ctrlTabShortcut.activated.connect(self.cycleTabs)

        self.highlightedItem = ''

        self.openFileNames = None

        self.cycleTabFilesList = None

        dbgMsg("self.editorWindow.pos()=",
               str(self.editorWindow.pos()) + "\n\n\n\n")
예제 #3
0
    def acceptConnection(self):
        dbgMsg("ACCEPTING NEW CONNECTION")

        self.clientSocket = self.tcpServer.nextPendingConnection(
        )  # this is connecting tcp socket from the client

        self.clientSocket.disconnected.connect(self.clientSocket.deleteLater)

        self.clientSocket.readyRead.connect(self.readFileName)
예제 #4
0
    def doneRecording(self):

        dbgMsg(" Done recording")

        self.releaseKeyboard()

        self.recording = False

        self.grabButton.setEnabled(True)
예제 #5
0
    def installAutocompletionAPIs(self):

        # first determine where APIs are located

        # initial guess is in the "APIs" subrirestory of the directory which holds Configuration.py

        # tweditRootPath = os.path.dirname(Configuration.__file__)
        osp_dir = os.path.dirname
        tweditRootPath = osp_dir(osp_dir(twedit.__file__))
        apisPath = os.path.join(tweditRootPath, "APIs")

        # check if it exists

        if not os.path.exists(apisPath):
            # when packaging on Windows with pyinstaller the path to executable is accesible via
            # sys.executable as Python is bundled with the distribution

            # os.path.dirname(Configuration.__file__) returned by pyInstaller will not work without some
            # modifications so it is best tu use os.path.dirname(sys.executable) approach

            tweditRootPath = os.path.dirname(sys.executable)

            apisPath = os.path.join(tweditRootPath, "APIs")

        dbgMsg("apisPath=", os.path.abspath(apisPath))

        self.loadSingleAPI(
            "QsciLexerCPP",
            os.path.abspath(os.path.join(apisPath, "cplusplus.api")))

        self.loadSingleAPI(
            "QsciLexerCSharp",
            os.path.abspath(os.path.join(apisPath, "csharp.api")))

        self.loadSingleAPI("QsciLexerCSS",
                           os.path.abspath(os.path.join(apisPath, "css.api")))

        self.loadSingleAPI("QsciLexerHTML",
                           os.path.abspath(os.path.join(apisPath, "html.api")))

        self.loadSingleAPI("QsciLexerJava",
                           os.path.abspath(os.path.join(apisPath, "java.api")))

        self.loadSingleAPI(
            "QsciLexerJavaScript",
            os.path.abspath(os.path.join(apisPath, "javascript.api")))

        self.loadSingleAPI("QsciLexerPearl",
                           os.path.abspath(os.path.join(apisPath, "perl.api")))

        self.loadSingleAPI(
            "QsciLexerPython",
            os.path.abspath(os.path.join(apisPath, "python.api")))

        self.loadSingleAPI("QsciLexerRuby",
                           os.path.abspath(os.path.join(apisPath, "ruby.api")))
예제 #6
0
    def readFileName(self):
        # fileName=self.clientSocket.readData(bytesInSocket)

        fileName = self.clientSocket.read(self.clientSocket.bytesAvailable())

        dbgMsg("THIS IS FILENAME READ FROM CLIENT=", fileName)

        self.clientSocket.disconnectFromHost()

        self.newlyReadFileName.emit(fileName)
예제 #7
0
    def cancelRecording(self):

        dbgMsg("Recording Cancelled")

        self.doneRecording()

        self.keySequence = QKeySequence()

        self.sequence = None

        self.recording = False
예제 #8
0
    def keyPressEvent(self, event):

        if event.key() == self.CtrlKeyEquivalent:
            dbgMsg("CTRL key pressed")

            self.ctrlPressed = True

            # if event.modifiers()==Qt.CtrlModifier:

            # dbgMsg("CTRL key pressed")

            self.ctrlPressed = True
예제 #9
0
    def reassignNewShortcuts(self):

        for changeIdx in range(0, len(self.changesInActionShortcutList), 2):
            dbgMsg("actionText=", self.changesInActionShortcutList[changeIdx])

            dbgMsg(
                "sequence=",
                str(self.changesInActionShortcutList[changeIdx +
                                                     1].toString()))

            am.setActionKeyboardShortcut(
                self.changesInActionShortcutList[changeIdx],
                self.changesInActionShortcutList[changeIdx + 1])
예제 #10
0
    def setSetting(self, _key, _value):

        # Boolean values
        if _key in [
                "UseTabSpaces", "DisplayLineNumbers", "FoldText",
                "TabGuidelines", "DisplayWhitespace", "DisplayEOL",
                "WrapLines", "ShowWrapSymbol", "DontShowWrapLinesWarning",
                "RestoreTabsOnStartup", "EnableAutocompletion",
                "EnableQuickTextDecoding", "FRInSelection",
                "FRInAllSubfolders", "FRTransparencyEnable", "FROnLosingFocus",
                "FRAlways"
        ]:

            self.settings.setValue(_key, QVariant(_value))

        # integer values
        elif _key in [
                "TabSpaces", "ZoomRange", "ZoomRangeFindDisplayWidget",
                "AutocompletionThreshold", "FRSyntaxIndex", "FROpacity",
                "CurrentTabIndex", "CurrentPanelIndex"
        ]:

            self.settings.setValue(_key, _value)

        # string values
        elif _key in ["BaseFontName", "BaseFontSize", "Theme"]:

            self.settings.setValue(_key, QVariant(_value))

        # QSize, QPoint,QStringList , QString values
        elif _key in [
                "RecentDocuments", "RecentDirectories", "InitialSize",
                "InitialPosition", "ListOfOpenFiles",
                "ListOfOpenFilesAndPanels", "FRSyntax", "FRFindHistory",
                "FRReplaceHistory", "FRFiltersHistory", "FRDirectoryHistory",
                "KeyboardShortcuts", "PluginAutoloadData"
        ]:

            self.settings.setValue(_key, QVariant(_value))

        # QByteArray
        elif _key in ["PanelSplitterState"]:

            self.settings.setValue(_key, QVariant(_value))

        else:

            dbgMsg("Wrong format of configuration option:", _key, ":", _value)
예제 #11
0
    def keyReleaseEvent(self, event):

        if event.key() == self.CtrlKeyEquivalent:
            dbgMsg("CTRL RELEASED in QTextEdit")

            self.ctrlPressed = False

            self.close()

            # make lastly selected tab current

            self.cycleTabFilesList.makeItemCurrent(self.highlightedItem)

            self.openFileNames = None

            self.cycleTabFilesList = None
예제 #12
0
    def startRecording(self):

        dbgMsg("start recording")

        self.grabKeyboard()

        self.keyLabel.setText('')

        self.nonShiftModifierPreseed = False

        self.grabButton.setEnabled(False)

        self.keySequence = QKeySequence()

        self.sequence = None

        self.recording = True
예제 #13
0
    def cycleTabs(self):

        dbgMsg("QLabel cycleTabs")

        # highlightedItem is a list - [fileName,editor]

        highlightTextFlag = False

        if self.highlightedItem == self.openFileNames[
                -1]:  # we start highlighting cycle from the begining

            highlightTextFlag = True

        highlightingChanged = False

        if self.openFileNames:

            labelContent = ''

            for fileName in self.openFileNames:

                if highlightTextFlag:

                    dbgMsg("GOT HIGHLIGHT TEXT FLAG")

                    labelContent += "<b>" + fileName[0] + "</b><br>"

                    highlightTextFlag = False

                    self.highlightedItem = fileName

                    highlightingChanged = True

                    # dbgMsg("label content=",labelContent)

                else:

                    labelContent += fileName[0] + "<br>"

                    # if firstName=='':

                if self.highlightedItem[0] == fileName[
                        0] and not highlightingChanged:
                    highlightTextFlag = True

            self.setText(labelContent)
예제 #14
0
    def incomingConnection(self, socketId):

        dbgMsg("GOT INCOMMING CONNECTION self.socket=", self.socket)

        sendEditorOpenFlag = False

        if not self.socket:
            sendEditorOpenFlag = True

        self.socket = Socket(self)

        self.socket.setSocketDescriptor(socketId)

        # once we get connection we disable start CC3D action on the tool bar to prevent additional copies of CC3D being open

        if self.pluginObj:
            self.pluginObj.enableStartCC3DAction(False)

        dbgMsg("\n\n\n\n\n socket ID = ", socketId)
예제 #15
0
    def updateShortcutDisplay(self):

        # s=self.keySequence.toString(QKeySequence.NativeText)

        s = ''

        dbgMsg("key=", self.key)
        dbgMsg("shiftPeessed=%x" % (Qt.SHIFT & self.key))
        dbgMsg("Qt.SHIFT = %x" % (Qt.SHIFT & ~Qt.SHIFT))
        dbgMsg("Qt.SHIFT = %x" % ~(Qt.SHIFT + 1))

        if self.modifiers:
            dbgMsg("GOT MODIFIERS")
            if self.modifiers & (Qt.CTRL):
                s += "Ctrl+"

            if self.modifiers & (Qt.SHIFT):
                s += "Shift+"

            if self.modifiers & (Qt.ALT):
                s += "Alt+"

            if self.modifiers & (Qt.META):
                s += "Meta+"

            # pressing non modifier key ends recording

            if self.key != Qt.Key_Shift and self.key != Qt.Key_Control and \
                    self.key != Qt.Key_Alt and self.key != Qt.Key_Meta:
                # dbgMsg("REGULAR KEY=", QChar(self.key).toAscii())

                self.doneRecording()

        if not self.sequence:
            self.keyLabel.setText(s)

        else:

            self.keyLabel.setText(
                self.sequence.toString(QKeySequence.NativeText))
예제 #16
0
    def shortcutCellClicked(self, _row, _column):

        if _column == 1:

            # display grab shortcut widget

            shortcut_item = self.shortcutTable.item(_row, 1)
            action_item = self.shortcutTable.item(_row, 0)
            shortcut_text = shortcut_item.text()
            action_text = action_item.text()

            key_shortcut_dlg = KeyShortcutDlg(self, str(action_text),
                                              str(shortcut_text))
            ret = key_shortcut_dlg.exec_()

            if ret:
                new_key_sequence = key_shortcut_dlg.getKeySequence()

                dbgMsg("THIS IS NEW SHORTCUT:",
                       str(new_key_sequence.toString()))

                self.assignNewShortcut(new_key_sequence, action_item,
                                       shortcut_item)
예제 #17
0
    def keyPressEvent(self, e):

        dbgMsg("keyPressEvent")

        if e.key() == -1:
            self.cancelRecording()

        e.accept()

        newModifiers = e.modifiers() & (Qt.SHIFT | Qt.CTRL | Qt.ALT | Qt.META)

        dbgMsg("newModifiers=", newModifiers)

        # if newModifiers and not self.recording and not self.grabKey.isEnabled():

        # self.startRecording()

        dbgMsg("self.recording=", self.recording)

        if not self.recording:
            return

            # check if non-SHIFT modifier has been presed - this affects whether we can use shift in the shortcut or not

        # e.g. SHIFT with a letter is not a valid shortcut but if there
        # is additional modifier pressed than is it valid e.g. Ctrl+Shift+F

        if newModifiers & (Qt.CTRL | Qt.ALT | Qt.META):
            self.nonShiftModifierPreseed = True

        self.key = e.key()

        self.modifiers = int(newModifiers)

        if self.key == Qt.Key_AltGr:  # or else we get unicode salad

            return

        elif self.key == Qt.Key_Shift:

            self.updateShortcutDisplay()

        elif self.key == Qt.Key_Control:

            self.updateShortcutDisplay()

        elif self.key == Qt.Key_Alt:

            self.updateShortcutDisplay()

        elif self.key == Qt.Key_Meta:

            self.updateShortcutDisplay()

        else:

            if self.modifiers & (Qt.SHIFT | Qt.CTRL | Qt.ALT | Qt.META
                                 ):  # check if any of the modifiers is chc

                if self.isShiftAsModifierAllowed(self.key):

                    self.key |= (self.modifiers)

                else:  # filter out shift

                    self.key |= (self.modifiers & ~Qt.SHIFT)

                self.sequence = QKeySequence(self.key)

                dbgMsg("\t\t\t self.sequence=", self.sequence.toString())

                dbgMsg("self.modifiers=%x" % self.modifiers)

                self.updateShortcutDisplay()

                dbgMsg("GOT THIS KEY", self.key)

            else:  # pressing non-modifier key but none of modifier keys are pressed - not a valid shortcut

                self.cancelRecording()

        dbgMsg("END OF KEY PRESS EVENT")
예제 #19
0
from cc3d.twedit5.twedit.utils.global_imports import *
예제 #20
0
    def getPortFromCommandLine(self):

        import getopt

        import sys

        opts = None

        args = None

        try:

            opts, args = getopt.getopt(sys.argv[1:], "p",
                                       ["file=", "port=", "socket="])

            dbgMsg("opts=", opts)

            dbgMsg("args=", args)

        except getopt.GetoptError as err:

            # dbgMsg(help information and exit:)

            dbgMsg(str(
                err))  # will print something like "option -a not recognized")

            sys.exit(2)

        port = -1

        socketId = 1

        for o, a in opts:

            dbgMsg("o=", o)

            dbgMsg("a=", a)

            if o in ("--port"):
                port = a

                dbgMsg("THIS IS PORT=", port)

            if o in ("--socket"):
                socketId = a

                dbgMsg("THIS IS SOCKET=", socketId)

            if o in ("--file"):
                file = a

                dbgMsg("THIS IS file=", file)

        return int(port), int(socketId)
예제 #21
0
    def readRequest(self):

        dbgMsg("INSIDE READ REQUEST")

        stream = QDataStream(self)

        stream.setVersion(QDataStream.Qt_5_2)

        dbgMsg("BYTES AVAILABLE:", self.bytesAvailable())

        if self.nextBlockSize == 0:

            if self.bytesAvailable() < SIZEOF_UINT16:
                return

        self.nextBlockSize = stream.readUInt16()

        if self.bytesAvailable() < self.nextBlockSize:
            return

        action = ""

        fileName = ""

        line = 0

        column = 0

        # date = QDate()

        # stream >> action

        action = stream.readQString()

        dbgMsg("ACTION=", action)

        if str(action) in ("FILEOPEN"):

            fileName = stream.readQString()

            line = stream.readUInt16()

            col = stream.readUInt16()

            self.editorWindow.loadFile(str(fileName))

            currentEditor = self.editorWindow.getCurrentEditor()

            # currentEditor.setCursorPosition(line-1,col)

            currentEditor.setCursorPosition(line - 1, 0)

            dbgMsg("THIS IS FILENAME READ FROM CLIENT=", str(fileName),
                   " line=", line, " col=", col)

            dbgMsg("currentEditor=", " line=", line, " col=", col)

            self.setCurrentLineBackgroundColor(currentEditor)

            self.line = line - 1

            self.col = 0

            # bring up the window

            if sys.platform.startswith('win'):

                # self.editorWindow.activateWindow()

                # aparently

                # showTweditWindowInForeground() will not work because we are trying to set current window in the foreground using win32Api

                # doing the same from separate process works fine

                # have to construct full path from env vars

                # have to get python path here as well

                # from subprocess import Popen

                # p = Popen(["python", self.bringupTweditPath,str(self.editorWindow.getProcessId())])

                print("calling script")

            else:

                self.editorWindow.showNormal()

                self.editorWindow.activateWindow()

                self.editorWindow.raise_()

                self.editorWindow.setFocus(True)

        elif str(action) in ('NEWCONNECTION'):

            print("\n\n\n \t\t\t NEW CONNECTION")

            self.sendEditorOpen()

            # self.sendEditorClosed()

            self.flush()

        elif str(action) in ("CONNECTIONESTABLISHED"):

            print("CONNECTION ESTABLISHED - LISTENER ACKNOWLEDGED")

            self.flush()

        elif str(action) in ("NEWSIMULATIONRECEIVED"):

            print("NEWSIMULATIONRECEIVED SIMULATION NAME SENT SUCCESFULLY")

            self.flush()
예제 #22
0
    def refresh(self):

        dbgMsg("REFRESH FILE TAB LIST\n\n\n\n")

        for tabWidget in self.editorWindow.panels:

            for i in range(tabWidget.count()):

                editor = tabWidget.widget(i)

                try:

                    self.tabDict[editor]

                    # checking if file name has not changed

                    documentName = self.editorWindow.getEditorFileName(editor)

                    if documentName == "":
                        documentName = tabWidget.tabText(
                            tabWidget.indexOf(editor))

                    if documentName != self.tabDict[editor]:

                        dbgMsg("fileName has changed in the open tab")

                        # linear search for item entry with matchin editor entry

                        for i in range(len(self.tabList)):

                            if self.tabList[i][1] == editor:
                                self.tabList[i][0] = documentName

                                self.tabDict[editor] = self.tabList[i][0]

                                break

                                # sys.exit()

                except KeyError as e:

                    # found new editor window

                    dbgMsg("# found new editor window")

                    if self.editorWindow.getEditorFileName(
                            editor
                    ) != "":  # if the name of the item is non empty

                        self.insertNewItem([
                            self.editorWindow.getEditorFileName(editor), editor
                        ])

                        # self.tabDict[editor]=self.tabList.insert[1][0] # new item was inserted at position 1

                        # self.tabDict[editor]=self.editorWindow.fileDict[editor][0]

                    else:  # otherwise get tab text

                        documentName = tabWidget.tabText(
                            tabWidget.indexOf(editor))

                        self.insertNewItem([documentName, editor])

                        # self.tabDict[editor]=self.tabList.insert[1][0]# new item was inserted at position 1

                        # self.tabDict[editor]=documentName

        # check if a tab has been deleted

        editorItemsToBeDeleted = []

        for editor in list(self.tabDict.keys()):

            # print '\t\t editor=',editor,' FNAME=',self.editorWindow.getEditorFileName(editor),' exists=',self.editorWindow.checkIfEditorExists(editor)

            if not self.editorWindow.checkIfEditorExists(editor):
                # this editor has been deleted from tab widget

                editorItemsToBeDeleted.append(editor)

                # try:

                # self.editorWindow.fileDict[editor]

                # except KeyError,e:

                # # this editor has been deleted from tab widget

                # editorItemsToBeDeleted.append(editor)

        # print '*******editorItemsToBeDeleted=',editorItemsToBeDeleted

        for editorItem in editorItemsToBeDeleted:

            del self.tabDict[editorItem]

            # linear search for editor entry in the tabList

            for i in range(len(self.tabList)):

                if self.tabList[i][1] == editorItem:
                    del self.tabList[i]

                    break

        activeTab = self.editorWindow.getActivePanel()

        # make sure current item is listed at the top

        currentEditor = self.editorWindow.getActiveEditor()

        # print 'currentEditor=',currentEditor,' fileName=',self.editorWindow.getEditorFileName(currentEditor)

        currentItem = [self.tabDict[currentEditor], currentEditor]

        self.makeItemCurrent(currentItem)
예제 #23
0
    def __init__(self, parent=None):

        super(CC3DListener, self).__init__(parent)

        self.editorWindow = parent

        # self.port=47406 # initial port - might be reassigned by calling program - vial --port=... command line option

        self.port = -1  # initial port - might be reassigned by calling program - vial --port=... command line option

        self.socketId = -1

        self.port, self.socketId = self.getPortFromCommandLine()

        dbgMsg("PORT=", self.port)

        print("PORT=", self.port)

        self.clientSocket = None

        # on some linux distros QHostAddress.LocalHost does not work

        # if not self.tcpServer.listen(QHostAddress.LocalHost,47405):

        dbgMsg("\n\n\n LISTENING ON PORT ", self.port)

        self.nextBlockSize = 0

        self.socket = None

        self.socketSender = None

        self.nextBlockSize = 0

        self.cc3dPath = getCC3DPlayerRunScriptPath()

        # # # if sys.platform.startswith('win'):

        # # # self.cc3dPath=os.path.join(environ['PREFIX_CC3D'],'compucell3d.bat')

        # # # elif sys.platform.startswith('darwin'):

        # # # self.cc3dPath=os.path.join(environ['PREFIX_CC3D'],'compucell3d.command')

        # # # else : # linux/unix

        # # # self.cc3dPath=os.path.join(environ['PREFIX_CC3D'],'compucell3d.sh')

        # # # self.cc3dPath=os.path.abspath(self.cc3dPath)

        self.pluginObj = None

        self.cc3dProcess = None

        if self.port > 0 and not self.listen(QHostAddress("127.0.0.1"),
                                             self.port):
            QMessageBox.critical(
                None, "FileNameReceiver",
                "CONSTRUCTOR Unable to start the server: %s." %
                str(self.errorString()))

            # self.getOpenPort()

            return
예제 #24
0
    def initializeTabFileList(self):

        if not len(
                self.tabList
        ):  # initialize from scratch if the list is empty - this is done on startup

            dbgMsg("INITIALIZE FILE TAB LIST\n\n\n\n")

            openFileDict = {}

            for tabWidget in self.editorWindow.panels:

                for i in range(tabWidget.count()):

                    editor = tabWidget.widget(i)

                    if editor == tabWidget.currentWidget():

                        if self.editorWindow.getEditorFileName(editor) != "":

                            self.tabList.insert(0, [
                                self.editorWindow.getEditorFileName(editor),
                                editor
                            ])

                        else:

                            documentName = tabWidget.tabText(
                                tabWidget.indexOf(editor))

                            self.tabList.insert(0, [documentName, editor])

                        self.tabDict[editor] = self.tabList[0][0]

                    else:

                        if self.editorWindow.getEditorFileName(editor) != "":

                            self.tabList.append([
                                self.editorWindow.getEditorFileName(editor),
                                editor
                            ])

                        else:

                            documentName = tabWidget.tabText(
                                tabWidget.indexOf(editor))

                            self.tabList.append([documentName, editor])

                            # self.tabList.append([self.editorWindow.fileDict[editor][0],editor])

                        self.tabDict[editor] = self.tabList[-1][0]

                        # storing items in the tabDict. tab dict will be used to compare if new items have been added to self.editorWindow.fileDict

                        # self.tabDict[editor]=self.editorWindow.fileDict[editor][0]

                        # self.tabDict[editor]=self.tabList[-1]

        else:

            self.refresh()
예제 #25
0
    def keyReleaseEvent(self, e):

        dbgMsg("keyReleaseEvent")
예제 #26
0
if __name__ == '__main__':

    if __name__ == '__main__':
        # enable it during debugging in pycharm
        sys.excepthook = except_hook

    try:

        twedit = Twedit()

        twedit.processCommandLineOptions()

    except OSError as e:

        dbgMsg("GOT OS ERROR")

        # argvSendSocket=QUdpSocket()

        fileList = twedit.getFileList()

        print("\n\n\n\n FILE LIST=", fileList)

        for fileName in fileList:
            datagram = fileName

            # argvSendSocket.writeDatagram(datagram,QHostAddress.LocalHost,47405)

            fileSender = FileNameSender(datagram)

            fileSender.send()
예제 #27
0
from cc3d.twedit5.twedit.utils.global_imports import *
from cc3d.twedit5.twedit.utils.global_imports import *
예제 #29
0
from cc3d.twedit5.twedit.utils.global_imports import *
예제 #30
0
"""