Can split views

This commit is contained in:
Olivier Keshavjee 2016-04-10 17:29:27 +02:00
parent c3613f0687
commit 373b36406a
9 changed files with 377 additions and 73 deletions

View file

@ -314,9 +314,8 @@ class MainWindow(QMainWindow, Ui_MainWindow):
self.makeConnections()
# Load settings
for i in settings.openIndexes:
idx = self.mdlOutline.getIndexByID(i)
self.mainEditor.setCurrentModelIndex(idx, newTab=True)
if settings.openIndexes:
self.mainEditor.tabSplitter.restoreOpenIndexes(settings.openIndexes)
self.generateViewMenu()
self.mainEditor.sldCorkSizeFactor.setValue(settings.corkSizeFactor)
self.actSpellcheck.setChecked(settings.spellcheck)
@ -447,10 +446,7 @@ class MainWindow(QMainWindow, Ui_MainWindow):
if self.currentProject:
# Remembering the current items (stores outlineItem's ID)
sel = []
for i in range(self.mainEditor.tab.count()):
sel.append(self.mdlOutline.ID(self.mainEditor.tab.widget(i).currentIndex))
settings.openIndexes = sel
settings.openIndexes = self.mainEditor.tabSplitter.openIndexes()
# Save data from models
if self.currentProject and settings.saveOnQuit:

View file

