Files
IfcOpenShell/src/ifcopenshell-python/ifcopenshell/geom/code_editor_pane.py
T

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

163 lines
6.1 KiB
Python
Raw Normal View History

# IfcOpenShell - IFC toolkit and geometry engine
# Copyright (C) 2021 Thomas Krijnen <thomas@aecgeeks.com>
#
# This file is part of IfcOpenShell.
#
# IfcOpenShell is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# IfcOpenShell is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
2025-12-19 18:53:04 +05:00
import logging
import os
import sys
from code import InteractiveConsole
2025-12-19 18:53:04 +05:00
2018-05-17 15:53:40 +02:00
from PyQt5 import QtCore, QtGui, QtWidgets
try:
2018-05-17 15:53:40 +02:00
from PyQt5 import QtWidgets
2017-11-06 11:06:40 +01:00
except BaseException:
QtWidgets = QtGui
try:
2025-12-19 18:53:04 +05:00
from pyqode.core import api, modes, panels
from pyqode.core.api import CodeEdit, ColorScheme
2025-12-19 18:53:04 +05:00
from pyqode.core.panels import CheckerPanel
from pyqode.python import modes as pymodes
from pyqode.python import panels as pypanels
from pyqode.python import widgets
from pyqode.python.backend import server
2025-12-19 18:53:04 +05:00
from pyqode.python.modes import PyAutoIndentMode, PythonSH
from pyqode.python.widgets import PyInteractiveConsole
2017-11-06 11:06:40 +01:00
has_pyqode = True
2017-11-06 11:06:40 +01:00
except BaseException:
has_pyqode = False
CodeEdit = QtWidgets.QPlainTextEdit
2017-11-06 09:10:28 +01:00
2024-05-07 16:03:07 +10:00
class StdoutRedirector:
2017-11-27 15:10:56 +01:00
"""A class for redirecting stdout to this Text widget."""
def __init__(self, widget):
2017-11-06 09:10:28 +01:00
self.widget = widget
self.isError = False
2017-11-27 15:10:56 +01:00
def write(self, myStr):
self.widget.moveCursor(QtGui.QTextCursor.End)
if self.isError:
self.widget.setTextColor(QtCore.Qt.red)
else:
self.widget.setTextColor(QtCore.Qt.white)
2017-11-27 15:10:56 +01:00
self.widget.insertPlainText(myStr)
self.widget.moveCursor(QtGui.QTextCursor.End)
2018-05-17 15:53:40 +02:00
class code_edit(QtWidgets.QWidget):
class Console(InteractiveConsole):
def __init__(*args):
InteractiveConsole.__init__(*args)
def enter(self, source):
self.runcode(source)
def runCode(self):
sys.stdout = StdoutRedirector(self.output)
sys.stderr = StdoutRedirector(self.output)
2017-11-06 09:10:28 +01:00
sys.stderr.isError = True
if not self.model:
print("please load a model first", file=sys.stderr)
else:
self.c.enter(str(self.editor.toPlainText()))
2017-11-06 09:10:28 +01:00
sys.stdout = sys.__stdout__
sys.stderr = sys.__stderr__
2017-11-06 09:10:28 +01:00
def select(self, product):
2020-11-01 20:08:27 +07:00
self.c = self.Console({"model": self.model, "viewer": self.viewer, "selection": product})
2017-11-06 09:10:28 +01:00
def __init__(self, viewer, snippets=None):
self.model = None
self.viewer = viewer
2018-05-17 15:53:40 +02:00
QtWidgets.QWidget.__init__(self)
self.layout = QtWidgets.QVBoxLayout(self)
self.setLayout(self.layout)
self.c = None
2018-05-17 15:53:40 +02:00
self.tools = QtWidgets.QHBoxLayout(self)
self.layout.addLayout(self.tools)
2018-05-17 15:53:40 +02:00
self.runbutton = QtWidgets.QPushButton("Run")
width = self.runbutton.fontMetrics().boundingRect("Run").width() + 20
self.runbutton.setMaximumWidth(width)
self.tools.addWidget(self.runbutton)
self.runbutton.clicked.connect(self.runCode)
2017-11-06 09:10:28 +01:00
editor = CodeEdit()
if has_pyqode:
editor.backend.start(server.__file__)
editor.panels.append(panels.FoldingPanel())
editor.panels.append(panels.LineNumberPanel())
2020-11-01 20:08:27 +07:00
editor.panels.append(panels.SearchAndReplacePanel(), panels.SearchAndReplacePanel.Position.BOTTOM)
editor.panels.append(panels.EncodingPanel(), api.Panel.Position.TOP)
editor.add_separator()
editor.panels.append(pypanels.QuickDocPanel(), api.Panel.Position.BOTTOM)
sh = editor.modes.append(PythonSH(editor.document()))
editor.modes.append(modes.CaretLineHighlighterMode())
editor.modes.append(modes.CodeCompletionMode())
editor.modes.append(modes.ExtendedSelectionMode())
editor.modes.append(modes.FileWatcherMode())
editor.modes.append(modes.OccurrencesHighlighterMode())
editor.modes.append(modes.RightMarginMode())
editor.modes.append(modes.SmartBackSpaceMode())
editor.modes.append(modes.SymbolMatcherMode())
editor.modes.append(modes.ZoomMode())
editor.modes.append(pymodes.CommentsMode())
editor.modes.append(pymodes.CalltipsMode())
auto = pymodes.PyAutoCompleteMode()
auto.logger.setLevel(logging.CRITICAL)
editor.modes.append(auto)
editor.modes.append(pymodes.PyAutoIndentMode())
editor.modes.append(pymodes.PyIndenterMode())
editor.show()
else:
2020-11-01 20:08:27 +07:00
editor.setStyleSheet("font-size: 10pt; font-family: Consolas, Courier;")
self.editor = editor
self.snippets = snippets
if self.snippets:
self.list = QtWidgets.QComboBox(self)
self.replace_snippet(0)
for snip_name in self.snippets.keys():
self.list.addItem(snip_name)
self.tools.addWidget(self.list)
2018-05-17 15:53:40 +02:00
self.list.currentIndexChanged[int].connect(self.replace_snippet)
self.layout.addWidget(self.editor)
2018-05-17 15:53:40 +02:00
self.output = QtWidgets.QTextEdit()
self.output.setReadOnly(True)
2020-11-01 20:08:27 +07:00
self.output.setStyleSheet("font-size: 10pt; font-family: Consolas, Courier; background-color: #444;")
self.layout.addWidget(self.output)
def replace_snippet(self, number=None):
snip = list(self.snippets.values())[number]
if has_pyqode:
self.editor.setPlainText(snip, "", "")
else:
self.editor.setPlainText(snip)
def load_file(self, f, **kwargs):
output = []
sys.stdout = StdoutRedirector(self.output)
self.model = f
2020-11-01 20:08:27 +07:00
self.c = self.Console({"model": self.model, "selection": None, "viewer": self.viewer})
sys.stdout = sys.__stdout__