Package node_manager_fkie :: Module select_dialog
[frames] | no frames]

Source Code for Module node_manager_fkie.select_dialog

  1  # Software License Agreement (BSD License) 
  2  # 
  3  # Copyright (c) 2012, Fraunhofer FKIE/US, Alexander Tiderko 
  4  # All rights reserved. 
  5  # 
  6  # Redistribution and use in source and binary forms, with or without 
  7  # modification, are permitted provided that the following conditions 
  8  # are met: 
  9  # 
 10  #  * Redistributions of source code must retain the above copyright 
 11  #    notice, this list of conditions and the following disclaimer. 
 12  #  * Redistributions in binary form must reproduce the above 
 13  #    copyright notice, this list of conditions and the following 
 14  #    disclaimer in the documentation and/or other materials provided 
 15  #    with the distribution. 
 16  #  * Neither the name of Fraunhofer nor the names of its 
 17  #    contributors may be used to endorse or promote products derived 
 18  #    from this software without specific prior written permission. 
 19  # 
 20  # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
 21  # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
 22  # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
 23  # FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
 24  # COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 
 25  # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
 26  # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
 27  # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 
 28  # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
 29  # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 
 30  # ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
 31  # POSSIBILITY OF SUCH DAMAGE. 
 32   
 33  from python_qt_binding.QtCore import Qt, Signal 
 34  try: 
 35      from python_qt_binding.QtGui import QCheckBox, QDialog, QFrame, QDialogButtonBox, QLabel, QLineEdit, QScrollArea, QWidget 
 36      from python_qt_binding.QtGui import QFormLayout, QHBoxLayout, QVBoxLayout, QSizePolicy, QSpacerItem 
 37  except: 
 38      from python_qt_binding.QtWidgets import QCheckBox, QDialog, QFrame, QDialogButtonBox, QLabel, QLineEdit, QScrollArea, QWidget 
 39      from python_qt_binding.QtWidgets import QFormLayout, QHBoxLayout, QVBoxLayout, QSizePolicy, QSpacerItem 
 40  from python_qt_binding.QtGui import QPixmap 
 41  import re 
 42   
 43  import threading 
 44  from node_manager_fkie.common import utf8 
 45  from node_manager_fkie.editor.line_edit import EnchancedLineEdit 