@ -26,21 +26,14 @@ class mainEditor(QWidget, Ui_mainEditor):
self._updating = False
self.mw = mainWindow()
self.tab.tabCloseRequested.connect(self.closeTab)
self.tab.currentChanged.connect(self.tabChanged)
# UI
try:
self.tab.setTabBarAutoHide(True)
except AttributeError:
print("Info: install Qt 5.4 or higher to use tabbar auto-hide in editor.")
# Connections --------------------------------------------------------
self.sldCorkSizeFactor.valueChanged.connect(
self.setCorkSizeFactor, AUC)
self.btnRedacFolderCork.toggled.connect(
self.sldCorkSizeFactor.setVisible, AUC)
self.sldCorkSizeFactor.setVisible, AUC
)
self.btnRedacFolderText.clicked.connect(
lambda v: self.setFolderView("text"), AUC)
self.btnRedacFolderCork.clicked.connect(
@ -51,28 +44,33 @@ class mainEditor(QWidget, Ui_mainEditor):
self.btnRedacFullscreen.clicked.connect(
self.showFullScreen, AUC)
self.tab.setDocumentMode(False)
self.tab.setStyleSheet(style.mainEditorTabSS())
# self.tab.setDocumentMode(False)
###############################################################################
# TABS
###############################################################################
def currentEditor(self):
return self.tab.currentWidget()
def currentTabWidget(self):
"""Returns the tabSplitter that has focus."""
ts = self.tabSplitter
while ts:
if ts.focusTab == 1:
return ts.tab
else:
ts = ts.secondTab
def tabChanged(self, index):
def currentEditor(self):
return self.currentTabWidget().currentWidget()
# return self.tab.currentWidget()
def tabChanged(self, index=QModelIndex()):
if self.currentEditor():
index = self.currentEditor().currentIndex
view = self.currentEditor().folderView
self.updateFolderViewButtons(view)
if index.isValid():
hidden = not index.internalPointer().isFolder()
else:
hidden = False
else:
index = QModelIndex()
hidden = False
self._updating = True
self.mw.treeRedacOutline.setCurrentIndex(index)
@ -81,18 +79,35 @@ class mainEditor(QWidget, Ui_mainEditor):
self.updateStats()
self.updateThingsVisible(index)
def closeTab(self, index):
w = self.tab.widget(index)
self.tab.removeTab(index)
w.setCurrentModelIndex(QModelIndex())
w.deleteLater()
def closeAllTabs(self):
while(self.tab.count()):
self.closeTab(0)
for ts in self.allTabSplitters():
while(ts.tab.count()):
ts.closeTab(0)
for ts in reversed(self.allTabSplitters()):
ts.closeSplit()
def allTabs(self, tabWidget=None):
"""Returns all the tabs from the given tabWidget. If tabWidget is None, from the current tabWidget."""
if tabWidget is None:
tabWidget = self.currentTabWidget()
return [tabWidget.widget(i) for i in range(tabWidget.count())]
def allAllTabs(self):
"""Returns a list of all tabs, from all tabWidgets."""
r = []
for ts in self.allTabSplitters():
r.extend(self.allTabs(ts.tab))
return r
def allTabSplitters(self):
r = []
ts = self.tabSplitter
while ts:
r.append(ts)
ts = ts.secondTab
return r
def allTabs(self):
return [self.tab.widget(i) for i in range(self.tab.count())]
###############################################################################
# SELECTION AND UPDATES
@ -126,20 +141,20 @@ class mainEditor(QWidget, Ui_mainEditor):
# Checking if tab is already openned
for w in self.allTabs():
if w.currentIndex == index:
self.tab.setCurrentWidget(w)
self.currentTabWidget().setCurrentWidget(w)
return
if qApp.keyboardModifiers() & Qt.ControlModifier:
newTab = True
if newTab or not self.tab.count():
if newTab or not self.currentTabWidget().count():
editor = editorWidget(self)
editor.setCurrentModelIndex(index)
self.tab.addTab(editor, title)
self.tab.setCurrentIndex(self.tab.count() - 1)
self.currentTabWidget().addTab(editor, title)
self.currentTabWidget().setCurrentIndex(self.currentTabWidget().count() - 1)
else:
self.currentEditor().setCurrentModelIndex(index)
self.tab.setTabText(self.tab.currentIndex(), title)
self.currentTabWidget().setTabText(self.currentTabWidget().currentIndex(), title)
###############################################################################
# UI
@ -157,7 +172,7 @@ class mainEditor(QWidget, Ui_mainEditor):
self.btnRedacFolderText.setVisible(visible)
self.btnRedacFolderCork.setVisible(visible)
self.btnRedacFolderOutline.setVisible(visible)
self.sldCorkSizeFactor.setVisible(visible)
self.sldCorkSizeFactor.setVisible(visible and self.btnRedacFolderCork.isChecked())
self.btnRedacFullscreen.setVisible(not visible)
def updateFolderViewButtons(self, view):
@ -216,20 +231,20 @@ class mainEditor(QWidget, Ui_mainEditor):
self.currentEditor().setFolderView(view)
def setCorkSizeFactor(self, val):
for w in self.allTabs():
for w in self.allAllTabs():
w.setCorkSizeFactor(val)
settings.corkSizeFactor = val
def updateCorkView(self):
for w in self.allTabs():
for w in self.allAllTabs():
w.corkView.viewport().update()
def updateCorkBackground(self):
for w in self.allTabs():
for w in self.allAllTabs():
w.corkView.updateBackground()
def updateTreeView(self):
for w in self.allTabs():
for w in self.allAllTabs():
w.outlineView.viewport().update()
def showFullScreen(self):
@ -242,9 +257,9 @@ class mainEditor(QWidget, Ui_mainEditor):
def setDict(self, dict):
print(dict)
for w in self.allTabs():
for w in self.allAllTabs():
w.setDict(dict)
def toggleSpellcheck(self, val):
for w in self.allTabs():
for w in self.allAllTabs():
w.toggleSpellcheck(val)

View file

@ -2,7 +2,7 @@
# Form implementation generated from reading ui file 'manuskript/ui/editors/mainEditor_ui.ui'
#
# Created: Fri Apr 8 18:15:49 2016
# Created: Sun Apr 10 11:19:00 2016
# by: PyQt5 UI code generator 5.2.1
#
# WARNING! All changes made in this file will be lost!
@ -14,15 +14,17 @@ 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.setObjectName("verticalLayout")
self.tab = QtWidgets.QTabWidget(mainEditor)
self.tab.setDocumentMode(True)
self.tab.setTabsClosable(True)
self.tab.setMovable(True)
self.tab.setProperty("tabBarAutoHide", False)
self.tab.setObjectName("tab")
self.verticalLayout.addWidget(self.tab)
self.tabSplitter = tabSplitter(mainEditor)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Expanding)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.tabSplitter.sizePolicy().hasHeightForWidth())
self.tabSplitter.setSizePolicy(sizePolicy)
self.tabSplitter.setObjectName("tabSplitter")
self.verticalLayout.addWidget(self.tabSplitter)
self.horizontalLayout_19 = QtWidgets.QHBoxLayout()
self.horizontalLayout_19.setObjectName("horizontalLayout_19")
self.btnRedacFolderText = QtWidgets.QPushButton(mainEditor)
@ -89,7 +91,6 @@ class Ui_mainEditor(object):
self.verticalLayout.addLayout(self.horizontalLayout_19)
self.retranslateUi(mainEditor)
self.tab.setCurrentIndex(-1)
QtCore.QMetaObject.connectSlotsByName(mainEditor)
def retranslateUi(self, mainEditor):
@ -100,4 +101,5 @@ class Ui_mainEditor(object):
self.btnRedacFolderOutline.setText(_translate("mainEditor", "Outline"))
self.btnRedacFullscreen.setShortcut(_translate("mainEditor", "F11"))
from manuskript.ui.editors.tabSplitter import tabSplitter
from manuskript.ui.editors.textFormat import textFormat

