00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 import os
00034
00035 from python_qt_binding import loadUi
00036 from python_qt_binding.QtGui import QApplication, QCursor, QFileDialog, QIcon, QItemSelectionModel, QMenu, QMessageBox, QTableView, QWidget
00037 from python_qt_binding.QtCore import QRect, QRegExp, Qt, qWarning
00038
00039 import time
00040 import datetime
00041
00042 from .filters.custom_filter import CustomFilter
00043 from .filters.location_filter import LocationFilter
00044 from .filters.message_filter import MessageFilter
00045 from .filters.node_filter import NodeFilter
00046 from .filters.severity_filter import SeverityFilter
00047 from .filters.time_filter import TimeFilter
00048 from .filters.topic_filter import TopicFilter
00049
00050 from .filters.custom_filter_widget import CustomFilterWidget
00051 from .filters.filter_wrapper_widget import FilterWrapperWidget
00052 from .filters.list_filter_widget import ListFilterWidget
00053 from .filters.text_filter_widget import TextFilterWidget
00054 from .filters.time_filter_widget import TimeFilterWidget
00055 from .filters.filter_utils import pack, unpack
00056
00057 from .text_browse_dialog import TextBrowseDialog
00058
00059
00060 class ConsoleTableView(QTableView):
00061 def __init__(self, parent=None):
00062 super(ConsoleTableView, self).__init__()
00063
00064
00065 class ConsoleWidget(QWidget):
00066 """
00067 Primary widget for the rqt_console plugin.
00068 """
00069 def __init__(self, proxymodel, minimal=False):
00070 """
00071 :param proxymodel: the proxy model to display in the widget,''QSortFilterProxyModel''
00072 :param minimal: if true the load, save and column buttons will be hidden as well as the filter splitter, ''bool''
00073 """
00074 super(ConsoleWidget, self).__init__()
00075 ui_file = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'console_widget.ui')
00076 loadUi(ui_file, self, {'ConsoleTableView': ConsoleTableView})
00077
00078 if minimal:
00079 self.load_button.hide()
00080 self.save_button.hide()
00081 self.column_resize_button.hide()
00082 self.setObjectName('ConsoleWidget')
00083 self.table_view.setModel(proxymodel)
00084 self._proxymodel = proxymodel
00085 self._datamodel = proxymodel.sourceModel()
00086
00087 self._columnwidth = (600, 140, 200, 430, 200, 600)
00088 for idx, width in enumerate(self._columnwidth):
00089 self.table_view.horizontalHeader().resizeSection(idx, width)
00090 self.table_view.sortByColumn(3, Qt.DescendingOrder)
00091
00092 self.add_exclude_button.setIcon(QIcon.fromTheme('list-add'))
00093 self.add_highlight_button.setIcon(QIcon.fromTheme('list-add'))
00094 self._pauseicon = QIcon.fromTheme('media-playback-pause')
00095 self._recordicon = QIcon.fromTheme('media-record')
00096 self.pause_button.setIcon(self._pauseicon)
00097 self.load_button.setIcon(QIcon.fromTheme('document-open'))
00098 self.save_button.setIcon(QIcon.fromTheme('document-save'))
00099 self.highlight_exclude_button.setIcon(QIcon.fromTheme('format-text-strikethrough'))
00100
00101 self.pause_button.clicked[bool].connect(self._handle_pause_clicked)
00102 self.load_button.clicked[bool].connect(self._handle_load_clicked)
00103 self.save_button.clicked[bool].connect(self._handle_save_clicked)
00104 self.column_resize_button.clicked[bool].connect(self._handle_column_resize_clicked)
00105 self.clear_button.clicked[bool].connect(self._handle_clear_button_clicked)
00106
00107 self.table_view.mouseDoubleClickEvent = self._handle_mouse_double_click
00108 self.table_view.mousePressEvent = self._handle_mouse_press
00109 self.table_view.keyPressEvent = self._handle_custom_keypress
00110 self.severitylist = self._datamodel.get_severity_list()
00111
00112
00113 self._exclude_filters = []
00114 self._highlight_filters = []
00115
00116 self.highlight_exclude_button.clicked[bool].connect(self._proxymodel.set_show_highlighted_only)
00117
00118 self.add_highlight_button.clicked.connect(self._add_highlight_filter)
00119 self.add_exclude_button.clicked.connect(self._add_exclude_filter)
00120
00121
00122
00123
00124 self.filter_factory = {'message': (self.tr('Message Filter'), MessageFilter, TextFilterWidget, []),
00125 'severity': (self.tr('Severity Filter'), SeverityFilter, ListFilterWidget, [self._datamodel.get_severity_list]),
00126 'node': (self.tr('Node Filter'), NodeFilter, ListFilterWidget, [self._datamodel.get_unique_col_data, 2]),
00127 'time': (self.tr('Time Filter'), TimeFilter, TimeFilterWidget, [self.get_time_range_from_selection]),
00128 'topic': (self.tr('Topic Filter'), TopicFilter, ListFilterWidget, [self._datamodel.get_unique_col_data, 4]),
00129 'location': (self.tr('Location Filter'), LocationFilter, TextFilterWidget, []),
00130 'custom': (self.tr('Custom Filter'), CustomFilter, CustomFilterWidget, [self._datamodel.get_severity_list, self._datamodel.get_unique_col_data, 2, self._datamodel.get_unique_col_data, 4])}
00131
00132
00133 self._browsers = []
00134
00135
00136 if(minimal):
00137 self.table_splitter.setSizes([1, 0])
00138 else:
00139 self.table_splitter.setSizes([1, 1])
00140 self.exclude_table.resizeColumnsToContents()
00141 self.highlight_table.resizeColumnsToContents()
00142
00143 def get_message_summary(self, start_time_offset=None, end_time_offset=None):
00144 """
00145 :param start_time: number of seconds before now to start, ''int'' (optional)
00146 :param end_time: number of seconds before now to end, ''int'' (optional)
00147 :returns: summary of message numbers within time
00148 """
00149 current_time = time.mktime(datetime.datetime.now().timetuple())
00150 if start_time_offset is None:
00151 start_time = current_time - 240
00152 else:
00153 start_time = current_time - start_time_offset
00154 if end_time_offset is not None:
00155 end_time = current_time - end_time_offset
00156 else:
00157 end_time = None
00158
00159 message_subset = self._datamodel.get_message_list(start_time, end_time)
00160
00161 class Message_Summary(object):
00162 __slots__ = 'fatal', 'error', 'warn', 'info', 'debug'
00163
00164 def __init__(self, messages):
00165 self.fatal = 0
00166 self.error = 0
00167 self.warn = 0
00168 self.info = 0
00169 self.debug = 0
00170 for message in messages:
00171 severity = message.get_data(1)
00172 if severity == 'Debug':
00173 self.debug += 1
00174 elif severity == 'Info':
00175 self.info += 1
00176 elif severity == 'Warn':
00177 self.warn += 1
00178 elif severity == 'Error':
00179 self.error += 1
00180 elif severity == 'Fatal':
00181 self.fatal += 1
00182
00183 return Message_Summary(message_subset)
00184
00185 def get_time_range_from_selection(self):
00186 """
00187 :returns: the range of time of messages in the current table selection (min, max), ''tuple(str,str)''
00188 """
00189 rowlist = []
00190 indexes = self.table_view.selectionModel().selectedIndexes()
00191
00192 if len(indexes) != 0:
00193 for current in indexes:
00194 rowlist.append(self._proxymodel.mapToSource(current).row())
00195 rowlist = list(set(rowlist))
00196 rowlist.sort()
00197
00198 mintime, maxtime = self._datamodel.get_time_range(rowlist)
00199 return (mintime, maxtime)
00200 return (-1, -1)
00201
00202 def _delete_highlight_filter(self):
00203 """
00204 Deletes any highlight filters which have a checked delete button
00205 """
00206 for index, item in enumerate(self._highlight_filters):
00207 if item[1].delete_button.isChecked():
00208 if self._proxymodel.delete_highlight_filter(index):
00209 self.highlight_table.removeCellWidget(index, 0)
00210 self.highlight_table.removeRow(index)
00211 item[0].filter_changed_signal.disconnect(self._proxymodel.handle_filters_changed)
00212 item[1].delete_button.clicked.disconnect(self._delete_highlight_filter)
00213 del self._highlight_filters[index]
00214
00215 def _delete_exclude_filter(self):
00216 """
00217 Deletes any exclude filters which have a checked delete button
00218 """
00219 for index, item in enumerate(self._exclude_filters):
00220 if item[1].delete_button.isChecked():
00221 if self._proxymodel.delete_exclude_filter(index):
00222 self.exclude_table.removeCellWidget(index, 0)
00223 self.exclude_table.removeRow(index)
00224 item[0].filter_changed_signal.disconnect(self._proxymodel.handle_filters_changed)
00225 item[1].delete_button.clicked.disconnect(self._delete_exclude_filter)
00226 del self._exclude_filters[index]
00227
00228 def _add_highlight_filter(self, filter_index=False):
00229 """
00230 :param filter_index: if false then this function shows a QMenu to allow the user to choose a type of message filter. ''bool''
00231 OR
00232 :param filter_index: the index of the filter to be added, ''int''
00233 :return: if a filter was added then the index is returned, ''int''
00234 OR
00235 :return: if no filter was added then None is returned, ''NoneType''
00236 """
00237 if filter_index is False:
00238 filter_index = -1
00239 filter_select_menu = QMenu()
00240 for index, item in self.filter_factory.items():
00241
00242 if self.filter_factory[index][0] == self.tr('Message Filter') or not self.filter_factory[index][1] in [type(item) for sublist in self._highlight_filters for item in sublist]:
00243 filter_select_menu.addAction(self.filter_factory[index][0])
00244 action = filter_select_menu.exec_(QCursor.pos())
00245 if action is None:
00246 return
00247 for index, item in self.filter_factory.items():
00248 if self.filter_factory[index][0] == action.text():
00249 filter_index = index
00250 if filter_index == -1:
00251 return
00252
00253 index = len(self._highlight_filters)
00254 newfilter = self.filter_factory[filter_index][1]()
00255 newwidget = self.filter_factory[filter_index][2](newfilter, self.filter_factory[filter_index][3])
00256
00257
00258 self._highlight_filters.append((newfilter, FilterWrapperWidget(newwidget, self.filter_factory[filter_index][0]), filter_index))
00259 self._proxymodel.add_highlight_filter(newfilter)
00260 newfilter.filter_changed_signal.connect(self._proxymodel.handle_filters_changed)
00261 self._highlight_filters[index][1].delete_button.clicked.connect(self._delete_highlight_filter)
00262 self._datamodel.rowsInserted.connect(self._highlight_filters[index][1].repopulate)
00263
00264
00265 self.highlight_table.insertRow(index)
00266 self.highlight_table.setCellWidget(index, 0, self._highlight_filters[index][1])
00267 self.highlight_table.resizeColumnsToContents()
00268 self.highlight_table.resizeRowsToContents()
00269 newfilter.filter_changed_signal.emit()
00270 return index
00271
00272 def _add_exclude_filter(self, filter_index=False):
00273 """
00274 :param filter_index: if false then this function shows a QMenu to allow the user to choose a type of message filter. ''bool''
00275 OR
00276 :param filter_index: the index of the filter to be added, ''int''
00277 :return: if a filter was added then the index is returned, ''int''
00278 OR
00279 :return: if no filter was added then None is returned, ''NoneType''
00280 """
00281 if filter_index is False:
00282 filter_index = -1
00283 filter_select_menu = QMenu()
00284 for index, item in self.filter_factory.items():
00285
00286 if self.filter_factory[index][0] == self.tr('Message Filter') or not self.filter_factory[index][1] in [type(item) for sublist in self._exclude_filters for item in sublist]:
00287 filter_select_menu.addAction(self.filter_factory[index][0])
00288 action = filter_select_menu.exec_(QCursor.pos())
00289 if action is None:
00290 return None
00291 for index, item in self.filter_factory.items():
00292 if self.filter_factory[index][0] == action.text():
00293 filter_index = index
00294 if filter_index == -1:
00295 return None
00296
00297 index = len(self._exclude_filters)
00298 newfilter = self.filter_factory[filter_index][1]()
00299 newwidget = self.filter_factory[filter_index][2](newfilter, self.filter_factory[filter_index][3])
00300
00301
00302 self._exclude_filters.append((newfilter, FilterWrapperWidget(newwidget, self.filter_factory[filter_index][0]), filter_index))
00303 self._proxymodel.add_exclude_filter(newfilter)
00304 newfilter.filter_changed_signal.connect(self._proxymodel.handle_filters_changed)
00305 self._exclude_filters[index][1].delete_button.clicked.connect(self._delete_exclude_filter)
00306 self._datamodel.rowsInserted.connect(self._exclude_filters[index][1].repopulate)
00307
00308
00309 self.exclude_table.insertRow(index)
00310 self.exclude_table.setCellWidget(index, 0, self._exclude_filters[index][1])
00311 self.exclude_table.resizeColumnsToContents()
00312 self.exclude_table.resizeRowsToContents()
00313 newfilter.filter_changed_signal.emit()
00314 return index
00315
00316 def _process_highlight_exclude_filter(self, selection, selectiontype, exclude=False):
00317 """
00318 Modifies the relevant filters (based on selectiontype) to remove (exclude=True)
00319 or highlight (exclude=False) the selection from the dataset in the tableview.
00320 :param selection: the actual selection, ''str''
00321 :param selectiontype: the type of selection, ''str''
00322 :param exclude: If True process as an exclude filter, False process as an highlight filter, ''bool''
00323 """
00324 types = {self.tr('Node'): 2, self.tr('Topic'): 4, self.tr('Severity'): 1, self.tr('Message'): 0}
00325 try:
00326 col = types[selectiontype]
00327 except:
00328 raise RuntimeError("Bad Column name in ConsoleWidget._process_highlight_exclude_filter()")
00329
00330 if col == 0:
00331 unique_messages = set()
00332 selected_indexes = self.table_view.selectionModel().selectedIndexes()
00333 num_selected = len(selected_indexes) / 6
00334 for index in range(num_selected):
00335 unique_messages.add(selected_indexes[num_selected * col + index].data())
00336 unique_messages = list(unique_messages)
00337 for message in unique_messages:
00338 message = message.replace('\\', '\\\\')
00339 message = message.replace('.', '\\.')
00340 if exclude:
00341 filter_index = self._add_exclude_filter(selectiontype.lower())
00342 filter_widget = self._exclude_filters[filter_index][1].findChildren(QWidget, QRegExp('.*FilterWidget.*'))[0]
00343 filter_widget.set_regex(True)
00344 filter_widget.set_text('^' + message + '$')
00345 else:
00346 filter_index = self._add_highlight_filter(col)
00347 filter_widget = self._highlight_filters[filter_index][1].findChildren(QWidget, QRegExp('.*FilterWidget.*'))[0]
00348 filter_widget.set_regex(True)
00349 filter_widget.set_text('^' + message + '$')
00350
00351 else:
00352 if exclude:
00353
00354 if self.filter_factory[selectiontype.lower()][1] not in [type(item) for sublist in self._exclude_filters for item in sublist]:
00355 filter_index = self._add_exclude_filter(selectiontype.lower())
00356 else:
00357 for index, item in enumerate(self._exclude_filters):
00358 if type(item[0]) == self.filter_factory[selectiontype.lower()][1]:
00359 filter_index = index
00360 else:
00361
00362 if self.filter_factory[selectiontype.lower()][1] not in [type(item) for sublist in self._highlight_filters for item in sublist]:
00363 filter_index = self._add_highlight_filter(col)
00364 else:
00365 for index, item in enumerate(self._highlight_filters):
00366 if type(item[0]) == self.filter_factory[selectiontype.lower()][1]:
00367 filter_index = index
00368
00369 if exclude:
00370 filter_widget = self._exclude_filters[filter_index][1].findChildren(QWidget, QRegExp('.*FilterWidget.*'))[0]
00371 filter_widget.select_item(selection)
00372 else:
00373 filter_widget = self._highlight_filters[filter_index][1].findChildren(QWidget, QRegExp('.*FilterWidget.*'))[0]
00374 filter_widget.select_item(selection)
00375
00376 def _rightclick_menu(self, event):
00377 """
00378 Dynamically builds the rightclick menu based on the unique column data
00379 from the passed in datamodel and then launches it modally
00380 :param event: the mouse event object, ''QMouseEvent''
00381 """
00382 severities = self._datamodel.get_unique_col_data(1)
00383 nodes = self._datamodel.get_unique_col_data(2)
00384 topics = self._datamodel.get_unique_col_data(4)
00385 temp = []
00386 for topic in topics:
00387 if topic.find(', ') == -1:
00388 temp.append(topic)
00389 else:
00390 temp = temp + topic.split(', ')
00391 topics = list(set(temp))
00392
00393 columns = list(self._datamodel.message_members())
00394 for index in range(len(columns)):
00395 columns[index] = [columns[index][1:].capitalize()]
00396
00397
00398 menutext = []
00399 menutext.append([self.tr('Exclude'), [[self.tr('Severity'), severities], [self.tr('Node'), nodes], [self.tr('Topic'), topics], [self.tr('Selected Message(s)')]]])
00400 menutext.append([self.tr('Highlight'), [[self.tr('Severity'), severities], [self.tr('Node'), nodes], [self.tr('Topic'), topics], [self.tr('Selected Message(s)')]]])
00401 menutext.append([self.tr('Copy Selected')])
00402 menutext.append([self.tr('Browse Selected')])
00403
00404 menu = QMenu()
00405 submenus = []
00406 subsubmenus = []
00407 for item in menutext:
00408 if len(item) > 1:
00409 submenus.append(QMenu(item[0], menu))
00410 for subitem in item[1]:
00411 if len(subitem) > 1:
00412 subsubmenus.append(QMenu(subitem[0], submenus[-1]))
00413 for subsubitem in subitem[1]:
00414 subsubmenus[-1].addAction(subsubitem)
00415 submenus[-1].addMenu(subsubmenus[-1])
00416 else:
00417 submenus[-1].addAction(subitem[0])
00418 menu.addMenu(submenus[-1])
00419 else:
00420 menu.addAction(item[0])
00421 action = menu.exec_(event.globalPos())
00422
00423 if action is None or action == 0:
00424 return
00425 elif action.text() == self.tr('Browse Selected'):
00426 self._show_browsers()
00427 elif action.text() == self.tr('Copy Selected'):
00428 rowlist = []
00429 for current in self.table_view.selectionModel().selectedIndexes():
00430 rowlist.append(self._proxymodel.mapToSource(current).row())
00431 copytext = self._datamodel.get_selected_text(rowlist)
00432 if copytext is not None:
00433 clipboard = QApplication.clipboard()
00434 clipboard.setText(copytext)
00435 elif action.text() == self.tr('Selected Message(s)'):
00436 if action.parentWidget().title() == self.tr('Highlight'):
00437 self._process_highlight_exclude_filter(action.text(), 'Message', False)
00438 elif action.parentWidget().title() == self.tr('Exclude'):
00439 self._process_highlight_exclude_filter(action.text(), 'Message', True)
00440 else:
00441 raise RuntimeError("Menu format corruption in ConsoleWidget._rightclick_menu()")
00442 else:
00443
00444 try:
00445 roottitle = action.parentWidget().parentWidget().title()
00446 except:
00447 raise RuntimeError("Menu format corruption in ConsoleWidget._rightclick_menu()")
00448
00449 if roottitle == self.tr('Highlight'):
00450 self._process_highlight_exclude_filter(action.text(), action.parentWidget().title(), False)
00451 elif roottitle == self.tr('Exclude'):
00452 self._process_highlight_exclude_filter(action.text(), action.parentWidget().title(), True)
00453 else:
00454 raise RuntimeError("Unknown Root Action %s selected in ConsoleWidget._rightclick_menu()" % roottitle)
00455 self.update_status()
00456
00457 def update_status(self):
00458 """
00459 Sets the message display label to the current value
00460 """
00461 if self._datamodel.rowCount() == self._proxymodel.rowCount():
00462 tip = self.tr('Displaying %d messages') % (self._datamodel.rowCount())
00463 else:
00464 tip = self.tr('Displaying %d of %d messages') % (self._proxymodel.rowCount(), self._datamodel.rowCount())
00465 self.messages_label.setText(tip)
00466
00467 def cleanup_browsers_on_close(self):
00468 for browser in self._browsers:
00469 browser.close()
00470
00471 def _show_browsers(self):
00472 rowlist = []
00473 for current in self.table_view.selectionModel().selectedIndexes():
00474 rowlist.append(self._proxymodel.mapToSource(current).row())
00475 browsetext = self._datamodel.get_selected_text(rowlist)
00476 if browsetext is not None:
00477 self._browsers.append(TextBrowseDialog(browsetext))
00478 self._browsers[-1].show()
00479
00480 def _handle_clear_button_clicked(self, checked):
00481 self.table_view.setSelection(QRect(0, 0, self._datamodel._message_limit, self._datamodel._message_limit), QItemSelectionModel.Select)
00482 self._delete_selected_rows()
00483
00484 def _handle_load_clicked(self, checked):
00485 filename = QFileDialog.getOpenFileName(self, self.tr('Load from File'), '.', self.tr('rqt_console message file {.csv} (*.csv)'))
00486 if filename[0] != '':
00487 try:
00488 handle = open(filename[0])
00489 except IOError as e:
00490 qWarning(str(e))
00491 return
00492 self.pause_button.setChecked(True)
00493 self._handle_pause_clicked(True)
00494 self._datamodel.load_from_file(handle)
00495 handle.close()
00496 self.update_status()
00497
00498 def _handle_save_clicked(self, checked):
00499 filename = QFileDialog.getSaveFileName(self, 'Save to File', '.', self.tr('rqt_console msg file {.csv} (*.csv)'))
00500 if filename[0] != '':
00501 filename = filename[0]
00502 if filename[-4:] != '.csv':
00503 filename += '.csv'
00504 try:
00505 handle = open(filename, 'w')
00506 except IOError as e:
00507 qWarning(str(e))
00508 return
00509 self._proxymodel.save_to_file(handle)
00510 handle.close()
00511 self.update_status()
00512
00513 def _handle_pause_clicked(self, checked):
00514 self._datamodel._paused = checked
00515 if self._datamodel._paused:
00516 self.pause_button.setIcon(self._recordicon)
00517 self.pause_button.setText(self.tr('Resume'))
00518 else:
00519 self.pause_button.setIcon(self._pauseicon)
00520 self.pause_button.setText(self.tr('Pause'))
00521
00522 def _handle_column_resize_clicked(self):
00523 self.table_view.resizeColumnsToContents()
00524
00525 def _delete_selected_rows(self):
00526 rowlist = []
00527 for current in self.table_view.selectionModel().selectedIndexes():
00528 rowlist.append(self._proxymodel.mapToSource(current).row())
00529 rowlist = list(set(rowlist))
00530 return self._datamodel.remove_rows(rowlist)
00531
00532 def _handle_custom_keypress(self, event, old_keyPressEvent=QTableView.keyPressEvent):
00533 """
00534 Handles the delete key.
00535 The delete key removes the tableview's selected rows from the datamodel
00536 """
00537 if event.key() == Qt.Key_Delete and len(self._datamodel.get_message_list()) > 0:
00538 delete = QMessageBox.Yes
00539 if len(self.table_view.selectionModel().selectedIndexes()) == 0:
00540 delete = QMessageBox.question(self, self.tr('Message'), self.tr("Are you sure you want to delete all messages?"), QMessageBox.Yes | QMessageBox.No, QMessageBox.No)
00541 if delete == QMessageBox.Yes and event.key() == Qt.Key_Delete and event.modifiers() == Qt.NoModifier:
00542 if self._delete_selected_rows():
00543 self.update_status()
00544 event.accept()
00545 return old_keyPressEvent(self.table_view, event)
00546
00547 def _handle_mouse_double_click(self, event, old_doubleclickevent=QTableView.mouseDoubleClickEvent):
00548 if event.buttons() & Qt.LeftButton and event.modifiers() == Qt.NoModifier:
00549 self._show_browsers()
00550 event.accept()
00551 return old_doubleclickevent(self.table_view, event)
00552
00553 def _handle_mouse_press(self, event, old_pressEvent=QTableView.mousePressEvent):
00554 if event.buttons() & Qt.RightButton and event.modifiers() == Qt.NoModifier:
00555 self._rightclick_menu(event)
00556 event.accept()
00557 return old_pressEvent(self.table_view, event)
00558
00559 def save_settings(self, plugin_settings, instance_settings):
00560 instance_settings.set_value('settings_exist', True)
00561
00562 instance_settings.set_value('table_splitter', self.table_splitter.saveState())
00563 instance_settings.set_value('filter_splitter', self.filter_splitter.saveState())
00564
00565 instance_settings.set_value('paused', self.pause_button.isChecked())
00566 instance_settings.set_value('show_highlighted_only', self.highlight_exclude_button.isChecked())
00567
00568 exclude_filters = []
00569 for index, item in enumerate(self._exclude_filters):
00570 exclude_filters.append(item[2])
00571 filter_settings = instance_settings.get_settings('exclude_filter_' + str(index))
00572 item[1].save_settings(filter_settings)
00573 instance_settings.set_value('exclude_filters', pack(exclude_filters))
00574
00575 highlight_filters = []
00576 for index, item in enumerate(self._highlight_filters):
00577 highlight_filters.append(item[2])
00578 filter_settings = instance_settings.get_settings('highlight_filter_' + str(index))
00579 item[1].save_settings(filter_settings)
00580 instance_settings.set_value('highlight_filters', pack(highlight_filters))
00581
00582 def restore_settings(self, pluggin_settings, instance_settings):
00583 if instance_settings.contains('table_splitter'):
00584 self.table_splitter.restoreState(instance_settings.value('table_splitter'))
00585 else:
00586 self.table_splitter.setSizes([1000, 100])
00587 if instance_settings.contains('filter_splitter'):
00588 self.filter_splitter.restoreState(instance_settings.value('filter_splitter'))
00589 else:
00590 self.table_splitter.setSizes([500, 500])
00591
00592 self.pause_button.setChecked(instance_settings.value('paused') in [True, 'true'])
00593 self._handle_pause_clicked(self.pause_button.isChecked())
00594 self.highlight_exclude_button.setChecked(instance_settings.value('show_highlighted_only') in [True, 'true'])
00595 self._proxymodel.set_show_highlighted_only(self.highlight_exclude_button.isChecked())
00596
00597 for item in self._exclude_filters:
00598 item[1].delete_button.setChecked(True)
00599 self._delete_exclude_filter()
00600 if instance_settings.contains('exclude_filters'):
00601 exclude_filters = unpack(instance_settings.value('exclude_filters'))
00602 if exclude_filters is not None:
00603 for index, item in enumerate(exclude_filters):
00604 self._add_exclude_filter(item)
00605 filter_settings = instance_settings.get_settings('exclude_filter_' + str(index))
00606 self._exclude_filters[-1][1].restore_settings(filter_settings)
00607 else:
00608 self._add_exclude_filter('severity')
00609
00610 for item in self._highlight_filters:
00611 item[1].delete_button.setChecked(True)
00612 self._delete_highlight_filter()
00613 if instance_settings.contains('highlight_filters'):
00614 highlight_filters = unpack(instance_settings.value('highlight_filters'))
00615 if highlight_filters is not None:
00616 for index, item in enumerate(highlight_filters):
00617 self._add_highlight_filter(item)
00618 filter_settings = instance_settings.get_settings('highlight_filter_' + str(index))
00619 self._highlight_filters[-1][1].restore_settings(filter_settings)
00620 else:
00621 self._add_highlight_filter('message')