manuskript/manuskript/ui/welcome.py

401 lines
14 KiB
Python
Raw Normal View History

2015-06-24 04:22:39 +12:00
#!/usr/bin/env python
2016-02-07 00:34:22 +13:00
# --!-- coding: utf8 --!--
2015-06-24 04:22:39 +12:00
import locale
2015-06-25 20:01:28 +12:00
import imp
2016-02-07 00:34:22 +13:00
import os
from PyQt5.QtCore import QSettings, QRegExp, Qt
from PyQt5.QtGui import QIcon, QBrush, QColor, QStandardItemModel, QStandardItem
from PyQt5.QtWidgets import QWidget, QAction, QFileDialog, QSpinBox, QLineEdit, QLabel, QPushButton, QTreeWidgetItem
from manuskript import settings
from manuskript.enums import Outline
from manuskript.functions import mainWindow, iconFromColor
from manuskript.models.outlineModel import outlineItem
from manuskript.models.outlineModel import outlineModel
from manuskript.models.persosModel import persosModel
from manuskript.models.plotModel import plotModel
from manuskript.ui.welcome_ui import Ui_welcome
2015-06-25 20:01:28 +12:00
2015-06-24 04:22:39 +12:00
locale.setlocale(locale.LC_ALL, '')
class welcome(QWidget, Ui_welcome):
def __init__(self, parent=None):
QWidget.__init__(self, parent)
self.setupUi(self)
2016-02-07 00:34:22 +13:00
self.template = []
2016-02-07 00:34:22 +13:00
2015-06-24 04:22:39 +12:00
self.mw = mainWindow()
self.btnOpen.clicked.connect(self.openFile)
self.btnCreate.clicked.connect(self.createFile)
self.chkLoadLastProject.toggled.connect(self.setAutoLoad)
self.tree.itemActivated.connect(self.changeTemplate)
self.btnAddLevel.clicked.connect(self.templateAddLevel)
self.btnAddWC.clicked.connect(self.templateAddWordCount)
2016-02-07 00:34:22 +13:00
2015-06-24 04:22:39 +12:00
self.populateTemplates()
2016-02-07 00:34:22 +13:00
2015-06-24 04:22:39 +12:00
def updateValues(self):
# Auto load
autoLoad, last = self.getAutoLoadValues()
self.chkLoadLastProject.setChecked(autoLoad)
2016-02-07 00:34:22 +13:00
2015-06-24 04:22:39 +12:00
# Recent Files
self.loadRecents()
2016-02-07 00:34:22 +13:00
###############################################################################
# AUTOLOAD
###############################################################################
2015-06-24 04:22:39 +12:00
def showEvent(self, event):
"""Waiting for things to be fully loaded to start opening projects."""
QWidget.showEvent(self, event)
2016-02-07 00:34:22 +13:00
2015-06-24 04:22:39 +12:00
# Auto load last project
autoLoad, last = self.getAutoLoadValues()
2016-02-07 00:34:22 +13:00
2015-06-24 04:22:39 +12:00
if autoLoad and last:
self.mw.loadProject(last)
2016-02-07 00:34:22 +13:00
2015-06-24 04:22:39 +12:00
def getAutoLoadValues(self):
sttgns = QSettings()
if sttgns.contains("autoLoad"):
autoLoad = True if sttgns.value("autoLoad") == "true" else False
else:
autoLoad = False
if autoLoad and sttgns.contains("lastProject"):
last = sttgns.value("lastProject")
else:
last = ""
2016-02-07 00:34:22 +13:00
2015-06-24 04:22:39 +12:00
return autoLoad, last
2016-02-07 00:34:22 +13:00
2015-06-24 04:22:39 +12:00
def setAutoLoad(self, v):
QSettings().setValue("autoLoad", v)
2016-02-07 00:34:22 +13:00
###############################################################################
# RECENTS
###############################################################################
2015-06-24 04:22:39 +12:00
def loadRecents(self):
sttgns = QSettings()
2015-09-29 22:17:03 +13:00
self.mw.menuRecents.setIcon(QIcon.fromTheme("folder-recent"))
2015-06-24 04:22:39 +12:00
if sttgns.contains("recentFiles"):
lst = sttgns.value("recentFiles")
self.mw.menuRecents.clear()
for f in lst:
name = os.path.split(f)[1]
a = QAction(name, self)
a.setData(f)
a.setStatusTip(f)
a.triggered.connect(self.loadRecentFile)
self.mw.menuRecents.addAction(a)
2016-02-07 00:34:22 +13:00
2015-06-24 04:22:39 +12:00
self.btnRecent.setMenu(self.mw.menuRecents)
2016-02-07 00:34:22 +13:00
2015-06-24 04:22:39 +12:00
def appendToRecentFiles(self, project):
sttgns = QSettings()
if sttgns.contains("recentFiles"):
recentFiles = sttgns.value("recentFiles")
else:
recentFiles = []
2016-02-07 00:34:22 +13:00
2015-06-24 04:22:39 +12:00
while project in recentFiles:
recentFiles.remove(project)
recentFiles.insert(0, project)
recentFiles = recentFiles[:10]
sttgns.setValue("recentFiles", recentFiles)
def loadRecentFile(self):
act = self.sender()
self.appendToRecentFiles(act.data())
self.mw.loadProject(act.data())
2016-02-07 00:34:22 +13:00
###############################################################################
# DIALOGS
###############################################################################
2015-06-24 04:22:39 +12:00
def openFile(self):
"""File dialog that request an existing file. For opening project."""
2016-02-07 00:34:22 +13:00
filename = QFileDialog.getOpenFileName(self,
self.tr("Open project"),
".",
self.tr("Manuskript project (*.msk)"))[0]
2015-06-24 04:22:39 +12:00
if filename:
self.appendToRecentFiles(filename)
self.mw.loadProject(filename)
2016-02-07 00:34:22 +13:00
2015-06-24 04:22:39 +12:00
def saveAsFile(self):
"""File dialog that request a file, existing or not.
Save datas to that file, which then becomes the current project."""
2016-02-07 00:34:22 +13:00
filename = QFileDialog.getSaveFileName(self,
self.tr("Save project as..."),
".",
self.tr("Manuskript project (*.msk)"))[0]
2015-06-24 04:22:39 +12:00
if filename:
self.appendToRecentFiles(filename)
self.mw.saveDatas(filename)
2016-02-07 00:34:22 +13:00
2015-06-24 04:22:39 +12:00
def createFile(self):
"""When starting a new project, ask for a place to save it.
Datas are not loaded from file, so they must be populated another way."""
2016-02-07 00:34:22 +13:00
filename = QFileDialog.getSaveFileName(self,
self.tr("Create New Project"),
".",
self.tr("Manuskript project (*.msk)"))[0]
2015-06-24 04:22:39 +12:00
if filename:
self.appendToRecentFiles(filename)
self.loadDefaultDatas()
self.mw.loadProject(filename, loadFromFile=False)
2016-02-07 00:34:22 +13:00
###############################################################################
# TEMPLATES
###############################################################################
2015-06-24 04:22:39 +12:00
def templates(self):
return [
(self.tr("Empty"), []),
(self.tr("Novel"), [
2016-02-07 00:34:22 +13:00
(20, self.tr("Chapter")),
(5, self.tr("Scene")),
(500, None) # A line with None is word count
]),
2015-06-24 04:22:39 +12:00
(self.tr("Novella"), [
2016-02-07 00:34:22 +13:00
(10, self.tr("Chapter")),
(5, self.tr("Scene")),
(500, None)
]),
2015-06-24 04:22:39 +12:00
(self.tr("Short Story"), [
2016-02-07 00:34:22 +13:00
(10, self.tr("Scene")),
2015-06-24 04:22:39 +12:00
(1000, None)
2016-02-07 00:34:22 +13:00
]),
2015-06-24 04:22:39 +12:00
(self.tr("Trilogy"), [
2016-02-07 00:34:22 +13:00
(3, self.tr("Book")),
(3, self.tr("Section")),
(10, self.tr("Chapter")),
(5, self.tr("Scene")),
(500, None)
]),
2015-06-24 04:22:39 +12:00
(self.tr("Research paper"), [
2016-02-07 00:34:22 +13:00
(3, self.tr("Section")),
2015-06-24 04:22:39 +12:00
(1000, None)
2016-02-07 00:34:22 +13:00
])
]
def defaultTextType(self):
return [
("t2t", self.tr("Txt2Tags"), "text-x-generic"),
("html", self.tr("Rich Text (html)"), "text-html"),
("txt", self.tr("Plain Text"), "text-x-generic"),
2016-02-07 00:34:22 +13:00
]
2015-06-24 04:22:39 +12:00
def changeTemplate(self, item, column):
2015-06-24 09:59:56 +12:00
template = [i for i in self.templates() if i[0] == item.text(0)]
if len(template):
self.template = template[0][1]
self.updateTemplate()
2016-02-07 00:34:22 +13:00
2015-06-24 04:22:39 +12:00
def updateTemplate(self):
# Clear layout
def clearLayout(l):
while l.count() != 0:
i = l.takeAt(0)
if i.widget():
i.widget().deleteLater()
if i.layout():
clearLayout(i.layout())
2016-02-07 00:34:22 +13:00
2015-06-24 04:22:39 +12:00
clearLayout(self.lytTemplate)
2016-02-07 00:34:22 +13:00
# self.templateLayout.addStretch()
# l = QGridLayout()
# self.templateLayout.addLayout(l)
2015-06-24 04:22:39 +12:00
k = 0
hasWC = False
for d in self.template:
spin = QSpinBox(self)
spin.setRange(0, 999999)
spin.setValue(d[0])
spin.valueChanged.connect(self.updateWordCount)
2016-02-07 00:34:22 +13:00
2015-06-24 04:22:39 +12:00
if d[1] != None:
txt = QLineEdit(self)
txt.setText(d[1])
2016-02-07 00:34:22 +13:00
2015-06-24 04:22:39 +12:00
else:
hasWC = True
txt = QLabel(self.tr("words each."), self)
2016-02-07 00:34:22 +13:00
2015-06-24 04:22:39 +12:00
if k != 0:
of = QLabel(self.tr("of"), self)
self.lytTemplate.addWidget(of, k, 0)
2016-02-07 00:34:22 +13:00
2015-06-24 04:22:39 +12:00
btn = QPushButton("", self)
btn.setIcon(QIcon.fromTheme("edit-delete"))
btn.setProperty("deleteRow", k)
btn.clicked.connect(self.deleteTemplateRow)
2016-02-07 00:34:22 +13:00
2015-06-24 04:22:39 +12:00
self.lytTemplate.addWidget(btn, k, 3)
2016-02-07 00:34:22 +13:00
2015-06-24 04:22:39 +12:00
self.lytTemplate.addWidget(spin, k, 1)
self.lytTemplate.addWidget(txt, k, 2)
k += 1
2016-02-07 00:34:22 +13:00
2015-06-24 04:22:39 +12:00
self.btnAddWC.setEnabled(not hasWC and len(self.template) > 0)
self.btnAddLevel.setEnabled(True)
self.lblTotal.setVisible(hasWC)
self.updateWordCount()
2016-02-07 00:34:22 +13:00
2015-06-24 04:22:39 +12:00
def templateAddLevel(self):
if len(self.template) > 0 and \
2016-02-07 00:34:22 +13:00
self.template[len(self.template) - 1][1] == None:
2015-06-24 04:22:39 +12:00
# has word cound, so insert before
self.template.insert(len(self.template) - 1, (10, self.tr("Text")))
else:
# No word count, so insert at end
self.template.append((10, self.tr("Something")))
self.updateTemplate()
2016-02-07 00:34:22 +13:00
2015-06-24 04:22:39 +12:00
def templateAddWordCount(self):
self.template.append((500, None))
self.updateTemplate()
2016-02-07 00:34:22 +13:00
2015-06-24 04:22:39 +12:00
def deleteTemplateRow(self):
btn = self.sender()
row = btn.property("deleteRow")
self.template.pop(row)
self.updateTemplate()
2016-02-07 00:34:22 +13:00
2015-06-24 04:22:39 +12:00
def updateWordCount(self):
total = 1
for s in self.findChildren(QSpinBox, QRegExp(".*"),
Qt.FindChildrenRecursively):
total = total * s.value()
2016-02-07 00:34:22 +13:00
if total == 1:
2015-06-24 04:22:39 +12:00
total = 0
2016-02-07 00:34:22 +13:00
2015-06-24 04:22:39 +12:00
self.lblTotal.setText(self.tr("<b>Total:</b> {} words (~ {} pages)").format(
2016-02-07 00:34:22 +13:00
locale.format("%d", total, grouping=True),
locale.format("%d", total / 250, grouping=True)
2015-06-24 04:22:39 +12:00
))
2016-02-07 00:34:22 +13:00
2015-06-24 04:22:39 +12:00
def addTopLevelItem(self, name):
item = QTreeWidgetItem(self.tree, [name])
item.setBackground(0, QBrush(QColor(Qt.blue).lighter(190)))
item.setForeground(0, QBrush(Qt.darkBlue))
item.setTextAlignment(0, Qt.AlignCenter)
item.setFlags(Qt.ItemIsEnabled)
f = item.font(0)
f.setBold(True)
item.setFont(0, f)
return item
2016-02-07 00:34:22 +13:00
2015-06-24 04:22:39 +12:00
def populateTemplates(self):
self.tree.clear()
self.tree.setIndentation(0)
2016-02-07 00:34:22 +13:00
2015-06-24 04:22:39 +12:00
# Add templates
item = self.addTopLevelItem(self.tr("Templates"))
templates = self.templates()
for t in templates:
sub = QTreeWidgetItem(item, [t[0]])
2016-02-07 00:34:22 +13:00
2015-06-24 04:22:39 +12:00
# Add Demo project
item = self.addTopLevelItem(self.tr("Demo projects"))
# FIXME: none yet
2016-02-07 00:34:22 +13:00
# Populates default text type
self.cmbDefaultType.clear()
for t in self.defaultTextType():
self.cmbDefaultType.addItem(QIcon.fromTheme(t[2]), t[1], t[0])
2016-02-07 00:34:22 +13:00
2015-06-24 04:22:39 +12:00
self.tree.expandAll()
2016-02-07 00:34:22 +13:00
2015-06-24 04:22:39 +12:00
def loadDefaultDatas(self):
2016-02-07 00:34:22 +13:00
2015-06-25 20:01:28 +12:00
# Empty settings
imp.reload(settings)
2016-02-07 00:34:22 +13:00
2015-06-24 04:22:39 +12:00
# Données
self.mw.mdlFlatData = QStandardItemModel(2, 8, self.mw)
2015-06-24 04:22:39 +12:00
# Persos
2016-02-07 00:34:22 +13:00
# self.mw.mdlPersos = QStandardItemModel(0, 0, self.mw)
2015-06-29 09:46:51 +12:00
self.mw.mdlPersos = persosModel(self.mw)
2016-02-07 00:34:22 +13:00
# self.mdlPersosProxy = None # persosProxyModel() # None
# self.mw.mdlPersosProxy = persosProxyModel(self.mw)
2015-06-24 04:22:39 +12:00
2016-02-07 00:34:22 +13:00
# self.mw.mdlPersosInfos = QStandardItemModel(1, 0, self.mw)
# self.mw.mdlPersosInfos.insertColumn(0, [QStandardItem("ID")])
# self.mw.mdlPersosInfos.setHorizontalHeaderLabels(["Description"])
2015-06-24 04:22:39 +12:00
# Labels
self.mw.mdlLabels = QStandardItemModel(self.mw)
2015-06-24 04:22:39 +12:00
for color, text in [
(Qt.transparent, ""),
(Qt.yellow, self.tr("Idea")),
(Qt.green, self.tr("Note")),
(Qt.blue, self.tr("Chapter")),
(Qt.red, self.tr("Scene")),
(Qt.cyan, self.tr("Research"))
2016-02-07 00:34:22 +13:00
]:
2015-06-24 04:22:39 +12:00
self.mw.mdlLabels.appendRow(QStandardItem(iconFromColor(color), text))
# Status
self.mw.mdlStatus = QStandardItemModel(self.mw)
2015-06-24 04:22:39 +12:00
for text in [
2016-02-07 00:34:22 +13:00
"",
self.tr("TODO"),
self.tr("First draft"),
self.tr("Second draft"),
self.tr("Final")
]:
2015-06-24 04:22:39 +12:00
self.mw.mdlStatus.appendRow(QStandardItem(text))
# Plot
self.mw.mdlPlots = plotModel(self.mw)
2015-06-24 04:22:39 +12:00
# Outline
self.mw.mdlOutline = outlineModel(self.mw)
2016-02-07 00:34:22 +13:00
2015-06-24 04:22:39 +12:00
root = self.mw.mdlOutline.rootItem
_type = self.cmbDefaultType.currentData()
2015-06-25 20:01:28 +12:00
settings.defaultTextType = _type
2016-02-07 00:34:22 +13:00
2015-06-24 04:22:39 +12:00
def addElement(parent, datas):
if len(datas) == 2 and datas[1][1] == None or \
2016-02-07 00:34:22 +13:00
len(datas) == 1:
2015-06-24 04:22:39 +12:00
# Next item is word count
n = 0
2016-02-07 00:34:22 +13:00
for i in range(datas[0][0]):
2015-06-24 04:22:39 +12:00
n += 1
item = outlineItem(title="{} {}".format(
2016-02-07 00:34:22 +13:00
datas[0][1],
str(n)),
_type=_type,
parent=parent)
2015-06-24 04:22:39 +12:00
if len(datas) == 2:
item.setData(Outline.setGoal.value, datas[1][0])
2016-02-07 00:34:22 +13:00
# parent.appendChild(item)
2015-06-24 04:22:39 +12:00
else:
n = 0
for i in range(datas[0][0]):
n += 1
item = outlineItem(title="{} {}".format(
2016-02-07 00:34:22 +13:00
datas[0][1],
str(n)),
_type="folder",
parent=parent)
# parent.appendChild(item)
2015-06-24 04:22:39 +12:00
addElement(item, datas[1:])
2016-02-07 00:34:22 +13:00
if self.template:
addElement(root, self.template)