View file

@ -14,6 +14,9 @@
<string>Form</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<property name="spacing">
<number>0</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
@ -27,21 +30,12 @@
<number>0</number>
</property>
<item>
<widget class="QTabWidget" name="tab">
<property name="currentIndex">
<number>-1</number>
</property>
<property name="documentMode">
<bool>true</bool>
</property>
<property name="tabsClosable">
<bool>true</bool>
</property>
<property name="movable">
<bool>true</bool>
</property>
<property name="tabBarAutoHide" stdset="0">
<bool>false</bool>
<widget class="tabSplitter" name="tabSplitter" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
@ -228,6 +222,12 @@
<header>manuskript.ui.editors.textFormat.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>tabSplitter</class>
<extends>QWidget</extends>
<header>manuskript.ui.editors.tabSplitter.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<resources/>
<connections/>

View file

@ -0,0 +1,163 @@
#!/usr/bin/env python
# --!-- coding: utf8 --!--
import locale
from PyQt5.QtCore import QModelIndex, QRect, QPoint
from PyQt5.QtCore import Qt, QObject, QSize
from PyQt5.QtGui import QPixmap, QPainter
from PyQt5.QtWidgets import QWidget, QPushButton, qApp
from manuskript.functions import mainWindow
from manuskript.ui import style
from manuskript.ui.editors.tabSplitter_ui import Ui_tabSplitter
class tabSplitter(QWidget, Ui_tabSplitter):
def __init__(self, parent=None, mainEditor=None):
QWidget.__init__(self, parent)
self.setupUi(self)
self.tab.setStyleSheet(style.mainEditorTabSS())
try:
self.tab.setTabBarAutoHide(True)
except AttributeError:
print("Info: install Qt 5.4 or higher to use tabbar auto-hide in editor.")
#Remove empty widget
# self.splitter.widget(1).setParent(None)
self.btmSplit = QPushButton()
self.btnSplit = QPushButton("S", self)
self.btnSplit.setGeometry(QRect(0, 0, 24, 24))
self.btnSplit.setMinimumSize(QSize(24, 24))
self.btnSplit.setMaximumSize(QSize(24, 24))
self.btnSplit.setCheckable(True)
self.btnSplit.setFlat(True)
self.btnSplit.setObjectName("btnSplit")
self.mainEditor = mainEditor or parent
self.btnSplit.clicked.connect(self.split)
self.secondTab = None
self.splitState = 0
self.focusTab = 1
self.tab.tabCloseRequested.connect(self.closeTab)
self.tab.currentChanged.connect(self.mainEditor.tabChanged)
qApp.focusChanged.connect(self.focusChanged)
###############################################################################
# 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:
self.split(state=openIndexes[0])
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:
print("Failed to load indexes from settings...")
print("Indexes:", openIndexes)
###############################################################################
# SPLITTER
###############################################################################
def split(self, toggled=None, state=None):
if state is None and self.splitState == 0 or state == 1:
if self.secondTab is None:
self.addSecondTab()
self.splitState = 1
self.splitter.setOrientation(Qt.Horizontal)
self.btnSplit.setChecked(True)
elif state is None and self.splitState == 1 or state == 2:
if self.secondTab is None:
self.addSecondTab()
self.splitter.setOrientation(Qt.Vertical)
self.splitState = 2
self.btnSplit.setChecked(True)
else:
self.closeSplit()
def addSecondTab(self):
self.secondTab = tabSplitter(mainEditor=self.mainEditor)
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):
if self.secondTab:
self.secondTab.setParent(None)
self.secondTab.deleteLater()
qApp.focusChanged.disconnect(self.secondTab.focusChanged)
self.focusTab = 1
self.secondTab = None
self.btnSplit.setChecked(False)
self.splitState = 0
# 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):
if self.secondTab is None or new is None:
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:
self.mainEditor.tabChanged()

