diff --git a/spyder/app/mainwindow.py b/spyder/app/mainwindow.py index 0bd5918c9ba..e854cdcda13 100644 --- a/spyder/app/mainwindow.py +++ b/spyder/app/mainwindow.py @@ -1025,7 +1025,7 @@ def create_edit_action(text, tr_text, icon): #----- Tours self.tour = tour.AnimatedTour(self) - self.tours_menu = QMenu(_("Interactive tours")) + self.tours_menu = QMenu(_("Interactive tours"), self) self.tour_menu_actions = [] # TODO: Only show intro tour for now. When we are close to finish # 3.0, we will finish and show the other tour @@ -1097,7 +1097,7 @@ def add_ipm_action(text, path): add_actions(pymods_menu, ipm_actions) self.help_menu_actions.append(pymods_menu) # Online documentation - web_resources = QMenu(_("Online documentation")) + web_resources = QMenu(_("Online documentation"), self) webres_actions = create_module_bookmark_actions(self, self.BOOKMARKS) webres_actions.insert(2, None) diff --git a/spyder/app/tour.py b/spyder/app/tour.py index 3301452bc64..2a769c38a6c 100644 --- a/spyder/app/tour.py +++ b/spyder/app/tour.py @@ -28,10 +28,18 @@ # Local imports from spyder.config.base import _, get_image_path +from spyder.config.gui import is_dark_interface from spyder.py3compat import to_binary_string from spyder.utils.qthelpers import add_actions, create_action from spyder.utils import icon_manager as ima + +if is_dark_interface(): + MAIN_TOP_COLOR = MAIN_BG_COLOR = QColor.fromRgb(35, 38, 41) +else: + MAIN_TOP_COLOR = QColor.fromRgb(230, 230, 230) + MAIN_BG_COLOR = QColor.fromRgb(255, 255, 255) + # FIXME: Known issues # How to handle if an specific dockwidget does not exists/load, like ipython # on python3.3, should that frame be removed? should it display a warning? @@ -527,7 +535,8 @@ def focusOutEvent(self, event): class FadingTipBox(FadingDialog): """ """ - def __init__(self, parent, opacity, duration, easing_curve, tour=None): + def __init__(self, parent, opacity, duration, easing_curve, tour=None, + color_top=None, color_back=None, combobox_background=None): super(FadingTipBox, self).__init__(parent, opacity, duration, easing_curve) self.holder = self.anim # needed for qt to work @@ -535,8 +544,6 @@ def __init__(self, parent, opacity, duration, easing_curve, tour=None): self.tour = tour self.frames = None - self.color_top = QColor.fromRgb(230, 230, 230) - self.color_back = QColor.fromRgb(255, 255, 255) self.offset_shadow = 0 self.fixed_width = 300 @@ -584,26 +591,29 @@ def toolbutton(icon): arrow = get_image_path('hide.png') - self.stylesheet = '''QComboBox { + self.color_top = color_top + self.color_back = color_back + self.combobox_background = combobox_background + self.stylesheet = '''QComboBox {{ padding-left: 5px; - background-color: rgbs(230,230,230,100%); + background-color: {} border-width: 0px; border-radius: 0px; min-height:20px; max-height:20px; - } + }} - QComboBox::drop-down { + QComboBox::drop-down {{ subcontrol-origin: padding; subcontrol-position: top left; border-width: 0px; - } + }} - QComboBox::down-arrow { - image: url(''' + arrow + '''); - } + QComboBox::down-arrow {{ + image: url({}); + }} - ''' + '''.format(self.combobox_background.name(), arrow) # Windows fix, slashes should be always in unix-style self.stylesheet = self.stylesheet.replace('\\', '/') @@ -869,7 +879,9 @@ def __init__(self, parent): self.color, tour=self) self.tips = FadingTipBox(self.parent, self.opacity_tips, self.duration_tips, self.easing_curve, - tour=self) + tour=self, color_top=MAIN_TOP_COLOR, + color_back=MAIN_BG_COLOR, + combobox_background=MAIN_TOP_COLOR) # Widgets setup # Needed to fix issue #2204 diff --git a/spyder/config/gui.py b/spyder/config/gui.py index 26b45992ab8..aec33b8fa8a 100644 --- a/spyder/config/gui.py +++ b/spyder/config/gui.py @@ -173,5 +173,19 @@ def is_dark_font_color(color_scheme): return dark_color(font_color) +def is_dark_interface(): + ui_theme = CONF.get('color_schemes', 'ui_theme') + color_scheme = CONF.get('color_schemes', 'selected') + if ui_theme == 'dark': + return True + elif ui_theme == 'automatic': + if not is_dark_font_color(color_scheme): + return True + else: + return False + else: + return False + + for _name in sh.COLOR_SCHEME_NAMES: set_default_color_scheme(_name, replace=False) diff --git a/spyder/plugins/plots/plugin.py b/spyder/plugins/plots/plugin.py index 7e434366d91..c10c4c7f30d 100644 --- a/spyder/plugins/plots/plugin.py +++ b/spyder/plugins/plots/plugin.py @@ -13,12 +13,19 @@ # Local imports from spyder.config.base import _ +from spyder.config.gui import is_dark_interface from spyder.api.plugins import SpyderPluginWidget from spyder.api.preferences import PluginConfigPage from spyder.utils import icon_manager as ima from spyder.plugins.plots.widgets.figurebrowser import FigureBrowser +if is_dark_interface(): + MAIN_BG_COLOR = '#232629' +else: + MAIN_BG_COLOR = 'white' + + class PlotsConfigPage(PluginConfigPage): def setup_page(self): @@ -89,7 +96,8 @@ def add_shellwidget(self, shellwidget): if shellwidget_id not in self.shellwidgets: self.options_button.setVisible(True) fig_browser = FigureBrowser( - self, options_button=self.options_button) + self, options_button=self.options_button, + background_color=MAIN_BG_COLOR) fig_browser.set_shellwidget(shellwidget) fig_browser.setup(**self.get_settings()) fig_browser.sig_option_changed.connect( diff --git a/spyder/plugins/plots/widgets/figurebrowser.py b/spyder/plugins/plots/widgets/figurebrowser.py index 857aa3b3c67..ff1cfa489a8 100644 --- a/spyder/plugins/plots/widgets/figurebrowser.py +++ b/spyder/plugins/plots/widgets/figurebrowser.py @@ -70,13 +70,15 @@ class FigureBrowser(QWidget): sig_option_changed = Signal(str, object) sig_collapse = Signal() - def __init__(self, parent, options_button=None, plugin_actions=[]): + def __init__(self, parent, options_button=None, plugin_actions=[], + background_color=None): super(FigureBrowser, self).__init__(parent) self.shellwidget = None self.is_visible = True self.figviewer = None self.setup_in_progress = False + self.background_color = background_color # Options : self.mute_inline_plotting = None @@ -101,7 +103,7 @@ def setup(self, mute_inline_plotting=None, show_plot_outline=None): self.show_plot_outline_action.setChecked(show_plot_outline) return - self.figviewer = FigureViewer() + self.figviewer = FigureViewer(background_color=self.background_color) self.figviewer.setStyleSheet("FigureViewer{" "border: 1px solid lightgrey;" "border-top-width: 0px;" @@ -311,10 +313,11 @@ class FigureViewer(QScrollArea): sig_zoom_changed = Signal(float) - def __init__(self, parent=None): + def __init__(self, parent=None, background_color=None): super(FigureViewer, self).__init__(parent) self.setAlignment(Qt.AlignCenter) - self.viewport().setStyleSheet("background-color: white") + self.viewport().setStyleSheet( + "background-color: {}".format(background_color)) self.setFrameStyle(0) self._scalefactor = 0 diff --git a/spyder/plugins/profiler/plugin.py b/spyder/plugins/profiler/plugin.py index c2d06ef628b..11ceacb1af0 100644 --- a/spyder/plugins/profiler/plugin.py +++ b/spyder/plugins/profiler/plugin.py @@ -19,6 +19,7 @@ # Local imports from spyder.config.base import _ +from spyder.config.gui import is_dark_interface from spyder.api.plugins import SpyderPluginWidget from spyder.api.preferences import PluginConfigPage from spyder.preferences.runconfig import get_run_configuration @@ -27,6 +28,12 @@ from .widgets.profilergui import (ProfilerWidget, is_profiler_installed) +if is_dark_interface(): + MAIN_TEXT_COLOR = 'white' +else: + MAIN_TEXT_COLOR = '#444444' + + class ProfilerConfigPage(PluginConfigPage): def setup_page(self): results_group = QGroupBox(_("Results")) @@ -65,7 +72,8 @@ def __init__(self, parent=None): max_entries = self.get_option('max_entries', 50) self.profiler = ProfilerWidget(self, max_entries, - options_button=self.options_button) + options_button=self.options_button, + text_color=MAIN_TEXT_COLOR) layout = QVBoxLayout() layout.addWidget(self.profiler) diff --git a/spyder/plugins/profiler/widgets/profilergui.py b/spyder/plugins/profiler/widgets/profilergui.py index ba07679a20b..9d729bdba9c 100644 --- a/spyder/plugins/profiler/widgets/profilergui.py +++ b/spyder/plugins/profiler/widgets/profilergui.py @@ -67,14 +67,17 @@ class ProfilerWidget(QWidget): VERSION = '0.0.1' redirect_stdio = Signal(bool) - def __init__(self, parent, max_entries=100, options_button=None): + def __init__(self, parent, max_entries=100, options_button=None, + text_color=None): QWidget.__init__(self, parent) self.setWindowTitle("Profiler") self.output = None self.error_output = None - + + self.text_color = text_color + self._last_wdir = None self._last_args = None self._last_pythonpath = None @@ -365,9 +368,10 @@ def show_data(self, justanalyzed=False): self.datatree.load_data(self.DATAPATH) self.datatree.show_tree() - text_style = "%s " - date_text = text_style % time.strftime("%Y-%m-%d %H:%M:%S", - time.localtime()) + text_style = "%s " + date_text = text_style % (self.text_color, + time.strftime("%Y-%m-%d %H:%M:%S", + time.localtime())) self.datelabel.setText(date_text) diff --git a/spyder/plugins/pylint/plugin.py b/spyder/plugins/pylint/plugin.py index 2dad88b0b59..b5239256a14 100644 --- a/spyder/plugins/pylint/plugin.py +++ b/spyder/plugins/pylint/plugin.py @@ -23,6 +23,7 @@ # Local imports from spyder.config.base import _ +from spyder.config.gui import is_dark_interface from spyder.api.plugins import SpyderPluginWidget from spyder.api.preferences import PluginConfigPage from spyder.utils import icon_manager as ima @@ -31,6 +32,14 @@ from .widgets.pylintgui import PylintWidget +if is_dark_interface(): + MAIN_TEXT_COLOR = 'white' + MAIN_PREVRATE_COLOR = 'white' +else: + MAIN_TEXT_COLOR = '#444444' + MAIN_PREVRATE_COLOR = '#666666' + + class PylintConfigPage(PluginConfigPage): def setup_page(self): settings_group = QGroupBox(_("Settings")) @@ -90,7 +99,9 @@ def __init__(self, parent=None): max_entries = self.get_option('max_entries', 50) self.pylint = PylintWidget(self, max_entries=max_entries, - options_button=self.options_button) + options_button=self.options_button, + text_color=MAIN_TEXT_COLOR, + prevrate_color=MAIN_PREVRATE_COLOR) layout = QVBoxLayout() layout.addWidget(self.pylint) diff --git a/spyder/plugins/pylint/widgets/pylintgui.py b/spyder/plugins/pylint/widgets/pylintgui.py index 0474a4b93ea..d26bcf5736d 100644 --- a/spyder/plugins/pylint/widgets/pylintgui.py +++ b/spyder/plugins/pylint/widgets/pylintgui.py @@ -150,14 +150,18 @@ class PylintWidget(QWidget): VERSION = '1.1.0' redirect_stdio = Signal(bool) - def __init__(self, parent, max_entries=100, options_button=None): + def __init__(self, parent, max_entries=100, options_button=None, + text_color=None, prevrate_color=None): QWidget.__init__(self, parent) self.setWindowTitle("Pylint") self.output = None self.error_output = None - + + self.text_color = text_color + self.prevrate_color = prevrate_color + self.max_entries = max_entries self.rdata = [] if osp.isfile(self.DATAPATH): @@ -432,26 +436,26 @@ def show_data(self, justanalyzed=False): self.treewidget.clear_results() date_text = '' else: - text_style = "%s " + text_style = "%s " rate_style = "%s" - prevrate_style = "%s" + prevrate_style = "%s" color = "#FF0000" if float(rate) > 5.: color = "#22AA22" elif float(rate) > 3.: color = "#EE5500" text = _('Global evaluation:') - text = (text_style % text)+(rate_style % (color, - ('%s/10' % rate))) + text = ((text_style % (self.text_color, text)) + + (rate_style % (color, ('%s/10' % rate)))) if previous_rate: text_prun = _('previous run:') text_prun = ' (%s %s/10)' % (text_prun, previous_rate) - text += prevrate_style % text_prun + text += prevrate_style % (self.prevrate_color, text_prun) self.treewidget.set_results(filename, results) date = to_text_string(time.strftime("%Y-%m-%d %H:%M:%S", datetime), encoding='utf8') - date_text = text_style % date + date_text = text_style % (self.text_color, date) self.ratelabel.setText(text) self.datelabel.setText(date_text) diff --git a/spyder/plugins/variableexplorer/widgets/dataframeeditor.py b/spyder/plugins/variableexplorer/widgets/dataframeeditor.py index fd03fdb7b79..8ab7ef10a38 100644 --- a/spyder/plugins/variableexplorer/widgets/dataframeeditor.py +++ b/spyder/plugins/variableexplorer/widgets/dataframeeditor.py @@ -705,10 +705,6 @@ def data(self, index, role): return None row, col = ((index.row(), index.column()) if self.axis == 0 else (index.column(), index.row())) - if role == Qt.BackgroundRole: - prev = self.model.header(self.axis, col - 1, row) if col else None - cur = self.model.header(self.axis, col, row) - return self._palette.midlight() if prev != cur else None if role != Qt.DisplayRole: return None if self.axis == 0 and self._shape[0] <= 1: diff --git a/spyder/utils/icon_manager.py b/spyder/utils/icon_manager.py index a81f84f7cc8..c5278c3696d 100644 --- a/spyder/utils/icon_manager.py +++ b/spyder/utils/icon_manager.py @@ -14,30 +14,15 @@ # Local imports from spyder.config.base import get_image_path from spyder.config.main import CONF -from spyder.config.gui import is_dark_font_color +from spyder.config.gui import is_dark_interface import qtawesome as qta -def get_foreground_color(): - """ - Get main color for the icons based on the color theme - and color scheme currently selected. - """ - ui_theme = CONF.get('color_schemes', 'ui_theme') - color_scheme = CONF.get('color_schemes', 'selected') - if ui_theme == 'dark': - foreground_color = 'white' - elif ui_theme == 'automatic': - if not is_dark_font_color(color_scheme): - foreground_color = 'white' - else: - foreground_color = 'black' - else: - foreground_color = 'black' - return foreground_color - +if is_dark_interface(): + MAIN_FG_COLOR = 'white' +else: + MAIN_FG_COLOR = 'black' -MAIN_FG_COLOR = get_foreground_color() _resource = { 'directory': osp.join(osp.dirname(osp.realpath(__file__)), '../fonts'),