示例#1
0
def getEditor():
    editor = QsciScintilla()
    lexer = QsciLexerYAML()
    editor.setLexer(lexer)
    font = getFont()
    # lexer.setDefaultFont(font)
    lexer.setFont(font)
    settings = QSettings()
    lexer.readSettings(settings)
    print(settings.allKeys())
    lexer.setDefaultPaper(QColor('#252721'))
    for i in range(10):
        lexer.setPaper(QColor('#252721'), i)
        lexer.setColor(QColor('#f8f8f2'), i)
        print(lexer.color(i).name())
    lexer.setColor(QColor('#e6db74'), 0)  # foreground (yellow)
    lexer.setColor(QColor('#75715e'), 1)  # comment (gray)
    lexer.setColor(QColor('#f92672'), 2)  # identifier (red)
    lexer.setColor(QColor('#ae81ff'), 3)  # keyword (purple)
    lexer.setColor(QColor('#ae81ff'), 4)  # number (purple)
    lexer.setColor(QColor('#ae81ff'), 5)  # reference (purple)
    lexer.setColor(QColor('#ae81ff'), 6)  # documentdelimiter (purple)
    lexer.setColor(QColor('#ae81ff'), 7)  # text block marker (purple)
    lexer.setColor(QColor('#f92672'), 8)  # syntax error marker (red)
    lexer.setColor(QColor('#f92672'), 9)  # operator (red)
    # editor.setFont(font)
    # editor.setMarginsFont(font)
    editor.setCaretForegroundColor(QColor('#f8f8f0'))
    editor.setMarginWidth(0, getMarginWidth(font))
    editor.setMarginWidth(1, 0)
    editor.setMarginLineNumbers(0, True)
    editor.setMarginsBackgroundColor(QColor('#252721'))
    editor.setMarginsForegroundColor(QColor('#f8f8f2'))
    editor.setExtraAscent(3)
    editor.setTabWidth(4)
    editor.setMinimumSize(600, 450)
    return editor
