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

Source Code for Module node_manager_fkie.message_frame

  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  import os 
 34  from python_qt_binding import loadUi 
 35  from python_qt_binding.QtCore import Qt, Signal 
 36  from python_qt_binding.QtGui import QColor, QPixmap 
 37  from node_manager_fkie.common import utf8 
 38  from node_manager_fkie.html_delegate import HTMLDelegate 
 39  import node_manager_fkie as nm 
 40   
 41  try: 
 42      from python_qt_binding.QtGui import QFrame, QLabel 
 43  except Exception: 
 44      from python_qt_binding.QtWidgets import QFrame, QLabel 
 45   
 46   
47 -class MessageData(object):
48 ''' ''' 49
50 - def __init__(self, data, data_list=[]):
51 self.data = data 52 self.data_list = data_list
53
54 - def __str__(self):
55 return utf8(self.data)
56
57 - def __eq__(self, other):
58 return self.data == other.data
59
60 - def __ne__(self, other):
61 return self.data != other.data
62 63
64 -class MessageQueue(object):
65
66 - def __init__(self):
77
78 - def add(self, questionid, text, data):
79 if questionid in self._queue.keys(): 80 for txt, dt in self._queue[questionid]: 81 if txt == text and dt == data: 82 no_in_list = [x for x in data.data_list if x not in dt.data_list] 83 for item in no_in_list: 84 dt.data_list.append(item) 85 return 86 self._queue[questionid].append((text, data))
87
88 - def get(self):
89 ''' 90 Returns a tuple of (questionid, text, data) 91 ''' 92 for qid, values in self._queue.iteritems(): 93 if values: 94 text, data = values.pop(0) 95 return (qid, text, data) 96 return (0, '', None)
97 98
99 -class MessageFrame(QFrame):
100 101 accept_signal = Signal(int, MessageData) 102 ''' @ivar: A signal on accept button clicked (id, data)''' 103 104 cancel_signal = Signal(int, MessageData) 105 ''' @ivar: A signal on cancel button clicked (id, data)''' 106 107 TYPE_INVALID = 0 108 TYPE_EMPTY = 1 109 TYPE_QUESTION = 2 110 TYPE_LAUNCH_FILE = 3 111 TYPE_DEFAULT_CFG = 4 112 TYPE_NODELET = 5 113 TYPE_TRANSFER = 6 114 TYPE_BINARY = 7 115 TYPE_NOSCREEN = 8 116 117 ICON_SIZE = 32 118
119 - def __init__(self, parent=None, info=False):
120 QFrame.__init__(self, parent=parent) 121 self.setObjectName('MessageFrame') 122 self.questionid = self.TYPE_INVALID 123 self.text = "" 124 self.data = MessageData(None) 125 self.IMAGES = {1: QPixmap(), 126 2: QPixmap(':/icons/crystal_clear_question.png').scaled(self.ICON_SIZE, self.ICON_SIZE, Qt.IgnoreAspectRatio, Qt.SmoothTransformation), 127 3: QPixmap(':/icons/crystal_clear_launch_file.png').scaled(self.ICON_SIZE, self.ICON_SIZE, Qt.IgnoreAspectRatio, Qt.SmoothTransformation), 128 4: QPixmap(":/icons/default_cfg.png").scaled(self.ICON_SIZE, self.ICON_SIZE, Qt.IgnoreAspectRatio, Qt.SmoothTransformation), 129 5: QPixmap(":/icons/crystal_clear_nodelet_q.png").scaled(self.ICON_SIZE, self.ICON_SIZE, Qt.IgnoreAspectRatio, Qt.SmoothTransformation), 130 6: QPixmap(":/icons/crystal_clear_launch_file_transfer.png").scaled(self.ICON_SIZE, self.ICON_SIZE, Qt.IgnoreAspectRatio, Qt.SmoothTransformation), 131 7: QPixmap(":/icons/crystal_clear_question.png").scaled(self.ICON_SIZE, self.ICON_SIZE, Qt.IgnoreAspectRatio, Qt.SmoothTransformation), 132 8: QPixmap(":/icons/crystal_clear_no_io.png").scaled(self.ICON_SIZE, self.ICON_SIZE, Qt.IgnoreAspectRatio, Qt.SmoothTransformation) 133 } 134 self._new_request = False 135 self.frameui = QFrame() 136 ui_file = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'MessageFrame.ui') 137 loadUi(ui_file, self.frameui) 138 color = QColor(255, 207, 121) 139 self.frameui.setVisible(False) 140 self.frameui.listLabel.setVisible(False) 141 self.frameui.questionOkButton.clicked.connect(self._on_question_ok) 142 self.frameui.questionCancelButton.clicked.connect(self._on_question_cancel) 143 self.frameui.checkBox_dnaa.stateChanged.connect(self._on_checkbox_state_changed) 144 self._ask = 'ask' 145 if info: 146 color = QColor(232, 104, 80) 147 self.frameui.questionCancelButton.setVisible(False) 148 self._ask = 'show' 149 bg_style = "QFrame#questionFame { background-color: %s;}" % color.name() 150 self.frameui.setStyleSheet("%s" % (bg_style)) 151 self._queue = MessageQueue() 152 self._do_not_ask = {}
153
154 - def show_question(self, questionid, text, data=MessageData(None), color=None):
155 if questionid == 0: 156 return 157 try: 158 # is it in the list for not ask again? 159 if self._do_not_ask[questionid]: 160 self.accept_signal.emit(questionid, data) 161 else: 162 self.cancel_signal.emit(questionid, data) 163 return 164 except Exception: 165 pass 166 if self.questionid != questionid or self.text != text or data != self.data: 167 self._queue.add(questionid, text, data) 168 elif data.data_list: # same question again 169 # update the list of files or nodes which causes this question in current question 170 for dt in data.data_list: 171 if dt not in self.data.data_list: 172 self.data.data_list.append(dt) 173 self._update_list_label(self.data.data_list) 174 # if no question is active pop first element from the queue 175 if self.questionid == self.TYPE_INVALID: 176 self._new_request = self._read_next_item() 177 self._frameui_4_request(self._new_request) 178 if self.questionid in [self.TYPE_NODELET, self.TYPE_NOSCREEN]: 179 self.frameui.checkBox_dnaa.setText("don't %s again, never!" % self._ask) 180 else: 181 self.frameui.checkBox_dnaa.setText("don't %s again, for session" % self._ask)
182
183 - def show_info(self, infoid, text, data=MessageData(None), color=None):
184 self.show_question(infoid, text=text, data=data, color=color)
185
186 - def is_do_not_ask(self, questionid):
187 try: 188 # is it in the list for not ask again? 189 return self._do_not_ask[questionid] 190 except Exception: 191 return False
192
193 - def hide_question(self, questionids):
194 if self.questionid in questionids: 195 self._new_request = False 196 self.frameui.setVisible(False) 197 self.cancel_signal.emit(self.questionid, self.data) 198 self.questionid = 0 199 self._update_list_label([]) 200 self._new_request = self._read_next_item() 201 self._frameui_4_request(self._new_request)
202
203 - def _update_list_label(self, items=[]):
204 ''' 205 Put list elements into the list label in the question frame 206 ''' 207 if items: 208 self.frameui.listLabel.setText('') 209 for item in items: 210 ltext = self.frameui.listLabel.text() 211 if ltext: 212 self.frameui.listLabel.setText("%s, %s" % (ltext, HTMLDelegate.toHTML(item))) 213 else: 214 self.frameui.listLabel.setText("%s" % (HTMLDelegate.toHTML(item))) 215 self.frameui.listLabel.setVisible(True) 216 else: 217 self.frameui.listLabel.setText('') 218 self.frameui.listLabel.setVisible(False)
219
220 - def _frameui_4_request(self, request):
221 if request: 222 self.frameui.checkBox_dnaa.setChecked(False) 223 self.frameui.setVisible(True) 224 self.frameui.listLabel.setVisible(True) 225 else: 226 self.questionid = 0 227 self.frameui.setVisible(False) 228 self.frameui.listLabel.setVisible(False)
229
230 - def _on_question_ok(self):
231 self._new_request = False 232 self.frameui.setVisible(False) 233 self.accept_signal.emit(self.questionid, self.data) 234 self.questionid = 0 235 self._update_list_label([]) 236 self._new_request = self._read_next_item() 237 self._frameui_4_request(self._new_request)
238
239 - def _on_question_cancel(self):
240 self._new_request = False 241 self.frameui.setVisible(False) 242 self.cancel_signal.emit(self.questionid, self.data) 243 self.questionid = 0 244 self._update_list_label([]) 245 self._new_request = self._read_next_item() 246 self._frameui_4_request(self._new_request)
247
248 - def _is_launch_data_in_queue(self, newdata):
249 for _, data, _ in self._queue_launchfile: 250 if data == newdata: 251 return True 252 return False
253
254 - def _is_transfer_data_in_queue(self, newdata):
255 for _, data, _ in self._queue_transfer_files: 256 if data == newdata: 257 return True 258 return False
259
260 - def _is_other_data_in_queue(self, questionid, text, data):
261 for cqid, ctxt, cd, _ in self._queue_other: 262 if cqid == questionid and cd == data and ctxt == text: 263 return True 264 return False
265
266 - def _read_next_item(self):
267 (qid, text, data) = self._queue.get() 268 if qid != self.TYPE_INVALID: 269 self.questionid = qid 270 self.text = text 271 self.data = data 272 self.frameui.questionIcon.setPixmap(self.IMAGES[qid]) 273 self.frameui.questionLabel.setText(text) 274 self._update_list_label(self.data.data_list) 275 return qid != self.TYPE_INVALID
276
277 - def _on_checkbox_state_changed(self, state):
278 if self.questionid == self.TYPE_NODELET: 279 self.frameui.questionOkButton.setVisible(not state) 280 nm.settings().check_for_nodelets_at_start = not state 281 elif self.questionid == self.TYPE_NOSCREEN: 282 self.frameui.questionCancelButton.setVisible(not state) 283 nm.settings().show_noscreen_error = not state 284 else: 285 self._do_not_ask[self.questionid] = state
286
287 - def _clear_scroll_area(self):
288 child = self.frameui.scrollAreaLayout.takeAt(0) 289 while child: 290 child.widget().setParent(None) 291 del child 292 child = self.frameui.scrollAreaLayout.takeAt(0)
293