Skip to content

Commit

Permalink
Added a Preferences dialog and some tikz settings to be changed along…
Browse files Browse the repository at this point in the history
…side it (although these are not currently used in the actual tikz export). This is more a proof of concept.
  • Loading branch information
jvdwetering committed Oct 17, 2023
1 parent 44cf15e commit 865634b
Show file tree
Hide file tree
Showing 2 changed files with 172 additions and 4 deletions.
12 changes: 8 additions & 4 deletions zxlive/mainwindow.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@
export_diagram_dialog, export_proof_dialog,
export_rule_dialog, get_lemma_name_and_description,
import_diagram_dialog, show_error_msg)
from zxlive.settings_dialog import open_settings_dialog

from .edit_panel import GraphEditPanel
from .proof_panel import ProofPanel
from .rule_panel import RulePanel
Expand All @@ -56,7 +58,7 @@ class MainWindow(QMainWindow):

def __init__(self) -> None:
super().__init__()
conf = QSettings("zxlive", "zxlive")
self.settings = QSettings("zxlive", "zxlive")

self.setWindowTitle("zxlive")

Expand All @@ -68,7 +70,7 @@ def __init__(self) -> None:
self.resize(1200, 800)

# restore the window from the last time it was opened
geom = conf.value("main_window_geometry")
geom = self.settings.value("main_window_geometry")
if geom and isinstance(geom, QByteArray):
self.restoreGeometry(geom)
self.show()
Expand Down Expand Up @@ -122,6 +124,7 @@ def __init__(self) -> None:
self.select_all_action = self._new_action("Select &All", self.select_all, QKeySequence.StandardKey.SelectAll, "Select all")
self.deselect_all_action = self._new_action("&Deselect All", self.deselect_all, QKeySequence.StandardKey.Deselect,
"Deselect all", alt_shortcut = QKeySequence("Ctrl+D"))
self.preferences_action = self._new_action("&Preferences...", open_settings_dialog, None, "Open the preferences dialog")

edit_menu = menu.addMenu("&Edit")
edit_menu.addAction(self.undo_action)
Expand All @@ -134,6 +137,8 @@ def __init__(self) -> None:
edit_menu.addSeparator()
edit_menu.addAction(self.select_all_action)
edit_menu.addAction(self.deselect_all_action)
edit_menu.addSeparator()
edit_menu.addAction(self.preferences_action)

self.zoom_in_action = self._new_action("Zoom in", self.zoom_in, QKeySequence.StandardKey.ZoomIn,"Zooms in by a fixed amount",
alt_shortcut = QKeySequence("Ctrl+="))
Expand Down Expand Up @@ -226,8 +231,7 @@ def closeEvent(self, e: QCloseEvent) -> None:
return

# save the shape/size of this window on close
conf = QSettings("zxlive", "zxlive")
conf.setValue("main_window_geometry", self.saveGeometry())
self.settings.setValue("main_window_geometry", self.saveGeometry())
e.accept()

def undo(self,e: QEvent) -> None:
Expand Down
164 changes: 164 additions & 0 deletions zxlive/settings_dialog.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
# zxlive - An interactive tool for the ZX calculus
# Copyright (C) 2023 - Aleks Kissinger
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at

# http://www.apache.org/licenses/LICENSE-2.0

# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

from __future__ import annotations

from typing import Optional,TYPE_CHECKING, Dict, Any

from PySide6.QtCore import QFile, QIODevice, QTextStream, QSettings
from PySide6.QtWidgets import (QDialog, QDialogButtonBox, QFileDialog,
QFormLayout, QLineEdit, QMessageBox,
QPushButton, QTextEdit, QWidget,
QVBoxLayout, QSpinBox, QDoubleSpinBox,
QLabel, QHBoxLayout)

import pyzx

if TYPE_CHECKING:
from .mainwindow import MainWindow

defaults: Dict[str,Any] = {
"tikz/Z-spider-export": "Z dot",
"tikz/Z-phase-export": "Z phase dot",
"tikz/X-spider-export": "X dot",
"tikz/X-phase-export": "X phase dot",
"tikz/Hadamard-export": "hadamard",
"tikz/boundary-export": "none",
"tikz/w-input-export": "W input",
"tikz/w-output-export": "W triangle",
"tikz/z-box-export": "Z box",

"tikz/Z-spider-import": ", ".join(pyzx.tikz.synonyms_z),
"tikz/X-spider-import": ", ".join(pyzx.tikz.synonyms_x),
"tikz/Hadamard-import": ", ".join(pyzx.tikz.synonyms_hadamard),
"tikz/boundary-import": ", ".join(pyzx.tikz.synonyms_boundary),
"tikz/w-input-import": ", ".join(pyzx.tikz.synonyms_w_input),
"tikz/w-output-import": ", ".join(pyzx.tikz.synonyms_w_output),
"tikz/z-box-import": ", ".join(pyzx.tikz.synonyms_z_box),

"tikz/edge-export": "",
"tikz/edge-H-export": "hadamard edge",
"tikz/edge-W-export": "W io edge",
"tikz/edge-import": ", ".join(pyzx.tikz.synonyms_edge),
"tikz/edge-H-import": ", ".join(pyzx.tikz.synonyms_hedge),
"tikz/edge-W-import": ", ".join(pyzx.tikz.synonyms_wedge),
}


