Issue 459 - session progress/goal window

This commit is contained in:
nephlm 2019-01-22 00:37:22 -05:00
parent 4ff84d328d
commit 4f2d57e86f
6 changed files with 472 additions and 6 deletions

View file

@ -27,6 +27,7 @@ from manuskript.ui.exporters.exporter import exporterDialog
from manuskript.ui.helpLabel import helpLabel
from manuskript.ui.mainWindow import Ui_MainWindow
from manuskript.ui.tools.frequencyAnalyzer import frequencyAnalyzer
from manuskript.ui.tools.targets import targetsDialog
from manuskript.ui.views.outlineDelegates import outlineCharacterDelegate
from manuskript.ui.views.plotDelegate import plotDelegate
from manuskript.ui.views.MDEditView import MDEditView
@ -67,6 +68,7 @@ class MainWindow(QMainWindow, Ui_MainWindow):
self._defaultCursorFlashTime = 1000 # Overriden at startup with system
# value. In manuskript.main.
self._autoLoadProject = None # Used to load a command line project
self.sessionStartWordCount = 0 # Used to track session targets
self.readSettings()
@ -177,10 +179,15 @@ class MainWindow(QMainWindow, Ui_MainWindow):
# Main Menu:: Tool
self.actToolFrequency.triggered.connect(self.frequencyAnalyzer)
self.actToolTargets.triggered.connect(self.sessionTargets)
self.actAbout.triggered.connect(self.about)
self.makeUIConnections()
# Tools non-modal windows
self.td = None # Targets Dialog
self.fw = None # Frequency Window
# self.loadProject(os.path.join(appPath(), "test_project.zip"))
def updateDockVisibility(self, restore=False):
@ -635,6 +642,10 @@ class MainWindow(QMainWindow, Ui_MainWindow):
self.currentProject = project
QSettings().setValue("lastProject", project)
item = self.mdlOutline.rootItem
wc = item.data(Outline.wordCount)
self.sessionStartWordCount = wc
# Show main Window
self.switchToProject()
@ -747,6 +758,12 @@ class MainWindow(QMainWindow, Ui_MainWindow):
# closeEvent
# QMainWindow.closeEvent(self, event) # Causing segfaults?
# Close non-modal windows if they are open.
if self.td:
self.td.close()
if self.fw:
self.fw.close()
def startTimerNoChanges(self):
if settings.autoSaveNoChanges:
self.saveTimerNoChanges.start()
@ -1341,6 +1358,10 @@ class MainWindow(QMainWindow, Ui_MainWindow):
self.fw = frequencyAnalyzer(self)
self.fw.show()
def sessionTargets(self):
self.td = targetsDialog(self)
self.td.show()
###############################################################################
# VIEW MENU
###############################################################################

View file

