1# -*- coding: utf-8 -*-
2
3"""
4***************************************************************************
5    CheckBoxesPanel.py
6    ---------------------
7    Date                 : January 2015
8    Copyright            : (C) 2015 by Arnaud Morvan
9    Email                : arnaud dot morvan at camptocamp dot com
10    Contributors         : Arnaud Morvan
11***************************************************************************
12*                                                                         *
13*   This program is free software; you can redistribute it and/or modify  *
14*   it under the terms of the GNU General Public License as published by  *
15*   the Free Software Foundation; either version 2 of the License, or     *
16*   (at your option) any later version.                                   *
17*                                                                         *
18***************************************************************************
19"""
20
21__author__ = 'Arnaud Morvan'
22__date__ = 'January 2015'
23__copyright__ = '(C) 2015, Arnaud Morvan'
24
25from qgis.PyQt.QtCore import Qt
26from qgis.PyQt.QtWidgets import (
27    QCheckBox,
28    QRadioButton,
29    QGridLayout,
30    QButtonGroup,
31    QSizePolicy,
32    QSpacerItem,
33    QWidget,
34    QMenu,
35    QAction
36)
37from qgis.PyQt.QtGui import QCursor
38
39
40class CheckboxesPanel(QWidget):
41
42    def __init__(self, options, multiple, columns=2, parent=None):
43        super(CheckboxesPanel, self).__init__(parent)
44
45        self._options = []
46        for i, option in enumerate(options):
47            if isinstance(option, str):
48                self._options.append((i, option))
49            else:
50                self.options.append(option)
51        self._multiple = multiple
52        self._buttons = []
53        rows = len(options) / columns
54
55        self._buttonGroup = QButtonGroup()
56        self._buttonGroup.setExclusive(not multiple)
57        layout = QGridLayout()
58        layout.setContentsMargins(0, 0, 0, 0)
59        layout.setMargin(0)
60        for i, (v, t) in enumerate(self._options):
61            if multiple:
62                button = QCheckBox(t)
63            else:
64                button = QRadioButton(t)
65            self._buttons.append((v, button))
66            self._buttonGroup.addButton(button, i)
67            layout.addWidget(button, i % rows, i / rows)
68        layout.addItem(QSpacerItem(0, 0, QSizePolicy.Expanding, QSizePolicy.Minimum),
69                       0, columns)
70        self.setLayout(layout)
71
72        if multiple:
73            self.setContextMenuPolicy(Qt.CustomContextMenu)
74            self.customContextMenuRequested.connect(self.showPopupMenu)
75
76    def showPopupMenu(self):
77        popup_menu = QMenu()
78        select_all_action = QAction(self.tr('Select All'), popup_menu)
79        select_all_action.triggered.connect(self.selectAll)
80        clear_all_action = QAction(self.tr('Clear Selection'), popup_menu)
81        clear_all_action.triggered.connect(self.deselectAll)
82        popup_menu.addAction(select_all_action)
83        popup_menu.addAction(clear_all_action)
84        popup_menu.exec_(QCursor.pos())
85
86    def selectAll(self):
87        for (v, button) in self._buttons:
88            button.setChecked(True)
89
90    def deselectAll(self):
91        for (v, button) in self._buttons:
92            button.setChecked(False)
93
94    def value(self):
95        if self._multiple:
96            value = []
97            for (v, checkbox) in self._buttons:
98                if checkbox.isChecked():
99                    value.append(v)
100            return value
101        else:
102            return self._options[self._buttonGroup.checkedId()][0]
103
104    def setValue(self, value):
105        if self._multiple:
106            for (v, button) in self._buttons:
107                button.setChecked(v in value)
108        else:
109            for v, button in self._buttons:
110                button.setChecked(v == value)
111