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')