示例#2
0
class BrowserWindow(QWidget):
    launcherWindow = None
    logoPixmap = None

    def __init__(self, launcherWindow, app):
        super().__init__()
        self.app = app
        self.launcherWindow = launcherWindow
        self.fontSize = 14
        self.fontSizeLarge = 24
        self.fontSizeSmall = 10
        self.setCursor(AppData.cursors['arrow'])
        self.initUI()

    def multiple_replace(self, string, rep_dict):
        pattern = re.compile("|".join([re.escape(k) for k in rep_dict.keys()]),
                             re.M)
        return pattern.sub(lambda x: rep_dict[x.group(0)], string)

    def styleEsc(self, string):
        return self.multiple_replace(string, {
            '{': '{{',
            '}': '}}',
            '@<': '{',
            '>@': '}'
        })

    def initUI(self):
        ##        pal = QPalette();
        ##        pal.setColor(QPalette.Background, Qt.black);
        ##        self.setPalette(pal);
        self.setSizePolicy(QSizePolicy.Maximum, QSizePolicy.Maximum)
        self.styleTemplate = self.styleEsc("""
            QWidget{
                background-color: black;
                border-color: red;
                border-style: solid;
                border-width: 1px;
                border-radius: 0px;
                font: bold @<fontSize>@px;
                color: red;
                padding: 0px;
                font-family: "Candara";
                font-size: @<fontSize:d>@px;
            }
            QLabel{
                font-size: @<fontSizeLarge:d>@px;
                 border-width: 0px;
            }
            QTreeView::item:hover {
                background: black;
                border: 1px solid red;
            }
            QTreeView::item:selected {
                border: 1px solid red;
                color: red;
            }
            QTreeView::item:selected:active{
                background: black;
                border: 1px solid red;
            }
            QTreeView::item:selected:!active {
                border: 1px solid red;
                color: red;
            }
            QTreeView::branch:has-siblings:!adjoins-item {
                border-image: url(Gui/stylesheet-vline.png) 0;
            }

            QTreeView::branch:has-siblings:adjoins-item {
                border-image: url(Gui/stylesheet-branch-more.png) 0;
            }

            QTreeView::branch:!has-children:!has-siblings:adjoins-item {
                border-image: url(Gui/stylesheet-branch-end.png) 0;
            }

            QTreeView::branch:has-children:!has-siblings:closed,
            QTreeView::branch:closed:has-children:has-siblings {
                    border-image: none;
                    image: url(Gui/stylesheet-branch-closed.png);
            }

            QTreeView::branch:open:has-children:!has-siblings,
            QTreeView::branch:open:has-children:has-siblings  {
                    border-image: none;
                    image: url(Gui/stylesheet-branch-open.png);
            }

            QScrollBar:vertical {
                 border: 2px solid red;
                 background: black;
                 width: 40px;
                 margin: 22px 0 22px 0;
             }
             QScrollBar::handle:vertical {
                 background: red;
                 min-height: 20px;
             }
             QScrollBar::add-line:vertical {
                 border: 2px red;
                 background: black;
                 height: 20px;
                 subcontrol-position: bottom;
                 subcontrol-origin: margin;
             }
             QScrollBar::sub-line:vertical {
                 border: 2px red;
                 background: black;
                 height: 20px;
                 subcontrol-position: top;
                 subcontrol-origin: margin;
             }
             QScrollBar::up-arrow:vertical, QScrollBar::down-arrow:vertical {
                 border: 2px solid black;
                 width: 3px;
                 height: 3px;
                 background: red;
             }

             QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical {
                 background: none;
             }
            """)

        self.setStyleSheet(
            self.styleTemplate.format(fontSize=int(self.fontSize),
                                      fontSizeLarge=int(self.fontSizeLarge)))
        #gridWidget = QWidget(self)
        #self.gridWidget = gridWidget
        grid = QGridLayout()
        #treeMooker = QWidget(self)
        #treeMooker.setStyleSheet("background-color: transparent;")
        #treeMooker.setAttribute(Qt.WA_TransparentForMouseEvents)
        #treeMooker.installEventFilter(self)
        #treeMookerGrid = QGridLayout()
        #stack = QStackedLayout()
        #stack.setStackingMode(QStackedLayout.StackAll)

        logo = QLabel(self)
        self.logoPixmap = QPixmap("./Project/Media/Gears.png")
        logo.setPixmap(self.logoPixmap)
        logo.setAlignment(Qt.AlignHCenter | Qt.AlignVCenter)
        grid.addWidget(logo, 2, 3, 1, 1)
        self.titleTemplate = self.styleEsc('''
<p align="left"><strong>
<span style='font-size:@<fontSizeLarge>@pt; font-weight:600; color:#ff0000;'>GPU Eye And Retina Stimulation  </span></strong><span style='font-size:10pt; font-weight:600; color:#aa0000;'>beta test version 0.4</span></p>
<table border="0" cellpadding="0" cellspacing="0">
	<tbody>
		<tr>
			<td >
			<p align="left"><span style='font-size:@<fontSize>@pt; font-weight:600; color:#ff0000;'>László Szécsi</span></p>
			</td>
			<td >
			<p><span style='font-size:@<fontSizeSmall>@pt; font-weight:600; color:#aa0000;'>Budapest University of Technology and Economics</span></p>
			</td>
		</tr>
		<tr>
			<td >
			<p align="left"> <span style='font-size:@<fontSize>@pt; font-weight:600; color:#ff0000;'>Péter Hantz</span></p>
			</td>
			<td >
			<p><span style='font-size:@<fontSizeSmall>@pt; font-weight:600; color:#aa0000;'>University of Pécs, Medical School</span></p>
			</td>
		</tr>
		<tr>
			<td >
			<p align="left"> <span style='font-size:@<fontSize>@pt; font-weight:600; color:#ff0000;'>Ágota Kacsó</span></p>
			</td>
			<td >
			<p><span style='font-size:@<fontSizeSmall>@pt; font-weight:600; color:#aa0000;'>Budapest University of Technology and Economics</span></p>
			</td>
		</tr>
		<tr>
			<td >
			<p align="left"><span style='font-size:@<fontSize>@pt; font-weight:600; color:#ff0000;'>Günther Zeck</span></p>
			</td>
			<td >
			<p><span style='font-size:@<fontSizeSmall>@pt; font-weight:600; color:#aa0000;'>Natural and Medical Sciences Institute Reutlingen</span></p>
			</td>
		</tr>
		<tr>
			<td >
			<p align="left"><span style='font-size:@<fontSizeSmall>@pt; font-weight:600; color:#aa0000;'>http://www.gears.vision</span></p>
			</td>
			<td >
            <p><span style='font-size:@<fontSizeSmall>@pt; font-weight:600; color:#aa0000;'>[email protected]</span></p>
			</td>
		</tr>
	</tbody>
</table>
                ''')
        self.titleLabel = QLabel(
            self.titleTemplate.format(fontSize=self.fontSize,
                                      fontSizeLarge=self.fontSizeLarge,
                                      fontSizeSmall=self.fontSizeSmall))
        self.titleLabel.setTextFormat(Qt.RichText)
        self.titleLabel.setAlignment(Qt.AlignHCenter | Qt.AlignVCenter)
        grid.addWidget(self.titleLabel, 1, 3, 1, 1)

        self.instructionsTemplate = self.styleEsc('''
<p align="left"><strong>
<table border="0" cellpadding="0" cellspacing="0">
	<tbody>
		<tr>
			<td >
			<p align="left"><span style='font-size:@<fontSize>@pt; font-weight:600; color:#ff0000;'>Reset tree</span></p>
			</td>
			<td >
			<p><span style='font-size:@<fontSizeSmall>@pt; font-weight:600; color:#aa0000;'>press space</span></p>
			</td>
		</tr>
		<tr>
			<td >
			<p align="left"><span style='font-size:@<fontSize>@pt; font-weight:600; color:#ff0000;'>Navigate</span></p>
			</td>
			<td >
			<p><span style='font-size:@<fontSizeSmall>@pt; font-weight:600; color:#aa0000;'>press key for first character</span></p>
			</td>
		</tr>
		<tr>
			<td >
			<p align="left"> <span style='font-size:@<fontSize>@pt; font-weight:600; color:#ff0000;'>Change font size</span></p>
			</td>
			<td >
			<p><span style='font-size:@<fontSizeSmall>@pt; font-weight:600; color:#aa0000;'>ctrl+mouse wheel</span></p>
			</td>
		</tr>
		<tr>
			<td >
			<p align="left"><span style='font-size:@<fontSize>@pt; font-weight:600; color:#ff0000;'>Edit or configure</span></p>
			</td>
			<td >
			<p><span style='font-size:@<fontSizeSmall>@pt; font-weight:600; color:#aa0000;'>right click tree item</span></p>
			</td>
		</tr>
		<tr>
			<td >
			<p align="left"><span style='font-size:@<fontSize>@pt; font-weight:600; color:#ff0000;'>/</span></p>
			</td>
			<td >
			<p><span style='font-size:@<fontSizeSmall>@pt; font-weight:600; color:#aa0000;'> @<emptyFolderOp>@ empty folders</span></p>
			</td>
		</tr>
	</tbody>
</table>
                ''')
        self.instructionsLabel = QLabel(
            self.instructionsTemplate.format(fontSize=self.fontSize,
                                             fontSizeLarge=self.fontSizeLarge,
                                             fontSizeSmall=self.fontSizeSmall,
                                             emptyFolderOp='show'))
        self.instructionsLabel.setStyleSheet('''
            QLabel{
                 border-width: 1px;
            }
            ''')

        self.instructionsLabel.setTextFormat(Qt.RichText)
        self.instructionsLabel.setAlignment(Qt.AlignHCenter)
        grid.addWidget(self.instructionsLabel, 3, 1, 1, 1)

        specs = QLabel(gears.getSpecs())
        #self.titleLabel.setTextFormat( Qt.RichText )
        self.titleLabel.setAlignment(Qt.AlignHCenter | Qt.AlignVCenter)
        specs.setFocusPolicy(Qt.NoFocus)
        #specsButton.clicked.connect(self.onSpecs)
        grid.addWidget(specs, 4, 1, 1, 1)

        quitButton = QPushButton('Quit')
        quitButton.setFocusPolicy(Qt.NoFocus)
        quitButton.clicked.connect(self.onQuit)
        grid.addWidget(quitButton, 4, 3, 1, 1)

        #settingsButton = QPushButton('Measurement hardware')
        #settingsButton.setFocusPolicy(Qt.NoFocus)
        #settingsButton.clicked.connect(self.onSet)
        #grid.addWidget(settingsButton, 3, 3, 1, 1)

        tree = BrowserTree(self.launcherWindow, self)
        tree.setAttribute(Qt.WA_TransparentForMouseEvents, on=False)
        self.tree = tree
        tree.setFocusPolicy(Qt.NoFocus)
        tree.setHeaderHidden(True)
        tree.setStyleSheet("background-color: black;")
        item0 = QTreeWidgetItem(tree)
        item0.setText(0, 'Sequences')

        itemMap = dict()
        itemMap["./Project/Sequences"] = item0
        rootPath = "./Project/Sequences"
        emptyDirs = find_empty_dirs(rootPath)
        for (path, dirs, files) in os.walk(rootPath):
            for subdir in dirs:
                if subdir != "__pycache__":
                    fullPath = os.path.join(path, subdir)
                    #if(rootPath == path):
                    #    item0 = QTreeWidgetItem(tree)
                    #    itemMap[fullPath] = item0
                    #    item0.setText(0, subdir)
                    #else:
                    item1 = QTreeWidgetItem()
                    itemMap[fullPath] = item1
                    item1.setText(0, subdir)
                    itemMap[path].addChild(item1)
                    if fullPath in emptyDirs:
                        item1.setText(
                            1, "gears_folder_not_holding_any_sequence_scripts")
                        item1.setHidden(True)
            for item in files:
                if item.endswith('.pyx'):
                    #if(rootPath == path):
                    #    item0 = QTreeWidgetItem(tree)
                    #    itemMap[os.path.join(path, item)] = item0
                    #    item0.setText(0, item)
                    #else:
                    item1 = QTreeWidgetItem()
                    itemMap[os.path.join(path, item)] = item1
                    item1.setText(0, item)
                    item1.setText(1, "tags spot spatial temporal")
                    itemMap[path].addChild(item1)

        item0.setExpanded(True)
        grid.addWidget(tree, 1, 1, 4, 3, Qt.AlignLeft | Qt.AlignTop)

        #qbtn = QPushButton('Quit', self)
        #qbtn.clicked.connect(QCoreApplication.instance().quit)
        #qbtn.resize(qbtn.sizeHint())
        #grid.addWidget(qbtn, 8, 9)

        #treeMooker.setLayout(treeMookerGrid)
        #gridWidget.setLayout(grid)
        #stack.addWidget(treeMooker)
        #stack.addWidget(gridWidget)
        self.setLayout(grid)

        self.setWindowTitle('O\u0398\u03a6O')
        #        self.setWindowIcon(QIcon('web.png'))
        self.showFullScreen()
        self.setFixedSize(self.size())
        self.tree.setCurrentIndex(self.tree.model().index(0, 0))

    def keyPressEvent(self, e):
        if e.key() == Qt.Key_Escape or e.text() == 'q':
            box = QMessageBox(self)
            QGuiApplication.setOverrideCursor(AppData.cursors['arrow'])
            box.setText('Are you sure you want to quit?')
            box.setWindowTitle('Please confirm!')
            box.setWindowFlags(Qt.FramelessWindowHint | Qt.Dialog)
            box.setStandardButtons(QMessageBox.Yes | QMessageBox.No)
            box.setDefaultButton(QMessageBox.No)
            if box.exec() == QMessageBox.Yes:
                self.close()
            QGuiApplication.restoreOverrideCursor()
        elif e.key() == Qt.Key_Space or e.key() == Qt.Key_Backspace:
            self.tree.setCurrentItem(self.tree.topLevelItem(0))
            self.tree.collapseAll()
            self.tree.topLevelItem(0).setExpanded(True)
        elif e.key() == Qt.Key_Down:
            ni = self.tree.itemBelow(self.tree.currentItem())
            if (ni != None):
                self.tree.setCurrentItem(ni)
        elif e.key() == Qt.Key_Up:
            ni = self.tree.itemAbove(self.tree.currentItem())
            if (ni != None):
                self.tree.setCurrentItem(ni)
        elif e.key() == Qt.Key_Left:
            ni = self.tree.currentItem().parent()
            if (ni != None):
                self.tree.setCurrentItem(ni)
        elif e.key() == Qt.Key_Right or e.key() == Qt.Key_Return or e.key(
        ) == Qt.Key_Enter:
            ni = self.tree.currentItem().child(0)
            if (ni != None):
                self.tree.setCurrentItem(ni)
            else:
                self.tree.open(self.tree.currentItem(), False)
        elif e.key() == Qt.Key_Slash:
            self.tree.hideEmptyFolders(not self.tree.isHidingEmptyFolders)
            self.instructionsLabel.setText(
                self.instructionsTemplate.format(
                    fontSize=int(self.fontSize),
                    fontSizeLarge=int(self.fontSizeLarge),
                    fontSizeSmall=int(self.fontSizeSmall),
                    emptyFolderOp=('show' if self.tree.isHidingEmptyFolders
                                   else 'hide')))
        #elif e.key()==Qt.Key_0 or e.key()==Qt.Key_1 or e.key()==Qt.Key_2 or e.key()==Qt.Key_3 or e.key()==Qt.Key_4 or e.key()==Qt.Key_5 or e.key()==Qt.Key_6 or e.key()==Qt.Key_7 or e.key()==Qt.Key_8 or e.key()==Qt.Key_9 :
        else:
            self.tree.clearSelection()
            self.tree.keyboardSearch(e.text())
            sel = self.tree.selectedItems()
            if len(sel) > 0:
                self.tree.onClick(sel[0], 0)

    def onSpecs(self):
        box = QMessageBox(self)
        horizontalSpacer = QSpacerItem(1000, 0, QSizePolicy.Minimum,
                                       QSizePolicy.Expanding)
        box.setText(gears.getSpecs())
        box.setWindowTitle('System specs')
        box.setWindowFlags(Qt.FramelessWindowHint | Qt.Dialog)
        box.setStandardButtons(QMessageBox.Ok)
        box.setDefaultButton(QMessageBox.Ok)
        layout = box.layout()
        layout.addItem(horizontalSpacer, layout.rowCount(), 0, 1,
                       layout.columnCount())
        box.exec()

    def onQuit(self):
        box = QMessageBox(self)
        #box.setCursor(AppData.cursors['arrow'])
        QGuiApplication.setOverrideCursor(AppData.cursors['arrow'])
        box.setText('Are you sure you want to quit?')
        box.setWindowTitle('Please confirm!')
        box.setWindowFlags(Qt.FramelessWindowHint | Qt.Dialog)
        box.setStandardButtons(QMessageBox.Yes | QMessageBox.No)
        box.setDefaultButton(QMessageBox.No)
        if box.exec() == QMessageBox.Yes:
            self.close()
        QGuiApplication.restoreOverrideCursor()

    def onSet(self):
        #from subprocess import call
        #call("notepad ./Project/Sequences/DefaultSequence.py")

        self.editor = QsciScintilla()

        # define the font to use
        font = QFont()
        font.setFamily('Courier')
        font.setFixedPitch(True)
        font.setPointSize(10)
        # the font metrics here will help
        # building the margin width later
        fm = QFontMetrics(font)

        ## set the default font of the editor
        ## and take the same font for line numbers
        self.editor.setFont(font)
        self.editor.setMarginsFont(font)

        ## Line numbers
        # conventionnaly, margin 0 is for line numbers
        self.editor.setMarginWidth(0, fm.width("00000") + 5)
        self.editor.setMarginLineNumbers(0, True)

        ## Edge Mode shows a red vetical bar at 80 chars
        self.editor.setEdgeMode(QsciScintilla.EdgeLine)
        self.editor.setEdgeColumn(80)
        self.editor.setEdgeColor(QColor("#FF0000"))

        ## Folding visual : we will use boxes
        self.editor.setFolding(QsciScintilla.BoxedTreeFoldStyle)

        ## Braces matching
        self.editor.setBraceMatching(QsciScintilla.SloppyBraceMatch)

        ## Editing line color
        self.editor.setCaretLineVisible(True)
        self.editor.setCaretLineBackgroundColor(QColor("#CDA869"))

        ## Margins colors
        # line numbers margin
        self.editor.setMarginsBackgroundColor(QColor("#333333"))
        self.editor.setMarginsForegroundColor(QColor("#CCCCCC"))

        # folding margin colors (foreground,background)
        self.editor.setFoldMarginColors(QColor("#99CC66"), QColor("#333300"))

        ## Choose a lexer
        lexer = QsciLexerPython()
        lexer.setDefaultFont(font)
        api = QsciStrictAPIs(lexer)
        api.prepare()
        lexer.setDefaultFont(font)
        self.editor.setLexer(lexer)
        self.editor.setMinimumSize(1024, 768)
        self.editor.show()
        ## Show this file in the editor
        text = open("./Project/Sequences/DefaultSequence.py").read()
        self.editor.setText(text)

    def wheelEvent(self, event):
        if self.app.keyboardModifiers() & Qt.ControlModifier:
            self.fontSize += event.angleDelta().y() / 120
            self.fontSizeLarge += event.angleDelta().y() / 120
            self.fontSizeSmall += event.angleDelta().y() / 120
            self.setStyleSheet(
                self.styleTemplate.format(fontSize=int(self.fontSize),
                                          fontSizeLarge=int(
                                              self.fontSizeLarge)))
            self.titleLabel.setText(
                self.titleTemplate.format(
                    fontSize=int(self.fontSize),
                    fontSizeLarge=int(self.fontSizeLarge),
                    fontSizeSmall=int(self.fontSizeSmall)))
            self.instructionsLabel.setText(
                self.instructionsTemplate.format(
                    fontSize=int(self.fontSize),
                    fontSizeLarge=int(self.fontSizeLarge),
                    fontSizeSmall=int(self.fontSizeSmall),
                    emptyFolderOp=('show' if self.tree.isHidingEmptyFolders
                                   else 'hide')))
            self.tree.resizeColumnToContents(0)
            self.updateGeometry()

    #def eventFilter(self, obj, event):
    #    #if event.type() in [ QEvent.MouseMove, QEvent.MouseButtonPress, QEvent.MouseButtonRelease, QEvent.MouseButtonDblClick]:
    #    self.app.sendEvent(self.gridWidget, event)
    #    return super().eventFilter(obj, event)

    def sizeHint(self):
        return self.app.desktop().screenGeometry().size()
