# Copyright (c) 2011-2014, B.I.Stepanov Institute of Physics, National Academy
# of Sciences of Belarus.
#
# This program is free software; you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free Software
# Foundation; either version 2 of the License, or (at your option) any later
# version.
#
# 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 General Public License for more
# details.
#
# You should have received a copy of the GNU General Public License along with
# this program; if not, write to the Free Software Foundation, Inc., 51
# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.

"""Miscellaneous GUI-related classes and functions."""

from PyQt4.QtCore import *
from PyQt4.QtGui import *

from common.utils import utils

# **** Window settings ********************************************************
def saveWindowSettings(window, settings):
    """Save 'window's size, position and maximization state to a 'QSettings'
    instance, under a subgroup with a predefined name."""

    with utils.SettingsGrouper(settings, 'WindowGeometry'):

        # Window's client area rectangle in unmaximized state.
        normalGeometry = window.normalGeometry()
        # Width and height of the client area in unmaximized state.
        settings.setValue('windowSize', normalGeometry.size())
        # Position of the window's frame top left corner in unmaximized state.
        # Assume that window's client area offset is the same in normal and
        # maximized states.
        windowPos = (normalGeometry.topLeft() - window.geometry().topLeft() +
            window.frameGeometry().topLeft())
        settings.setValue('windowPos', windowPos)
        # True if window is maximized, False otherwise.
        settings.setValue('windowMaximized', window.isMaximized())

def loadWindowSettings(window, settings):
    """Set 'window's size, position and maximization state according to the
    settings saved by 'saveWindowSettings', if any."""

    with utils.SettingsGrouper(settings, 'WindowGeometry'):

        # Width and height of the window's client area in unmaximized state.
        if settings.contains('windowSize'):
            window.resize(settings.value('windowSize').toSize());
        # Position of the window's frame top left corner in unmaximized state.
        if settings.contains('windowPos'):
            window.move(settings.value('windowPos').toPoint());
        # True if window is maximized, False otherwise.
        if settings.contains('windowMaximized'):
            if settings.value('windowMaximized').toBool():
                window.setWindowState(Qt.WindowMaximized)
            else:
                window.setWindowState(Qt.WindowNoState)

# **** Icon functions *********************************************************
def loadIcon(iconName):
    """Load a 'QIcon' by its string ID."""

    # Use standard system icons whenever possible.
    if iconName == 'open':
        return qApp.style().standardIcon(QStyle.SP_DirOpenIcon)

    elif iconName == 'question':
        return qApp.style().standardIcon(QStyle.SP_MessageBoxQuestion)
    elif iconName == 'info':
        return qApp.style().standardIcon(QStyle.SP_MessageBoxInformation)
    elif iconName == 'warning':
        return qApp.style().standardIcon(QStyle.SP_MessageBoxWarning)
    elif iconName == 'error':
        return qApp.style().standardIcon(QStyle.SP_MessageBoxCritical)

    # Load the icon file stored in a predefined local directory.
    return QIcon('code/media/icons/' + iconName + '.png')

def suppressDisabledIconAppearance(icon):
    """Replace an icon's disabled pixmaps with normal ones, so that the icon
    will never appear in the disabled monochrome style."""

    for size in icon.availableSizes():
        # Besides icon mode, 'addPixmap' and 'pixmap' also take the 'State'
        # parameter, which may be 'On' or 'Off'. However, using just the
        # default value for that seems to be enough.
        icon.addPixmap(icon.pixmap(size, QIcon.Normal), QIcon.Disabled)

# *****************************************************************************
class SignalBlocker:
    """Utility class that may be used with 'with' statement to temporarily
    block any of the signals emitted by the given list of 'QObject's.

    Pass the 'QObject's to block signals from to constructor, and use the
    returned instance as the argument for 'with' statement."""

    def __init__(self, *widgetList):
        self.widgetList = widgetList

    def __enter__(self):
        for widget in self.widgetList:
            widget.blockSignals(True)

    def __exit__(self, excType, excValue, traceback):
        for widget in self.widgetList:
            widget.blockSignals(False)

# *****************************************************************************
class UnhidableWidgetItem(QWidgetItem):
    """A widget layout item that occupies the same space regardless of whether
    its widget is visible or hidden."""

    def __init__(self, widget):
        QWidgetItem.__init__(self, widget)

    def isEmpty(self):
        return False
