mirror of
https://github.com/olivierkes/manuskript.git
synced 2024-05-17 11:22:28 +12:00
Saving seems to work kind of smoothly
This commit is contained in:
parent
da5bfb8951
commit
dc1b757770
|
@ -217,16 +217,16 @@ def saveProject(zip=None):
|
|||
|
||||
files.append((cpath, content))
|
||||
|
||||
# List removed characters
|
||||
for c in mdl.removed:
|
||||
# generate file's path
|
||||
cpath = path.format(name="{ID}-{slugName}".format(
|
||||
ID=c.ID(),
|
||||
slugName=slugify(c.name())
|
||||
))
|
||||
|
||||
# Mark for removal
|
||||
removes.append(cpath)
|
||||
# # List removed characters
|
||||
# for c in mdl.removed:
|
||||
# # generate file's path
|
||||
# cpath = path.format(name="{ID}-{slugName}".format(
|
||||
# ID=c.ID(),
|
||||
# slugName=slugify(c.name())
|
||||
# ))
|
||||
#
|
||||
# # Mark for removal
|
||||
# removes.append(cpath)
|
||||
|
||||
mdl.removed.clear()
|
||||
|
||||
|
@ -235,11 +235,19 @@ def saveProject(zip=None):
|
|||
# In an outline folder
|
||||
|
||||
mdl = mw.mdlOutline
|
||||
|
||||
# Go through the tree
|
||||
f, m, r = exportOutlineItem(mdl.rootItem)
|
||||
files += f
|
||||
moves += m
|
||||
removes += r
|
||||
|
||||
# List removed items
|
||||
# for item in mdl.removed:
|
||||
# path = outlineItemPath(item)
|
||||
# log("* Marking for removal:", path)
|
||||
|
||||
|
||||
####################################################################################################################
|
||||
# World
|
||||
# Either in an XML file, or in lots of plain texts?
|
||||
|
@ -299,6 +307,8 @@ def saveProject(zip=None):
|
|||
|
||||
else:
|
||||
|
||||
global cache
|
||||
|
||||
# Project path
|
||||
dir = os.path.dirname(project)
|
||||
|
||||
|
@ -316,27 +326,23 @@ def saveProject(zip=None):
|
|||
newPath = os.path.join(dir, folder, new)
|
||||
|
||||
# Move the old file to the new place
|
||||
os.replace(oldPath, newPath)
|
||||
log("* Renaming {} to {}".format(old, new))
|
||||
try:
|
||||
os.replace(oldPath, newPath)
|
||||
log("* Renaming/moving {} to {}".format(old, new))
|
||||
except FileNotFoundError:
|
||||
# Maybe parent folder has been renamed
|
||||
pass
|
||||
|
||||
# Update cache
|
||||
if old in cache:
|
||||
cache[new] = cache.pop(old)
|
||||
|
||||
for path in removes:
|
||||
if path not in [p for p,c in files]:
|
||||
filename = os.path.join(dir, folder, path)
|
||||
log("* Removing", path)
|
||||
|
||||
if os.path.isdir(filename):
|
||||
shutil.rmtree(filename)
|
||||
|
||||
else: # elif os.path.exists(filename)
|
||||
os.remove(filename)
|
||||
|
||||
# Clear cache
|
||||
cache.pop(path, 0)
|
||||
cache2 = {}
|
||||
for f in cache:
|
||||
f2 = f.replace(old, new)
|
||||
if f2 != f:
|
||||
log(" * Updating cache:", f, f2)
|
||||
cache2[f2] = cache[f]
|
||||
cache = cache2
|
||||
|
||||
# Writing files
|
||||
for path, content in files:
|
||||
filename = os.path.join(dir, folder, path)
|
||||
os.makedirs(os.path.dirname(filename), exist_ok=True)
|
||||
|
@ -355,6 +361,31 @@ def saveProject(zip=None):
|
|||
pass
|
||||
# log(" In cache, and identical. Do nothing.")
|
||||
|
||||
# Removing phantoms
|
||||
for path in [p for p in cache if p not in [p for p,c in files]]:
|
||||
filename = os.path.join(dir, folder, path)
|
||||
log("* Removing", path)
|
||||
|
||||
if os.path.isdir(filename):
|
||||
shutil.rmtree(filename)
|
||||
|
||||
else: # elif os.path.exists(filename)
|
||||
os.remove(filename)
|
||||
|
||||
# Clear cache
|
||||
cache.pop(path, 0)
|
||||
|
||||
# Removing empty directories
|
||||
for root, dirs, files in os.walk(os.path.join(dir, folder, "outline")):
|
||||
for dir in dirs:
|
||||
newDir = os.path.join(root, dir)
|
||||
try:
|
||||
os.removedirs(newDir)
|
||||
log("* Removing empty directory:", newDir)
|
||||
except:
|
||||
# Directory not empty, we don't remove.
|
||||
pass
|
||||
|
||||
|
||||
def addWorldItem(root, mdl, parent=QModelIndex()):
|
||||
"""
|
||||
|
@ -457,21 +488,22 @@ def exportOutlineItem(root):
|
|||
moves = []
|
||||
removes = []
|
||||
|
||||
path = "outline"
|
||||
|
||||
k=0
|
||||
for child in root.children():
|
||||
spath = os.path.join(path, *outlineItemPath(child))
|
||||
itemPath = outlineItemPath(child)
|
||||
spath = os.path.join(*itemPath)
|
||||
|
||||
k += 1
|
||||
|
||||
# Has the item been renamed?
|
||||
if child.lastPath and spath != child.lastPath:
|
||||
moves.append((child.lastPath, spath))
|
||||
log(child.title(), "has been renamed (", child.lastPath, " → ", spath, ")")
|
||||
log(" → We mark for moving:", child.lastPath)
|
||||
lp = child._lastPath
|
||||
if lp and spath != lp:
|
||||
moves.append((lp, spath))
|
||||
log(child.title(), "has been renamed (", lp, " → ", spath, ")")
|
||||
log(" → We mark for moving:", lp)
|
||||
|
||||
# Updates item last's path
|
||||
child.lastPath = spath
|
||||
child._lastPath = spath # itemPath[-1]
|
||||
|
||||
# Generating content
|
||||
if child.type() == "folder":
|
||||
|
@ -484,7 +516,7 @@ def exportOutlineItem(root):
|
|||
files.append((spath, content))
|
||||
|
||||
elif child.type() in ["html"]:
|
||||
# FIXME: Convert first
|
||||
# Save as html. Not the most beautiful, but hey.
|
||||
content = outlineToMMD(child)
|
||||
files.append((spath, content))
|
||||
|
||||
|
@ -499,14 +531,20 @@ def exportOutlineItem(root):
|
|||
return files, moves, removes
|
||||
|
||||
def outlineItemPath(item):
|
||||
"""
|
||||
Returns the outlineItem file path (like the path where it will be written on the disk). As a list of folder's
|
||||
name. To be joined by os.path.join.
|
||||
@param item: outlineItem
|
||||
@return: list of folder's names
|
||||
"""
|
||||
# Root item
|
||||
if not item.parent():
|
||||
return []
|
||||
return ["outline"]
|
||||
else:
|
||||
name = "{ID}-{name}{ext}".format(
|
||||
ID=item.row(),
|
||||
name=slugify(item.title()),
|
||||
ext="" if item.type() == "folder" else ".{}".format(item.type())
|
||||
ext="" if item.type() == "folder" else ".md" # ".{}".format(item.type()) # To have .txt, .t2t, .html, ...
|
||||
)
|
||||
return outlineItemPath(item.parent()) + [name]
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@ from manuskript.enums import Outline
|
|||
from manuskript.functions import mainWindow, toInt, wordCount
|
||||
|
||||
locale.setlocale(locale.LC_ALL, '')
|
||||
import time
|
||||
import time, os
|
||||
|
||||
|
||||
class outlineModel(QAbstractItemModel):
|
||||
|
@ -27,6 +27,9 @@ class outlineModel(QAbstractItemModel):
|
|||
|
||||
self.rootItem = outlineItem(self, title="root", ID="0")
|
||||
|
||||
# Stores removed item, in order to remove them on disk when saving, depending on the file format.
|
||||
self.removed = []
|
||||
|
||||
def index(self, row, column, parent):
|
||||
|
||||
if not self.hasIndex(row, column, parent):
|
||||
|
@ -363,7 +366,8 @@ class outlineModel(QAbstractItemModel):
|
|||
|
||||
self.beginRemoveRows(parent, row, row + count - 1)
|
||||
for i in range(count):
|
||||
parentItem.removeChild(row)
|
||||
item = parentItem.removeChild(row)
|
||||
self.removed.append(item)
|
||||
|
||||
self.endRemoveRows()
|
||||
return True
|
||||
|
@ -418,7 +422,7 @@ class outlineItem():
|
|||
self._model = model
|
||||
self.defaultTextType = None
|
||||
self.IDs = [] # used by root item to store unique IDs
|
||||
self.lastPath = "" # used by loadSave version_1 to remember which files the items comes from,
|
||||
self._lastPath = "" # used by loadSave version_1 to remember which files the items comes from,
|
||||
# in case it is renamed / removed
|
||||
|
||||
if title:
|
||||
|
@ -592,7 +596,7 @@ class outlineItem():
|
|||
self.parent().updateWordCount(emit)
|
||||
|
||||
def row(self):
|
||||
if self.parent:
|
||||
if self.parent():
|
||||
return self.parent().childItems.index(self)
|
||||
|
||||
def appendChild(self, child):
|
||||
|
@ -634,9 +638,15 @@ class outlineItem():
|
|||
c.emitDataChanged(cols, recursive=True)
|
||||
|
||||
def removeChild(self, row):
|
||||
self.childItems.pop(row)
|
||||
"""
|
||||
Removes child at position `row` and returns it.
|
||||
@param row: index (int) of the child to remove.
|
||||
@return: the removed outlineItem
|
||||
"""
|
||||
r = self.childItems.pop(row)
|
||||
# Might be causing segfault when updateWordCount emits dataChanged
|
||||
self.updateWordCount(emit=False)
|
||||
return r
|
||||
|
||||
def parent(self):
|
||||
return self._parent
|
||||
|
@ -748,7 +758,7 @@ class outlineItem():
|
|||
item.append(revItem)
|
||||
|
||||
# Saving lastPath
|
||||
item.set("lastPath", self.lastPath)
|
||||
item.set("lastPath", self._lastPath)
|
||||
|
||||
for i in self.childItems:
|
||||
item.append(ET.XML(i.toXML()))
|
||||
|
@ -766,7 +776,7 @@ class outlineItem():
|
|||
self.setData(Outline.__members__[k].value, str(root.attrib[k]))
|
||||
|
||||
if "lastPath" in root.attrib:
|
||||
self.lastPath = root.attrib["lastPath"]
|
||||
self._lastPath = root.attrib["lastPath"]
|
||||
|
||||
for child in root:
|
||||
if child.tag == "outlineItem":
|
||||
|
|
Loading…
Reference in a new issue