mirror of
https://github.com/olivierkes/manuskript.git
synced 2024-05-10 16:02:33 +12:00
Checkpoint: basic mechanics of settings implemented
This commit is contained in:
parent
340fceeda3
commit
221c7a181d
|
@ -0,0 +1,12 @@
|
|||
#!/usr/bin/env python
|
||||
# --!-- coding: utf8 --!--
|
||||
|
||||
from manuskript.importer.folderImporter import folderImporter
|
||||
from manuskript.importer.markdownImporter import markdownImporter
|
||||
from manuskript.importer.opmlImporter import opmlImporter
|
||||
|
||||
importers = [
|
||||
markdownImporter,
|
||||
opmlImporter,
|
||||
folderImporter,
|
||||
]
|
39
manuskript/importer/abstractImporter.py
Normal file
39
manuskript/importer/abstractImporter.py
Normal file
|
@ -0,0 +1,39 @@
|
|||
#!/usr/bin/env python
|
||||
# --!-- coding: utf8 --!--
|
||||
import os
|
||||
import shutil
|
||||
import subprocess
|
||||
|
||||
from PyQt5.QtCore import QSettings
|
||||
from PyQt5.QtWidgets import QWidget
|
||||
|
||||
|
||||
class abstractImporter:
|
||||
"""
|
||||
abstractImporter is used to import documents into manuskript.
|
||||
|
||||
The startImport function must be subclassed. It takes a filePath (str to
|
||||
the document to import), and must return `outlineItem`s.
|
||||
"""
|
||||
|
||||
name = ""
|
||||
description = ""
|
||||
fileFormat = "" # File format accepted. For example: "OPML Files (*.opml)"
|
||||
# For folder, use "<<folder>>"
|
||||
icon = ""
|
||||
|
||||
@classmethod
|
||||
def startImport(cls, filePath):
|
||||
"""
|
||||
Takes a str path to the file/folder to import, and return `outlineItem`s.
|
||||
"""
|
||||
pass
|
||||
|
||||
@classmethod
|
||||
def settingsWidget(cls):
|
||||
"""
|
||||
Returns a QWidget if needed for settings.
|
||||
"""
|
||||
return None
|
||||
|
||||
|
12
manuskript/importer/folderImporter.py
Normal file
12
manuskript/importer/folderImporter.py
Normal file
|
@ -0,0 +1,12 @@
|
|||
#!/usr/bin/env python
|
||||
# --!-- coding: utf8 --!--
|
||||
|
||||
from manuskript.importer.abstractImporter import abstractImporter
|
||||
|
||||
|
||||
class folderImporter(abstractImporter):
|
||||
|
||||
name = "Folder"
|
||||
description = ""
|
||||
fileFormat = "<<folder>>"
|
||||
icon = "folder"
|
12
manuskript/importer/markdownImporter.py
Normal file
12
manuskript/importer/markdownImporter.py
Normal file
|
@ -0,0 +1,12 @@
|
|||
#!/usr/bin/env python
|
||||
# --!-- coding: utf8 --!--
|
||||
|
||||
from manuskript.importer.abstractImporter import abstractImporter
|
||||
|
||||
|
||||
class markdownImporter(abstractImporter):
|
||||
|
||||
name = "Markdown"
|
||||
description = ""
|
||||
fileFormat = "Markdown files (*.md; *.txt; *)"
|
||||
icon = "text-x-markdown"
|
|
@ -1,127 +0,0 @@
|
|||
#!/usr/bin/env python
|
||||
# --!-- coding: utf8 --!--
|
||||
|
||||
from PyQt5.QtWidgets import QMessageBox
|
||||
from manuskript.models.outlineModel import outlineItem
|
||||
from manuskript.enums import Outline
|
||||
from lxml import etree as ET
|
||||
from manuskript.functions import mainWindow
|
||||
|
||||
|
||||
def importOpml(opmlFilePath, idx):
|
||||
"""
|
||||
Import/export outline cards in OPML format.
|
||||
"""
|
||||
ret = False
|
||||
mw = mainWindow()
|
||||
|
||||
try:
|
||||
with open(opmlFilePath, 'r') as opmlFile:
|
||||
opmlContent = saveNewlines(opmlFile.read())
|
||||
except:
|
||||
# TODO: Translation
|
||||
QMessageBox.critical(mw, mw.tr("OPML Import"),
|
||||
mw.tr("File open failed."))
|
||||
return False
|
||||
|
||||
mdl = mw.mdlOutline
|
||||
|
||||
if idx.internalPointer() is not None:
|
||||
parentItem = idx.internalPointer()
|
||||
else:
|
||||
parentItem = mdl.rootItem
|
||||
|
||||
try:
|
||||
parsed = ET.fromstring(bytes(opmlContent, 'utf-8'))
|
||||
|
||||
opmlNode = parsed
|
||||
bodyNode = opmlNode.find("body")
|
||||
|
||||
if bodyNode is not None:
|
||||
outlineEls = bodyNode.findall("outline")
|
||||
|
||||
if outlineEls is not None:
|
||||
for element in outlineEls:
|
||||
parseItems(element, parentItem)
|
||||
|
||||
mdl.layoutChanged.emit()
|
||||
mw.treeRedacOutline.viewport().update()
|
||||
ret = True
|
||||
except:
|
||||
pass
|
||||
|
||||
# TODO: Translation
|
||||
if ret:
|
||||
QMessageBox.information(mw, mw.tr("OPML Import"),
|
||||
mw.tr("Import Complete."))
|
||||
else:
|
||||
QMessageBox.critical(mw, mw.tr("OPML Import"),
|
||||
mw.tr("This does not appear to be a valid OPML file."))
|
||||
|
||||
return ret
|
||||
|
||||
|
||||
def parseItems(underElement, parentItem):
|
||||
text = underElement.get('text')
|
||||
if text is not None:
|
||||
|
||||
# In the case where the title is exceptionally long, trim it so it isn't
|
||||
# distracting in the tab label
|
||||
title = text[0:32]
|
||||
if len(title) < len(text):
|
||||
title += '...'
|
||||
|
||||
card = outlineItem(parent=parentItem, title=title)
|
||||
|
||||
body = ""
|
||||
summary = ""
|
||||
note = underElement.get('_note')
|
||||
if note is not None and not isWhitespaceOnly(note):
|
||||
body = restoreNewLines(note)
|
||||
summary = body[0:128]
|
||||
else:
|
||||
|
||||
# There's no note (body), but there is a title. Fill the
|
||||
# body with the title to support cards that consist only
|
||||
# of a title.
|
||||
body = text
|
||||
|
||||
card.setData(Outline.summaryFull.value, summary)
|
||||
|
||||
children = underElement.findall('outline')
|
||||
if children is not None and len(children) > 0:
|
||||
for el in children:
|
||||
parseItems(el, card)
|
||||
else:
|
||||
card.setData(Outline.type.value, 'md')
|
||||
card.setData(Outline.text.value, body)
|
||||
|
||||
# I assume I don't have to do the following
|
||||
# parentItem.appendChild(card)
|
||||
|
||||
return
|
||||
|
||||
def saveNewlines(inString):
|
||||
"""
|
||||
Since XML parsers are notorious for stripping out significant newlines,
|
||||
save them in a form we can restore after the parse.
|
||||
"""
|
||||
inString = inString.replace("\r\n", "\n")
|
||||
inString = inString.replace("\n", "{{lf}}")
|
||||
|
||||
return inString
|
||||
|
||||
def restoreNewLines(inString):
|
||||
"""
|
||||
Restore any significant newlines
|
||||
"""
|
||||
return inString.replace("{{lf}}", "\n")
|
||||
|
||||
def isWhitespaceOnly(inString):
|
||||
"""
|
||||
Determine whether or not a string only contains whitespace.
|
||||
"""
|
||||
str = restoreNewLines(inString)
|
||||
str = ''.join(str.split())
|
||||
|
||||
return len(str) is 0
|
134
manuskript/importer/opmlImporter.py
Normal file
134
manuskript/importer/opmlImporter.py
Normal file
|
@ -0,0 +1,134 @@
|
|||
#!/usr/bin/env python
|
||||
# --!-- coding: utf8 --!--
|
||||
|
||||
from PyQt5.QtWidgets import QMessageBox
|
||||
from manuskript.models.outlineModel import outlineItem
|
||||
from manuskript.enums import Outline
|
||||
from lxml import etree as ET
|
||||
from manuskript.functions import mainWindow
|
||||
from manuskript.importer.abstractImporter import abstractImporter
|
||||
|
||||
class opmlImporter(abstractImporter):
|
||||
|
||||
name = "OPML"
|
||||
description = ""
|
||||
fileFormat = "OPML Files (*.opml)"
|
||||
icon = "text-x-opml+xml"
|
||||
|
||||
def importOpml(opmlFilePath, idx):
|
||||
"""
|
||||
Import/export outline cards in OPML format.
|
||||
"""
|
||||
ret = False
|
||||
mw = mainWindow()
|
||||
|
||||
try:
|
||||
with open(opmlFilePath, 'r') as opmlFile:
|
||||
opmlContent = saveNewlines(opmlFile.read())
|
||||
except:
|
||||
# TODO: Translation
|
||||
QMessageBox.critical(mw, mw.tr("OPML Import"),
|
||||
mw.tr("File open failed."))
|
||||
return False
|
||||
|
||||
mdl = mw.mdlOutline
|
||||
|
||||
if idx.internalPointer() is not None:
|
||||
parentItem = idx.internalPointer()
|
||||
else:
|
||||
parentItem = mdl.rootItem
|
||||
|
||||
try:
|
||||
parsed = ET.fromstring(bytes(opmlContent, 'utf-8'))
|
||||
|
||||
opmlNode = parsed
|
||||
bodyNode = opmlNode.find("body")
|
||||
|
||||
if bodyNode is not None:
|
||||
outlineEls = bodyNode.findall("outline")
|
||||
|
||||
if outlineEls is not None:
|
||||
for element in outlineEls:
|
||||
parseItems(element, parentItem)
|
||||
|
||||
mdl.layoutChanged.emit()
|
||||
mw.treeRedacOutline.viewport().update()
|
||||
ret = True
|
||||
except:
|
||||
pass
|
||||
|
||||
# TODO: Translation
|
||||
if ret:
|
||||
QMessageBox.information(mw, mw.tr("OPML Import"),
|
||||
mw.tr("Import Complete."))
|
||||
else:
|
||||
QMessageBox.critical(mw, mw.tr("OPML Import"),
|
||||
mw.tr("This does not appear to be a valid OPML file."))
|
||||
|
||||
return ret
|
||||
|
||||
|
||||
def parseItems(underElement, parentItem):
|
||||
text = underElement.get('text')
|
||||
if text is not None:
|
||||
|
||||
# In the case where the title is exceptionally long, trim it so it isn't
|
||||
# distracting in the tab label
|
||||
title = text[0:32]
|
||||
if len(title) < len(text):
|
||||
title += '...'
|
||||
|
||||
card = outlineItem(parent=parentItem, title=title)
|
||||
|
||||
body = ""
|
||||
summary = ""
|
||||
note = underElement.get('_note')
|
||||
if note is not None and not isWhitespaceOnly(note):
|
||||
body = restoreNewLines(note)
|
||||
summary = body[0:128]
|
||||
else:
|
||||
|
||||
# There's no note (body), but there is a title. Fill the
|
||||
# body with the title to support cards that consist only
|
||||
# of a title.
|
||||
body = text
|
||||
|
||||
card.setData(Outline.summaryFull.value, summary)
|
||||
|
||||
children = underElement.findall('outline')
|
||||
if children is not None and len(children) > 0:
|
||||
for el in children:
|
||||
parseItems(el, card)
|
||||
else:
|
||||
card.setData(Outline.type.value, 'md')
|
||||
card.setData(Outline.text.value, body)
|
||||
|
||||
# I assume I don't have to do the following
|
||||
# parentItem.appendChild(card)
|
||||
|
||||
return
|
||||
|
||||
def saveNewlines(inString):
|
||||
"""
|
||||
Since XML parsers are notorious for stripping out significant newlines,
|
||||
save them in a form we can restore after the parse.
|
||||
"""
|
||||
inString = inString.replace("\r\n", "\n")
|
||||
inString = inString.replace("\n", "{{lf}}")
|
||||
|
||||
return inString
|
||||
|
||||
def restoreNewLines(inString):
|
||||
"""
|
||||
Restore any significant newlines
|
||||
"""
|
||||
return inString.replace("{{lf}}", "\n")
|
||||
|
||||
def isWhitespaceOnly(inString):
|
||||
"""
|
||||
Determine whether or not a string only contains whitespace.
|
||||
"""
|
||||
str = restoreNewLines(inString)
|
||||
str = ''.join(str.split())
|
||||
|
||||
return len(str) is 0
|
|
@ -14,7 +14,6 @@ from manuskript.ui import style
|
|||
from manuskript.ui.editors.editorWidget import editorWidget
|
||||
from manuskript.ui.editors.fullScreenEditor import fullScreenEditor
|
||||
from manuskript.ui.editors.mainEditor_ui import Ui_mainEditor
|
||||
from manuskript.importer import opml as opmlInputExport
|
||||
|
||||
locale.setlocale(locale.LC_ALL, '')
|
||||
|
||||
|
@ -84,10 +83,6 @@ class mainEditor(QWidget, Ui_mainEditor):
|
|||
self.btnRedacFullscreen.clicked.connect(
|
||||
self.showFullScreen, AUC)
|
||||
|
||||
self.btnImport.clicked.connect(
|
||||
lambda v: self.importOPML()
|
||||
)
|
||||
|
||||
# self.tab.setDocumentMode(False)
|
||||
|
||||
# Bug in Qt < 5.5: doesn't always load icons from custom theme.
|
||||
|
@ -264,7 +259,6 @@ class mainEditor(QWidget, Ui_mainEditor):
|
|||
self.btnRedacFolderText.setVisible(visible)
|
||||
self.btnRedacFolderCork.setVisible(visible)
|
||||
self.btnRedacFolderOutline.setVisible(visible)
|
||||
self.btnImport.setVisible(visible)
|
||||
self.sldCorkSizeFactor.setVisible(visible and self.btnRedacFolderCork.isChecked())
|
||||
self.btnRedacFullscreen.setVisible(not visible)
|
||||
|
||||
|
@ -344,20 +338,6 @@ class mainEditor(QWidget, Ui_mainEditor):
|
|||
if self.currentEditor():
|
||||
self._fullScreen = fullScreenEditor(self.currentEditor().currentIndex)
|
||||
|
||||
def importOPML(self):
|
||||
from PyQt5.QtWidgets import QFileDialog
|
||||
options = QFileDialog.Options()
|
||||
options |= QFileDialog.DontUseNativeDialog
|
||||
fileName, _ = QFileDialog.getOpenFileName(self, "Import OPML", "",
|
||||
"OPML Files (*.opml)", options=options)
|
||||
if fileName:
|
||||
if len(self.mw.treeRedacOutline.selectionModel().
|
||||
selection().indexes()) == 0:
|
||||
idx = QModelIndex()
|
||||
else:
|
||||
idx = self.mw.treeRedacOutline.currentIndex()
|
||||
opmlInputExport.importOpml(fileName, idx)
|
||||
|
||||
###############################################################################
|
||||
# DICT AND STUFF LIKE THAT
|
||||
###############################################################################
|
||||
|
|
|
@ -2,8 +2,7 @@
|
|||
|
||||
# Form implementation generated from reading ui file 'manuskript/ui/editors/mainEditor_ui.ui'
|
||||
#
|
||||
# Created: Sat Oct 14 21:30:36 2017
|
||||
# by: PyQt5 UI code generator 5.2.1
|
||||
# Created by: PyQt5 UI code generator 5.9
|
||||
#
|
||||
# WARNING! All changes made in this file will be lost!
|
||||
|
||||
|
@ -14,8 +13,8 @@ class Ui_mainEditor(object):
|
|||
mainEditor.setObjectName("mainEditor")
|
||||
mainEditor.resize(791, 319)
|
||||
self.verticalLayout = QtWidgets.QVBoxLayout(mainEditor)
|
||||
self.verticalLayout.setSpacing(0)
|
||||
self.verticalLayout.setContentsMargins(0, 0, 0, 0)
|
||||
self.verticalLayout.setSpacing(0)
|
||||
self.verticalLayout.setObjectName("verticalLayout")
|
||||
self.tabSplitter = tabSplitter(mainEditor)
|
||||
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Expanding)
|
||||
|
@ -55,14 +54,6 @@ class Ui_mainEditor(object):
|
|||
self.btnRedacFolderOutline.setObjectName("btnRedacFolderOutline")
|
||||
self.buttonGroup.addButton(self.btnRedacFolderOutline)
|
||||
self.horizontalLayout_19.addWidget(self.btnRedacFolderOutline)
|
||||
self.btnImport = QtWidgets.QPushButton(mainEditor)
|
||||
self.btnImport.setText("")
|
||||
icon = QtGui.QIcon.fromTheme("document-open")
|
||||
self.btnImport.setIcon(icon)
|
||||
self.btnImport.setFlat(True)
|
||||
self.btnImport.setObjectName("btnImport")
|
||||
self.buttonGroup.addButton(self.btnImport)
|
||||
self.horizontalLayout_19.addWidget(self.btnImport)
|
||||
self.sldCorkSizeFactor = QtWidgets.QSlider(mainEditor)
|
||||
self.sldCorkSizeFactor.setMinimumSize(QtCore.QSize(100, 0))
|
||||
self.sldCorkSizeFactor.setMaximumSize(QtCore.QSize(200, 16777215))
|
||||
|
@ -117,8 +108,6 @@ class Ui_mainEditor(object):
|
|||
self.btnRedacFolderCork.setText(_translate("mainEditor", "Index cards"))
|
||||
self.btnRedacFolderOutline.setText(_translate("mainEditor", "Outline"))
|
||||
self.btnRedacFullscreen.setShortcut(_translate("mainEditor", "F11"))
|
||||
# TODO: Translation
|
||||
self.btnImport.setToolTip(_translate("mainEditor", "Import items from an OPML file into the current folder"))
|
||||
|
||||
from manuskript.ui.editors.tabSplitter import tabSplitter
|
||||
from manuskript.ui.editors.textFormat import textFormat
|
||||
|
|
|
@ -50,7 +50,9 @@
|
|||
<string/>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset theme="go-up"/>
|
||||
<iconset theme="go-up">
|
||||
<normaloff/>
|
||||
</iconset>
|
||||
</property>
|
||||
<property name="shortcut">
|
||||
<string>Alt+Up</string>
|
||||
|
@ -111,23 +113,6 @@
|
|||
</attribute>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="btnImport">
|
||||
<property name="toolTip">
|
||||
<!-- TODO: Translation -->
|
||||
<string>Import items from an OPML file into the current folder</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset theme="document-open"/>
|
||||
</property>
|
||||
<property name="flat">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QSlider" name="sldCorkSizeFactor">
|
||||
<property name="minimumSize">
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
# Form implementation generated from reading ui file 'manuskript/ui/exporters/manuskript/plainTextSettings_ui.ui'
|
||||
#
|
||||
# Created by: PyQt5 UI code generator 5.4.2
|
||||
# Created by: PyQt5 UI code generator 5.9
|
||||
#
|
||||
# WARNING! All changes made in this file will be lost!
|
||||
|
||||
|
@ -28,9 +28,10 @@ class Ui_exporterSettings(object):
|
|||
"}")
|
||||
self.toolBox.setObjectName("toolBox")
|
||||
self.content = QtWidgets.QWidget()
|
||||
self.content.setGeometry(QtCore.QRect(0, 0, 491, 842))
|
||||
self.content.setGeometry(QtCore.QRect(0, 0, 497, 834))
|
||||
self.content.setObjectName("content")
|
||||
self.verticalLayout_5 = QtWidgets.QVBoxLayout(self.content)
|
||||
self.verticalLayout_5.setContentsMargins(0, 0, 0, 0)
|
||||
self.verticalLayout_5.setObjectName("verticalLayout_5")
|
||||
self.label = QtWidgets.QLabel(self.content)
|
||||
self.label.setObjectName("label")
|
||||
|
@ -111,9 +112,10 @@ class Ui_exporterSettings(object):
|
|||
self.verticalLayout_5.addItem(spacerItem1)
|
||||
self.toolBox.addItem(self.content, "")
|
||||
self.separations = QtWidgets.QWidget()
|
||||
self.separations.setGeometry(QtCore.QRect(0, 0, 511, 522))
|
||||
self.separations.setGeometry(QtCore.QRect(0, 0, 511, 534))
|
||||
self.separations.setObjectName("separations")
|
||||
self.verticalLayout_8 = QtWidgets.QVBoxLayout(self.separations)
|
||||
self.verticalLayout_8.setContentsMargins(0, 0, 0, 0)
|
||||
self.verticalLayout_8.setObjectName("verticalLayout_8")
|
||||
self.label_3 = QtWidgets.QLabel(self.separations)
|
||||
font = QtGui.QFont()
|
||||
|
@ -319,10 +321,11 @@ class Ui_exporterSettings(object):
|
|||
self.verticalLayout_8.addItem(spacerItem6)
|
||||
self.toolBox.addItem(self.separations, "")
|
||||
self.transformations = QtWidgets.QWidget()
|
||||
self.transformations.setGeometry(QtCore.QRect(0, 0, 511, 522))
|
||||
self.transformations.setGeometry(QtCore.QRect(0, 0, 511, 534))
|
||||
self.transformations.setStyleSheet("QGroupBox{font-weight:bold;}")
|
||||
self.transformations.setObjectName("transformations")
|
||||
self.verticalLayout_6 = QtWidgets.QVBoxLayout(self.transformations)
|
||||
self.verticalLayout_6.setContentsMargins(0, 0, 0, 0)
|
||||
self.verticalLayout_6.setObjectName("verticalLayout_6")
|
||||
self.grpTransTypo = collapsibleGroupBox2(self.transformations)
|
||||
self.grpTransTypo.setStyleSheet("")
|
||||
|
@ -481,10 +484,11 @@ class Ui_exporterSettings(object):
|
|||
self.verticalLayout_6.addItem(spacerItem10)
|
||||
self.toolBox.addItem(self.transformations, "")
|
||||
self.preview = QtWidgets.QWidget()
|
||||
self.preview.setGeometry(QtCore.QRect(0, 0, 511, 522))
|
||||
self.preview.setGeometry(QtCore.QRect(0, 0, 511, 534))
|
||||
self.preview.setStyleSheet("QGroupBox{font-weight:bold;}")
|
||||
self.preview.setObjectName("preview")
|
||||
self.verticalLayout_11 = QtWidgets.QVBoxLayout(self.preview)
|
||||
self.verticalLayout_11.setContentsMargins(0, 0, 0, 0)
|
||||
self.verticalLayout_11.setObjectName("verticalLayout_11")
|
||||
self.groupBox = QtWidgets.QGroupBox(self.preview)
|
||||
self.groupBox.setObjectName("groupBox")
|
||||
|
|
|
@ -53,8 +53,8 @@ QToolBox::tab:selected, QToolBox::tab:hover{
|
|||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>491</width>
|
||||
<height>842</height>
|
||||
<width>497</width>
|
||||
<height>834</height>
|
||||
</rect>
|
||||
</property>
|
||||
<attribute name="label">
|
||||
|
@ -233,7 +233,7 @@ QToolBox::tab:selected, QToolBox::tab:hover{
|
|||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>511</width>
|
||||
<height>522</height>
|
||||
<height>534</height>
|
||||
</rect>
|
||||
</property>
|
||||
<attribute name="label">
|
||||
|
@ -773,7 +773,7 @@ QToolBox::tab:selected, QToolBox::tab:hover{
|
|||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>511</width>
|
||||
<height>522</height>
|
||||
<height>534</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
|
@ -1162,7 +1162,7 @@ QToolBox::tab:selected, QToolBox::tab:hover{
|
|||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>511</width>
|
||||
<height>522</height>
|
||||
<height>534</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
|
|
46
manuskript/ui/importers/generalSettings.py
Normal file
46
manuskript/ui/importers/generalSettings.py
Normal file
|
@ -0,0 +1,46 @@
|
|||
#!/usr/bin/env python
|
||||
# --!-- coding: utf8 --!--
|
||||
import json
|
||||
import os
|
||||
|
||||
from PyQt5.QtCore import Qt, QSize, QSortFilterProxyModel
|
||||
from PyQt5.QtGui import QIcon, QFontMetrics, QFont
|
||||
from PyQt5.QtWidgets import QWidget, QTableWidgetItem, QListWidgetItem, QTreeView
|
||||
|
||||
from manuskript.functions import mainWindow, writablePath
|
||||
from manuskript.ui.importers.generalSettings_ui import Ui_generalSettings
|
||||
from manuskript.enums import Outline
|
||||
|
||||
class generalSettings(QWidget, Ui_generalSettings):
|
||||
def __init__(self, parent=None):
|
||||
QWidget.__init__(self, parent)
|
||||
self.setupUi(self)
|
||||
|
||||
self.mw = mainWindow()
|
||||
|
||||
# TreeView to select parent
|
||||
# We use a proxy to display only folders
|
||||
proxy = QSortFilterProxyModel()
|
||||
proxy.setFilterKeyColumn(Outline.type.value)
|
||||
proxy.setFilterFixedString("folder")
|
||||
proxy.setSourceModel(self.mw.mdlOutline)
|
||||
self.treeGeneralParent.setModel(proxy)
|
||||
for i in range(1, self.mw.mdlOutline.columnCount()):
|
||||
self.treeGeneralParent.hideColumn(i)
|
||||
self.treeGeneralParent.setCurrentIndex(self.getParentIndex())
|
||||
self.chkGeneralParent.toggled.connect(self.treeGeneralParent.setVisible)
|
||||
self.treeGeneralParent.hide()
|
||||
self.treeGeneralParent.selectionModel().currentChanged.connect(
|
||||
lambda: print(self.treeGeneralParent.currentIndex().row()))
|
||||
|
||||
def getParentIndex(self):
|
||||
"""
|
||||
Returns the currently selected index in the mainWindow.
|
||||
"""
|
||||
if len(self.mw.treeRedacOutline.selectionModel().
|
||||
selection().indexes()) == 0:
|
||||
idx = QModelIndex()
|
||||
else:
|
||||
idx = self.mw.treeRedacOutline.currentIndex()
|
||||
return idx
|
||||
|
67
manuskript/ui/importers/generalSettings_ui.py
Normal file
67
manuskript/ui/importers/generalSettings_ui.py
Normal file
|
@ -0,0 +1,67 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Form implementation generated from reading ui file 'manuskript/ui/importers/generalSettings_ui.ui'
|
||||
#
|
||||
# Created by: PyQt5 UI code generator 5.9
|
||||
#
|
||||
# WARNING! All changes made in this file will be lost!
|
||||
|
||||
from PyQt5 import QtCore, QtGui, QtWidgets
|
||||
|
||||
class Ui_generalSettings(object):
|
||||
def setupUi(self, generalSettings):
|
||||
generalSettings.setObjectName("generalSettings")
|
||||
generalSettings.resize(289, 396)
|
||||
self.verticalLayout_2 = QtWidgets.QVBoxLayout(generalSettings)
|
||||
self.verticalLayout_2.setContentsMargins(0, 0, 0, 0)
|
||||
self.verticalLayout_2.setSpacing(10)
|
||||
self.verticalLayout_2.setObjectName("verticalLayout_2")
|
||||
self.toolBox = QtWidgets.QToolBox(generalSettings)
|
||||
self.toolBox.setStyleSheet("QToolBox::tab{\n"
|
||||
" background-color: #BBB;\n"
|
||||
" padding: 2px;\n"
|
||||
" border: none;\n"
|
||||
"}\n"
|
||||
"\n"
|
||||
"QToolBox::tab:selected, QToolBox::tab:hover{\n"
|
||||
" background-color:skyblue;\n"
|
||||
"}")
|
||||
self.toolBox.setObjectName("toolBox")
|
||||
self.general = QtWidgets.QWidget()
|
||||
self.general.setGeometry(QtCore.QRect(0, 0, 289, 373))
|
||||
self.general.setObjectName("general")
|
||||
self.verticalLayout_5 = QtWidgets.QVBoxLayout(self.general)
|
||||
self.verticalLayout_5.setContentsMargins(0, 0, 0, 0)
|
||||
self.verticalLayout_5.setObjectName("verticalLayout_5")
|
||||
self.formLayout_4 = QtWidgets.QFormLayout()
|
||||
self.formLayout_4.setRowWrapPolicy(QtWidgets.QFormLayout.WrapLongRows)
|
||||
self.formLayout_4.setObjectName("formLayout_4")
|
||||
self.chkGeneralParent = QtWidgets.QCheckBox(self.general)
|
||||
self.chkGeneralParent.setObjectName("chkGeneralParent")
|
||||
self.formLayout_4.setWidget(0, QtWidgets.QFormLayout.LabelRole, self.chkGeneralParent)
|
||||
self.chkGeneralSplitScenes = QtWidgets.QCheckBox(self.general)
|
||||
self.chkGeneralSplitScenes.setObjectName("chkGeneralSplitScenes")
|
||||
self.formLayout_4.setWidget(1, QtWidgets.QFormLayout.LabelRole, self.chkGeneralSplitScenes)
|
||||
self.txtGeneralSplitScenes = QtWidgets.QLineEdit(self.general)
|
||||
self.txtGeneralSplitScenes.setObjectName("txtGeneralSplitScenes")
|
||||
self.formLayout_4.setWidget(1, QtWidgets.QFormLayout.FieldRole, self.txtGeneralSplitScenes)
|
||||
self.treeGeneralParent = QtWidgets.QTreeView(self.general)
|
||||
self.treeGeneralParent.setHeaderHidden(True)
|
||||
self.treeGeneralParent.setObjectName("treeGeneralParent")
|
||||
self.formLayout_4.setWidget(0, QtWidgets.QFormLayout.FieldRole, self.treeGeneralParent)
|
||||
self.verticalLayout_5.addLayout(self.formLayout_4)
|
||||
self.toolBox.addItem(self.general, "")
|
||||
self.verticalLayout_2.addWidget(self.toolBox)
|
||||
|
||||
self.retranslateUi(generalSettings)
|
||||
self.toolBox.setCurrentIndex(0)
|
||||
self.toolBox.layout().setSpacing(0)
|
||||
QtCore.QMetaObject.connectSlotsByName(generalSettings)
|
||||
|
||||
def retranslateUi(self, generalSettings):
|
||||
_translate = QtCore.QCoreApplication.translate
|
||||
generalSettings.setWindowTitle(_translate("generalSettings", "Form"))
|
||||
self.chkGeneralParent.setText(_translate("generalSettings", "Import under:"))
|
||||
self.chkGeneralSplitScenes.setText(_translate("generalSettings", "Split scenes at:"))
|
||||
self.toolBox.setItemText(self.toolBox.indexOf(self.general), _translate("generalSettings", "General"))
|
||||
|
103
manuskript/ui/importers/generalSettings_ui.ui
Normal file
103
manuskript/ui/importers/generalSettings_ui.ui
Normal file
|
@ -0,0 +1,103 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>generalSettings</class>
|
||||
<widget class="QWidget" name="generalSettings">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>289</width>
|
||||
<height>396</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Form</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<property name="spacing">
|
||||
<number>10</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QToolBox" name="toolBox">
|
||||
<property name="styleSheet">
|
||||
<string notr="true">QToolBox::tab{
|
||||
background-color: #BBB;
|
||||
padding: 2px;
|
||||
border: none;
|
||||
}
|
||||
|
||||
QToolBox::tab:selected, QToolBox::tab:hover{
|
||||
background-color:skyblue;
|
||||
}</string>
|
||||
</property>
|
||||
<property name="currentIndex">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="tabSpacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="general">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>289</width>
|
||||
<height>373</height>
|
||||
</rect>
|
||||
</property>
|
||||
<attribute name="label">
|
||||
<string>General</string>
|
||||
</attribute>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_5">
|
||||
<item>
|
||||
<layout class="QFormLayout" name="formLayout_4">
|
||||
<property name="rowWrapPolicy">
|
||||
<enum>QFormLayout::WrapLongRows</enum>
|
||||
</property>
|
||||
<item row="0" column="0">
|
||||
<widget class="QCheckBox" name="chkGeneralParent">
|
||||
<property name="text">
|
||||
<string>Import under:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QCheckBox" name="chkGeneralSplitScenes">
|
||||
<property name="text">
|
||||
<string>Split scenes at:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QLineEdit" name="txtGeneralSplitScenes"/>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QTreeView" name="treeGeneralParent">
|
||||
<property name="headerHidden">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
|
@ -7,15 +7,11 @@ from PyQt5.QtCore import Qt
|
|||
from PyQt5.QtGui import QBrush, QColor, QIcon
|
||||
from PyQt5.QtWidgets import QWidget, QFileDialog
|
||||
|
||||
from manuskript import exporter
|
||||
from manuskript.functions import lightBlue, writablePath, appPath
|
||||
from manuskript.ui.importers.importer_ui import Ui_importer
|
||||
|
||||
class importFormat:
|
||||
def __init__(self, name, icon, fileFormat):
|
||||
self.name = name
|
||||
self.icon = icon
|
||||
self.fileFormat = fileFormat
|
||||
from manuskript.ui.importers.generalSettings import generalSettings
|
||||
from manuskript.ui import style
|
||||
from manuskript import importer
|
||||
|
||||
class importerDialog(QWidget, Ui_importer):
|
||||
|
||||
|
@ -37,15 +33,10 @@ class importerDialog(QWidget, Ui_importer):
|
|||
# Var
|
||||
self.mw = mw
|
||||
self.fileName = ""
|
||||
self.setStyleSheet(style.mainWindowSS())
|
||||
|
||||
# Register importFormats:
|
||||
self.formats = []
|
||||
self.formats.append(importFormat("OPML", "text-x-opml+xml",
|
||||
"OPML Files (*.opml)"))
|
||||
self.formats.append(importFormat("Markdown", "text-x-markdown",
|
||||
"Markdown files (*.md; *.txt; *)"))
|
||||
self.formats.append(importFormat("Folder", "folder",
|
||||
"<<folder>>"))
|
||||
self.importers = importer.importers
|
||||
|
||||
# Populate combo box with formats
|
||||
self.populateImportList()
|
||||
|
@ -54,7 +45,10 @@ class importerDialog(QWidget, Ui_importer):
|
|||
self.btnChoseFile.clicked.connect(self.selectFile)
|
||||
self.btnClearFileName.clicked.connect(self.setFileName)
|
||||
self.btnPreview.clicked.connect(self.preview)
|
||||
self.setFileName("")
|
||||
self.cmbImporters.currentTextChanged.connect(self.updateSettings)
|
||||
|
||||
#self.setFileName("")
|
||||
self.setFileName("/home/olivier/Dropbox/Documents/Travail/Geekeries/Python/PyCharmProjects/manuskript/test-projects/IMPORTS/End Plan 2.opml")
|
||||
|
||||
############################################################################
|
||||
# Combobox / Formats
|
||||
|
@ -65,18 +59,25 @@ class importerDialog(QWidget, Ui_importer):
|
|||
def addFormat(name, icon):
|
||||
self.cmbImporters.addItem(QIcon.fromTheme(icon), name)
|
||||
|
||||
for f in self.formats:
|
||||
for f in self.importers:
|
||||
addFormat(f.name, f.icon)
|
||||
|
||||
def currentFormat(self):
|
||||
formatName = self.cmbImporters.currentText()
|
||||
F = [F for F in self.importers if F.name == formatName][0]
|
||||
return F
|
||||
|
||||
############################################################################
|
||||
# Import file
|
||||
############################################################################
|
||||
|
||||
def selectFile(self):
|
||||
"""
|
||||
Called to select a file in the file system. Uses QFileDialog.
|
||||
"""
|
||||
|
||||
# We find the current selected format
|
||||
formatName = self.cmbImporters.currentText()
|
||||
F = [F for F in self.formats if F.name == formatName][0]
|
||||
F = self.currentFormat()
|
||||
|
||||
options = QFileDialog.Options()
|
||||
options |= QFileDialog.DontUseNativeDialog
|
||||
|
@ -90,47 +91,70 @@ class importerDialog(QWidget, Ui_importer):
|
|||
self.setFileName(fileName)
|
||||
|
||||
def setFileName(self, fileName):
|
||||
"""
|
||||
Updates Ui with given filename. Filename can be empty.
|
||||
"""
|
||||
if fileName:
|
||||
self.fileName = fileName
|
||||
self.btnPreview.setEnabled(True)
|
||||
self.lblFileName.setText(os.path.basename(fileName))
|
||||
self.lblFileName.setToolTip(fileName)
|
||||
self.btnClearFileName.setVisible(True)
|
||||
ext = os.path.splitext(fileName)[1]
|
||||
if ext and ext in self.formatsIcon:
|
||||
self.lblIcon.setVisible(True)
|
||||
h = self.lblFileName.height()
|
||||
self.lblIcon.setPixmap(
|
||||
QIcon.fromTheme(self.formatsIcon[ext]).pixmap(h, h)
|
||||
)
|
||||
icon = QIcon.fromTheme(self.formatsIcon[ext])
|
||||
elif os.path.isdir(fileName):
|
||||
self.lblIcon.setVisible(True)
|
||||
h = self.lblFileName.height()
|
||||
self.lblIcon.setPixmap(QIcon.fromTheme("folder").pixmap(h, h))
|
||||
icon = QIcon.fromTheme("folder")
|
||||
|
||||
#self.lblIcon.setVisible(True)
|
||||
h = self.lblFileName.height()
|
||||
self.lblIcon.setPixmap(icon.pixmap(h, h))
|
||||
|
||||
else:
|
||||
self.fileName = None
|
||||
self.btnPreview.setEnabled(False)
|
||||
self.lblFileName.setText("")
|
||||
self.btnClearFileName.setVisible(False)
|
||||
self.lblIcon.setVisible(False)
|
||||
|
||||
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)
|
||||
|
||||
############################################################################
|
||||
# Preview
|
||||
# UI
|
||||
############################################################################
|
||||
|
||||
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)
|
||||
|
||||
#TODO: custom format widget
|
||||
|
||||
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)
|
||||
|
||||
############################################################################
|
||||
# Preview / Import
|
||||
############################################################################
|
||||
|
||||
def preview(self):
|
||||
# TODO
|
||||
pass
|
||||
|
||||
############################################################################
|
||||
#
|
||||
############################################################################
|
||||
|
||||
def getParentIndex(self):
|
||||
if len(self.mw.treeRedacOutline.selectionModel().
|
||||
selection().indexes()) == 0:
|
||||
idx = QModelIndex()
|
||||
else:
|
||||
idx = self.mw.treeRedacOutline.currentIndex()
|
||||
return idx
|
||||
|
|
|
@ -22,12 +22,6 @@ class Ui_importer(object):
|
|||
self.cmbImporters = QtWidgets.QComboBox(importer)
|
||||
self.cmbImporters.setObjectName("cmbImporters")
|
||||
self.horizontalLayout.addWidget(self.cmbImporters)
|
||||
self.btnManageImporters = QtWidgets.QPushButton(importer)
|
||||
self.btnManageImporters.setText("")
|
||||
icon = QtGui.QIcon.fromTheme("preferences-system")
|
||||
self.btnManageImporters.setIcon(icon)
|
||||
self.btnManageImporters.setObjectName("btnManageImporters")
|
||||
self.horizontalLayout.addWidget(self.btnManageImporters)
|
||||
spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
|
||||
self.horizontalLayout.addItem(spacerItem)
|
||||
self.btnChoseFile = QtWidgets.QPushButton(importer)
|
||||
|
@ -59,8 +53,14 @@ class Ui_importer(object):
|
|||
self.btnPreview = QtWidgets.QPushButton(importer)
|
||||
icon = QtGui.QIcon.fromTheme("document-print-preview")
|
||||
self.btnPreview.setIcon(icon)
|
||||
self.btnPreview.setFlat(True)
|
||||
self.btnPreview.setObjectName("btnPreview")
|
||||
self.horizontalLayout.addWidget(self.btnPreview)
|
||||
self.btnImport = QtWidgets.QPushButton(importer)
|
||||
icon = QtGui.QIcon.fromTheme("document-import")
|
||||
self.btnImport.setIcon(icon)
|
||||
self.btnImport.setObjectName("btnImport")
|
||||
self.horizontalLayout.addWidget(self.btnImport)
|
||||
self.verticalLayout.addLayout(self.horizontalLayout)
|
||||
self.splitter = QtWidgets.QSplitter(importer)
|
||||
self.splitter.setOrientation(QtCore.Qt.Horizontal)
|
||||
|
@ -77,6 +77,10 @@ class Ui_importer(object):
|
|||
self.verticalLayout_2.setContentsMargins(0, 0, 0, 0)
|
||||
self.verticalLayout_2.setSpacing(0)
|
||||
self.verticalLayout_2.setObjectName("verticalLayout_2")
|
||||
self.splitter_2 = QtWidgets.QSplitter(self.grpPreview)
|
||||
self.splitter_2.setOrientation(QtCore.Qt.Horizontal)
|
||||
self.splitter_2.setObjectName("splitter_2")
|
||||
self.verticalLayout_2.addWidget(self.splitter_2)
|
||||
self.verticalLayout.addWidget(self.splitter)
|
||||
|
||||
self.retranslateUi(importer)
|
||||
|
@ -86,9 +90,10 @@ class Ui_importer(object):
|
|||
_translate = QtCore.QCoreApplication.translate
|
||||
importer.setWindowTitle(_translate("importer", "Import"))
|
||||
self.label.setText(_translate("importer", "Format:"))
|
||||
self.btnManageImporters.setToolTip(_translate("importer", "Manage importers"))
|
||||
self.btnChoseFile.setText(_translate("importer", "Chose file"))
|
||||
self.btnClearFileName.setToolTip(_translate("importer", "Clear file"))
|
||||
self.btnPreview.setText(_translate("importer", "Preview"))
|
||||
self.btnImport.setText(_translate("importer", "Import"))
|
||||
self.grpSettings.setTitle(_translate("importer", "Settings"))
|
||||
self.grpPreview.setTitle(_translate("importer", "Preview"))
|
||||
|
||||
|
|
|
@ -26,21 +26,6 @@
|
|||
<item>
|
||||
<widget class="QComboBox" name="cmbImporters"/>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="btnManageImporters">
|
||||
<property name="toolTip">
|
||||
<string>Manage importers</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset theme="preferences-system">
|
||||
<normaloff/>
|
||||
</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_2">
|
||||
<property name="orientation">
|
||||
|
@ -60,7 +45,8 @@
|
|||
<string>Chose file</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset theme="document-import"/>
|
||||
<iconset theme="document-import">
|
||||
<normaloff>../../../../../../../../../../.designer/backup</normaloff>../../../../../../../../../../.designer/backup</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
@ -86,11 +72,15 @@
|
|||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="btnClearFileName">
|
||||
<property name="toolTip">
|
||||
<string>Clear file</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset theme="edit-clear"/>
|
||||
<iconset theme="edit-clear">
|
||||
<normaloff>../../../../../../../../../../.designer/backup</normaloff>../../../../../../../../../../.designer/backup</iconset>
|
||||
</property>
|
||||
<property name="flat">
|
||||
<bool>true</bool>
|
||||
|
@ -117,8 +107,20 @@
|
|||
</property>
|
||||
<property name="icon">
|
||||
<iconset theme="document-print-preview">
|
||||
<normaloff/>
|
||||
</iconset>
|
||||
<normaloff>../../../../../../../../../../.designer/backup</normaloff>../../../../../../../../../../.designer/backup</iconset>
|
||||
</property>
|
||||
<property name="flat">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="btnImport">
|
||||
<property name="text">
|
||||
<string>Import</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset theme="document-import"/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
@ -171,6 +173,13 @@
|
|||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QSplitter" name="splitter_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
|
|
Loading…
Reference in a new issue