1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152
|
#!/usr/bin/env python3
from xasyqtui.labelTextEditor import Ui_Dialog
import PySide6.QtWidgets as QtWidgets
import PySide6.QtSvg as QtSvg
import PySide6.QtGui as QtGui
import PySide6.QtCore as QtCore
import xasyArgs as xasyArgs
import xasyOptions as xasyOptions
import xasyUtils as xasyUtils
import subprocess
import tempfile
import uuid
import os
class labelEditor(QtWidgets.QDialog):
def __init__(self, text=''):
super().__init__()
self.ui = Ui_Dialog()
self.ui.setupUi(self)
self.ui.btnAccept.clicked.connect(self.accept)
self.ui.btnCancel.clicked.connect(self.reject)
self.ui.chkMathMode.stateChanged.connect(self.chkMathModeChecked)
self.ui.btnPreview.clicked.connect(self.btnPreviewOnClick)
self.ui.btnGetText.clicked.connect(self.btnGetTextOnClick)
self.svgPreview = None
self.initializeText(text)
def initializeText(self, text: str):
if text[0] == '$' and text[-1] == '$':
self.ui.chkMathMode.setChecked(True)
text = text.strip('$')
if text.startswith('\\displaystyle{'):
self.ui.cmbMathStyle.setCurrentText('Display Style')
text = text.rstrip('}')
text = text.replace('\\displaystyle{', '', 1)
elif text.startswith('\\scriptstyle{'):
self.ui.cmbMathStyle.setCurrentText('Script Style')
text = text.rstrip('}')
text = text.replace('\\scriptstyle{', '', 1)
self.ui.txtLabelEdit.setPlainText(text)
def chkMathModeChecked(self, checked):
self.ui.cmbMathStyle.setEnabled(checked)
def getText(self):
rawText = self.ui.txtLabelEdit.toPlainText()
rawText.replace('\n', ' ')
if self.ui.chkMathMode.isChecked():
prefix = ''
suffix = ''
if self.ui.cmbMathStyle.currentText() == 'Display Style':
prefix = '\\displaystyle{'
suffix = '}'
elif self.ui.cmbMathStyle.currentText() == 'Script Style':
prefix = '\\scriptstyle{'
suffix = '}'
return '${0}{1}{2}$'.format(prefix, rawText, suffix)
else:
return rawText
def btnPreviewOnClick(self):
path = xasyArgs.getArgs().asypath
if path is None:
opt = xasyOptions.BasicConfigs.defaultOpt
path = opt['asyPath']
asyInput = """
frame f;
label(f, "{0}");
write(min(f), newl);
write(max(f), newl);
shipout(f);
"""
self.svgPreview = QtSvg.QSvgRenderer()
with tempfile.TemporaryDirectory(prefix='xasylbl_') as tmpdir:
random_id = str(uuid.uuid4())
tmpFile = os.path.join(tmpdir, 'lbl-{0}.svg'.format(random_id))
with subprocess.Popen(args=[path, '-fsvg', '-o', tmpFile, '-'], encoding='utf-8', stdin=subprocess.PIPE,
stdout=subprocess.PIPE) as asy:
asy.stdin.write(asyInput.format(self.getText()))
asy.stdin.close()
out = asy.stdout.read()
raw_array = out.splitlines()
bounds_1, bounds_2 = [val.strip() for val in raw_array]
min_bounds = xasyUtils.listize(bounds_1, (float, float))
max_bounds = xasyUtils.listize(bounds_2, (float, float))
new_rect = self.processBounds(min_bounds, max_bounds)
self.svgPreview.load(tmpFile)
self.drawPreview(new_rect)
def drawPreview(self, naturalBounds):
img = QtGui.QPixmap(self.ui.lblLabelPreview.size())
img.fill(QtGui.QColor.fromRgbF(1, 1, 1, 1))
if self.svgPreview is None:
pass
else:
with QtGui.QPainter(img) as pnt:
scale_ratio = self.getIdealScaleRatio(naturalBounds, self.ui.lblLabelPreview.rect())
pnt.translate(self.ui.lblLabelPreview.rect().center())
pnt.scale(scale_ratio, scale_ratio)
self.svgPreview.render(pnt, naturalBounds)
self.ui.lblLabelPreview.setPixmap(img)
def getIdealScaleRatio(self, rect, boundsRect):
assert isinstance(rect, (QtCore.QRect, QtCore.QRectF))
assert isinstance(rect, (QtCore.QRect, QtCore.QRectF))
magic_ratio = 0.50
idealRatioHeight = (magic_ratio * boundsRect.height()) / rect.height()
magicRatioWidth = 0.50
if idealRatioHeight * rect.width() > magicRatioWidth * boundsRect.width():
idealRatioWidth = (magicRatioWidth * boundsRect.width()) / rect.width()
idealRatio = min(idealRatioHeight, idealRatioWidth)
else:
idealRatio = idealRatioHeight
return idealRatio
def processBounds(self, minPt, maxPt):
p1x, p1y = minPt
p2x, p2y = maxPt
minPt = QtCore.QPointF(p1x, p1y)
maxPt = QtCore.QPointF(p2x, p2y)
newRect = QtCore.QRectF(minPt, maxPt)
return newRect
def btnGetTextOnClick(self):
msgbox = QtWidgets.QMessageBox()
msgbox.setText('Text Preview:\n' + self.getText())
msgbox.setWindowTitle('Text preview')
msgbox.show()
return msgbox.exec_()
|