View file

@ -0,0 +1,41 @@
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'manuskript/ui/editors/tabSplitter_ui.ui'
#
# Created: Sun Apr 10 16:27:03 2016
# by: PyQt5 UI code generator 5.2.1
#
# WARNING! All changes made in this file will be lost!
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_tabSplitter(object):
def setupUi(self, tabSplitter):
tabSplitter.setObjectName("tabSplitter")
tabSplitter.resize(400, 300)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(tabSplitter.sizePolicy().hasHeightForWidth())
tabSplitter.setSizePolicy(sizePolicy)
tabSplitter.setWindowTitle("tabSPlitter")
self.verticalLayout = QtWidgets.QVBoxLayout(tabSplitter)
self.verticalLayout.setSpacing(0)
self.verticalLayout.setContentsMargins(0, 0, 0, 0)
self.verticalLayout.setObjectName("verticalLayout")
self.splitter = QtWidgets.QSplitter(tabSplitter)
self.splitter.setMinimumSize(QtCore.QSize(30, 30))
self.splitter.setOrientation(QtCore.Qt.Horizontal)
self.splitter.setObjectName("splitter")
self.tab = QtWidgets.QTabWidget(self.splitter)
self.tab.setTabsClosable(True)
self.tab.setMovable(True)
self.tab.setObjectName("tab")
self.verticalLayout.addWidget(self.splitter)
self.retranslateUi(tabSplitter)
QtCore.QMetaObject.connectSlotsByName(tabSplitter)
def retranslateUi(self, tabSplitter):
pass

View file

@ -0,0 +1,63 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>tabSplitter</class>
<widget class="QWidget" name="tabSplitter">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>300</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="windowTitle">
<string notr="true">tabSPlitter</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<property name="spacing">
<number>0</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="QSplitter" name="splitter">
<property name="minimumSize">
<size>
<width>30</width>
<height>30</height>
</size>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<widget class="QTabWidget" name="tab">
<property name="tabsClosable">
<bool>true</bool>
</property>
<property name="movable">
<bool>true</bool>
</property>
</widget>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

View file

@ -90,7 +90,7 @@ def mainEditorTabSS():
border: 1px solid #999;
}
QTabWidget::tab-bar{
left:10px;
left:25px;
}
QTabBar{
background: transparent;
@ -113,6 +113,29 @@ def mainEditorTabSS():
QTabBar::tab:!selected:hover{
background:#ddd;
}
QScrollBar:vertical {
border: none;
background: transparent;
width: 10px;
}
QScrollBar::handle {
background: rgba(180, 180, 180, 40%);
}
QScrollBar::add-line:vertical {
width:0;
height: 0;
border: none;
background: none;
}
QScrollBar::sub-line:vertical {
width:0;
height: 0;
border: none;
background: none;
}
"""
def toolBarSS():

View file

@ -29,6 +29,7 @@ class corkView(QListView, dndView, outlineBasics):
self.setStyleSheet("""QListView {{
background:{color};
background-image: url({url});
background-attachment: fixed;
}}""".format(
color=settings.corkBackground["color"],
url=img