@ -2,7 +2,7 @@
# Form implementation generated from reading ui file 'manuskript/ui/mainWindow.ui'
#
# Created by: PyQt5 UI code generator 5.5.1
# Created by: PyQt5 UI code generator 5.11.3
#
# WARNING! All changes made in this file will be lost!
@ -378,7 +378,7 @@ class Ui_MainWindow(object):
self.scrollAreaPersoInfos.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignTop)
self.scrollAreaPersoInfos.setObjectName("scrollAreaPersoInfos")
self.scrollAreaPersoInfosWidget = QtWidgets.QWidget()
self.scrollAreaPersoInfosWidget.setGeometry(QtCore.QRect(0, 0, 204, 606))
self.scrollAreaPersoInfosWidget.setGeometry(QtCore.QRect(0, 0, 252, 664))
self.scrollAreaPersoInfosWidget.setObjectName("scrollAreaPersoInfosWidget")
self.formLayout_8 = QtWidgets.QFormLayout(self.scrollAreaPersoInfosWidget)
self.formLayout_8.setFieldGrowthPolicy(QtWidgets.QFormLayout.AllNonFixedFieldsGrow)
@ -833,6 +833,7 @@ class Ui_MainWindow(object):
self.layoutWidget = QtWidgets.QWidget(self.splitterOutlineH)
self.layoutWidget.setObjectName("layoutWidget")
self.verticalLayout_14 = QtWidgets.QVBoxLayout(self.layoutWidget)
self.verticalLayout_14.setContentsMargins(0, 0, 0, 0)
self.verticalLayout_14.setObjectName("verticalLayout_14")
self.splitterOutlineV = QtWidgets.QSplitter(self.layoutWidget)
self.splitterOutlineV.setOrientation(QtCore.Qt.Vertical)
@ -1029,7 +1030,7 @@ class Ui_MainWindow(object):
self.horizontalLayout_2.addWidget(self.stack)
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 1112, 30))
self.menubar.setGeometry(QtCore.QRect(0, 0, 1112, 25))
self.menubar.setObjectName("menubar")
self.menuFile = QtWidgets.QMenu(self.menubar)
self.menuFile.setObjectName("menuFile")
@ -1270,6 +1271,8 @@ class Ui_MainWindow(object):
self.actFormatList.setObjectName("actFormatList")
self.actFormatBlockquote = QtWidgets.QAction(MainWindow)
self.actFormatBlockquote.setObjectName("actFormatBlockquote")
self.actToolTargets = QtWidgets.QAction(MainWindow)
self.actToolTargets.setObjectName("actToolTargets")
self.menuFile.addAction(self.actOpen)
self.menuFile.addAction(self.menuRecents.menuAction())
self.menuFile.addAction(self.actSave)
@ -1284,6 +1287,7 @@ class Ui_MainWindow(object):
self.menuHelp.addAction(self.actAbout)
self.menuTools.addAction(self.actSpellcheck)
self.menuTools.addAction(self.actToolFrequency)
self.menuTools.addAction(self.actToolTargets)
self.mnuHeader.addAction(self.actHeaderSetextL1)
self.mnuHeader.addAction(self.actHeaderSetextL2)
self.mnuHeader.addSeparator()
@ -1539,6 +1543,9 @@ class Ui_MainWindow(object):
self.actFormatOrderedList.setText(_translate("MainWindow", "&Ordered list"))
self.actFormatList.setText(_translate("MainWindow", "&Unordered list"))
self.actFormatBlockquote.setText(_translate("MainWindow", "B&lockquote"))
self.actToolTargets.setText(_translate("MainWindow", "&Targets"))
self.actToolTargets.setToolTip(_translate("MainWindow", "Draft and session word count targets"))
self.actToolTargets.setShortcut(_translate("MainWindow", "Ctrl+,"))
from manuskript.ui.cheatSheet import cheatSheet
from manuskript.ui.editors.mainEditor import mainEditor
@ -1554,3 +1561,13 @@ from manuskript.ui.views.sldImportance import sldImportance
from manuskript.ui.views.storylineView import storylineView
from manuskript.ui.views.treeView import treeView
from manuskript.ui.welcome import welcome
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
MainWindow = QtWidgets.QMainWindow()
ui = Ui_MainWindow()
ui.setupUi(MainWindow)
MainWindow.show()
sys.exit(app.exec_())

View file

@ -815,8 +815,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>204</width>
<height>606</height>
<width>252</width>
<height>664</height>
</rect>
</property>
<layout class="QFormLayout" name="formLayout_8">
@ -2095,7 +2095,7 @@
<x>0</x>
<y>0</y>
<width>1112</width>
<height>30</height>
<height>25</height>
</rect>
</property>
<widget class="QMenu" name="menuFile">
@ -2135,6 +2135,7 @@
</property>
<addaction name="actSpellcheck"/>
<addaction name="actToolFrequency"/>
<addaction name="actToolTargets"/>
</widget>
<widget class="QMenu" name="menuEdit">
<property name="title">
@ -2818,6 +2819,17 @@
<string>B&amp;lockquote</string>
</property>
</action>
<action name="actToolTargets">
<property name="text">
<string>&amp;Targets</string>
</property>
<property name="toolTip">
<string>Draft and session word count targets</string>
</property>
<property name="shortcut">
<string>Ctrl+,</string>
</property>
</action>
</widget>
<customwidgets>
<customwidget>

View file

@ -0,0 +1,66 @@
import locale
from PyQt5.QtGui import QIcon, QPixmap
from PyQt5.QtWidgets import QWidget
from PyQt5.QtCore import QTimer
from manuskript.enums import Outline
from manuskript.functions import appPath
from manuskript.ui.tools.targets_ui import Ui_targets
class targetsDialog(QWidget, Ui_targets):
def __init__(self, parent=None, mw=None):
QWidget.__init__(self)
self.mw = parent
self.setupUi(self)
iconPic = appPath("icons/Manuskript/icon-64px.png")
self.setWindowIcon(QIcon(iconPic))
self.session_reset.clicked.connect(self.resetSession)
#self.mw.onClose.connect(self.parentClosed)
self.tick()
self.timer = QTimer()
self.timer.timeout.connect(self.tick)
self.timer.start(2000)
def getDraftStats(self):
item = self.mw.mdlOutline.rootItem
wc = item.data(Outline.wordCount)
goal = item.data(Outline.goal)
progress = item.data(Outline.goalPercentage)
return (wc, goal, progress)
def resetSession(self):
wc, _, _ = self.getDraftStats()
self.mw.sessionStartWordCount = wc
print('reset session')
self.tick()
@staticmethod
def progress_bar_value(value):
return min(max(float(value) * 100, 0), 100)
def tick(self):
wc, goal, progress = self.getDraftStats()
print(wc, goal, progress)
self.draft_wc_label.setText(locale.format("%d", wc, grouping=True))
self.draft_goal_label.setText(locale.format("%d", goal, grouping=True))
# limit to 0-100 for display
self.draft_progress_bar.setValue(self.progress_bar_value(progress))
session_wc = wc - self.mw.sessionStartWordCount
self.session_wc_label.setText(locale.format("%d", session_wc, grouping=True))
if self.session_target.value() == 0:
self.session_progress_bar.setValue(0)
else:
self.session_progress_bar.setValue(self.progress_bar_value(session_wc / self.session_target.value()))
print(self.mw.sessionStartWordCount, session_wc, self.session_progress_bar.value())
def closeEvent(self, event):
self.timer = None
def parentClosed(self):
print('App closed')

