Skip to content

Commit

Permalink
Merge pull request #21616 from ccordoba12/start-stop-spinner-deps
Browse files Browse the repository at this point in the history
PR: Start spinner in dependencies dialog only when it's visible
  • Loading branch information
ccordoba12 authored Dec 16, 2023
2 parents e40ed64 + 5a69be4 commit 8149cca
Show file tree
Hide file tree
Showing 9 changed files with 118 additions and 35 deletions.
3 changes: 3 additions & 0 deletions .github/scripts/modules_test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,9 @@ for f in spyder/*/*/*/*.py; do
if [[ $f == spyder/plugins/editor/panels/__init__.py ]]; then
continue
fi
if [[ $f == spyder/plugins/findinfiles/widgets/main_widget.py ]]; then
continue
fi
python "$f"
if [ $? -ne 0 ]; then
exit 1
Expand Down
2 changes: 1 addition & 1 deletion binder/environment.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ dependencies:
- pyzmq >=22.1.0
- qdarkstyle >=3.2.0,<3.3.0
- qstylizer >=0.2.2
- qtawesome >=1.2.1
- qtawesome >=1.3.0
- qtconsole >=5.5.0,<5.6.0
- qtpy >=2.4.0
- rtree >=0.9.7
Expand Down
2 changes: 1 addition & 1 deletion requirements/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ dependencies:
- pyzmq >=22.1.0
- qdarkstyle >=3.2.0,<3.3.0
- qstylizer >=0.2.2
- qtawesome >=1.2.1
- qtawesome >=1.3.0
- qtconsole >=5.5.0,<5.6.0
- qtpy >=2.4.0
- rtree >=0.9.7
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,7 @@ def run(self):
'pyzmq>=22.1.0',
'qdarkstyle>=3.2.0,<3.3.0',
'qstylizer>=0.2.2',
'qtawesome>=1.2.1',
'qtawesome>=1.3.0',
'qtconsole>=5.5.0,<5.6.0',
'qtpy>=2.4.0',
'rtree>=0.9.7',
Expand Down
2 changes: 1 addition & 1 deletion spyder/dependencies.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@
PYZMQ_REQVER = '>=22.1.0'
QDARKSTYLE_REQVER = '>=3.2.0,<3.3.0'
QSTYLIZER_REQVER = '>=0.2.2'
QTAWESOME_REQVER = '>=1.2.1'
QTAWESOME_REQVER = '>=1.3.0'
QTCONSOLE_REQVER = '>=5.5.0,<5.6.0'
QTPY_REQVER = '>=2.4.0'
RTREE_REQVER = '>=0.9.7'
Expand Down
2 changes: 1 addition & 1 deletion spyder/utils/icon_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -352,7 +352,7 @@ def __init__(self):
'folding.arrow_down_on': [('mdi.menu-down',), {'color': self.MAIN_FG_COLOR}],
'lspserver.down': [('mdi.close',), {'color': self.MAIN_FG_COLOR}],
'lspserver.ready': [('mdi.check',), {'color': self.MAIN_FG_COLOR}],
'dependency_ok': [('mdi.check',), {'color': self.MAIN_FG_COLOR}],
'dependency_ok': [('mdi.check',), {'color': SpyderPalette.COLOR_SUCCESS_2}],
'dependency_warning': [('mdi.alert',), {'color': SpyderPalette.COLOR_WARN_2}],
'dependency_error': [('mdi.alert',), {'color': SpyderPalette.COLOR_ERROR_1}],
'broken_image': [('mdi.image-broken-variant',), {'color': self.MAIN_FG_COLOR}],
Expand Down
7 changes: 4 additions & 3 deletions spyder/utils/stylesheet.py
Original file line number Diff line number Diff line change
Expand Up @@ -232,9 +232,10 @@ def _customize_stylesheet(self):
)

# Adjust padding of QPushButton's in QDialog's
css["QDialog QPushButton"].setValues(
padding='3px 15px 3px 15px',
)
for widget in ["QPushButton", "QPushButton:disabled"]:
css[f"QDialog {widget}"].setValues(
padding='3px 15px 3px 15px',
)

css["QDialogButtonBox QPushButton:!default"].setValues(
padding='3px 0px 3px 0px',
Expand Down
84 changes: 62 additions & 22 deletions spyder/widgets/dependencies.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
import sys

# Third party imports
from qtpy.QtCore import Qt
from qtpy.QtGui import QColor
from qtpy.QtWidgets import (QApplication, QDialog, QDialogButtonBox,
QHBoxLayout, QVBoxLayout, QLabel, QPushButton,
Expand All @@ -19,9 +18,11 @@
# Local imports
from spyder import __version__
from spyder.config.base import _
from spyder.dependencies import MANDATORY, OPTIONAL, PLUGIN
from spyder.config.gui import is_dark_interface
from spyder.dependencies import OPTIONAL, PLUGIN
from spyder.utils.icon_manager import ima
from spyder.utils.palette import SpyderPalette
from spyder.utils.palette import QStylePalette, SpyderPalette
from spyder.utils.stylesheet import AppStyle, MAC, WIN
from spyder.widgets.helperwidgets import PaneEmptyWidget


Expand Down Expand Up @@ -56,16 +57,29 @@ def update_dependencies(self, dependencies):
dependency.required_version,
dependency.installed_version,
dependency.features])

# Format content
if dependency.check():
item.setIcon(0, ima.icon('dependency_ok'))
elif dependency.kind == OPTIONAL:
item.setIcon(0, ima.icon('dependency_warning'))
item.setBackground(2, QColor(SpyderPalette.COLOR_WARN_1))

# Fix foreground color in the light theme
if not is_dark_interface():
item.setForeground(
2, QColor(QStylePalette.COLOR_BACKGROUND_1)
)
else:
item.setIcon(0, ima.icon('dependency_error'))
item.setBackground(2, QColor(SpyderPalette.COLOR_ERROR_1))

# Fix foreground color in the light theme
if not is_dark_interface():
item.setForeground(
2, QColor(QStylePalette.COLOR_BACKGROUND_1)
)

# Add to tree
if dependency.kind == OPTIONAL:
optional_item.addChild(item)
Expand All @@ -87,20 +101,40 @@ def __init__(self, parent):
QDialog.__init__(self, parent)

# Widgets
self.label = QLabel(_("Optional modules are not required to run "
"Spyder but enhance its functions."))
self.label2 = QLabel(_("<b>Note:</b> New dependencies or changed ones "
"will be correctly detected only after Spyder "
"is restarted."))
note1 = _(
"Optional modules are not required to run Spyder but enhance "
"its functions."
)

note2 = _(
"New dependencies or changed ones will be correctly detected only "
"after Spyder is restarted."
)

notes_vmargin = "0.4em" if WIN else "0.3em"
label = QLabel(
(
"<style>"
"ul, li {{margin-left: -15px}}"
"li {{margin-bottom: {}}}"
"</style>"
"<ul>"
"<li>{}</li>"
"<li>{}</li>"
"</ul>"
).format(notes_vmargin, note1, note2)
)

self.treewidget = DependenciesTreeWidget(self)
btn = QPushButton(_("Copy to clipboard"), )
bbox = QDialogButtonBox(QDialogButtonBox.Ok)
self.copy_btn = QPushButton(_("Copy to clipboard"))
ok_btn = QDialogButtonBox(QDialogButtonBox.Ok)

# Widget setup
self.setWindowTitle("Spyder %s: %s" % (__version__,
_("Dependencies")))
self.setWindowIcon(ima.icon('tooloptions'))
self.setWindowTitle(
_("Dependencies for Spyder {}").format(__version__)
)
self.setModal(False)
self.copy_btn.setEnabled(False)

# Create a QStackedWidget
self.stacked_widget = QStackedWidget()
Expand All @@ -109,7 +143,8 @@ def __init__(self, parent):
self.loading_pane = PaneEmptyWidget(
self,
"dependencies",
_("Please wait while we prepare your dependencies..."),
_("Dependency information will be retrieved shortly. "
"Please wait..."),
bottom_stretch=1,
spinner=True,
)
Expand All @@ -123,22 +158,24 @@ def __init__(self, parent):

# Layout
hlayout = QHBoxLayout()
hlayout.addWidget(btn)
hlayout.addWidget(self.copy_btn)
hlayout.addStretch()
hlayout.addWidget(bbox)
hlayout.addWidget(ok_btn)

vlayout = QVBoxLayout()
vlayout.setContentsMargins(*((5 * AppStyle.MarginSize,) * 4))
vlayout.addWidget(self.stacked_widget)
vlayout.addWidget(self.label)
vlayout.addWidget(self.label2)
vlayout.addSpacing(AppStyle.MarginSize)
vlayout.addWidget(label)
vlayout.addSpacing((-2 if MAC else 1) * AppStyle.MarginSize)
vlayout.addLayout(hlayout)

self.setLayout(vlayout)
self.resize(860, 560)
self.setFixedSize(860, 560)

# Signals
btn.clicked.connect(self.copy_to_clipboard)
bbox.accepted.connect(self.accept)
self.copy_btn.clicked.connect(self.copy_to_clipboard)
ok_btn.accepted.connect(self.accept)

def set_data(self, dependencies):
self.treewidget.update_dependencies(dependencies)
Expand All @@ -147,6 +184,9 @@ def set_data(self, dependencies):
# Once data is loaded, switch to the tree widget
self.stacked_widget.setCurrentWidget(self.treewidget)

# Enable copy button
self.copy_btn.setEnabled(True)

def copy_to_clipboard(self):
from spyder.dependencies import status

Expand All @@ -169,7 +209,7 @@ def test():
">=0.10", kind=OPTIONAL)

from spyder.utils.qthelpers import qapplication
app = qapplication()
app = qapplication() # noqa
dlg = DependenciesDialog(None)
dlg.set_data(dependencies.DEPENDENCIES)
dlg.show()
Expand Down
49 changes: 44 additions & 5 deletions spyder/widgets/helperwidgets.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,7 @@
from spyder.utils.stringmatching import get_search_regex
from spyder.utils.palette import QStylePalette, SpyderPalette
from spyder.utils.image_path_manager import get_image_path
from spyder.utils.stylesheet import AppStyle, DialogStyle
from spyder.utils.qthelpers import create_waitspinner
from spyder.utils.stylesheet import AppStyle


# Valid finder chars. To be improved
Expand Down Expand Up @@ -579,6 +578,10 @@ def __init__(
):
super().__init__(parent)

# Attributes
self._is_shown = False
self._spin = None

interface_font_size = self.get_font(
SpyderFontType.Interface).pointSize()

Expand Down Expand Up @@ -625,17 +628,20 @@ def __init__(
pane_empty_layout.addWidget(image_label)

# Display spinner if requested
if spinner is not False:
if spinner:
spin_widget = qta.IconWidget()
self._spin = qta.Spin(spin_widget, interval=3, autostart=False)
spin_icon = qta.icon(
"mdi.loading",
color="white",
animation=qta.Spin(spin_widget, interval=3),
color=ima.MAIN_FG_COLOR,
animation=self._spin
)

spin_widget.setIconSize(QSize(32, 32))
spin_widget.setIcon(spin_icon)
spin_widget.setStyleSheet(image_label_qss.toString())
spin_widget.setAlignment(Qt.AlignCenter)

pane_empty_layout.addWidget(spin_widget)
pane_empty_layout.addItem(QSpacerItem(20, 20))

Expand All @@ -656,6 +662,8 @@ def __init__(
self.setFocusPolicy(Qt.StrongFocus)
self._apply_stylesheet(False)

# ---- Public methods
# -------------------------------------------------------------------------
def setup(self, *args, **kwargs):
"""
This method is needed when using this widget to show a "no connected
Expand Down Expand Up @@ -711,6 +719,22 @@ def get_icon(self, icon_filename):

return final_pm

# ---- Qt methods
# -------------------------------------------------------------------------
def showEvent(self, event):
"""Adjustments when the widget is shown."""
if not self._is_shown:
self._start_spinner()
self._is_shown = True

super().showEvent(event)

def hideEvent(self, event):
"""Adjustments when the widget is hidden."""
self._stop_spinner()
self._is_shown = False
super().hideEvent(event)

def focusInEvent(self, event):
self._apply_stylesheet(True)
super().focusOutEvent(event)
Expand All @@ -719,6 +743,8 @@ def focusOutEvent(self, event):
self._apply_stylesheet(False)
super().focusOutEvent(event)

# ---- Private methods
# -------------------------------------------------------------------------
def _apply_stylesheet(self, focus):
if focus:
border_color = QStylePalette.COLOR_ACCENT_3
Expand All @@ -735,6 +761,19 @@ def _apply_stylesheet(self, focus):

self.setStyleSheet(qss.toString())

def _start_spinner(self):
"""
Start spinner when requested, in case the widget has one (it's stopped
by default).
"""
if self._spin is not None:
self._spin.start()

def _stop_spinner(self):
"""Stop spinner when requested, in case the widget has one."""
if self._spin is not None:
self._spin.stop()


class HoverRowsTableView(QTableView):
"""
Expand Down

0 comments on commit 8149cca

Please sign in to comment.