manuskript/manuskript/ui/exporters/manuskript/plainTextSettings.py

422 lines
16 KiB
Python
Raw Normal View History

#!/usr/bin/env python
# --!-- coding: utf8 --!--
import json
import os
from PyQt5.QtCore import Qt, QSize
from PyQt5.QtGui import QIcon, QFontMetrics, QFont
from PyQt5.QtWidgets import QWidget, QTableWidgetItem, QListWidgetItem, QTreeView
from manuskript.functions import mainWindow, writablePath
from manuskript.ui.exporters.manuskript.plainTextSettings_ui import Ui_exporterSettings
2017-11-15 02:48:28 +13:00
from manuskript.ui import style as S
class exporterSettings(QWidget, Ui_exporterSettings):
def __init__(self, _format, parent=None):
QWidget.__init__(self, parent)
self.setupUi(self)
2017-11-15 02:48:28 +13:00
self.toolBox.setStyleSheet(S.toolBoxSS())
self.mw = mainWindow()
self._format = _format
self.settings = {}
#################################################################
# Content
self.grpContentFilters.button.setChecked(False)
h = self.tblContent.horizontalHeader()
h.setSectionResizeMode(h.ResizeToContents)
h.setSectionResizeMode(0, h.Stretch)
self.contentUpdateTable()
self.chkContentMore.toggled.connect(self.contentTableToggle)
self.contentTableToggle(False)
# Labels
self.lstContentLabels.clear()
h = QFontMetrics(self.font()).height()
for i in range(0, self.mw.mdlLabels.rowCount()):
item = self.mw.mdlLabels.item(i, 0)
if item:
item = QListWidgetItem(item.icon(), item.text())
item.setFlags(item.flags() | Qt.ItemIsUserCheckable)
item.setCheckState(Qt.Checked)
item.setSizeHint(QSize(100, h))
self.lstContentLabels.addItem(item)
self.chkContentLabels.toggled.connect(self.lstContentLabels.setVisible)
self.chkContentLabels.toggled.connect(lambda: self.listWidgetAdjustToContent(self.lstContentLabels))
self.lstContentLabels.setVisible(False)
# Status
self.lstContentStatus.clear()
h = QFontMetrics(self.font()).height()
for i in range(0, self.mw.mdlStatus.rowCount()):
item = self.mw.mdlStatus.item(i, 0)
if item:
item = QListWidgetItem(item.icon(), item.text())
item.setFlags(item.flags() | Qt.ItemIsUserCheckable)
item.setCheckState(Qt.Checked)
item.setSizeHint(QSize(100, h))
self.lstContentStatus.addItem(item)
self.chkContentStatus.toggled.connect(self.lstContentStatus.setVisible)
self.chkContentStatus.toggled.connect(lambda: self.listWidgetAdjustToContent(self.lstContentStatus))
self.lstContentStatus.setVisible(False)
# Root item
self.cmbContentParent.setModel(self.mw.mdlOutline)
v = QTreeView()
self.cmbContentParent.setView(v)
v.setHeaderHidden(True)
for i in range(1, self.mw.mdlOutline.columnCount()):
v.hideColumn(i)
self.chkContentParent.toggled.connect(self.cmbContentParent.setVisible)
self.cmbContentParent.hide()
#################################################################
# Separations
for cmb in [self.cmbSepFF, self.cmbSepTT, self.cmbSepFT, self.cmbSepTF]:
cmb.clear()
cmb.addItem(self.tr("Empty line"), "empty")
cmb.addItem(self.tr("Custom"), "custom")
cmb.currentIndexChanged.connect(self.sepCmbChanged)
#################################################################
# Transformations
h = self.tblReplacements.horizontalHeader()
h.setSectionResizeMode(h.ResizeToContents)
h.setSectionResizeMode(1, h.Stretch)
h.setSectionResizeMode(2, h.Stretch)
# Cf. https://en.wikipedia.org/wiki/Quotation_mark
self.cmbTransDoubleQuotes.clear()
self.cmbTransDoubleQuotes.addItems(["”___“", "“___”", "«___»"])
self.cmbTransSingleQuote.clear()
self.cmbTransSingleQuote.addItems(["___", "___"])
for cmb in [self.cmbTransDoubleQuotes, self.cmbTransSingleQuote]:
cmb.addItem(self.tr("Custom"), "custom")
cmb.currentIndexChanged.connect(self.transCmbChanged)
cmb.currentIndexChanged.emit(0)
2016-04-08 00:27:51 +12:00
self.btnTransAdd.clicked.connect(lambda: self.transAddTableRow(checked=True))
self.btnTransRemove.clicked.connect(self.transRemoveTableRow)
self.tableWidgetAdjustToContent(self.tblReplacements)
#################################################################
# Preview
self.cmbPreviewFont.setCurrentFont(self.font())
self.spnPreviewSize.setValue(self.font().pointSize())
#################################################################
# Final stuff
self.toolBox.setCurrentIndex(0)
###################################################################################################################
# SETTINGS
###################################################################################################################
def loadSettings(self):
filename = self.getSettingsPath()
if os.path.exists(filename):
with open(filename, "r", encoding="utf-8", newline="\n") as f:
self.settings = json.load(f)
self.updateFromSettings()
# Default values
else:
self.getSettings()
def writeSettings(self):
2016-04-15 23:45:53 +12:00
self.getSettings()
with open(self.getSettingsPath(), 'w', encoding="utf-8", newline="\n") as f:
# json.dumps(json.loads(json.dumps(allSettings)), indent=4, sort_keys=True)
json.dump(self.settings, f, indent=4, sort_keys=True)
def getSettingsPath(self):
return os.path.join(writablePath(), "exporter.ini")
def updateFromSettings(self):
settings = self.settings
# Content
s = settings["Content"]
self.chkContentMore.setChecked(s["More"])
if not s["More"]:
self.tblContent.item(0, 1).setCheckState(Qt.Checked if s["FolderTitle"] else Qt.Unchecked)
self.tblContent.item(1, 1).setCheckState(Qt.Checked if s["TextTitle"] else Qt.Unchecked)
self.tblContent.item(1, 2).setCheckState(Qt.Checked if s["TextText"] else Qt.Unchecked)
else:
nLevel = len(s["FolderTitle"])
for i in range(nLevel):
item = self.tblContent.item(i + 2, 1)
if item:
item.setCheckState(Qt.Checked if s["FolderTitle"][i] else Qt.Unchecked)
item = self.tblContent.item(i + 2 + nLevel, 1)
if item:
item.setCheckState(Qt.Checked if s["TextTitle"][i] else Qt.Unchecked)
item = self.tblContent.item(i + 2 + nLevel, 2)
if item:
item.setCheckState(Qt.Checked if s["TextText"][i] else Qt.Unchecked)
self.chkContentIgnoreCompile.setChecked(s["IgnoreCompile"])
self.chkContentParent.setChecked(s["Parent"])
self.chkContentLabels.setChecked(s["Labels"])
self.chkContentStatus.setChecked(s["Status"])
# FIXME: parent, labels, status
# Separations
s = settings["Separator"]
for val, cmb, txt in [
("FF", self.cmbSepFF, self.txtSepFF),
("TT", self.cmbSepTT, self.txtSepTT),
("FT", self.cmbSepFT, self.txtSepFT),
("TF", self.cmbSepTF, self.txtSepTF),
]:
if s[val] == "\n":
cmb.setCurrentIndex(0)
else:
cmb.setCurrentIndex(1)
txt.setText(self._format.escapes(s[val]))
# Transformations
s = settings["Transform"]
self.chkTransEllipse.setChecked(s["Ellipse"])
self.chkTransDash.setChecked(s["Dash"])
for val, chk, cmb, txtA, txtB in [
("DoubleQuotes", self.chkTransDoubleQuotes, self.cmbTransDoubleQuotes, self.txtTransDoubleQuotesA, self.txtTransDoubleQuotesB),
("SingleQuote", self.chkTransSingleQuote, self.cmbTransSingleQuote, self.txtTransSingleQuoteA, self.txtTransSingleQuoteB),
]:
chk.setChecked(s[val] != False)
if s[val]:
if cmb.findText(s[val]) != -1:
cmb.setCurrentText(s[val])
else:
cmb.setCurrentIndex(cmb.count() - 1)
txtA.setText(s[val].split("___")[0])
txtB.setText(s[val].split("___")[1])
self.chkTransSpaces.setChecked(s["Spaces"])
for i in s["Custom"]:
self.transAddTableRow(i[0], i[1], i[2], i[3])
# Preview
s = settings["Preview"]
f = QFont()
f.fromString(s["PreviewFont"])
self.cmbPreviewFont.setCurrentFont(f)
self.spnPreviewSize.setValue(f.pointSize())
def getSettings(self):
"""Updates settings from ui, and return."""
# Content
s = self.settings.get("Content", {})
s["More"] = self.chkContentMore.isChecked()
if not s["More"]:
s["FolderTitle"] = self.tblContent.item(0, 1).checkState() == Qt.Checked
s["TextTitle"] = self.tblContent.item(1, 1).checkState() == Qt.Checked
s["TextText"] = self.tblContent.item(1, 2).checkState() == Qt.Checked
else:
s["FolderTitle"] = []
s["TextTitle"] = []
s["TextText"] = []
nLevel = int((self.tblContent.rowCount() - 2) / 2)
for row in range(nLevel):
s["FolderTitle"].append(self.tblContent.item(2 + row, 1).checkState() == Qt.Checked)
s["TextTitle"].append(self.tblContent.item(2 + row + nLevel, 1).checkState() == Qt.Checked)
s["TextText"].append(self.tblContent.item(2 + row + nLevel, 2).checkState() == Qt.Checked)
s["IgnoreCompile"] = self.chkContentIgnoreCompile.isChecked()
s["Parent"] = self.chkContentParent.isChecked()
s["Labels"] = self.chkContentLabels.isChecked()
s["Status"] = self.chkContentStatus.isChecked()
self.settings["Content"] = s
# FIXME: parent, labels, status
# Separations
s = self.settings.get("Separator", {})
for val, cmb, txt in [
("FF", self.cmbSepFF, self.txtSepFF),
("TT", self.cmbSepTT, self.txtSepTT),
("FT", self.cmbSepFT, self.txtSepFT),
("TF", self.cmbSepTF, self.txtSepTF),
]:
if cmb.currentIndex() == 0:
s[val] = "\n"
else:
s[val] = self._format.descapes(txt.text())
self.settings["Separator"] = s
# Transformations
s = self.settings.get("Transform", {})
s["Ellipse"] = self.chkTransEllipse.isChecked()
s["Dash"] = self.chkTransDash.isChecked()
for val, chk, cmb, txtA, txtB in [
("DoubleQuotes", self.chkTransDoubleQuotes, self.cmbTransDoubleQuotes, self.txtTransDoubleQuotesA, self.txtTransDoubleQuotesB),
("SingleQuote", self.chkTransSingleQuote, self.cmbTransSingleQuote, self.txtTransSingleQuoteA, self.txtTransSingleQuoteB),
]:
if not chk.isChecked():
s[val] = False
else:
if cmb.currentData() == "custom":
s[val] = txtA.text() + "___" + txtB.text()
else:
s[val] = cmb.currentText()
s["Spaces"] = self.chkTransSpaces.isChecked()
s["Custom"] = []
for i in range(self.tblReplacements.rowCount()):
s["Custom"].append(self.getTableRowValues(self.tblReplacements, i))
self.settings["Transform"] = s
# Preview
s = self.settings.get("Preview", {})
f = self.cmbPreviewFont.currentFont()
f.setPointSize(self.spnPreviewSize.value())
s["PreviewFont"] = f.toString()
self.settings["Preview"] = s
return self.settings
def sepCmbChanged(self, index):
cmb = self.sender()
map = {
self.cmbSepFF: self.txtSepFF,
self.cmbSepTT: self.txtSepTT,
self.cmbSepFT: self.txtSepFT,
self.cmbSepTF: self.txtSepTF
}
map[cmb].setEnabled(cmb.currentData() == "custom")
def transCmbChanged(self, index):
cmb = self.sender()
map = {
self.cmbTransDoubleQuotes: (self.txtTransDoubleQuotesA, self.lblTransDoubleQuotes, self.txtTransDoubleQuotesB),
self.cmbTransSingleQuote: (self.txtTransSingleQuoteA, self.lblTransSingleQuote, self.txtTransSingleQuoteB),
}
for txt in map[cmb]:
txt.setVisible(cmb.currentData() == "custom")
def contentUpdateTable(self):
2016-04-08 00:27:51 +12:00
def addFolderRow(text=self.tr("Folder")):
self.tableWidgetAddRow(self.tblContent, [
self.tableWidgetMakeItem(text, "folder"),
self.tableWidgetMakeItem("", "", True, True),
])
2016-04-08 00:27:51 +12:00
def addTextRow(text=self.tr("Text")):
self.tableWidgetAddRow(self.tblContent, [
self.tableWidgetMakeItem(text, "text-x-generic"),
self.tableWidgetMakeItem("", "", True, False),
self.tableWidgetMakeItem("", "", True, True),
])
self.tblContent.setRowCount(0)
# Basic
addFolderRow()
addTextRow()
# Detailed
level = self.mw.mdlOutline.maxLevel()
for i in range(level):
2016-04-08 00:27:51 +12:00
addFolderRow(self.tr("{}Level {} folder").format(" " * i, i + 1))
for i in range(level):
2016-04-08 00:27:51 +12:00
addTextRow(self.tr("{}Level {} text").format(" " * i, i + 1))
self.tableWidgetAdjustToContent(self.tblContent)
def contentTableToggle(self, detailed):
for i in range(self.tblContent.rowCount()):
self.tblContent.setRowHidden(i, i in [0, 1] and detailed or (not i in [0, 1] and not detailed))
self.tableWidgetAdjustToContent(self.tblContent)
def getTableRowValues(self, table, row):
r = []
for col in range(table.columnCount()):
item = table.item(row, col)
if not item:
r.append(None)
elif item.flags() & Qt.ItemIsUserCheckable == Qt.ItemIsUserCheckable:
r.append(item.checkState() == Qt.Checked)
else:
r.append(item.text())
return r
def transAddTableRow(self, checked=True, A="", B="", regexp=False):
self.tableWidgetAddRow(self.tblReplacements, [
self.tableWidgetMakeItem("", "", True, checked),
self.tableWidgetMakeItem(A, "", False, False),
self.tableWidgetMakeItem(B, "", False, False),
self.tableWidgetMakeItem("", "", True, regexp),
])
self.tableWidgetAdjustToContent(self.tblReplacements)
def transRemoveTableRow(self):
self.tblReplacements.removeRow(self.tblReplacements.currentRow())
self.tableWidgetAdjustToContent(self.tblReplacements)
def tableWidgetMakeItem(self, text="", icon="", checkable=False, checked=False):
"""Creates a QTableWidgetItem with the given attributes."""
item = QTableWidgetItem(QIcon.fromTheme(icon), text)
if checkable:
item.setFlags(item.flags() | Qt.ItemIsUserCheckable)
item.setCheckState(Qt.Checked if checked else Qt.Unchecked)
else:
item.setFlags(item.flags() & ~Qt.ItemIsUserCheckable)
return item
def tableWidgetAddRow(self, table, items):
"""Appends the given items (list of QTableWidgetItems) to table."""
table.setRowCount(table.rowCount() + 1)
k = 0
for i in items:
table.setItem(table.rowCount() - 1, k, i)
k += 1
def tableWidgetAdjustToContent(self, table):
"""Set sizehint of QTableWidget table so that it matches content vertically."""
h = 0
h += table.horizontalHeader().height()
for i in range(table.rowCount()):
h += table.rowHeight(i)
table.setMinimumSize(QSize(0, h + 2))
table.setMaximumSize(QSize(16777215, h + 2))
def listWidgetAdjustToContent(self, lst):
"""Adjust listWidget to content."""
h = 0
for i in range(lst.count()):
h += lst.item(i).sizeHint().height()
lst.setMinimumSize(QSize(0, h+2))
lst.setMaximumSize(QSize(16777215, h+2))