View file

@ -0,0 +1,149 @@
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'manuskript/ui/tools/targets_ui.ui'
#
# Created by: PyQt5 UI code generator 5.11.3
#
# WARNING! All changes made in this file will be lost!
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_targets(object):
def setupUi(self, targets):
targets.setObjectName("targets")
targets.resize(322, 216)
icon = QtGui.QIcon()
icon.addPixmap(QtGui.QPixmap("../../../../../../../../../../home/icons/Manuskript/icon-64px.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
targets.setWindowIcon(icon)
self.verticalLayout_2 = QtWidgets.QVBoxLayout(targets)
self.verticalLayout_2.setObjectName("verticalLayout_2")
self.verticalLayout = QtWidgets.QVBoxLayout()
self.verticalLayout.setObjectName("verticalLayout")
self.horizontalLayout = QtWidgets.QHBoxLayout()
self.horizontalLayout.setObjectName("horizontalLayout")
self.label = QtWidgets.QLabel(targets)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Minimum)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.label.sizePolicy().hasHeightForWidth())
self.label.setSizePolicy(sizePolicy)
self.label.setObjectName("label")
self.horizontalLayout.addWidget(self.label)
self.line = QtWidgets.QFrame(targets)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Maximum)
sizePolicy.setHorizontalStretch(1)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.line.sizePolicy().hasHeightForWidth())
self.line.setSizePolicy(sizePolicy)
self.line.setFrameShape(QtWidgets.QFrame.HLine)
self.line.setFrameShadow(QtWidgets.QFrame.Sunken)
self.line.setObjectName("line")
self.horizontalLayout.addWidget(self.line)
self.verticalLayout.addLayout(self.horizontalLayout)
self.verticalLayout_2.addLayout(self.verticalLayout)
self.draft_progress_bar = QtWidgets.QProgressBar(targets)
self.draft_progress_bar.setProperty("value", 0)
self.draft_progress_bar.setObjectName("draft_progress_bar")
self.verticalLayout_2.addWidget(self.draft_progress_bar)
self.horizontalLayout_4 = QtWidgets.QHBoxLayout()
self.horizontalLayout_4.setObjectName("horizontalLayout_4")
self.draft_wc_label = QtWidgets.QLabel(targets)
self.draft_wc_label.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
self.draft_wc_label.setObjectName("draft_wc_label")
self.horizontalLayout_4.addWidget(self.draft_wc_label)
self.draft_of_label = QtWidgets.QLabel(targets)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Preferred)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.draft_of_label.sizePolicy().hasHeightForWidth())
self.draft_of_label.setSizePolicy(sizePolicy)
self.draft_of_label.setObjectName("draft_of_label")
self.horizontalLayout_4.addWidget(self.draft_of_label)
self.draft_goal_label = QtWidgets.QLabel(targets)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Preferred)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.draft_goal_label.sizePolicy().hasHeightForWidth())
self.draft_goal_label.setSizePolicy(sizePolicy)
self.draft_goal_label.setObjectName("draft_goal_label")
self.horizontalLayout_4.addWidget(self.draft_goal_label)
self.label_8 = QtWidgets.QLabel(targets)
self.label_8.setObjectName("label_8")
self.horizontalLayout_4.addWidget(self.label_8)
self.verticalLayout_2.addLayout(self.horizontalLayout_4)
self.horizontalLayout_2 = QtWidgets.QHBoxLayout()
self.horizontalLayout_2.setObjectName("horizontalLayout_2")
self.label_2 = QtWidgets.QLabel(targets)
self.label_2.setObjectName("label_2")
self.horizontalLayout_2.addWidget(self.label_2)
self.line_2 = QtWidgets.QFrame(targets)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(1)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.line_2.sizePolicy().hasHeightForWidth())
self.line_2.setSizePolicy(sizePolicy)
self.line_2.setFrameShape(QtWidgets.QFrame.HLine)
self.line_2.setFrameShadow(QtWidgets.QFrame.Sunken)
self.line_2.setObjectName("line_2")
self.horizontalLayout_2.addWidget(self.line_2)
self.session_reset = QtWidgets.QPushButton(targets)
self.session_reset.setObjectName("session_reset")
self.horizontalLayout_2.addWidget(self.session_reset)
self.verticalLayout_2.addLayout(self.horizontalLayout_2)
self.session_progress_bar = QtWidgets.QProgressBar(targets)
self.session_progress_bar.setProperty("value", 0)
self.session_progress_bar.setObjectName("session_progress_bar")
self.verticalLayout_2.addWidget(self.session_progress_bar)
self.horizontalLayout_3 = QtWidgets.QHBoxLayout()
self.horizontalLayout_3.setObjectName("horizontalLayout_3")
self.session_wc_label = QtWidgets.QLabel(targets)
self.session_wc_label.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
self.session_wc_label.setObjectName("session_wc_label")
self.horizontalLayout_3.addWidget(self.session_wc_label)
self.label_3 = QtWidgets.QLabel(targets)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Preferred)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.label_3.sizePolicy().hasHeightForWidth())
self.label_3.setSizePolicy(sizePolicy)
self.label_3.setObjectName("label_3")
self.horizontalLayout_3.addWidget(self.label_3)
self.session_target = QtWidgets.QDoubleSpinBox(targets)
self.session_target.setDecimals(0)
self.session_target.setMaximum(99999999999999.0)
self.session_target.setSingleStep(50.0)
self.session_target.setProperty("value", 500.0)
self.session_target.setObjectName("session_target")
self.horizontalLayout_3.addWidget(self.session_target)
self.label_5 = QtWidgets.QLabel(targets)
self.label_5.setObjectName("label_5")
self.horizontalLayout_3.addWidget(self.label_5)
self.verticalLayout_2.addLayout(self.horizontalLayout_3)
self.retranslateUi(targets)
QtCore.QMetaObject.connectSlotsByName(targets)
def retranslateUi(self, targets):
_translate = QtCore.QCoreApplication.translate
targets.setWindowTitle(_translate("targets", "Project Targets"))
self.label.setText(_translate("targets", "Draft Target"))
self.draft_wc_label.setText(_translate("targets", "0"))
self.draft_of_label.setText(_translate("targets", "of"))
self.draft_goal_label.setText(_translate("targets", "10,000"))
self.label_8.setText(_translate("targets", "Words"))
self.label_2.setText(_translate("targets", "Session Target"))
self.session_reset.setText(_translate("targets", "Reset"))
self.session_wc_label.setText(_translate("targets", "0"))
self.label_3.setText(_translate("targets", "of"))
self.label_5.setText(_translate("targets", "words"))
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
targets = QtWidgets.QWidget()
ui = Ui_targets()
ui.setupUi(targets)
targets.show()
sys.exit(app.exec_())