示例#3
0
class JsonEditorDlg(QtWidgets.QDialog):
    """Dialog widget for JsonEditor."""
    def __init__(self, path, name, label_name, json, parent=None):
        super(JsonEditorDlg, self).__init__(parent)
        self.setWindowTitle("Json Editor")
        self._path = path
        self._name = name
        self._label_name = label_name
        self.orig_text = json

        self._label_file = QtWidgets.QLabel(label_name + ": " + name, self)
        self._save_button = QtWidgets.QPushButton("Save ...", self)
        self._save_button.clicked.connect(self._save_file)
        self._save_as_button = QtWidgets.QPushButton("Save as...", self)
        self._save_as_button.clicked.connect(self._save_as_file)
        self._cancel_button = QtWidgets.QPushButton("Cancel", self)
        self._cancel_button.clicked.connect(self._cancel)

        self._editor = QsciScintilla(self)

        # Set Yaml lexer
        self._editor.lexer = QsciLexerJavaScript()
        self._editor.setLexer(self._editor.lexer)
        self._editor.setMinimumSize(600, 450)
        self._editor.setText(json)

        appearance.set_default_appearence(self._editor)

        button_layout = QtWidgets.QHBoxLayout()
        button_layout.addWidget(self._label_file)
        button_layout.addWidget(self._save_button)
        button_layout.addWidget(self._save_as_button)
        button_layout.addWidget(self._cancel_button)

        layout = QtWidgets.QVBoxLayout(self)
        layout.addLayout(button_layout)
        layout.addWidget(self._editor)
        self.setLayout(layout)

    def _save_file(self):
        """Save json file"""
        try:
            file_name = os.path.join(self._path, self._name + ".json")
            file_d = open(file_name, 'w')
            file_d.write(self._editor.text())
            file_d.close()
        except (RuntimeError, IOError) as err:
            err_dialog = gm_base.geomop_dialogs.GMErrorDialog(self)
            err_dialog.open_error_dialog("Can't save file", err)

    def _save_as_file(self):
        """Save json file as"""
        file_name = os.path.join(self._path, self._name + ".json")
        json_file = QtWidgets.QFileDialog.getSaveFileName(
            self, "Set Json File", file_name, "Json Files (*.json)")
        if json_file[0]:
            new_name = os.path.split(json_file[0])[1][:-5]
            new_path = os.path.split(json_file[0])[0]
            self._name = new_name
            self._path = new_path
            self._label_file.setText(self._label_name + ": " + new_name)
            self._save_file()

    def _cancel(self):
        """Cancel dialog"""
        # ToDo:if is there chnges,  ask for save
        self.done(0)