class SettingsDialog(QDialog):
def __init__(self, parent: Optional[QWidget] = None) -> None:
super().__init__(parent)
self.setWindowTitle("Settings")
self.settings = QSettings("zxlive", "zxlive")
self.value_dict: Dict[str,QWidget] = {}

layout = QVBoxLayout()
self.setLayout(layout)
layout.setContentsMargins(0, 0, 0, 0)
layout.setSpacing(0)

layout.addWidget(QLabel("Tikz export settings"))
layout.addWidget(QLabel("These are the class names that will be used when exporting to tikz."))

form_export = QFormLayout()
w = QWidget()
w.setLayout(form_export)
layout.addWidget(w)

self.add_setting(form_export, "tikz/Z-spider-export", "Z-spider", 'str')
self.add_setting(form_export, "tikz/Z-phase-export", "Z-spider with phase", 'str')
self.add_setting(form_export, "tikz/X-spider-export", "X-spider", 'str')
self.add_setting(form_export, "tikz/X-phase-export", "X-spider with phase", 'str')
self.add_setting(form_export, "tikz/Hadamard-export", "Hadamard", 'str')
self.add_setting(form_export, "tikz/boundary-export", "Boundary", 'str')
self.add_setting(form_export, "tikz/edge-export", "Regular Edge", 'str')
self.add_setting(form_export, "tikz/edge-H-export", "Hadamard edge", 'str')

self.add_setting(form_export, "tikz/w-input-export", "W input", 'str')
self.add_setting(form_export, "tikz/w-output-export", "W output", 'str')
self.add_setting(form_export, "tikz/z-box-export", "Z box", 'str')
self.add_setting(form_export, "tikz/edge-W-export", "W io edge", 'str')

layout.addWidget(QLabel("Tikz import settings"))
layout.addWidget(QLabel("These are the class names that are understood when importing from tikz."))

form_import = QFormLayout()
w = QWidget()
w.setLayout(form_import)
layout.addWidget(w)

self.add_setting(form_import, "tikz/Z-spider-import", "Z-spider", 'str')
self.add_setting(form_import, "tikz/X-spider-import", "X-spider", 'str')
self.add_setting(form_import, "tikz/Hadamard-import", "Hadamard", 'str')
self.add_setting(form_import, "tikz/boundary-import", "Boundary", 'str')
self.add_setting(form_import, "tikz/edge-import", "Regular Edge", 'str')
self.add_setting(form_import, "tikz/edge-H-import", "Hadamard edge", 'str')

self.add_setting(form_import, "tikz/w-input-import", "W input", 'str')
self.add_setting(form_import, "tikz/w-output-import", "W output", 'str')
self.add_setting(form_import, "tikz/z-box-import", "Z box", 'str')
self.add_setting(form_import, "tikz/edge-W-import", "W io edge", 'str')

w= QWidget()
hlayout = QHBoxLayout()
hlayout.addStretch()
w.setLayout(hlayout)
layout.addWidget(w)
okay_button = QPushButton("Okay")
okay_button.clicked.connect(self.okay)
hlayout.addWidget(okay_button)
cancel_button = QPushButton("Cancel")
cancel_button.clicked.connect(self.cancel)
hlayout.addWidget(cancel_button)


def add_setting(self,form:QFormLayout, name:str, label:str, ty:str) -> None:
val = self.settings.value(name)
if val is None: val = defaults[name]
if ty == 'str':
widget = QLineEdit()
val = str(val)
widget.setText(val)
elif ty == 'int':
widget = QSpinBox()
val = int(val)
widget.setValue(val)
elif ty == 'float':
widget = QDoubleSpinBox()
val = float(int)
widget.setValue(val)

form.addRow(label, widget)
self.value_dict[name] = widget

def okay(self) -> None:
for name,widget in self.value_dict.items():
if isinstance(widget, QLineEdit):
self.settings.setValue(name, widget.text())
elif isinstance(widget, QSpinBox):
self.settings.setValue(name, widget.value())
elif isinstance(widget, QDoubleSpinBox):
self.settings.setValue(name, widget.value())
self.accept()

def cancel(self) -> None:
self.reject()




def open_settings_dialog():
dialog = SettingsDialog()
dialog.exec()

0 comments on commit 865634b

Please sign in to comment.