46 47 48 -class SelectDialog(QDialog):
49 ''' 50 This dialog creates an input mask for a string list and return selected entries. 51 ''' 52
53 - def __init__(self, items=list(), buttons=QDialogButtonBox.Cancel | QDialogButtonBox.Ok, exclusive=False, 54 preselect_all=False, title='', description='', icon='', parent=None, select_if_single=True, 55 checkitem1='', checkitem2='', closein=0):
56 ''' 57 Creates an input dialog. 58 @param items: a list with strings 59 @type items: C{list()} 60 ''' 61 QDialog.__init__(self, parent=parent) 62 self.setObjectName(' - '.join(['SelectDialog', utf8(items)])) 63 64 self.verticalLayout = QVBoxLayout(self) 65 self.verticalLayout.setObjectName("verticalLayout") 66 self.verticalLayout.setContentsMargins(1, 1, 1, 1) 67 68 # add filter row 69 self.filter_frame = QFrame(self) 70 filterLayout = QHBoxLayout(self.filter_frame) 71 filterLayout.setContentsMargins(1, 1, 1, 1) 72 label = QLabel("Filter:", self.filter_frame) 73 self.filter_field = EnchancedLineEdit(self.filter_frame) 74 filterLayout.addWidget(label) 75 filterLayout.addWidget(self.filter_field) 76 self.filter_field.textChanged.connect(self._on_filter_changed) 77 self.verticalLayout.addWidget(self.filter_frame) 78 79 if description: 80 self.description_frame = QFrame(self) 81 descriptionLayout = QHBoxLayout(self.description_frame) 82 # descriptionLayout.setContentsMargins(1, 1, 1, 1) 83 if icon: 84 self.icon_label = QLabel(self.description_frame) 85 self.icon_label.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) 86 self.icon_label.setPixmap(QPixmap(icon).scaled(30, 30, Qt.KeepAspectRatio)) 87 descriptionLayout.addWidget(self.icon_label) 88 self.description_label = QLabel(self.description_frame) 89 self.description_label.setWordWrap(True) 90 self.description_label.setText(description) 91 descriptionLayout.addWidget(self.description_label) 92 self.verticalLayout.addWidget(self.description_frame) 93 94 # create area for the parameter 95 self.content = MainBox(self) 96 if items: 97 self.scroll_area = QScrollArea(self) 98 self.scroll_area.setFocusPolicy(Qt.NoFocus) 99 self.scroll_area.setObjectName("scroll_area") 100 self.scroll_area.setWidgetResizable(True) 101 self.scroll_area.setWidget(self.content) 102 self.verticalLayout.addWidget(self.scroll_area) 103 104 self.checkitem1 = checkitem1 105 self.checkitem1_result = False 106 self.checkitem2 = checkitem2 107 self.checkitem2_result = False 108 109 # add select all option 110 if not exclusive and items: 111 self._ignore_next_toggle = False 112 self.select_all_checkbox = QCheckBox('all entries') 113 self.select_all_checkbox.setTristate(True) 114 self.select_all_checkbox.stateChanged.connect(self._on_select_all_checkbox_stateChanged) 115 self.verticalLayout.addWidget(self.select_all_checkbox) 116 self.content.toggled.connect(self._on_main_toggle) 117 if self.checkitem1: 118 self.checkitem1_checkbox = QCheckBox(self.checkitem1) 119 self.checkitem1_checkbox.stateChanged.connect(self._on_select_checkitem1_checkbox_stateChanged) 120 self.verticalLayout.addWidget(self.checkitem1_checkbox) 121 if self.checkitem2: 122 self.checkitem2_checkbox = QCheckBox(self.checkitem2) 123 self.checkitem2_checkbox.stateChanged.connect(self._on_select_checkitem2_checkbox_stateChanged) 124 self.verticalLayout.addWidget(self.checkitem2_checkbox) 125 if not items: 126 spacerItem = QSpacerItem(1, 1, QSizePolicy.Expanding, QSizePolicy.Expanding) 127 self.verticalLayout.addItem(spacerItem) 128 129 self._close_timer = None 130 self._closein = closein - 1 131 if closein > 0: 132 self.closein_label = QLabel("OK in %d sec..." % closein) 133 self.closein_label.setAlignment(Qt.AlignRight) 134 self.verticalLayout.addWidget(self.closein_label) 135 self._close_timer = threading.Timer(1.0, self._on_close_timer) 136 self._close_timer.start() 137 138 # create buttons 139 self.buttonBox = QDialogButtonBox(self) 140 self.buttonBox.setObjectName("buttonBox") 141 self.buttonBox.setOrientation(Qt.Horizontal) 142 self.buttonBox.setStandardButtons(buttons) 143 self.buttonBox.accepted.connect(self.accept) 144 self.buttonBox.rejected.connect(self.reject) 145 self.verticalLayout.addWidget(self.buttonBox) 146 147 # set the input fields 148 if items: 149 self.content.createFieldsFromValues(items, exclusive) 150 if (select_if_single and len(items) == 1) or preselect_all: 151 self.select_all_checkbox.setCheckState(Qt.Checked) 152 153 if not items or len(items) < 7: 154 self.filter_frame.setVisible(False)
155 # print '=============== create', self.objectName() 156 # 157 # def __del__(self): 158 # print "************ destroy", self.objectName() 159
160 - def _on_main_toggle(self, state):
161 self.cancel_autoclose() 162 self._ignore_next_toggle = state != self.select_all_checkbox.checkState() 163 self.select_all_checkbox.setCheckState(state)
164
166 self.cancel_autoclose() 167 if not self._ignore_next_toggle: 168 self.content.setState(state) 169 self._ignore_next_toggle = False
170
172 self.cancel_autoclose() 173 if state == Qt.Checked: 174 self.checkitem1_result = True 175 elif state == Qt.Unchecked: 176 self.checkitem1_result = False
177
179 self.cancel_autoclose() 180 if state == Qt.Checked: 181 self.checkitem2_result = True 182 elif state == Qt.Unchecked: 183 self.checkitem2_result = False
184
185 - def _on_filter_changed(self):
186 self.content.filter(self.filter_field.text())
187
188 - def _on_close_timer(self):
189 self.closein_label.setText("OK in %d sec..." % self._closein) 190 if self._closein == 0: 191 self.buttonBox.accepted.emit() 192 return 193 self._closein -= 1 194 self._close_timer = threading.Timer(1.0, self._on_close_timer) 195 self._close_timer.start()
196
197 - def cancel_autoclose(self):
198 if self._close_timer is not None: 199 self._close_timer.cancel() 200 self.closein_label.setVisible(False)
201
202 - def getSelected(self):
203 return self.content.getSelected()
204 205 @staticmethod
206 - def getValue(title, description='', items=list(), exclusive=False, preselect_all=False, icon='', parent=None, select_if_single=True, checkitem1='', checkitem2='', closein=0):
207 selectDia = SelectDialog(items, exclusive=exclusive, preselect_all=preselect_all, description=description, icon=icon, parent=parent, select_if_single=select_if_single, checkitem1=checkitem1, checkitem2=checkitem2, closein=closein) 208 selectDia.setWindowTitle(title) 209 selectDia.resize(480, 256) 210 if selectDia.exec_(): 211 if selectDia.checkitem2: 212 return selectDia.getSelected(), True, selectDia.checkitem1_result, selectDia.checkitem2_result 213 if selectDia.checkitem1: 214 return selectDia.getSelected(), True, selectDia.checkitem1_result 215 return selectDia.getSelected(), True 216 if selectDia.checkitem2: 217 return list(), False, False, False 218 if selectDia.checkitem1: 219 return list(), False, False 220 return list(), False
221 222 223 # %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 224 # %%%%%%%%%%%%%%%%%% close handling %%%%%%%%%%%%%%%%%%%%% 225 # %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 226
227 - def accept(self):
228 self.cancel_autoclose() 229 self.setResult(QDialog.Accepted) 230 self.hide()
231
232 - def reject(self):
233 self.cancel_autoclose() 234 self.setResult(QDialog.Rejected) 235 self.hide()
236
237 - def hideEvent(self, event):
238 self.close()
239
240 - def closeEvent(self, event):
241 ''' 242 Test the open files for changes and save this if needed. 243 ''' 244 self.cancel_autoclose() 245 self.setAttribute(Qt.WA_DeleteOnClose, True) 246 QDialog.closeEvent(self, event)
247
248 249 -class MainBox(QWidget):
250 ''' 251 A widget with entries. 252 ''' 253 254 toggled = Signal(Qt.CheckState) 255
256 - def __init__(self, parent=None):
257 QWidget.__init__(self, parent) 258 self.setObjectName("MainBox") 259 self.__on_intern_change = False 260 boxLayout = QFormLayout() 261 boxLayout.setVerticalSpacing(0) 262 self.setLayout(boxLayout)
263
264 - def createFieldsFromValues(self, values, exclusive=False):
265 self.setUpdatesEnabled(False) 266 try: 267 if isinstance(values, list): 268 for v in values: 269 checkbox = QCheckBox(v) 270 checkbox.toggled.connect(self._on_checkbox_toggled) 271 checkbox.setObjectName(v) 272 checkbox.setAutoExclusive(exclusive) 273 self.layout().addRow(checkbox) 274 finally: 275 self.setUpdatesEnabled(True)
276
277 - def _on_checkbox_toggled(self):
278 if not self.__on_intern_change: 279 sel_count = self.getSelected() 280 if len(sel_count) == 0: 281 self.toggled.emit(Qt.Unchecked) 282 elif len(sel_count) == self.layout().count(): 283 self.toggled.emit(Qt.Checked) 284 else: 285 self.toggled.emit(Qt.PartiallyChecked)
286
287 - def filter(self, arg):
288 ''' 289 Hide the parameter input field, which label dosn't contains the C{arg}. 290 @param arg: the filter text 291 @type arg: C{str} 292 ''' 293 for i in range(self.layout().count()): 294 item = self.layout().itemAt(i).widget() 295 if isinstance(item, QCheckBox): 296 new_state = (not re.search(arg, item.objectName()) is None) 297 item.setVisible(new_state) 298 if new_state: 299 self._on_checkbox_toggled()
300
301 - def getSelected(self):
302 result = list() 303 for i in range(self.layout().count()): 304 item = self.layout().itemAt(i).widget() 305 if isinstance(item, QCheckBox): 306 if item.isChecked(): 307 result.append(item.objectName()) 308 return result
309
310 - def setState(self, state):
311 self.__on_intern_change = True 312 for i in range(self.layout().count()): 313 item = self.layout().itemAt(i).widget() 314 if isinstance(item, QCheckBox): 315 if state == Qt.Checked: 316 item.setCheckState(Qt.Checked) 317 elif state == Qt.Unchecked: 318 item.setCheckState(Qt.Unchecked) 319 elif state == Qt.PartiallyChecked and item.isVisible(): 320 item.setCheckState(Qt.Checked) 321 self.__on_intern_change = False 322 self._on_checkbox_toggled()
323