from jmwright 72b67da

This commit is contained in:
jdegenstein
2022-09-16 13:52:44 -05:00
committed by GitHub
parent 04978a6f78
commit fffb6db0f2
50 changed files with 14900 additions and 0 deletions

341
cq_editor/main_window.py Normal file
View File

@@ -0,0 +1,341 @@
import sys
from PyQt5.QtWidgets import (QLabel, QMainWindow, QToolBar, QDockWidget, QAction)
import cadquery as cq
from .widgets.editor import Editor
from .widgets.viewer import OCCViewer
from .widgets.console import ConsoleWidget
from .widgets.object_tree import ObjectTree
from .widgets.traceback_viewer import TracebackPane
from .widgets.debugger import Debugger, LocalsView
from .widgets.cq_object_inspector import CQObjectInspector
from .widgets.log import LogViewer
from . import __version__
from .utils import dock, add_actions, open_url, about_dialog, check_gtihub_for_updates, confirm
from .mixins import MainMixin
from .icons import icon
from .preferences import PreferencesWidget
class MainWindow(QMainWindow,MainMixin):
name = 'CQ-Editor'
org = 'CadQuery'
def __init__(self,parent=None, filename=None):
super(MainWindow,self).__init__(parent)
MainMixin.__init__(self)
self.setWindowIcon(icon('app'))
self.viewer = OCCViewer(self)
self.setCentralWidget(self.viewer.canvas)
self.prepare_panes()
self.registerComponent('viewer',self.viewer)
self.prepare_toolbar()
self.prepare_menubar()
self.prepare_statusbar()
self.prepare_actions()
self.components['object_tree'].addLines()
self.prepare_console()
self.fill_dummy()
self.setup_logging()
self.restorePreferences()
self.restoreWindow()
if filename:
self.components['editor'].load_from_file(filename)
self.restoreComponentState()
def closeEvent(self,event):
self.saveWindow()
self.savePreferences()
self.saveComponentState()
if self.components['editor'].document().isModified():
rv = confirm(self, 'Confirm close', 'Close without saving?')
if rv:
event.accept()
super(MainWindow,self).closeEvent(event)
else:
event.ignore()
else:
super(MainWindow,self).closeEvent(event)
def prepare_panes(self):
self.registerComponent('editor',
Editor(self),
lambda c : dock(c,
'Editor',
self,
defaultArea='left'))
self.registerComponent('object_tree',
ObjectTree(self),
lambda c: dock(c,
'Objects',
self,
defaultArea='right'))
self.registerComponent('console',
ConsoleWidget(self),
lambda c: dock(c,
'Console',
self,
defaultArea='bottom'))
self.registerComponent('traceback_viewer',
TracebackPane(self),
lambda c: dock(c,
'Current traceback',
self,
defaultArea='bottom'))
self.registerComponent('debugger',Debugger(self))
self.registerComponent('variables_viewer',LocalsView(self),
lambda c: dock(c,
'Variables',
self,
defaultArea='right'))
self.registerComponent('cq_object_inspector',
CQObjectInspector(self),
lambda c: dock(c,
'CQ object inspector',
self,
defaultArea='right'))
self.registerComponent('log',
LogViewer(self),
lambda c: dock(c,
'Log viewer',
self,
defaultArea='bottom'))
for d in self.docks.values():
d.show()
def prepare_menubar(self):
menu = self.menuBar()
menu_file = menu.addMenu('&File')
menu_edit = menu.addMenu('&Edit')
menu_tools = menu.addMenu('&Tools')
menu_run = menu.addMenu('&Run')
menu_view = menu.addMenu('&View')
menu_help = menu.addMenu('&Help')
#per component menu elements
menus = {'File' : menu_file,
'Edit' : menu_edit,
'Run' : menu_run,
'Tools': menu_tools,
'View' : menu_view,
'Help' : menu_help}
for comp in self.components.values():
self.prepare_menubar_component(menus,
comp.menuActions())
#global menu elements
menu_view.addSeparator()
for d in self.findChildren(QDockWidget):
menu_view.addAction(d.toggleViewAction())
menu_view.addSeparator()
for t in self.findChildren(QToolBar):
menu_view.addAction(t.toggleViewAction())
menu_edit.addAction( \
QAction(icon('preferences'),
'Preferences',
self,triggered=self.edit_preferences))
menu_help.addAction( \
QAction(icon('help'),
'Documentation',
self,triggered=self.documentation))
menu_help.addAction( \
QAction('CQ documentation',
self,triggered=self.cq_documentation))
menu_help.addAction( \
QAction(icon('about'),
'About',
self,triggered=self.about))
menu_help.addAction( \
QAction('Check for CadQuery updates',
self,triggered=self.check_for_cq_updates))
def prepare_menubar_component(self,menus,comp_menu_dict):
for name,action in comp_menu_dict.items():
menus[name].addActions(action)
def prepare_toolbar(self):
self.toolbar = QToolBar('Main toolbar',self,objectName='Main toolbar')
for c in self.components.values():
add_actions(self.toolbar,c.toolbarActions())
self.addToolBar(self.toolbar)
def prepare_statusbar(self):
self.status_label = QLabel('',parent=self)
self.statusBar().insertPermanentWidget(0, self.status_label)
def prepare_actions(self):
self.components['debugger'].sigRendered\
.connect(self.components['object_tree'].addObjects)
self.components['debugger'].sigTraceback\
.connect(self.components['traceback_viewer'].addTraceback)
self.components['debugger'].sigLocals\
.connect(self.components['variables_viewer'].update_frame)
self.components['debugger'].sigLocals\
.connect(self.components['console'].push_vars)
self.components['object_tree'].sigObjectsAdded[list]\
.connect(self.components['viewer'].display_many)
self.components['object_tree'].sigObjectsAdded[list,bool]\
.connect(self.components['viewer'].display_many)
self.components['object_tree'].sigItemChanged.\
connect(self.components['viewer'].update_item)
self.components['object_tree'].sigObjectsRemoved\
.connect(self.components['viewer'].remove_items)
self.components['object_tree'].sigCQObjectSelected\
.connect(self.components['cq_object_inspector'].setObject)
self.components['object_tree'].sigObjectPropertiesChanged\
.connect(self.components['viewer'].redraw)
self.components['object_tree'].sigAISObjectsSelected\
.connect(self.components['viewer'].set_selected)
self.components['viewer'].sigObjectSelected\
.connect(self.components['object_tree'].handleGraphicalSelection)
self.components['traceback_viewer'].sigHighlightLine\
.connect(self.components['editor'].go_to_line)
self.components['cq_object_inspector'].sigDisplayObjects\
.connect(self.components['viewer'].display_many)
self.components['cq_object_inspector'].sigRemoveObjects\
.connect(self.components['viewer'].remove_items)
self.components['cq_object_inspector'].sigShowPlane\
.connect(self.components['viewer'].toggle_grid)
self.components['cq_object_inspector'].sigShowPlane[bool,float]\
.connect(self.components['viewer'].toggle_grid)
self.components['cq_object_inspector'].sigChangePlane\
.connect(self.components['viewer'].set_grid_orientation)
self.components['debugger'].sigLocalsChanged\
.connect(self.components['variables_viewer'].update_frame)
self.components['debugger'].sigLineChanged\
.connect(self.components['editor'].go_to_line)
self.components['debugger'].sigDebugging\
.connect(self.components['object_tree'].stashObjects)
self.components['debugger'].sigCQChanged\
.connect(self.components['object_tree'].addObjects)
self.components['debugger'].sigTraceback\
.connect(self.components['traceback_viewer'].addTraceback)
# trigger re-render when file is modified externally or saved
self.components['editor'].triggerRerender \
.connect(self.components['debugger'].render)
self.components['editor'].sigFilenameChanged\
.connect(self.handle_filename_change)
def prepare_console(self):
console = self.components['console']
obj_tree = self.components['object_tree']
#application related items
console.push_vars({'self' : self})
#CQ related items
console.push_vars({'show' : obj_tree.addObject,
'show_object' : obj_tree.addObject,
'cq' : cq})
def fill_dummy(self):
self.components['editor']\
.set_text('import cadquery as cq\nresult = cq.Workplane("XY" ).box(3, 3, 0.5).edges("|Z").fillet(0.125)')
def setup_logging(self):
from logbook.compat import redirect_logging
from logbook import INFO, Logger
redirect_logging()
self.components['log'].handler.level = INFO
self.components['log'].handler.push_application()
self._logger = Logger(self.name)
def handle_exception(exc_type, exc_value, exc_traceback):
if issubclass(exc_type, KeyboardInterrupt):
sys.__excepthook__(exc_type, exc_value, exc_traceback)
return
self._logger.error("Uncaught exception occurred",
exc_info=(exc_type, exc_value, exc_traceback))
sys.excepthook = handle_exception
def edit_preferences(self):
prefs = PreferencesWidget(self,self.components)
prefs.exec_()
def about(self):
about_dialog(
self,
f'About CQ-editor',
f'PyQt GUI for CadQuery.\nVersion: {__version__}.\nSource Code: https://github.com/CadQuery/CQ-editor',
)
def check_for_cq_updates(self):
check_gtihub_for_updates(self,cq)
def documentation(self):
open_url('https://github.com/CadQuery')
def cq_documentation(self):
open_url('https://cadquery.readthedocs.io/en/latest/')
def handle_filename_change(self, fname):
new_title = fname if fname else "*"
self.setWindowTitle(f"{self.name}: {new_title}")
if __name__ == "__main__":
pass