2017-11-06 21:16:44 +13:00
|
|
|
#!/usr/bin/env python
|
|
|
|
# --!-- coding: utf8 --!--
|
|
|
|
import json
|
|
|
|
import os
|
|
|
|
|
2017-11-08 02:25:47 +13:00
|
|
|
from PyQt5.QtCore import Qt, QTimer
|
2017-11-06 21:16:44 +13:00
|
|
|
from PyQt5.QtGui import QBrush, QColor, QIcon
|
2017-11-08 02:40:46 +13:00
|
|
|
from PyQt5.QtWidgets import QWidget, QFileDialog, QMessageBox
|
2017-11-06 21:16:44 +13:00
|
|
|
|
2017-11-07 06:21:40 +13:00
|
|
|
from manuskript.functions import lightBlue, writablePath, appPath
|
2017-11-06 21:16:44 +13:00
|
|
|
from manuskript.ui.importers.importer_ui import Ui_importer
|
2017-11-07 23:25:19 +13:00
|
|
|
from manuskript.ui.importers.generalSettings import generalSettings
|
|
|
|
from manuskript.ui import style
|
|
|
|
from manuskript import importer
|
2017-11-08 00:02:02 +13:00
|
|
|
from manuskript.models.outlineModel import outlineModel
|
2017-11-08 02:25:47 +13:00
|
|
|
from manuskript.enums import Outline
|
2017-11-06 21:16:44 +13:00
|
|
|
|
|
|
|
class importerDialog(QWidget, Ui_importer):
|
2017-11-07 06:21:40 +13:00
|
|
|
|
|
|
|
formatsIcon = {
|
|
|
|
".epub": "application-epub+zip",
|
|
|
|
".odt": "application-vnd.oasis.opendocument.text",
|
|
|
|
".docx": "application-vnd.openxmlformats-officedocument.wordprocessingml.document",
|
|
|
|
".md": "text-x-markdown",
|
|
|
|
".rst": "text-plain",
|
|
|
|
".tex": "text-x-tex",
|
|
|
|
".opml": "text-x-opml+xml",
|
2017-11-08 03:33:18 +13:00
|
|
|
".xml": "text-x-opml+xml",
|
2017-11-07 06:21:40 +13:00
|
|
|
".html": "text-html",
|
|
|
|
}
|
|
|
|
|
2017-11-06 21:16:44 +13:00
|
|
|
def __init__(self, parent=None, mw=None):
|
|
|
|
QWidget.__init__(self, parent)
|
|
|
|
self.setupUi(self)
|
|
|
|
|
|
|
|
# Var
|
|
|
|
self.mw = mw
|
2017-11-07 06:21:40 +13:00
|
|
|
self.fileName = ""
|
2017-11-07 23:25:19 +13:00
|
|
|
self.setStyleSheet(style.mainWindowSS())
|
2017-11-08 02:25:47 +13:00
|
|
|
self.tree.setStyleSheet("QTreeView{background:transparent;}")
|
|
|
|
self.editor.setStyleSheet("QWidget{background:transparent;}")
|
2017-11-08 03:33:18 +13:00
|
|
|
self.editor.toggleSpellcheck(False)
|
2017-11-07 06:21:40 +13:00
|
|
|
|
|
|
|
# Register importFormats:
|
2017-11-07 23:25:19 +13:00
|
|
|
self.importers = importer.importers
|
2017-11-07 06:21:40 +13:00
|
|
|
|
|
|
|
# Populate combo box with formats
|
|
|
|
self.populateImportList()
|
|
|
|
|
|
|
|
# Connections
|
|
|
|
self.btnChoseFile.clicked.connect(self.selectFile)
|
|
|
|
self.btnClearFileName.clicked.connect(self.setFileName)
|
|
|
|
self.btnPreview.clicked.connect(self.preview)
|
2017-11-08 02:40:46 +13:00
|
|
|
self.btnImport.clicked.connect(self.doImport)
|
2017-11-07 23:25:19 +13:00
|
|
|
self.cmbImporters.currentTextChanged.connect(self.updateSettings)
|
|
|
|
|
2017-11-08 03:33:18 +13:00
|
|
|
self.setFileName("")
|
|
|
|
self.updateSettings()
|
2017-11-07 06:21:40 +13:00
|
|
|
|
|
|
|
############################################################################
|
|
|
|
# Combobox / Formats
|
|
|
|
############################################################################
|
|
|
|
|
|
|
|
def populateImportList(self):
|
|
|
|
|
|
|
|
def addFormat(name, icon):
|
|
|
|
self.cmbImporters.addItem(QIcon.fromTheme(icon), name)
|
|
|
|
|
2017-11-07 23:25:19 +13:00
|
|
|
for f in self.importers:
|
2017-11-07 06:21:40 +13:00
|
|
|
addFormat(f.name, f.icon)
|
|
|
|
|
2017-11-07 23:25:19 +13:00
|
|
|
def currentFormat(self):
|
|
|
|
formatName = self.cmbImporters.currentText()
|
|
|
|
F = [F for F in self.importers if F.name == formatName][0]
|
|
|
|
return F
|
|
|
|
|
2017-11-07 06:21:40 +13:00
|
|
|
############################################################################
|
|
|
|
# Import file
|
|
|
|
############################################################################
|
|
|
|
|
|
|
|
def selectFile(self):
|
2017-11-07 23:25:19 +13:00
|
|
|
"""
|
|
|
|
Called to select a file in the file system. Uses QFileDialog.
|
|
|
|
"""
|
2017-11-07 06:21:40 +13:00
|
|
|
|
|
|
|
# We find the current selected format
|
2017-11-07 23:25:19 +13:00
|
|
|
F = self.currentFormat()
|
2017-11-07 06:21:40 +13:00
|
|
|
|
|
|
|
options = QFileDialog.Options()
|
|
|
|
options |= QFileDialog.DontUseNativeDialog
|
|
|
|
if F.fileFormat == "<<folder>>":
|
|
|
|
options = QFileDialog.DontUseNativeDialog | QFileDialog.ShowDirsOnly
|
|
|
|
fileName = QFileDialog.getExistingDirectory(self, "Select import folder",
|
|
|
|
"", options=options)
|
|
|
|
else:
|
|
|
|
fileName, _ = QFileDialog.getOpenFileName(self, "Import from file", "",
|
|
|
|
F.fileFormat, options=options)
|
|
|
|
self.setFileName(fileName)
|
|
|
|
|
|
|
|
def setFileName(self, fileName):
|
2017-11-07 23:25:19 +13:00
|
|
|
"""
|
|
|
|
Updates Ui with given filename. Filename can be empty.
|
|
|
|
"""
|
2017-11-07 06:21:40 +13:00
|
|
|
if fileName:
|
|
|
|
self.fileName = fileName
|
|
|
|
self.lblFileName.setText(os.path.basename(fileName))
|
|
|
|
self.lblFileName.setToolTip(fileName)
|
|
|
|
ext = os.path.splitext(fileName)[1]
|
2017-11-08 03:33:18 +13:00
|
|
|
icon = None
|
2017-11-07 06:21:40 +13:00
|
|
|
if ext and ext in self.formatsIcon:
|
2017-11-07 23:25:19 +13:00
|
|
|
icon = QIcon.fromTheme(self.formatsIcon[ext])
|
2017-11-07 06:21:40 +13:00
|
|
|
elif os.path.isdir(fileName):
|
2017-11-07 23:25:19 +13:00
|
|
|
icon = QIcon.fromTheme("folder")
|
|
|
|
|
2017-11-08 03:33:18 +13:00
|
|
|
if icon:
|
|
|
|
self.lblIcon.setVisible(True)
|
|
|
|
h = self.lblFileName.height()
|
|
|
|
self.lblIcon.setPixmap(icon.pixmap(h, h))
|
|
|
|
else:
|
|
|
|
self.lblIcon.hide()
|
2017-11-07 06:21:40 +13:00
|
|
|
|
|
|
|
else:
|
|
|
|
self.fileName = None
|
|
|
|
self.lblFileName.setText("")
|
2017-11-07 23:25:19 +13:00
|
|
|
|
|
|
|
hasFile = True if fileName else False
|
|
|
|
|
|
|
|
self.btnClearFileName.setVisible(hasFile)
|
|
|
|
self.lblIcon.setVisible(hasFile)
|
|
|
|
self.btnChoseFile.setVisible(not hasFile)
|
|
|
|
self.btnPreview.setEnabled(hasFile)
|
|
|
|
self.btnImport.setEnabled(hasFile)
|
2017-11-07 06:21:40 +13:00
|
|
|
|
|
|
|
############################################################################
|
2017-11-07 23:25:19 +13:00
|
|
|
# UI
|
2017-11-07 06:21:40 +13:00
|
|
|
############################################################################
|
|
|
|
|
2017-11-07 23:25:19 +13:00
|
|
|
def updateSettings(self):
|
|
|
|
"""
|
|
|
|
When the current format change (through the combobox), we update the
|
|
|
|
settings widget using the current format provided settings widget.
|
|
|
|
"""
|
|
|
|
|
|
|
|
F = self.currentFormat()
|
|
|
|
self.settingsWidget = generalSettings()
|
|
|
|
self.setGroupWidget(self.grpSettings, self.settingsWidget)
|
2017-11-08 02:25:47 +13:00
|
|
|
self.grpSettings.setMinimumWidth(200)
|
2017-11-07 23:25:19 +13:00
|
|
|
|
|
|
|
#TODO: custom format widget
|
2017-11-08 02:25:47 +13:00
|
|
|
#toolBox = self.settingsWidget.toolBox
|
|
|
|
#w = QWidget()
|
|
|
|
#toolBox.insertItem(toolBox.count(), w, "Pandoc")
|
|
|
|
#See pandoc's abstractPlainText
|
2017-11-07 23:25:19 +13:00
|
|
|
|
|
|
|
def setGroupWidget(self, group, widget):
|
|
|
|
"""
|
|
|
|
Sets the given widget as main widget for QGroupBox group.
|
|
|
|
"""
|
|
|
|
|
|
|
|
# Removes every items from given layout.
|
|
|
|
l = group.layout()
|
|
|
|
while l.count():
|
|
|
|
item = l.itemAt(0)
|
|
|
|
l.removeItem(item)
|
|
|
|
item.widget().deleteLater()
|
|
|
|
|
|
|
|
l.addWidget(widget)
|
|
|
|
widget.setParent(group)
|
2017-11-07 06:21:40 +13:00
|
|
|
|
|
|
|
############################################################################
|
2017-11-07 23:25:19 +13:00
|
|
|
# Preview / Import
|
2017-11-07 06:21:40 +13:00
|
|
|
############################################################################
|
2017-11-06 21:16:44 +13:00
|
|
|
|
2017-11-07 23:25:19 +13:00
|
|
|
def preview(self):
|
2017-11-08 00:50:40 +13:00
|
|
|
|
2017-11-08 02:40:46 +13:00
|
|
|
# Creating a temporary outlineModel
|
2017-11-08 00:02:02 +13:00
|
|
|
previewModel = outlineModel(self)
|
2017-11-08 02:25:47 +13:00
|
|
|
previewModel.loadFromXML(
|
|
|
|
self.mw.mdlOutline.saveToXML(),
|
|
|
|
fromString=True)
|
|
|
|
|
2017-11-08 02:40:46 +13:00
|
|
|
# Inserting elements
|
|
|
|
result = self.startImport(previewModel)
|
|
|
|
|
|
|
|
if result:
|
|
|
|
self.tree.setModel(previewModel)
|
|
|
|
for i in range(1, previewModel.columnCount()):
|
|
|
|
self.tree.hideColumn(i)
|
|
|
|
self.tree.selectionModel().currentChanged.connect(self.editor.setCurrentModelIndex)
|
|
|
|
self.previewSplitter.setStretchFactor(0, 10)
|
|
|
|
self.previewSplitter.setStretchFactor(1, 40)
|
|
|
|
|
|
|
|
def doImport(self):
|
|
|
|
"""
|
|
|
|
Called by the Import button.
|
|
|
|
"""
|
|
|
|
self.startImport(self.mw.mdlOutline)
|
|
|
|
|
2017-11-08 04:22:59 +13:00
|
|
|
# Signal every views that important model changes have happened.
|
|
|
|
self.mw.mdlOutline.layoutChanged.emit()
|
|
|
|
|
|
|
|
# I'm getting seg fault over this message sometimes...
|
|
|
|
# Using status bar message instead...
|
|
|
|
#QMessageBox.information(self, self.tr("Import status"),
|
|
|
|
#self.tr("Import Complete."))
|
|
|
|
self.mw.statusBar().showMessage("Import complete!", 5000)
|
2017-11-08 02:40:46 +13:00
|
|
|
|
|
|
|
self.close()
|
|
|
|
|
|
|
|
def startImport(self, outlineModel):
|
|
|
|
"""
|
|
|
|
Where most of the magic happens.
|
|
|
|
Is used by preview and by doImport (actual import).
|
|
|
|
|
|
|
|
`outlineModel` is the model where the imported items are added.
|
|
|
|
"""
|
|
|
|
|
|
|
|
# We find the current selected format
|
|
|
|
F = self.currentFormat()
|
|
|
|
|
2017-11-08 02:25:47 +13:00
|
|
|
# Parent item
|
|
|
|
ID = self.settingsWidget.importUnderID()
|
2017-11-08 02:40:46 +13:00
|
|
|
parentItem = outlineModel.getItemByID(ID)
|
2017-11-08 00:50:40 +13:00
|
|
|
|
2017-11-08 02:40:46 +13:00
|
|
|
# Calling the importer
|
2017-11-08 00:50:40 +13:00
|
|
|
items = F.startImport(self.fileName,
|
2017-11-08 02:25:47 +13:00
|
|
|
parentItem,
|
2017-11-08 00:50:40 +13:00
|
|
|
self.settingsWidget)
|
|
|
|
|
|
|
|
# Do transformations
|
2017-11-08 02:40:46 +13:00
|
|
|
items = self.doTransformations(items)
|
|
|
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
def doTransformations(self, items):
|
|
|
|
"""
|
|
|
|
Do general transformations.
|
|
|
|
"""
|
2017-11-08 02:25:47 +13:00
|
|
|
|
|
|
|
# Trim long titles
|
|
|
|
if self.settingsWidget.trimLongTitles():
|
|
|
|
def trim(item):
|
|
|
|
if len(item.title()) > 32:
|
|
|
|
item.setData(Outline.title.value, item.title()[:32])
|
|
|
|
for c in item.children():
|
|
|
|
trim(c)
|
|
|
|
for i in items:
|
|
|
|
trim(i)
|
2017-11-08 00:50:40 +13:00
|
|
|
|
2017-11-08 02:40:46 +13:00
|
|
|
return items
|
2017-11-08 00:50:40 +13:00
|
|
|
|
|
|
|
|