autosave to help restore unsaved projects in case of a crash
This commit is contained in:
parent
d417833193
commit
2cbae481c5
6
core.py
6
core.py
|
@ -8,6 +8,7 @@ import tempfile
|
||||||
from shutil import rmtree
|
from shutil import rmtree
|
||||||
import atexit
|
import atexit
|
||||||
import time
|
import time
|
||||||
|
from collections import OrderedDict
|
||||||
|
|
||||||
class Core():
|
class Core():
|
||||||
|
|
||||||
|
@ -150,3 +151,8 @@ class Core():
|
||||||
|
|
||||||
def reset(self):
|
def reset(self):
|
||||||
self.canceled = False
|
self.canceled = False
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def sortedStringDict(dictionary):
|
||||||
|
sorted_ = OrderedDict(sorted(dictionary.items(), key=lambda t: t[0]))
|
||||||
|
return repr(sorted_)
|
||||||
|
|
66
main.py
66
main.py
|
@ -1,7 +1,8 @@
|
||||||
import sys, io, os, shutil, atexit, string, signal
|
import sys, io, os, shutil, atexit, string, signal, filecmp
|
||||||
from os.path import expanduser
|
from os.path import expanduser
|
||||||
from queue import Queue
|
from queue import Queue
|
||||||
from importlib import import_module
|
from importlib import import_module
|
||||||
|
from collections import OrderedDict
|
||||||
from PyQt4 import QtCore, QtGui, uic
|
from PyQt4 import QtCore, QtGui, uic
|
||||||
from PyQt4.QtCore import QSettings, QModelIndex, Qt
|
from PyQt4.QtCore import QSettings, QModelIndex, Qt
|
||||||
from PyQt4.QtGui import QDesktopServices
|
from PyQt4.QtGui import QDesktopServices
|
||||||
|
@ -142,18 +143,18 @@ class Main(QtCore.QObject):
|
||||||
# print('main thread id: {}'.format(QtCore.QThread.currentThreadId()))
|
# print('main thread id: {}'.format(QtCore.QThread.currentThreadId()))
|
||||||
self.window = window
|
self.window = window
|
||||||
self.core = core.Core()
|
self.core = core.Core()
|
||||||
self.currentProject = None
|
|
||||||
self.pages = []
|
self.pages = []
|
||||||
self.selectedComponents = []
|
self.selectedComponents = []
|
||||||
|
|
||||||
# create data directory, load/create settings
|
# create data directory, load/create settings
|
||||||
self.dataDir = QDesktopServices.storageLocation(QDesktopServices.DataLocation)
|
self.dataDir = QDesktopServices.storageLocation(QDesktopServices.DataLocation)
|
||||||
|
self.autosavePath = os.path.join(self.dataDir, 'autosave.avp')
|
||||||
|
self.presetDir = os.path.join(self.dataDir, 'presets')
|
||||||
self.settings = QSettings(os.path.join(self.dataDir, 'settings.ini'), QSettings.IniFormat)
|
self.settings = QSettings(os.path.join(self.dataDir, 'settings.ini'), QSettings.IniFormat)
|
||||||
LoadDefaultSettings(self)
|
LoadDefaultSettings(self)
|
||||||
if not os.path.exists(self.dataDir):
|
if not os.path.exists(self.dataDir):
|
||||||
os.makedirs(self.dataDir)
|
os.makedirs(self.dataDir)
|
||||||
presetDir = os.path.join(self.dataDir, 'presets')
|
for neededDirectory in (self.presetDir, self.settings.value("projectDir")):
|
||||||
for neededDirectory in (presetDir, self.settings.value("projectDir")):
|
|
||||||
if not os.path.exists(neededDirectory):
|
if not os.path.exists(neededDirectory):
|
||||||
os.mkdir(neededDirectory)
|
os.mkdir(neededDirectory)
|
||||||
|
|
||||||
|
@ -208,14 +209,35 @@ class Main(QtCore.QObject):
|
||||||
self.window.pushButton_saveProject.clicked.connect(self.saveCurrentProject)
|
self.window.pushButton_saveProject.clicked.connect(self.saveCurrentProject)
|
||||||
self.window.pushButton_openProject.clicked.connect(self.openOpenProjectDialog)
|
self.window.pushButton_openProject.clicked.connect(self.openOpenProjectDialog)
|
||||||
|
|
||||||
self.openProject(self.settings.value("lastProject"))
|
# show the window and load current project
|
||||||
self.drawPreview()
|
|
||||||
window.show()
|
window.show()
|
||||||
|
self.currentProject = self.settings.value("currentProject")
|
||||||
|
if self.currentProject and os.path.exists(self.autosavePath) \
|
||||||
|
and filecmp.cmp(self.autosavePath, self.currentProject):
|
||||||
|
# delete autosave if it's identical to the project
|
||||||
|
os.remove(self.autosavePath)
|
||||||
|
|
||||||
|
if self.currentProject and os.path.exists(self.autosavePath):
|
||||||
|
ch = self.showMessage("Restore unsaved changes in project '%s'?" % os.path.basename(self.currentProject)[:-4], True)
|
||||||
|
if ch:
|
||||||
|
os.remove(self.currentProject)
|
||||||
|
os.rename(self.autosavePath, self.currentProject)
|
||||||
|
else:
|
||||||
|
os.remove(self.autosavePath)
|
||||||
|
|
||||||
|
self.openProject(self.currentProject)
|
||||||
|
self.drawPreview()
|
||||||
|
|
||||||
def cleanUp(self):
|
def cleanUp(self):
|
||||||
self.timer.stop()
|
self.timer.stop()
|
||||||
self.previewThread.quit()
|
self.previewThread.quit()
|
||||||
self.previewThread.wait()
|
self.previewThread.wait()
|
||||||
|
self.autosave()
|
||||||
|
|
||||||
|
def autosave(self):
|
||||||
|
if os.path.exists(self.autosavePath):
|
||||||
|
os.remove(self.autosavePath)
|
||||||
|
self.createProjectFile(self.autosavePath)
|
||||||
|
|
||||||
def openInputFileDialog(self):
|
def openInputFileDialog(self):
|
||||||
inputDir = self.settings.value("inputDir", expanduser("~"))
|
inputDir = self.settings.value("inputDir", expanduser("~"))
|
||||||
|
@ -303,9 +325,9 @@ class Main(QtCore.QObject):
|
||||||
self.drawPreview()
|
self.drawPreview()
|
||||||
|
|
||||||
def drawPreview(self):
|
def drawPreview(self):
|
||||||
#self.settings.setValue('visLayout', self.window.comboBox_visLayout.currentIndex())
|
|
||||||
self.newTask.emit(self.window.lineEdit_background.text(), self.selectedComponents)
|
self.newTask.emit(self.window.lineEdit_background.text(), self.selectedComponents)
|
||||||
# self.processTask.emit()
|
# self.processTask.emit()
|
||||||
|
self.autosave()
|
||||||
|
|
||||||
def showPreviewImage(self, image):
|
def showPreviewImage(self, image):
|
||||||
self.previewWindow.changePixmap(image)
|
self.previewWindow.changePixmap(image)
|
||||||
|
@ -387,7 +409,7 @@ class Main(QtCore.QObject):
|
||||||
def updateOpenPresetComboBox(self, component):
|
def updateOpenPresetComboBox(self, component):
|
||||||
self.window.comboBox_openPreset.clear()
|
self.window.comboBox_openPreset.clear()
|
||||||
self.window.comboBox_openPreset.addItem("Open Preset")
|
self.window.comboBox_openPreset.addItem("Open Preset")
|
||||||
destination = os.path.join(self.dataDir, 'presets',
|
destination = os.path.join(self.presetDir,
|
||||||
str(component).strip(), str(component.version()))
|
str(component).strip(), str(component.version()))
|
||||||
if not os.path.exists(destination):
|
if not os.path.exists(destination):
|
||||||
os.makedirs(destination)
|
os.makedirs(destination)
|
||||||
|
@ -417,12 +439,12 @@ class Main(QtCore.QObject):
|
||||||
break
|
break
|
||||||
|
|
||||||
def createPresetFile(self, componentName, version, saveValueStore, filename):
|
def createPresetFile(self, componentName, version, saveValueStore, filename):
|
||||||
dirname = os.path.join(self.dataDir, 'presets', componentName, str(version))
|
dirname = os.path.join(self.presetDir, componentName, str(version))
|
||||||
if not os.path.exists(dirname):
|
if not os.path.exists(dirname):
|
||||||
os.makedirs(dirname)
|
os.makedirs(dirname)
|
||||||
filepath = os.path.join(dirname, filename)
|
filepath = os.path.join(dirname, filename)
|
||||||
if os.path.exists(filepath):
|
if os.path.exists(filepath):
|
||||||
ch = self.showMessage("%s already exists! Overwrite it?" % filename, QtGui.QMessageBox.Warning, True)
|
ch = self.showMessage("%s already exists! Overwrite it?" % filename, True, QtGui.QMessageBox.Warning)
|
||||||
if not ch:
|
if not ch:
|
||||||
return
|
return
|
||||||
# remove old copies of the preset
|
# remove old copies of the preset
|
||||||
|
@ -430,7 +452,7 @@ class Main(QtCore.QObject):
|
||||||
if self.window.comboBox_openPreset.itemText(i) == filename:
|
if self.window.comboBox_openPreset.itemText(i) == filename:
|
||||||
self.window.comboBox_openPreset.removeItem(i)
|
self.window.comboBox_openPreset.removeItem(i)
|
||||||
with open(filepath, 'w') as f:
|
with open(filepath, 'w') as f:
|
||||||
f.write(repr(saveValueStore))
|
f.write(core.Core.sortedStringDict(saveValueStore))
|
||||||
self.window.comboBox_openPreset.addItem(filename)
|
self.window.comboBox_openPreset.addItem(filename)
|
||||||
self.window.comboBox_openPreset.setCurrentIndex(self.window.comboBox_openPreset.count()-1)
|
self.window.comboBox_openPreset.setCurrentIndex(self.window.comboBox_openPreset.count()-1)
|
||||||
|
|
||||||
|
@ -443,14 +465,14 @@ class Main(QtCore.QObject):
|
||||||
filename = self.window.comboBox_openPreset.itemText(self.window.comboBox_openPreset.currentIndex())
|
filename = self.window.comboBox_openPreset.itemText(self.window.comboBox_openPreset.currentIndex())
|
||||||
componentName = str(self.selectedComponents[index]).strip()
|
componentName = str(self.selectedComponents[index]).strip()
|
||||||
version = self.selectedComponents[index].version()
|
version = self.selectedComponents[index].version()
|
||||||
dirname = os.path.join(self.dataDir, 'presets', componentName, str(version))
|
dirname = os.path.join(self.presetDir, componentName, str(version))
|
||||||
filepath = os.path.join(dirname, filename)
|
filepath = os.path.join(dirname, filename)
|
||||||
if not os.path.exists(filepath):
|
if not os.path.exists(filepath):
|
||||||
self.window.comboBox_openPreset.removeItem(self.window.comboBox_openPreset.currentIndex())
|
self.window.comboBox_openPreset.removeItem(self.window.comboBox_openPreset.currentIndex())
|
||||||
return
|
return
|
||||||
with open(filepath, 'r') as f:
|
with open(filepath, 'r') as f:
|
||||||
for line in f:
|
for line in f:
|
||||||
saveValueStore = eval(line.strip())
|
saveValueStore = dict(eval(line.strip()))
|
||||||
break
|
break
|
||||||
self.selectedComponents[index].loadPreset(saveValueStore)
|
self.selectedComponents[index].loadPreset(saveValueStore)
|
||||||
self.drawPreview()
|
self.drawPreview()
|
||||||
|
@ -478,9 +500,10 @@ class Main(QtCore.QObject):
|
||||||
saveValueStore = comp.savePreset()
|
saveValueStore = comp.savePreset()
|
||||||
f.write('%s\n' % str(comp))
|
f.write('%s\n' % str(comp))
|
||||||
f.write('%s\n' % str(comp.version()))
|
f.write('%s\n' % str(comp.version()))
|
||||||
f.write('%s\n' % repr(saveValueStore))
|
f.write('%s\n' % core.Core.sortedStringDict(saveValueStore))
|
||||||
|
if filepath != self.autosavePath:
|
||||||
self.settings.setValue("projectDir", os.path.dirname(filepath))
|
self.settings.setValue("projectDir", os.path.dirname(filepath))
|
||||||
self.settings.setValue("lastProject", filepath)
|
self.settings.setValue("currentProject", filepath)
|
||||||
self.currentProject = filepath
|
self.currentProject = filepath
|
||||||
|
|
||||||
def openOpenProjectDialog(self):
|
def openOpenProjectDialog(self):
|
||||||
|
@ -494,10 +517,10 @@ class Main(QtCore.QObject):
|
||||||
return
|
return
|
||||||
self.clear()
|
self.clear()
|
||||||
self.currentProject = filepath
|
self.currentProject = filepath
|
||||||
self.settings.setValue("lastProject", filepath)
|
self.settings.setValue("currentProject", filepath)
|
||||||
self.settings.setValue("projectDir", os.path.dirname(filepath))
|
self.settings.setValue("projectDir", os.path.dirname(filepath))
|
||||||
compNames = [mod.Component.__doc__ for mod in self.modules]
|
compNames = [mod.Component.__doc__ for mod in self.modules]
|
||||||
|
try:
|
||||||
with open(filepath, 'r') as f:
|
with open(filepath, 'r') as f:
|
||||||
validSections = ('Components')
|
validSections = ('Components')
|
||||||
section = ''
|
section = ''
|
||||||
|
@ -516,18 +539,21 @@ class Main(QtCore.QObject):
|
||||||
continue
|
continue
|
||||||
if line and section == 'Components':
|
if line and section == 'Components':
|
||||||
if i == 0:
|
if i == 0:
|
||||||
compIndex = compNames.index(line.strip())
|
compIndex = compNames.index(line)
|
||||||
self.addComponent(compIndex)
|
self.addComponent(compIndex)
|
||||||
i += 1
|
i += 1
|
||||||
elif i == 1:
|
elif i == 1:
|
||||||
# version, not used yet
|
# version, not used yet
|
||||||
i += 1
|
i += 1
|
||||||
elif i == 2:
|
elif i == 2:
|
||||||
saveValueStore = eval(line.strip())
|
saveValueStore = dict(eval(line))
|
||||||
self.selectedComponents[-1].loadPreset(saveValueStore)
|
self.selectedComponents[-1].loadPreset(saveValueStore)
|
||||||
i = 0
|
i = 0
|
||||||
|
except:
|
||||||
|
self.clear()
|
||||||
|
self.showMessage("Project file '%s' is corrupted." % filepath)
|
||||||
|
|
||||||
def showMessage(self, string, icon=QtGui.QMessageBox.Information, showCancel=False):
|
def showMessage(self, string, showCancel=False, icon=QtGui.QMessageBox.Information):
|
||||||
msg = QtGui.QMessageBox()
|
msg = QtGui.QMessageBox()
|
||||||
msg.setIcon(icon)
|
msg.setIcon(icon)
|
||||||
msg.setText(string)
|
msg.setText(string)
|
||||||
|
|
Reference in New Issue