manuskript/manuskript/ui/editors/tabSplitter.py

259 lines
9.1 KiB
Python
Raw Normal View History

2016-04-11 03:29:27 +12:00
#!/usr/bin/env python
# --!-- coding: utf8 --!--
import locale
2016-04-11 08:04:31 +12:00
from PyQt5.QtCore import QModelIndex, QRect, QPoint, Qt, QObject, QSize
2016-04-11 17:50:44 +12:00
from PyQt5.QtGui import QIcon, QPalette
2016-04-11 03:29:27 +12:00
from PyQt5.QtWidgets import QWidget, QPushButton, qApp
2016-04-12 09:54:47 +12:00
from manuskript.functions import mainWindow, appPath
2016-04-11 03:29:27 +12:00
from manuskript.ui import style
from manuskript.ui.editors.tabSplitter_ui import Ui_tabSplitter
class tabSplitter(QWidget, Ui_tabSplitter):
"""
`tabSplitter` is used to have multiple `outlineItem`s open, either in tabs
and/or in split views. Each tab contains an `editorWidget` which is responsible
for showing one single `outlineItem` in several ways.
`tabSplitter` is managed mainly through the `mainEditor` which is responsible
for opening indexes and such.
`tabSplitter` main widget is a `QSplitter` named `self.splitter`. It contains one
`QTabWidget` called `self.tab`. A second `tabSplitter` can be loaded through
`self.split` in `self.splitter`. That way, a single `tabSplitter` can split
indefinitely.
`tabSplitter` also has two buttons:
1. `self.btnSplit`: used to split and unsplit
2. `self.btnTarget`: toggles whether `self.tab` is a target to open any
selected outlineItem in any other views.
"""
2016-04-11 03:29:27 +12:00
def __init__(self, parent=None, mainEditor=None):
QWidget.__init__(self, parent)
self.setupUi(self)
2016-04-12 01:14:24 +12:00
# try:
# self.tab.setTabBarAutoHide(True)
# except AttributeError:
# print("Info: install Qt 5.4 or higher to use tab bar auto-hide in editor.")
2016-04-11 03:29:27 +12:00
2016-04-12 01:14:24 +12:00
# Button to split
2016-04-11 08:04:31 +12:00
self.btnSplit = QPushButton(self)
2016-04-11 03:29:27 +12:00
self.btnSplit.setGeometry(QRect(0, 0, 24, 24))
self.btnSplit.setMinimumSize(QSize(24, 24))
self.btnSplit.setMaximumSize(QSize(24, 24))
2016-04-11 08:04:31 +12:00
# self.btnSplit.setCheckable(True)
2016-04-11 03:29:27 +12:00
self.btnSplit.setFlat(True)
self.btnSplit.setObjectName("btnSplit")
2016-04-11 17:50:44 +12:00
self.btnSplit.installEventFilter(self)
2016-04-12 01:14:24 +12:00
self.btnSplit.clicked.connect(self.split)
# Button to set target
self.isTarget = False
self.btnTarget = QPushButton(QIcon.fromTheme("set-target"), "", self)
self.btnTarget.setGeometry(QRect(25, 0, 24, 24))
self.btnTarget.setMinimumSize(QSize(24, 24))
self.btnTarget.setMaximumSize(QSize(24, 24))
# self.btnTarget.setCheckable(True)
self.btnTarget.setFlat(True)
self.btnTarget.setObjectName("btnTarget")
self.btnTarget.clicked.connect(self.setTarget)
2016-04-12 09:54:47 +12:00
self.btnTarget.setToolTip(self.tr("Open selected items in that view."))
2016-04-12 01:14:24 +12:00
self.updateTargetIcon(self.isTarget)
2016-04-11 03:29:27 +12:00
self.mainEditor = mainEditor or parent
self.secondTab = None
self.splitState = 0
self.focusTab = 1
2016-04-11 08:04:31 +12:00
self.closeSplit()
2016-04-11 03:29:27 +12:00
2016-04-12 01:14:24 +12:00
self.updateStyleSheet()
2016-04-11 03:29:27 +12:00
self.tab.tabCloseRequested.connect(self.closeTab)
self.tab.currentChanged.connect(self.mainEditor.tabChanged)
qApp.focusChanged.connect(self.focusChanged)
2016-04-12 01:14:24 +12:00
def updateStyleSheet(self):
self.setStyleSheet(style.mainEditorTabSS())
if self.secondTab:
self.secondTab.updateStyleSheet()
2016-04-11 03:29:27 +12:00
###############################################################################
# TABS
###############################################################################
def closeTab(self, index):
w = self.tab.widget(index)
self.tab.removeTab(index)
w.setCurrentModelIndex(QModelIndex())
w.deleteLater()
def tabOpenIndexes(self):
sel = []
for i in range(self.tab.count()):
sel.append(mainWindow().mdlOutline.ID(self.tab.widget(i).currentIndex))
return sel
def openIndexes(self):
r = [
self.splitState,
self.tabOpenIndexes(),
self.secondTab.openIndexes() if self.secondTab else None,
]
return r
def restoreOpenIndexes(self, openIndexes):
try:
2016-04-12 09:54:47 +12:00
if openIndexes[1]:
self.split(state=openIndexes[0])
2016-04-11 03:29:27 +12:00
for i in openIndexes[1]:
idx = mainWindow().mdlOutline.getIndexByID(i)
self.mainEditor.setCurrentModelIndex(idx, newTab=True)
if openIndexes[2]:
self.focusTab = 2
self.secondTab.restoreOpenIndexes(openIndexes[2])
except:
# Cannot load open indexes. Let's simply open root.
self.mainEditor.setCurrentModelIndex(QModelIndex(), newTab=True)
2016-04-11 03:29:27 +12:00
2016-04-12 01:14:24 +12:00
###############################################################################
# TARGET
###############################################################################
def setTarget(self):
self.isTarget = not self.isTarget
self.updateTargetIcon(self.isTarget)
def updateTargetIcon(self, val):
2016-04-12 09:54:47 +12:00
icon = QIcon.fromTheme("set-target", QIcon(appPath("icons/NumixMsk/256x256/actions/set-target.svg")))
2016-04-12 01:14:24 +12:00
if not val:
icon = QIcon(icon.pixmap(128, 128, icon.Disabled))
self.btnTarget.setIcon(icon)
2016-04-11 03:29:27 +12:00
###############################################################################
# SPLITTER
###############################################################################
def split(self, toggled=None, state=None):
2021-02-22 11:45:34 +13:00
if state == None and self.splitState == 0 or state == 1:
if self.secondTab == None:
2016-04-11 03:29:27 +12:00
self.addSecondTab()
self.splitState = 1
self.splitter.setOrientation(Qt.Horizontal)
2016-04-11 08:04:31 +12:00
# self.btnSplit.setChecked(True)
self.btnSplit.setIcon(QIcon.fromTheme("split-vertical"))
self.btnSplit.setToolTip(self.tr("Split horizontally"))
2016-04-11 03:29:27 +12:00
2021-02-22 11:45:34 +13:00
elif state == None and self.splitState == 1 or state == 2:
if self.secondTab == None:
2016-04-11 03:29:27 +12:00
self.addSecondTab()
self.splitter.setOrientation(Qt.Vertical)
self.splitState = 2
2016-04-11 08:04:31 +12:00
# self.btnSplit.setChecked(True)
self.btnSplit.setIcon(QIcon.fromTheme("split-horizontal"))
self.btnSplit.setToolTip(self.tr("Close split"))
2016-04-11 03:29:27 +12:00
else:
self.closeSplit()
def addSecondTab(self):
self.secondTab = tabSplitter(mainEditor=self.mainEditor)
2016-04-11 17:50:44 +12:00
self.secondTab.setObjectName(self.objectName() + "_")
2016-04-12 01:41:43 +12:00
self.secondTab.splitter.setObjectName(self.splitter.objectName() + "_")
2016-04-11 03:29:27 +12:00
self.splitter.addWidget(self.secondTab)
self.splitter.setStretchFactor(0, 10)
self.splitter.setStretchFactor(1, 10)
if self.mainEditor.currentEditor():
idx = self.mainEditor.currentEditor().currentIndex
self.focusTab = 2
self.mainEditor.setCurrentModelIndex(idx)
def closeSplit(self):
2016-04-11 17:50:44 +12:00
st = self.secondTab
l = []
while st:
l.append(st)
st = st.secondTab
for st in reversed(l):
st.setParent(None)
qApp.focusChanged.disconnect(st.focusChanged)
st.deleteLater()
2016-04-11 03:29:27 +12:00
self.focusTab = 1
self.secondTab = None
2016-04-11 08:04:31 +12:00
# self.btnSplit.setChecked(False)
2016-04-11 03:29:27 +12:00
self.splitState = 0
2016-04-11 08:04:31 +12:00
self.btnSplit.setIcon(QIcon.fromTheme("split-close"))
self.btnSplit.setToolTip(self.tr("Split vertically"))
2016-04-11 03:29:27 +12:00
2016-04-12 01:14:24 +12:00
if len(l):
self.mainEditor.tabChanged()
2016-04-11 03:29:27 +12:00
# def resizeEvent(self, event):
# r = self.geometry()
# r.moveLeft(0)
# r.moveTop(0)
# self.splitter.setGeometry(r)
# self.btnSplit.setGeometry(QRect(0, 0, 24, 24))
def focusChanged(self, old, new):
2021-02-22 11:45:34 +13:00
if self.secondTab == None or new == None:
2016-04-11 03:29:27 +12:00
return
oldFT = self.focusTab
while new:
if new == self.tab:
self.focusTab = 1
new = None
elif new == self.secondTab:
self.focusTab = 2
new = None
else:
new = new.parent()
if self.focusTab != oldFT:
2016-04-11 17:50:44 +12:00
self.mainEditor.tabChanged()
def eventFilter(self, object, event):
if object == self.btnSplit and event.type() == event.HoverEnter:
2016-04-12 09:54:47 +12:00
# self.setAutoFillBackground(True)
# self.setBackgroundRole(QPalette.Highlight)
2016-04-12 01:41:43 +12:00
# self.splitter.setAutoFillBackground(True)
# self.splitter.setStyleSheet("""QSplitter#{}{{
# border:1px solid darkblue;
# }}""".format(self.splitter.objectName()))
2016-04-12 09:54:47 +12:00
2017-11-15 02:48:28 +13:00
self.setStyleSheet(style.mainEditorTabSS() + """
QSplitter#{name},
QSplitter#{name} > QWidget > QSplitter{{
border:3px solid {color};
}}""".format(
name=self.splitter.objectName(),
color=style.highlight))
2016-04-11 17:50:44 +12:00
elif object == self.btnSplit and event.type() == event.HoverLeave:
2016-04-12 09:54:47 +12:00
# self.setAutoFillBackground(False)
# self.setBackgroundRole(QPalette.Window)
2016-04-12 01:41:43 +12:00
# self.splitter.setStyleSheet("""QSplitter#{}{{
# border: 1px solid transparent;
# }}""".format(self.splitter.objectName()))
2016-04-12 09:54:47 +12:00
self.setStyleSheet(style.mainEditorTabSS())
return QWidget.eventFilter(self, object, event)