Refactoring and upstream module like structure
- Improved start logic (including Qt 5 support) - Static selector menu button mode implemented - By default selector menu at front is now being used - List of selector menu workbenches is now customizable
This commit is contained in:
parent
e2036603d0
commit
c7984ce5c1
475
SelectorToolbar_Gui.py
Normal file
475
SelectorToolbar_Gui.py
Normal file
|
@ -0,0 +1,475 @@
|
|||
# Selector toolbar for FreeCAD
|
||||
# Copyright (C) 2015, 2016 (as part of TabBar) triplus @ FreeCAD
|
||||
# Copyright (C) 2017 triplus @ FreeCAD
|
||||
#
|
||||
#
|
||||
# This library is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU Lesser General Public
|
||||
# License as published by the Free Software Foundation; either
|
||||
# version 2.1 of the License, or (at your option) any later version.
|
||||
#
|
||||
# This library is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
# Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public
|
||||
# License along with this library; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
"""Selector toolbar for FreeCAD."""
|
||||
|
||||
import os
|
||||
import FreeCADGui as Gui
|
||||
import FreeCAD as App
|
||||
from PySide import QtGui
|
||||
from PySide import QtCore
|
||||
|
||||
actions = {}
|
||||
mw = Gui.getMainWindow()
|
||||
aMenu = QtGui.QAction(mw)
|
||||
aMenu.setObjectName("SelectorToolbarMenu")
|
||||
sMenu = QtGui.QMenu()
|
||||
aMenu.setMenu(sMenu)
|
||||
group = QtGui.QActionGroup(mw)
|
||||
dList = "ArchWorkbench,PartDesignWorkbench"
|
||||
path = os.path.dirname(__file__) + "/Resources/icons/"
|
||||
p = App.ParamGet("User parameter:BaseApp/SelectorToolbar")
|
||||
|
||||
|
||||
def onSelector(a):
|
||||
"""Activate workbench on selection."""
|
||||
Gui.doCommand('Gui.activateWorkbench("' + a.data() + '")')
|
||||
|
||||
|
||||
def wbIcon(i):
|
||||
"""Create workbench icon."""
|
||||
if str(i.find("XPM")) != "-1":
|
||||
icon = []
|
||||
for a in ((((i
|
||||
.split('{', 1)[1])
|
||||
.rsplit('}', 1)[0])
|
||||
.strip())
|
||||
.split("\n")):
|
||||
icon.append((a
|
||||
.split('"', 1)[1])
|
||||
.rsplit('"', 1)[0])
|
||||
icon = QtGui.QIcon(QtGui.QPixmap(icon))
|
||||
else:
|
||||
icon = QtGui.QIcon(QtGui.QPixmap(i))
|
||||
if icon.isNull():
|
||||
icon = QtGui.QIcon.fromTheme("freecad")
|
||||
return icon
|
||||
|
||||
|
||||
def wbActions():
|
||||
"""Create workbench actions."""
|
||||
wbList = Gui.listWorkbenches()
|
||||
for i in wbList:
|
||||
if i not in actions:
|
||||
action = QtGui.QAction(group)
|
||||
action.setCheckable(True)
|
||||
action.setText(wbList[i].MenuText)
|
||||
action.setData(i)
|
||||
try:
|
||||
action.setIcon(wbIcon(wbList[i].Icon))
|
||||
except:
|
||||
action.setIcon(QtGui.QIcon.fromTheme("freecad"))
|
||||
actions[i] = action
|
||||
|
||||
|
||||
def onOrientationChanged():
|
||||
"""Style buttons based on the toolbar orientation."""
|
||||
if tb.orientation() == QtCore.Qt.Orientation.Horizontal:
|
||||
for b in tb.findChildren(QtGui.QToolButton):
|
||||
b.setProperty("toolbar_orientation", "horizontal")
|
||||
b.style().polish(b)
|
||||
else:
|
||||
for b in tb.findChildren(QtGui.QToolButton):
|
||||
b.setProperty("toolbar_orientation", "vertical")
|
||||
b.style().polish(b)
|
||||
|
||||
|
||||
def onStyle():
|
||||
"""Manage the toolbutton style."""
|
||||
if p.GetString("Style") == "IconText":
|
||||
tb.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon)
|
||||
elif p.GetString("Style") == "Text":
|
||||
tb.setToolButtonStyle(QtCore.Qt.ToolButtonTextOnly)
|
||||
else:
|
||||
tb.setToolButtonStyle(QtCore.Qt.ToolButtonIconOnly)
|
||||
|
||||
|
||||
def selectorMenu():
|
||||
"""Selector button with menu."""
|
||||
sMenu.clear()
|
||||
static = p.GetBool("Static", 0)
|
||||
enabled = p.GetString("Enabled")
|
||||
partially = p.GetString("Partially")
|
||||
unchecked = p.GetString("Unchecked")
|
||||
position = p.GetString("Position")
|
||||
enabled = enabled.split(",")
|
||||
partially = partially.split(",")
|
||||
unchecked = unchecked.split(",")
|
||||
position = position.split(",")
|
||||
active = Gui.activeWorkbench().__class__.__name__
|
||||
l = []
|
||||
for i in partially:
|
||||
if i in actions:
|
||||
l.append(i)
|
||||
s = list(actions)
|
||||
s.sort()
|
||||
for i in s:
|
||||
if i not in l and i not in enabled and i not in unchecked:
|
||||
l.append(i)
|
||||
if active not in l:
|
||||
l.insert(0, active)
|
||||
for i in l:
|
||||
sMenu.addAction(actions[i])
|
||||
if static:
|
||||
aMenu.setText("")
|
||||
aMenu.setToolTip("Additional workbenches")
|
||||
aMenu.setIcon(QtGui.QIcon(path + "SelectorToolbarMenu.svg"))
|
||||
else:
|
||||
sMenu.setDefaultAction(actions[active])
|
||||
aMenu.setText(actions[active].text())
|
||||
aMenu.setIcon(actions[active].icon())
|
||||
|
||||
|
||||
def onWorkbenchActivated():
|
||||
"""Populate the selector toolbar."""
|
||||
tb.clear()
|
||||
wbActions()
|
||||
selectorMenu()
|
||||
static = p.GetBool("Static", 0)
|
||||
menu = p.GetString("Menu", "Front")
|
||||
enabled = p.GetString("Enabled", dList)
|
||||
enabled = enabled.split(",")
|
||||
active = Gui.activeWorkbench().__class__.__name__
|
||||
if active not in enabled:
|
||||
enabled.append(active)
|
||||
if menu == "Front" and not static:
|
||||
enabled.remove(active)
|
||||
elif menu == "End" and not static:
|
||||
enabled.remove(active)
|
||||
else:
|
||||
pass
|
||||
if menu == "Front":
|
||||
tb.addAction(aMenu)
|
||||
w = tb.widgetForAction(aMenu)
|
||||
w.setPopupMode(QtGui.QToolButton
|
||||
.ToolButtonPopupMode
|
||||
.InstantPopup)
|
||||
group.blockSignals(True)
|
||||
for i in enabled:
|
||||
for key in actions:
|
||||
if i == actions[key].data():
|
||||
a = actions[key]
|
||||
a.setChecked(False)
|
||||
tb.addAction(a)
|
||||
if active == a.data():
|
||||
a.setChecked(True)
|
||||
group.blockSignals(False)
|
||||
if menu == "End":
|
||||
tb.addAction(aMenu)
|
||||
w = tb.widgetForAction(aMenu)
|
||||
w.setPopupMode(QtGui.QToolButton
|
||||
.ToolButtonPopupMode
|
||||
.InstantPopup)
|
||||
|
||||
|
||||
def prefDialog():
|
||||
"""Preferences dialog."""
|
||||
dialog = QtGui.QDialog(mw)
|
||||
dialog.resize(800, 450)
|
||||
dialog.setWindowTitle("Selector toolbar")
|
||||
layout = QtGui.QVBoxLayout()
|
||||
dialog.setLayout(layout)
|
||||
selector = QtGui.QListWidget(dialog)
|
||||
selector.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
|
||||
btnClose = QtGui.QPushButton("Close", dialog)
|
||||
btnClose.setToolTip("Close the preferences dialog")
|
||||
btnClose.setDefault(True)
|
||||
btnUp = QtGui.QToolButton(dialog)
|
||||
btnUp.setToolTip("Move selected item up")
|
||||
btnUp.setArrowType(QtCore.Qt.UpArrow)
|
||||
btnDown = QtGui.QToolButton(dialog)
|
||||
btnDown.setToolTip("Move selected item down")
|
||||
btnDown.setArrowType(QtCore.Qt.DownArrow)
|
||||
l0 = QtGui.QVBoxLayout()
|
||||
g0 = QtGui.QGroupBox("Style:")
|
||||
g0.setLayout(l0)
|
||||
r0 = QtGui.QRadioButton("Icon", g0)
|
||||
r0.setObjectName("Icon")
|
||||
r0.setToolTip("Toolbar button icon style")
|
||||
r1 = QtGui.QRadioButton("Text", g0)
|
||||
r1.setObjectName("Text")
|
||||
r1.setToolTip("Toolbar button text style")
|
||||
r2 = QtGui.QRadioButton("Icon and text", g0)
|
||||
r2.setObjectName("IconText")
|
||||
r2.setToolTip("Toolbar button icon and text style")
|
||||
l0.addWidget(r0)
|
||||
l0.addWidget(r1)
|
||||
l0.addWidget(r2)
|
||||
l1 = QtGui.QVBoxLayout()
|
||||
g1 = QtGui.QGroupBox("Menu:")
|
||||
g1.setLayout(l1)
|
||||
r3 = QtGui.QRadioButton("Disabled", g1)
|
||||
r3.setObjectName("Off")
|
||||
r3.setToolTip("Disable selector menu")
|
||||
r4 = QtGui.QRadioButton("Front", g1)
|
||||
r4.setObjectName("Front")
|
||||
r4.setToolTip("Selector menu at front")
|
||||
r5 = QtGui.QRadioButton("End", g1)
|
||||
r5.setObjectName("End")
|
||||
r5.setToolTip("Selector menu at end")
|
||||
c1 = QtGui.QCheckBox("Static")
|
||||
c1.setToolTip("Do not adapt selector menu to active workbench")
|
||||
l1.addWidget(r3)
|
||||
l1.addWidget(r4)
|
||||
l1.addWidget(r5)
|
||||
l1.addWidget(c1)
|
||||
l2 = QtGui.QHBoxLayout()
|
||||
l2.addWidget(btnUp)
|
||||
l2.addWidget(btnDown)
|
||||
l2.addStretch(1)
|
||||
l2.addWidget(btnClose)
|
||||
l3 = QtGui.QHBoxLayout()
|
||||
l3.addStretch()
|
||||
l4 = QtGui.QVBoxLayout()
|
||||
l4.addWidget(g0)
|
||||
l4.addWidget(g1)
|
||||
l4.addStretch()
|
||||
l4.insertLayout(0, l3)
|
||||
l5 = QtGui.QHBoxLayout()
|
||||
l5.addWidget(selector)
|
||||
l5.insertLayout(1, l4)
|
||||
layout.insertLayout(0, l5)
|
||||
layout.insertLayout(1, l2)
|
||||
|
||||
def onAccepted():
|
||||
"""Close dialog on button close."""
|
||||
dialog.done(1)
|
||||
|
||||
def onFinished():
|
||||
"""Delete dialog on close."""
|
||||
dialog.deleteLater()
|
||||
|
||||
def onItemChanged(item=None):
|
||||
"""Save workbench list state."""
|
||||
if item:
|
||||
selector.blockSignals(True)
|
||||
if item.data(50) == "Unchecked":
|
||||
item.setCheckState(QtCore.Qt.CheckState(1))
|
||||
item.setData(50, "Partially")
|
||||
elif item.data(50) == "Partially":
|
||||
item.setCheckState(QtCore.Qt.CheckState(2))
|
||||
item.setData(50, "Checked")
|
||||
else:
|
||||
item.setCheckState(QtCore.Qt.CheckState(0))
|
||||
item.setData(50, "Unchecked")
|
||||
selector.blockSignals(False)
|
||||
enabled = []
|
||||
partially = []
|
||||
unchecked = []
|
||||
for index in range(selector.count()):
|
||||
if selector.item(index).checkState() == QtCore.Qt.Checked:
|
||||
enabled.append(selector.item(index).data(32))
|
||||
elif selector.item(index).checkState() == QtCore.Qt.PartiallyChecked:
|
||||
partially.append(selector.item(index).data(32))
|
||||
else:
|
||||
unchecked.append(selector.item(index).data(32))
|
||||
p.SetString("Enabled", ",".join(enabled))
|
||||
p.SetString("Partially", ",".join(partially))
|
||||
p.SetString("Unchecked", ",".join(unchecked))
|
||||
onWorkbenchActivated()
|
||||
|
||||
def onUp():
|
||||
"""Save workbench position list."""
|
||||
currentIndex = selector.currentRow()
|
||||
if currentIndex != 0:
|
||||
selector.blockSignals(True)
|
||||
currentItem = selector.takeItem(currentIndex)
|
||||
selector.insertItem(currentIndex - 1, currentItem)
|
||||
selector.setCurrentRow(currentIndex - 1)
|
||||
selector.blockSignals(False)
|
||||
position = []
|
||||
for index in range(selector.count()):
|
||||
position.append(selector.item(index).data(32))
|
||||
p.SetString("Position", ",".join(position))
|
||||
onItemChanged()
|
||||
|
||||
def onDown():
|
||||
"""Save workbench position list."""
|
||||
currentIndex = selector.currentRow()
|
||||
if currentIndex != selector.count() - 1 and currentIndex != -1:
|
||||
selector.blockSignals(True)
|
||||
currentItem = selector.takeItem(currentIndex)
|
||||
selector.insertItem(currentIndex + 1, currentItem)
|
||||
selector.setCurrentRow(currentIndex + 1)
|
||||
selector.blockSignals(False)
|
||||
position = []
|
||||
for index in range(selector.count()):
|
||||
position.append(selector.item(index).data(32))
|
||||
p.SetString("Position", ",".join(position))
|
||||
onItemChanged()
|
||||
|
||||
def onG0(r):
|
||||
"""Set toolbar button style."""
|
||||
if r:
|
||||
for i in g0.findChildren(QtGui.QRadioButton):
|
||||
if i.isChecked():
|
||||
p.SetString("Style", i.objectName())
|
||||
onStyle()
|
||||
onWorkbenchActivated()
|
||||
|
||||
def onG1(r):
|
||||
"""Manage the selector menu."""
|
||||
if r:
|
||||
for i in g1.findChildren(QtGui.QRadioButton):
|
||||
if i.isChecked():
|
||||
p.SetString("Menu", i.objectName())
|
||||
if i.objectName() == "Off":
|
||||
c1.setEnabled(False)
|
||||
else:
|
||||
c1.setEnabled(True)
|
||||
onWorkbenchActivated()
|
||||
|
||||
def onC1(c):
|
||||
"""Manage the static mode."""
|
||||
if c:
|
||||
p.SetBool("Static", 1)
|
||||
else:
|
||||
p.SetBool("Static", 0)
|
||||
onWorkbenchActivated()
|
||||
|
||||
enabled = p.GetString("Enabled", dList)
|
||||
unchecked = p.GetString("Unchecked")
|
||||
position = p.GetString("Position")
|
||||
enabled = enabled.split(",")
|
||||
unchecked = unchecked.split(",")
|
||||
position = position.split(",")
|
||||
s = list(actions)
|
||||
s.sort()
|
||||
for i in s:
|
||||
if i not in position:
|
||||
position.append(i)
|
||||
for i in position:
|
||||
if i in actions:
|
||||
item = QtGui.QListWidgetItem(selector)
|
||||
item.setText(actions[i].text())
|
||||
item.setIcon(actions[i].icon())
|
||||
item.setData(32, actions[i].data())
|
||||
if actions[i].data() in enabled:
|
||||
item.setCheckState(QtCore.Qt.CheckState(2))
|
||||
item.setData(50, "Checked")
|
||||
elif actions[i].data() in unchecked:
|
||||
item.setCheckState(QtCore.Qt.CheckState(0))
|
||||
item.setData(50, "Unchecked")
|
||||
else:
|
||||
item.setCheckState(QtCore.Qt.CheckState(1))
|
||||
item.setData(50, "Partially")
|
||||
style = p.GetString("Style")
|
||||
if style == "Text":
|
||||
r1.setChecked(True)
|
||||
elif style == "IconText":
|
||||
r2.setChecked(True)
|
||||
else:
|
||||
r0.setChecked(True)
|
||||
menu = p.GetString("Menu", "Front")
|
||||
if menu == "Front":
|
||||
r4.setChecked(True)
|
||||
elif menu == "End":
|
||||
r5.setChecked(True)
|
||||
else:
|
||||
r3.setChecked(True)
|
||||
c1.setEnabled(False)
|
||||
static = p.GetBool("Static", 0)
|
||||
if static:
|
||||
c1.setChecked(True)
|
||||
r0.toggled.connect(onG0)
|
||||
r1.toggled.connect(onG0)
|
||||
r2.toggled.connect(onG0)
|
||||
r3.toggled.connect(onG1)
|
||||
r4.toggled.connect(onG1)
|
||||
r5.toggled.connect(onG1)
|
||||
c1.stateChanged.connect(onC1)
|
||||
btnUp.clicked.connect(onUp)
|
||||
btnDown.clicked.connect(onDown)
|
||||
selector.itemChanged.connect(onItemChanged)
|
||||
dialog.finished.connect(onFinished)
|
||||
btnClose.clicked.connect(onAccepted)
|
||||
return dialog
|
||||
|
||||
|
||||
def onPreferences():
|
||||
"""Open the preferences dialog."""
|
||||
dialog = prefDialog()
|
||||
dialog.show()
|
||||
|
||||
|
||||
def accessoriesMenu():
|
||||
"""Add selector toolbar preferences to accessories menu."""
|
||||
pref = QtGui.QAction(mw)
|
||||
pref.setText("Selector toolbar")
|
||||
pref.setObjectName("SelectorToolbar")
|
||||
pref.triggered.connect(onPreferences)
|
||||
try:
|
||||
import AccessoriesMenu
|
||||
AccessoriesMenu.addItem("SelectorToolbar")
|
||||
except ImportError:
|
||||
a = mw.findChild(QtGui.QAction, "AccessoriesMenu")
|
||||
if a:
|
||||
a.menu().addAction(pref)
|
||||
else:
|
||||
mb = mw.menuBar()
|
||||
actionAccessories = QtGui.QAction(mw)
|
||||
actionAccessories.setObjectName("AccessoriesMenu")
|
||||
actionAccessories.setIconText("Accessories")
|
||||
menu = QtGui.QMenu()
|
||||
actionAccessories.setMenu(menu)
|
||||
menu.addAction(pref)
|
||||
|
||||
def addMenu():
|
||||
"""Add accessories menu to the menu bar."""
|
||||
toolsMenu = mb.findChild(QtGui.QMenu, "&Tools")
|
||||
if toolsMenu:
|
||||
toolsMenu.addAction(actionAccessories)
|
||||
addMenu()
|
||||
mw.workbenchActivated.connect(addMenu)
|
||||
|
||||
|
||||
def onClose():
|
||||
"""Remove selector toolbar on FreeCAD close."""
|
||||
pathTB = "User parameter:BaseApp/Workbench/Global/Toolbar"
|
||||
pTB = App.ParamGet(pathTB)
|
||||
pTB.RemGroup("Selector")
|
||||
|
||||
|
||||
def onStart():
|
||||
"""Start selector toolbar."""
|
||||
start = False
|
||||
try:
|
||||
mw.mainWindowClosed
|
||||
mw.workbenchActivated
|
||||
global tb
|
||||
tb = mw.findChild(QtGui.QToolBar, "Selector")
|
||||
tb.orientationChanged
|
||||
start = True
|
||||
except AttributeError:
|
||||
pass
|
||||
if start:
|
||||
t.stop()
|
||||
t.deleteLater()
|
||||
onStyle()
|
||||
accessoriesMenu()
|
||||
onWorkbenchActivated()
|
||||
group.triggered.connect(onSelector)
|
||||
mw.mainWindowClosed.connect(onClose)
|
||||
mw.workbenchActivated.connect(onWorkbenchActivated)
|
||||
tb.orientationChanged.connect(onOrientationChanged)
|
||||
|
||||
|
||||
t = QtCore.QTimer()
|
||||
t.timeout.connect(onStart)
|
||||
t.start(500)
|
Loading…
Reference in New Issue
Block a user