commit
d013d480f8
60
InitGui.py
60
InitGui.py
|
@ -6,66 +6,34 @@ wax = None
|
||||||
sea = None
|
sea = None
|
||||||
tbr = None
|
tbr = None
|
||||||
|
|
||||||
|
# Define the translation
|
||||||
|
translate = App.Qt.translate
|
||||||
|
|
||||||
|
|
||||||
def QT_TRANSLATE_NOOP(context, text):
|
def QT_TRANSLATE_NOOP(context, text):
|
||||||
return text
|
return text
|
||||||
|
|
||||||
|
|
||||||
def addToolSearchBox():
|
def addToolSearchBox():
|
||||||
import FreeCADGui
|
|
||||||
from PySide import QtGui
|
|
||||||
import SearchBoxLight
|
|
||||||
|
|
||||||
# Define the translation
|
|
||||||
translate = App.Qt.translate
|
|
||||||
|
|
||||||
global wax, sea, tbr
|
global wax, sea, tbr
|
||||||
mw = FreeCADGui.getMainWindow()
|
mw = Gui.getMainWindow()
|
||||||
|
import SearchBox
|
||||||
|
from PySide6.QtWidgets import QToolBar
|
||||||
|
from PySide6.QtGui import QShortcut, QKeySequence
|
||||||
|
|
||||||
if mw:
|
if mw:
|
||||||
if sea is None:
|
if sea is None:
|
||||||
sea = SearchBoxLight.SearchBoxLight(
|
wax = SearchBox.SearchBoxFunction(mw)
|
||||||
getItemGroups=lambda: __import__("GetItemGroups").getItemGroups(),
|
|
||||||
getToolTip=lambda groupId, setParent: __import__(
|
|
||||||
"GetItemGroups"
|
|
||||||
).getToolTip(groupId, setParent),
|
|
||||||
getItemDelegate=lambda: __import__(
|
|
||||||
"IndentedItemDelegate"
|
|
||||||
).IndentedItemDelegate(),
|
|
||||||
)
|
|
||||||
sea.resultSelected.connect(
|
|
||||||
lambda index, groupId: __import__("GetItemGroups").onResultSelected(
|
|
||||||
index, groupId
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
if wax is None:
|
|
||||||
wax = QtGui.QWidgetAction(None)
|
|
||||||
wax.setWhatsThis(
|
|
||||||
translate(
|
|
||||||
"SearchBar",
|
|
||||||
"Use this search bar to find tools, document objects, preferences and more",
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
sea.setWhatsThis(
|
|
||||||
translate(
|
|
||||||
"SearchBar",
|
|
||||||
"Use this search bar to find tools, document objects, preferences and more",
|
|
||||||
)
|
|
||||||
)
|
|
||||||
wax.setDefaultWidget(sea)
|
|
||||||
##mbr.addWidget(sea)
|
|
||||||
# mbr.addAction(wax)
|
|
||||||
if tbr is None:
|
if tbr is None:
|
||||||
tbr = QtGui.QToolBar("SearchBar") # QtGui.QDockWidget()
|
tbr = QToolBar("SearchBar") # QtGui.QDockWidget()
|
||||||
# Include FreeCAD in the name so that one can find windows labeled with FreeCAD easily in window managers which allow search through the list of open windows.
|
# Include FreeCAD in the name so that one can find windows labeled with
|
||||||
|
# FreeCAD easily in window managers which allow search through the list of open windows.
|
||||||
tbr.setObjectName("SearchBar")
|
tbr.setObjectName("SearchBar")
|
||||||
tbr.addAction(wax)
|
tbr.addAction(wax)
|
||||||
mw.addToolBar(tbr)
|
mw.addToolBar(tbr)
|
||||||
tbr.show()
|
tbr.show()
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
addToolSearchBox()
|
addToolSearchBox()
|
||||||
import FreeCADGui
|
Gui.getMainWindow().workbenchActivated.connect(addToolSearchBox)
|
||||||
|
|
||||||
FreeCADGui.getMainWindow().workbenchActivated.connect(addToolSearchBox)
|
|
||||||
|
|
|
@ -1,41 +1,49 @@
|
||||||
import os
|
import os
|
||||||
import FreeCAD as App
|
import FreeCAD as App
|
||||||
|
import FreeCADGui as Gui
|
||||||
|
import StyleMapping_SearchBar
|
||||||
|
|
||||||
# Define the translation
|
# Define the translation
|
||||||
translate = App.Qt.translate
|
translate = App.Qt.translate
|
||||||
|
|
||||||
|
|
||||||
def loadAllWorkbenches():
|
def loadAllWorkbenches():
|
||||||
from PySide import QtGui
|
import FreeCADGui as Gui
|
||||||
import FreeCADGui
|
from PySide.QtGui import QLabel
|
||||||
|
from PySide.QtCore import Qt, SIGNAL, Signal, QObject, QThread, QSize
|
||||||
|
from PySide.QtGui import QIcon, QPixmap, QAction, QGuiApplication
|
||||||
|
|
||||||
|
activeWorkbench = Gui.activeWorkbench().name()
|
||||||
|
lbl = QLabel(translate("SearchBar", "Loading workbench … (…/…)"))
|
||||||
|
lbl.setWindowFlags(Qt.WindowType.WindowStaysOnTopHint)
|
||||||
|
|
||||||
|
# Get the stylesheet from the main window and use it for this form
|
||||||
|
lbl.setStyleSheet("background-color: " + StyleMapping_SearchBar.ReturnStyleItem("Background_Color") + ";")
|
||||||
|
|
||||||
|
# # Get the main window from FreeCAD
|
||||||
|
# mw = Gui.getMainWindow()
|
||||||
|
# # Center the widget
|
||||||
|
# cp = QGuiApplication.screenAt(mw.pos()).geometry().center()
|
||||||
|
# lbl.move(cp)
|
||||||
|
|
||||||
activeWorkbench = FreeCADGui.activeWorkbench().name()
|
|
||||||
lbl = QtGui.QLabel(translate("SearchBar", "Loading workbench … (…/…)"))
|
|
||||||
lbl.show()
|
lbl.show()
|
||||||
lst = FreeCADGui.listWorkbenches()
|
lst = Gui.listWorkbenches()
|
||||||
for i, wb in enumerate(lst):
|
for i, wb in enumerate(lst):
|
||||||
msg = (
|
msg = translate("SearchBar", "Loading workbench ") + wb + " (" + str(i + 1) + "/" + str(len(lst)) + ")"
|
||||||
translate("SearchBar", "Loading workbench ")
|
|
||||||
+ wb
|
|
||||||
+ " ("
|
|
||||||
+ str(i)
|
|
||||||
+ "/"
|
|
||||||
+ str(len(lst))
|
|
||||||
+ ")"
|
|
||||||
)
|
|
||||||
print(msg)
|
print(msg)
|
||||||
lbl.setText(msg)
|
lbl.setText(msg)
|
||||||
geo = lbl.geometry()
|
geo = lbl.geometry()
|
||||||
geo.setSize(lbl.sizeHint())
|
geo.setSize(lbl.sizeHint())
|
||||||
lbl.setGeometry(geo)
|
lbl.setGeometry(geo)
|
||||||
lbl.repaint()
|
lbl.repaint()
|
||||||
FreeCADGui.updateGui() # Probably slower with this, because it redraws the entire GUI with all tool buttons changed etc. but allows the label to actually be updated, and it looks nice and gives a quick overview of all the workbenches…
|
Gui.updateGui() # Probably slower with this, because it redraws the entire GUI with all tool buttons changed etc. but allows the label to actually be updated, and it looks nice and gives a quick overview of all the workbenches…
|
||||||
try:
|
try:
|
||||||
FreeCADGui.activateWorkbench(wb)
|
Gui.activateWorkbench(wb)
|
||||||
except:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
lbl.hide()
|
lbl.hide()
|
||||||
FreeCADGui.activateWorkbench(activeWorkbench)
|
Gui.activateWorkbench(activeWorkbench)
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
def cachePath():
|
def cachePath():
|
||||||
|
@ -91,23 +99,25 @@ def refreshToolbars(doLoadAllWorkbenches=True):
|
||||||
|
|
||||||
|
|
||||||
def refreshToolsAction():
|
def refreshToolsAction():
|
||||||
from PySide import QtGui
|
from PySide.QtWidgets import QApplication, QMessageBox
|
||||||
|
from PySide.QtCore import Qt
|
||||||
|
|
||||||
print("Refresh cached results")
|
print("Refresh cached results")
|
||||||
fw = QtGui.QApplication.focusWidget()
|
msgBox = QMessageBox()
|
||||||
if fw is not None:
|
msgBox.setWindowFlags(Qt.WindowType.WindowStaysOnTopHint)
|
||||||
fw.clearFocus()
|
# Get the main window from FreeCAD
|
||||||
reply = QtGui.QMessageBox.question(
|
mw = Gui.getMainWindow()
|
||||||
None,
|
reply = msgBox.question(
|
||||||
|
mw,
|
||||||
translate("SearchBar", "Load all workbenches?"),
|
translate("SearchBar", "Load all workbenches?"),
|
||||||
translate(
|
translate(
|
||||||
"SearchBar",
|
"SearchBar",
|
||||||
"""Load all workbenches? This can cause FreeCAD to become unstable, and this "reload tools" feature contained a bug that crashed freecad systematically, so please make sure you save your work before. It\'s a good idea to restart FreeCAD after this operation.""",
|
"""Load all workbenches? This can cause FreeCAD to become unstable, and this "reload tools" feature contained a bug that crashed freecad systematically, so please make sure you save your work before. It\'s a good idea to restart FreeCAD after this operation.""",
|
||||||
),
|
),
|
||||||
QtGui.QMessageBox.Yes,
|
QMessageBox.Yes,
|
||||||
QtGui.QMessageBox.No,
|
QMessageBox.No,
|
||||||
)
|
)
|
||||||
if reply == QtGui.QMessageBox.Yes:
|
if reply == QMessageBox.Yes:
|
||||||
refreshToolbars()
|
refreshToolbars()
|
||||||
else:
|
else:
|
||||||
print("cancelled")
|
print("cancelled")
|
||||||
|
|
107
SearchBox.py
107
SearchBox.py
|
@ -27,6 +27,7 @@ from PySide.QtWidgets import (
|
||||||
QVBoxLayout,
|
QVBoxLayout,
|
||||||
QApplication,
|
QApplication,
|
||||||
QListWidget,
|
QListWidget,
|
||||||
|
QWidgetAction,
|
||||||
)
|
)
|
||||||
from PySide.QtGui import (
|
from PySide.QtGui import (
|
||||||
QIcon,
|
QIcon,
|
||||||
|
@ -48,6 +49,11 @@ globalIgnoreFocusOut = False
|
||||||
# Define the translation
|
# Define the translation
|
||||||
translate = App.Qt.translate
|
translate = App.Qt.translate
|
||||||
|
|
||||||
|
# Avoid garbage collection by storing the action in a global variable
|
||||||
|
wax = None
|
||||||
|
sea = None
|
||||||
|
tbr = None
|
||||||
|
|
||||||
|
|
||||||
def easyToolTipWidget(html):
|
def easyToolTipWidget(html):
|
||||||
foo = QTextEdit()
|
foo = QTextEdit()
|
||||||
|
@ -57,6 +63,41 @@ def easyToolTipWidget(html):
|
||||||
return foo
|
return foo
|
||||||
|
|
||||||
|
|
||||||
|
def SearchBoxFunction(mw):
|
||||||
|
import SearchBoxLight
|
||||||
|
|
||||||
|
global wax, sea, tbr
|
||||||
|
|
||||||
|
if mw:
|
||||||
|
if sea is None:
|
||||||
|
sea = SearchBoxLight.SearchBoxLight(
|
||||||
|
getItemGroups=lambda: __import__("GetItemGroups").getItemGroups(),
|
||||||
|
getToolTip=lambda groupId, setParent: __import__("GetItemGroups").getToolTip(groupId, setParent),
|
||||||
|
getItemDelegate=lambda: __import__("IndentedItemDelegate").IndentedItemDelegate(),
|
||||||
|
)
|
||||||
|
sea.resultSelected.connect(
|
||||||
|
lambda index, groupId: __import__("GetItemGroups").onResultSelected(index, groupId)
|
||||||
|
)
|
||||||
|
|
||||||
|
if wax is None:
|
||||||
|
wax = QWidgetAction(None)
|
||||||
|
wax.setWhatsThis(
|
||||||
|
translate(
|
||||||
|
"SearchBar",
|
||||||
|
"Use this search bar to find tools, document objects, preferences and more",
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
sea.setWhatsThis(
|
||||||
|
translate(
|
||||||
|
"SearchBar",
|
||||||
|
"Use this search bar to find tools, document objects, preferences and more",
|
||||||
|
)
|
||||||
|
)
|
||||||
|
wax.setDefaultWidget(sea)
|
||||||
|
return wax
|
||||||
|
|
||||||
|
|
||||||
class SearchBox(QLineEdit):
|
class SearchBox(QLineEdit):
|
||||||
# The following block of code is present in the lightweight proxy SearchBoxLight
|
# The following block of code is present in the lightweight proxy SearchBoxLight
|
||||||
"""
|
"""
|
||||||
|
@ -91,9 +132,7 @@ class SearchBox(QLineEdit):
|
||||||
self.getItemGroups = getItemGroups
|
self.getItemGroups = getItemGroups
|
||||||
self.getToolTip = getToolTip
|
self.getToolTip = getToolTip
|
||||||
self.itemGroups = None # Will be initialized by calling getItemGroups() the first time the search box gains focus, through focusInEvent and refreshItemGroups
|
self.itemGroups = None # Will be initialized by calling getItemGroups() the first time the search box gains focus, through focusInEvent and refreshItemGroups
|
||||||
self.maxVisibleRows = (
|
self.maxVisibleRows = maxVisibleRows # TODO: use this to compute the correct height
|
||||||
maxVisibleRows # TODO: use this to compute the correct height
|
|
||||||
)
|
|
||||||
# Create proxy model
|
# Create proxy model
|
||||||
self.proxyModel = QIdentityProxyModel()
|
self.proxyModel = QIdentityProxyModel()
|
||||||
# Filtered model to which items are manually added. Store it as a property of the object instead of a local variable, to prevent grbage collection.
|
# Filtered model to which items are manually added. Store it as a property of the object instead of a local variable, to prevent grbage collection.
|
||||||
|
@ -105,9 +144,7 @@ class SearchBox(QLineEdit):
|
||||||
self.listView.setWindowFlag(Qt.WindowType.FramelessWindowHint)
|
self.listView.setWindowFlag(Qt.WindowType.FramelessWindowHint)
|
||||||
self.listView.setSelectionMode(self.listView.SelectionMode.SingleSelection)
|
self.listView.setSelectionMode(self.listView.SelectionMode.SingleSelection)
|
||||||
self.listView.setModel(self.proxyModel)
|
self.listView.setModel(self.proxyModel)
|
||||||
self.listView.setItemDelegate(
|
self.listView.setItemDelegate(getItemDelegate()) # https://stackoverflow.com/a/65930408/324969
|
||||||
getItemDelegate()
|
|
||||||
) # https://stackoverflow.com/a/65930408/324969
|
|
||||||
self.listView.setMouseTracking(True)
|
self.listView.setMouseTracking(True)
|
||||||
# make the QListView non-editable
|
# make the QListView non-editable
|
||||||
self.listView.setEditTriggers(QAbstractItemView.EditTrigger.NoEditTriggers)
|
self.listView.setEditTriggers(QAbstractItemView.EditTrigger.NoEditTriggers)
|
||||||
|
@ -137,18 +174,10 @@ class SearchBox(QLineEdit):
|
||||||
# Note: should probably use the eventFilter method instead...
|
# Note: should probably use the eventFilter method instead...
|
||||||
wdgctx = Qt.ShortcutContext.WidgetShortcut
|
wdgctx = Qt.ShortcutContext.WidgetShortcut
|
||||||
|
|
||||||
QShortcut(
|
QShortcut(QKeySequence(Qt.Key.Key_Down), self, context=wdgctx).activated.connect(self.listDown)
|
||||||
QKeySequence(Qt.Key.Key_Down), self, context=wdgctx
|
QShortcut(QKeySequence(Qt.Key.Key_Up), self, context=wdgctx).activated.connect(self.listUp)
|
||||||
).activated.connect(self.listDown)
|
QShortcut(QKeySequence(Qt.Key.Key_PageDown), self, context=wdgctx).activated.connect(self.listPageDown)
|
||||||
QShortcut(QKeySequence(Qt.Key.Key_Up), self, context=wdgctx).activated.connect(
|
QShortcut(QKeySequence(Qt.Key.Key_PageUp), self, context=wdgctx).activated.connect(self.listPageUp)
|
||||||
self.listUp
|
|
||||||
)
|
|
||||||
QShortcut(
|
|
||||||
QKeySequence(Qt.Key.Key_PageDown), self, context=wdgctx
|
|
||||||
).activated.connect(self.listPageDown)
|
|
||||||
QShortcut(
|
|
||||||
QKeySequence(Qt.Key.Key_PageUp), self, context=wdgctx
|
|
||||||
).activated.connect(self.listPageUp)
|
|
||||||
|
|
||||||
# Home and End do not work, for some reason.
|
# Home and End do not work, for some reason.
|
||||||
# QShortcut(QKeySequence.MoveToEndOfDocument, self, context = wdgctx).activated.connect(self.listEnd)
|
# QShortcut(QKeySequence.MoveToEndOfDocument, self, context = wdgctx).activated.connect(self.listEnd)
|
||||||
|
@ -156,25 +185,13 @@ class SearchBox(QLineEdit):
|
||||||
# QShortcut(QKeySequence(Qt.Key.Key_End), self, context = wdgctx).activated.connect(self.listEnd)
|
# QShortcut(QKeySequence(Qt.Key.Key_End), self, context = wdgctx).activated.connect(self.listEnd)
|
||||||
# QShortcut(QKeySequence('Home'), self, context = wdgctx).activated.connect(self.listStart)
|
# QShortcut(QKeySequence('Home'), self, context = wdgctx).activated.connect(self.listStart)
|
||||||
|
|
||||||
QShortcut(
|
QShortcut(QKeySequence(Qt.Key.Key_Enter), self, context=wdgctx).activated.connect(self.listAccept)
|
||||||
QKeySequence(Qt.Key.Key_Enter), self, context=wdgctx
|
QShortcut(QKeySequence(Qt.Key.Key_Return), self, context=wdgctx).activated.connect(self.listAccept)
|
||||||
).activated.connect(self.listAccept)
|
QShortcut(QKeySequence("Ctrl+Return"), self, context=wdgctx).activated.connect(self.listAcceptToggle)
|
||||||
QShortcut(
|
QShortcut(QKeySequence("Ctrl+Enter"), self, context=wdgctx).activated.connect(self.listAcceptToggle)
|
||||||
QKeySequence(Qt.Key.Key_Return), self, context=wdgctx
|
QShortcut(QKeySequence("Ctrl+Space"), self, context=wdgctx).activated.connect(self.listAcceptToggle)
|
||||||
).activated.connect(self.listAccept)
|
|
||||||
QShortcut(QKeySequence("Ctrl+Return"), self, context=wdgctx).activated.connect(
|
|
||||||
self.listAcceptToggle
|
|
||||||
)
|
|
||||||
QShortcut(QKeySequence("Ctrl+Enter"), self, context=wdgctx).activated.connect(
|
|
||||||
self.listAcceptToggle
|
|
||||||
)
|
|
||||||
QShortcut(QKeySequence("Ctrl+Space"), self, context=wdgctx).activated.connect(
|
|
||||||
self.listAcceptToggle
|
|
||||||
)
|
|
||||||
|
|
||||||
QShortcut(
|
QShortcut(QKeySequence(Qt.Key.Key_Escape), self, context=wdgctx).activated.connect(self.listCancel)
|
||||||
QKeySequence(Qt.Key.Key_Escape), self, context=wdgctx
|
|
||||||
).activated.connect(self.listCancel)
|
|
||||||
|
|
||||||
# Initialize the model with the full list (assuming the text() is empty)
|
# Initialize the model with the full list (assuming the text() is empty)
|
||||||
# self.proxyFilterModel(self.text()) # This is done by refreshItemGroups on focusInEvent, because the initial loading from cache can take time
|
# self.proxyFilterModel(self.text()) # This is done by refreshItemGroups on focusInEvent, because the initial loading from cache can take time
|
||||||
|
@ -221,9 +238,7 @@ class SearchBox(QLineEdit):
|
||||||
[
|
[
|
||||||
QStandardItem(
|
QStandardItem(
|
||||||
genericToolIcon,
|
genericToolIcon,
|
||||||
translate(
|
translate("SearchBar", "Please wait, loading results from cache…"),
|
||||||
"SearchBar", "Please wait, loading results from cache…"
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
QStandardItem("0"),
|
QStandardItem("0"),
|
||||||
QStandardItem("-1"),
|
QStandardItem("-1"),
|
||||||
|
@ -275,17 +290,11 @@ class SearchBox(QLineEdit):
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def proxyListPageDown(self):
|
def proxyListPageDown(self):
|
||||||
self.movementKey(
|
self.movementKey(lambda current, nbRows: min(current + max(1, self.maxVisibleRows / 2), nbRows - 1))
|
||||||
lambda current, nbRows: min(
|
|
||||||
current + max(1, self.maxVisibleRows / 2), nbRows - 1
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def proxyListPageUp(self):
|
def proxyListPageUp(self):
|
||||||
self.movementKey(
|
self.movementKey(lambda current, nbRows: max(current - max(1, self.maxVisibleRows / 2), 0))
|
||||||
lambda current, nbRows: max(current - max(1, self.maxVisibleRows / 2), 0)
|
|
||||||
)
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def proxyListEnd(self):
|
def proxyListEnd(self):
|
||||||
|
@ -422,9 +431,7 @@ class SearchBox(QLineEdit):
|
||||||
def getScreenPosition(widget):
|
def getScreenPosition(widget):
|
||||||
geo = widget.geometry()
|
geo = widget.geometry()
|
||||||
parent = widget.parent()
|
parent = widget.parent()
|
||||||
parentPos = (
|
parentPos = getScreenPosition(parent) if parent is not None else QPoint(0, 0)
|
||||||
getScreenPosition(parent) if parent is not None else QPoint(0, 0)
|
|
||||||
)
|
|
||||||
return QPoint(geo.x() + parentPos.x(), geo.y() + parentPos.y())
|
return QPoint(geo.x() + parentPos.x(), geo.y() + parentPos.y())
|
||||||
|
|
||||||
pos = getScreenPosition(self)
|
pos = getScreenPosition(self)
|
||||||
|
|
239
StyleMapping_SearchBar.py
Normal file
239
StyleMapping_SearchBar.py
Normal file
|
@ -0,0 +1,239 @@
|
||||||
|
# *************************************************************************
|
||||||
|
# * *
|
||||||
|
# * Copyright (c) 2019-2024 Paul Ebbers *
|
||||||
|
# * *
|
||||||
|
# * This program is free software; you can redistribute it and/or modify *
|
||||||
|
# * it under the terms of the GNU Lesser General Public License (LGPL) *
|
||||||
|
# * as published by the Free Software Foundation; either version 3 of *
|
||||||
|
# * the License, or (at your option) any later version. *
|
||||||
|
# * for detail see the LICENCE text file. *
|
||||||
|
# * *
|
||||||
|
# * This program 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 Library General Public License for more details. *
|
||||||
|
# * *
|
||||||
|
# * You should have received a copy of the GNU Library General Public *
|
||||||
|
# * License along with this program; if not, write to the Free Software *
|
||||||
|
# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
|
||||||
|
# * USA *
|
||||||
|
# * *
|
||||||
|
# *************************************************************************
|
||||||
|
import FreeCAD as App
|
||||||
|
import FreeCADGui as Gui
|
||||||
|
import os
|
||||||
|
from PySide.QtGui import QIcon, QPixmap, QAction
|
||||||
|
from PySide.QtWidgets import (
|
||||||
|
QListWidgetItem,
|
||||||
|
QTableWidgetItem,
|
||||||
|
QListWidget,
|
||||||
|
QTableWidget,
|
||||||
|
QToolBar,
|
||||||
|
QToolButton,
|
||||||
|
QComboBox,
|
||||||
|
QPushButton,
|
||||||
|
QMenu,
|
||||||
|
QWidget,
|
||||||
|
QMainWindow,
|
||||||
|
)
|
||||||
|
from PySide.QtCore import Qt, SIGNAL, Signal, QObject, QThread
|
||||||
|
import sys
|
||||||
|
import json
|
||||||
|
from datetime import datetime
|
||||||
|
import shutil
|
||||||
|
import Standard_Functions_RIbbon as StandardFunctions
|
||||||
|
import Parameters_Ribbon
|
||||||
|
import webbrowser
|
||||||
|
import time
|
||||||
|
|
||||||
|
# Get the resources
|
||||||
|
pathIcons = Parameters_Ribbon.ICON_LOCATION
|
||||||
|
pathStylSheets = Parameters_Ribbon.STYLESHEET_LOCATION
|
||||||
|
pathUI = Parameters_Ribbon.UI_LOCATION
|
||||||
|
pathBackup = Parameters_Ribbon.BACKUP_LOCATION
|
||||||
|
sys.path.append(pathIcons)
|
||||||
|
sys.path.append(pathStylSheets)
|
||||||
|
sys.path.append(pathUI)
|
||||||
|
sys.path.append(pathBackup)
|
||||||
|
|
||||||
|
|
||||||
|
def ReturnStyleItem(ControlName, ShowCustomIcon=False, IgnoreOverlay=False):
|
||||||
|
"""
|
||||||
|
Enter one of the names below:
|
||||||
|
|
||||||
|
ControlName (string):
|
||||||
|
"Background_Color" returns string,
|
||||||
|
"Border_Color" returns string,
|
||||||
|
"FontColor" returns string,
|
||||||
|
"FontColor" returns string,
|
||||||
|
"""
|
||||||
|
# define a result holder and a dict for the StyleMapping file
|
||||||
|
result = "none"
|
||||||
|
|
||||||
|
# Get the current stylesheet for FreeCAD
|
||||||
|
FreeCAD_preferences = App.ParamGet("User parameter:BaseApp/Preferences/MainWindow")
|
||||||
|
currentStyleSheet = FreeCAD_preferences.GetString("StyleSheet")
|
||||||
|
IsInList = False
|
||||||
|
for key, value in StyleMapping_default["Stylesheets"].items():
|
||||||
|
if key == currentStyleSheet:
|
||||||
|
IsInList = True
|
||||||
|
break
|
||||||
|
if IsInList is False:
|
||||||
|
currentStyleSheet = "none"
|
||||||
|
|
||||||
|
try:
|
||||||
|
result = StyleMapping_default["Stylesheets"][currentStyleSheet][ControlName]
|
||||||
|
if result == "" or result is None:
|
||||||
|
result = StyleMapping_default["Stylesheets"][""][ControlName]
|
||||||
|
return result
|
||||||
|
except Exception as e:
|
||||||
|
print(e)
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def ReturnColor(ColorType="Background_Color"):
|
||||||
|
mw: QMainWindow = Gui.getMainWindow()
|
||||||
|
palette = mw.style().standardPalette()
|
||||||
|
# Get the color
|
||||||
|
Color = palette.base().color().toTuple() # RGBA tupple
|
||||||
|
if ColorType == "Border_Color":
|
||||||
|
Color = palette.buttonText().color().toTuple()
|
||||||
|
if ColorType == "Background_Color_Hover":
|
||||||
|
Color = palette.highlight().color().toTuple()
|
||||||
|
|
||||||
|
HexColor = StandardFunctions.ColorConvertor(Color, Color[3] / 255, True, False)
|
||||||
|
|
||||||
|
return HexColor
|
||||||
|
|
||||||
|
|
||||||
|
def ReturnFontColor():
|
||||||
|
fontColor = "#000000"
|
||||||
|
IsDarkTheme = DarkMode()
|
||||||
|
|
||||||
|
if IsDarkTheme is True:
|
||||||
|
fontColor = "#ffffff"
|
||||||
|
|
||||||
|
return fontColor
|
||||||
|
|
||||||
|
|
||||||
|
def DarkMode():
|
||||||
|
import xml.etree.ElementTree as ET
|
||||||
|
import os
|
||||||
|
|
||||||
|
# Define the standard result
|
||||||
|
IsDarkTheme = False
|
||||||
|
|
||||||
|
# Get the current stylesheet for FreeCAD
|
||||||
|
FreeCAD_preferences = App.ParamGet("User parameter:BaseApp/Preferences/MainWindow")
|
||||||
|
currentStyleSheet = FreeCAD_preferences.GetString("StyleSheet")
|
||||||
|
|
||||||
|
path = os.path.dirname(__file__)
|
||||||
|
# Get the folder with add-ons
|
||||||
|
for i in range(2):
|
||||||
|
# Starting point
|
||||||
|
path = os.path.dirname(path)
|
||||||
|
|
||||||
|
# Go through the sub-folders
|
||||||
|
for root, dirs, files in os.walk(path):
|
||||||
|
for name in dirs:
|
||||||
|
# if the current stylesheet matches a sub directory, try to geth the pacakgexml
|
||||||
|
if currentStyleSheet.replace(".qss", "").lower() in name.lower():
|
||||||
|
try:
|
||||||
|
packageXML = os.path.join(path, name, "package.xml")
|
||||||
|
|
||||||
|
# Get the tree and root of the xml file
|
||||||
|
tree = ET.parse(packageXML)
|
||||||
|
treeRoot = tree.getroot()
|
||||||
|
|
||||||
|
# Get all the tag elements
|
||||||
|
elements = []
|
||||||
|
namespaces = {"i": "https://wiki.freecad.org/Package_Metadata"}
|
||||||
|
elements = treeRoot.findall(".//i:content/i:preferencepack/i:tag", namespaces)
|
||||||
|
|
||||||
|
# go throug all tags. If 'dark' in the element text, this is a dark theme
|
||||||
|
for element in elements:
|
||||||
|
if "dark" in element.text.lower():
|
||||||
|
IsDarkTheme = True
|
||||||
|
break
|
||||||
|
except Exception:
|
||||||
|
continue
|
||||||
|
|
||||||
|
return IsDarkTheme
|
||||||
|
|
||||||
|
|
||||||
|
StyleMapping_default = {
|
||||||
|
"Stylesheets": {
|
||||||
|
"": {
|
||||||
|
"Background_Color": "#f0f0f0",
|
||||||
|
"Background_Color_Hover": "#ced4da",
|
||||||
|
"Border_Color": "#646464",
|
||||||
|
"FontColor": ReturnFontColor(),
|
||||||
|
},
|
||||||
|
"none": {
|
||||||
|
"Background_Color": "none",
|
||||||
|
"Background_Color_Hover": "#48a0f8",
|
||||||
|
"Border_Color": ReturnColor("Border_Color"),
|
||||||
|
"FontColor": ReturnFontColor(),
|
||||||
|
},
|
||||||
|
"FreeCAD Dark.qss": {
|
||||||
|
"Background_Color": "#333333",
|
||||||
|
"Background_Color_Hover": "#48a0f8",
|
||||||
|
"Border_Color": "#ffffff",
|
||||||
|
"FontColor": "#ffffff",
|
||||||
|
},
|
||||||
|
"FreeCAD Light.qss": {
|
||||||
|
"Background_Color": "#f0f0f0",
|
||||||
|
"Background_Color_Hover": "#48a0f8",
|
||||||
|
"Border_Color": "#646464",
|
||||||
|
"FontColor": "#000000",
|
||||||
|
},
|
||||||
|
"OpenLight.qss": {
|
||||||
|
"Background_Color": "#dee2e6",
|
||||||
|
"Background_Color_Hover": "#a5d8ff",
|
||||||
|
"Border_Color": "#1c7ed6",
|
||||||
|
"FontColor": "#000000",
|
||||||
|
},
|
||||||
|
"OpenDark.qss": {
|
||||||
|
"Background_Color": "#212529",
|
||||||
|
"Background_Color_Hover": "#1f364d",
|
||||||
|
"Border_Color": "#264b69",
|
||||||
|
"FontColor": "#ffffff",
|
||||||
|
},
|
||||||
|
"Behave-dark.qss": {
|
||||||
|
"Background_Color": "#232932",
|
||||||
|
"Background_Color_Hover": "#557bb6",
|
||||||
|
"Border_Color": "#3a7400",
|
||||||
|
"FontColor": ReturnFontColor(),
|
||||||
|
},
|
||||||
|
"ProDark.qss": {
|
||||||
|
"Background_Color": "#333333",
|
||||||
|
"Background_Color_Hover": "#557bb6",
|
||||||
|
"Border_Color": "#adc5ed",
|
||||||
|
"FontColor": ReturnFontColor(),
|
||||||
|
},
|
||||||
|
"Darker.qss": {
|
||||||
|
"Background_Color": "#444444",
|
||||||
|
"Background_Color_Hover": "#4aa5ff",
|
||||||
|
"Border_Color": "#696968",
|
||||||
|
"FontColor": ReturnFontColor(),
|
||||||
|
},
|
||||||
|
"Light-modern.qss": {
|
||||||
|
"Background_Color": "#f0f0f0",
|
||||||
|
"Background_Color_Hover": "#4aa5ff",
|
||||||
|
"Border_Color": "#646464",
|
||||||
|
"FontColor": ReturnFontColor(),
|
||||||
|
},
|
||||||
|
"Dark-modern.qss": {
|
||||||
|
"Background_Color": "#2b2b2b",
|
||||||
|
"Background_Color_Hover": "#4aa5ff",
|
||||||
|
"Border_Color": "#ffffff",
|
||||||
|
"FontColor": ReturnFontColor(),
|
||||||
|
},
|
||||||
|
"Dark-contrast.qss": {
|
||||||
|
"Background_Color": "#444444",
|
||||||
|
"Background_Color_Hover": "#4aa5ff",
|
||||||
|
"Border_Color": "#787878",
|
||||||
|
"FontColor": ReturnFontColor(),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
|
@ -5,7 +5,7 @@
|
||||||
|
|
||||||
<description>Adds a search bar widget for tools, document objects, and preferences</description>
|
<description>Adds a search bar widget for tools, document objects, and preferences</description>
|
||||||
|
|
||||||
<version>1.3.3</version>
|
<version>1.4.0</version>
|
||||||
|
|
||||||
<date>2022-06-01</date>
|
<date>2022-06-01</date>
|
||||||
|
|
||||||
|
|
|
@ -114,8 +114,10 @@ help() {
|
||||||
|
|
||||||
# Main function ------------------------------------------------------------------------------------
|
# Main function ------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
# LUPDATE="C:/Program Files/FreeCAD 1.0/bin/Lib/site-packages/PySide6/lupdate" # from Qt6
|
||||||
LUPDATE=/usr/lib/qt6/bin/lupdate # from Qt6
|
LUPDATE=/usr/lib/qt6/bin/lupdate # from Qt6
|
||||||
# LUPDATE=lupdate # from Qt5
|
# LUPDATE=lupdate # from Qt5
|
||||||
|
# LRELEASE="C:/Program Files/FreeCAD 1.0/bin/Lib/site-packages/PySide6/lrelease" # from Qt6
|
||||||
LRELEASE=/usr/lib/qt6/bin/lrelease # from Qt6
|
LRELEASE=/usr/lib/qt6/bin/lrelease # from Qt6
|
||||||
# LRELEASE=lrelease # from Qt5
|
# LRELEASE=lrelease # from Qt5
|
||||||
WB="SearchBar"
|
WB="SearchBar"
|
||||||
|
|
Loading…
Reference in New Issue
Block a user