示例#4
0
class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__(flags=0)
        self.code = QsciScintilla()
        # self.code.setTabStopWidth(4)
        self.code.setTabWidth(4)
        self.code.setMarginWidth(1, 100)
        self.code.setMarginLineNumbers(1, True)
        self.code.setAutoIndent(True)
        self.font = QFont('Courier New', 18)
        self.code.setFont(self.font)
        self.code.setMinimumSize(1024, 768)
        self.locations = {}
        self.debug_mode = False
        self.setCentralWidget(self.code)
        self.pane_output = QDockWidget('Output', self)
        self.output = QTextEdit(self.pane_output)
        self.pane_memory = QDockWidget('Memory', self)
        self.memory_list = QListWidget(self.pane_memory)
        self.memory = [0] * 65536
        self.setup_menu()
        self.setup_panes()
        self.cfg = Config()
        self.directory = self.cfg.get('directory')
        self.filename = self.cfg.get('filename')
        if self.filename:
            self.open_file(self.filename)
        self.mega = Mega()
        self.update_memory_list()
        self.load_settings()

    def load_settings(self):
        geom = self.cfg.get('geometry')
        if not isinstance(geom, str):
            self.restoreGeometry(geom)
        state = self.cfg.get('state')
        if not isinstance(state, str):
            self.restoreState(state)

    def closeEvent(self, e: QCloseEvent) -> None:
        self.cfg.set('geometry', self.saveGeometry())
        self.cfg.set('state', self.saveState())

    def setup_panes(self):
        self.pane_output.setObjectName('Output')
        self.pane_output.setAllowedAreas(Qt.BottomDockWidgetArea)
        self.output.setTextInteractionFlags(Qt.TextSelectableByMouse)
        self.output.setFont(self.font)
        self.pane_output.setWidget(self.output)
        self.addDockWidget(Qt.BottomDockWidgetArea, self.pane_output)

        self.pane_memory.setObjectName('Memory')
        self.pane_memory.setAllowedAreas(Qt.LeftDockWidgetArea
                                         | Qt.RightDockWidgetArea)
        self.pane_memory.setWidget(self.memory_list)
        self.memory_list.setFont(self.font)
        self.addDockWidget(Qt.RightDockWidgetArea, self.pane_memory)

    def setup_menu(self):
        mb = self.menuBar()
        m = mb.addMenu('&File')

        dir_open = QAction('Open &Dir', m)
        dir_open.triggered.connect(self.on_dir_open)
        m.addAction(dir_open)

        file_open = QAction('&Open', m)
        file_open.triggered.connect(self.on_file_open)
        file_open.setShortcut('Ctrl+O')
        m.addAction(file_open)

        file_save = QAction('&Save', m)
        file_save.triggered.connect(self.on_file_save)
        file_save.setShortcut('Ctrl+S')
        m.addAction(file_save)

        m = mb.addMenu('&Build')
        assemble = QAction('&Assemble', m)
        assemble.triggered.connect(self.on_assemble)
        assemble.setShortcut('F7')
        m.addAction(assemble)

        program = QAction('&Program', m)
        program.triggered.connect(self.on_program)
        program.setShortcut('F9')
        m.addAction(program)

        m = mb.addMenu('&Debug')

        start = QAction('&Mode', m)
        start.triggered.connect(self.on_toggle_debug)
        start.setShortcut('F5')
        m.addAction(start)

        clock = QAction('&Clock', m)
        clock.triggered.connect(self.on_clock)
        clock.setShortcut('F11')
        m.addAction(clock)

        clock = QAction('&AutoClock', m)
        clock.triggered.connect(self.on_auto_clock)
        m.addAction(clock)

        ram = QAction('&RAM Update', m)
        ram.triggered.connect(self.on_update_memory)
        ram.setShortcut('F6')
        m.addAction(ram)

    def on_dir_open(self):
        res = QFileDialog.getExistingDirectory(caption='Select Directory',
                                               directory=self.directory)
        print(res)

    def open_file(self, filename):
        try:
            self.code.setText(open(filename).read())
            self.cfg.set('filename', filename)
        except IOError:
            QMessageBox.warning(self,
                                title='Error',
                                text=f'Cannot open {filename}')

    def on_file_open(self):
        res = QFileDialog.getOpenFileName(caption='Open', filter='*.asm')
        filename = res[0]
        if filename:
            self.open_file(filename)

    def on_file_save(self):
        if self.filename:
            code = self.code.text()
            with open(self.filename, 'w') as f:
                f.write(code)

    def set_output(self, text, default=''):
        if not text:
            text = default
        self.output.setText(text)

    def on_assemble(self):
        work_dir = os.path.dirname(self.filename)
        filename = os.path.basename(self.filename)
        try:
            res = subprocess.run(['zasm', filename, '0', '0'],
                                 capture_output=True,
                                 cwd=work_dir,
                                 check=True)
            self.set_output(res.stdout.decode('utf-8'), 'Done')
        except subprocess.CalledProcessError:
            self.set_output('Assembler failed')

    def on_program(self):
        bin_name = self.filename.replace('.asm', '.bin')
        try:
            data = open(bin_name, 'rb').read()
            self.mega.write_memory(0, data)
        except IOError:
            QMessageBox.warning(parent=self,
                                title='Error',
                                text='Failed to open binary')

    def on_toggle_debug(self):
        if self.debug_mode:
            self.on_stop_debug()
        else:
            self.on_start_debug()

    def on_stop_debug(self):
        self.debug_mode = False
        try:
            self.code.setText(open(self.filename).read())
            self.code.setReadOnly(False)
        except IOError:
            QMessageBox.warning(parent=self,
                                title="Error",
                                text=f'File "{self.filename}" not found')

    def on_start_debug(self):
        self.debug_mode = True
        lst_name = self.filename.replace('.asm', '.lst')
        try:
            listing = open(lst_name).read()
            self.code.setText(listing)
            self.code.setReadOnly(True)
            i = 0
            for line in listing.split('\n'):
                parts = line.split()
                if parts:
                    address = int(parts[0], 0)
                    self.addr2line[address] = i
                i += 1
        except IOError:
            QMessageBox.warning(parent=self,
                                title='Error',
                                text='No listing found.  Try assemble')

    def on_clock(self):
        count = 0
        print("------------------------------------------------------")
        while True:
            address, data, flags = self.mega.clock_read_bus()
            print(f'{address:04x}:{data:02x}  {flags:02x} {flag_text(flags)}')
            if (flags & 3) == 0:
                count += 1
                if count >= 2:
                    if address in self.addr2line:
                        y = self.addr2line.get(address)
                        self.code.setSelection(y, 0, y + 1, 0)
                    break

    def on_auto_clock(self):
        self.mega.auto_clock()

    def update_memory_list(self):
        self.memory_list.clear()
        for address in range(0, 8192, 16):
            line = f'{address:04x}'
            for i in range(16):
                line = line + f' {self.memory[address + i]:02x}'
            self.memory_list.addItem(QListWidgetItem(line))

    def update_memory(self, address: int, length: int):
        if address < 0 or (address + length) > len(self.memory):
            QMessageBox.warning(parent=self,
                                title='Error',
                                text='Invalid memory range')
            return
        data = self.mega.read_memory(address, length)
        self.memory[address:(address + length)] = data
        self.update_memory_list()

    def on_update_memory(self):
        self.update_memory(0, 8192)