View file

@ -0,0 +1,201 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>targets</class>
<widget class="QWidget" name="targets">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>322</width>
<height>216</height>
</rect>
</property>
<property name="windowTitle">
<string>Project Targets</string>
</property>
<property name="windowIcon">
<iconset>
<normaloff>../../../../../../../../../../home/icons/Manuskript/icon-64px.png</normaloff>../../../../../../../../../../home/icons/Manuskript/icon-64px.png</iconset>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="label">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Draft Target</string>
</property>
</widget>
</item>
<item>
<widget class="Line" name="line">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
<horstretch>1</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</item>
<item>
<widget class="QProgressBar" name="draft_progress_bar">
<property name="value">
<number>0</number>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_4">
<item>
<widget class="QLabel" name="draft_wc_label">
<property name="text">
<string>0</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="draft_of_label">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>of</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="draft_goal_label">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>10,000</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_8">
<property name="text">
<string>Words</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QLabel" name="label_2">
<property name="text">
<string>Session Target</string>
</property>
</widget>
</item>
<item>
<widget class="Line" name="line_2">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>1</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="session_reset">
<property name="text">
<string>Reset</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QProgressBar" name="session_progress_bar">
<property name="value">
<number>0</number>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="QLabel" name="session_wc_label">
<property name="text">
<string>0</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_3">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>of</string>
</property>
</widget>
</item>
<item>
<widget class="QDoubleSpinBox" name="session_target">
<property name="decimals">
<number>0</number>
</property>
<property name="maximum">
<double>99999999999999.000000000000000</double>
</property>
<property name="singleStep">
<double>50.000000000000000</double>
</property>
<property name="value">
<double>500.000000000000000</double>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_5">
<property name="text">
<string>words</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>