class LogViewer(QWidget): """ The log (+stdout, +stderr) viewer widget """ def __init__(self, parent=None): QWidget.__init__(self, parent) self.__isEmpty = True self.__copyAvailable = False self.clearButton = None self.messages = None self.copyButton = None self.selectAllButton = None self.__createLayout(parent) # create the context menu self.__menu = QMenu(self) self.__selectAllMenuItem = self.__menu.addAction( PixmapCache().getIcon('selectall.png'), 'Select All', self.messages.selectAll) self.__copyMenuItem = self.__menu.addAction( PixmapCache().getIcon('copytoclipboard.png'), 'Copy', self.messages.copy) self.__menu.addSeparator() self.__clearMenuItem = self.__menu.addAction( PixmapCache().getIcon('trash.png'), 'Clear', self.__clear) self.messages.setContextMenuPolicy(Qt.CustomContextMenu) self.messages.customContextMenuRequested.connect( self.__handleShowContextMenu) self.messages.copyAvailable.connect(self.__onCopyAvailable) self.cNormalFormat = self.messages.currentCharFormat() self.cErrorFormat = self.messages.currentCharFormat() self.cErrorFormat.setForeground(QBrush(QColor(Qt.red))) self.__updateToolbarButtons() return def __createLayout(self, parent): " Helper to create the viewer layout " # Messages list area self.messages = QPlainTextEdit(parent) self.messages.setLineWrapMode(QPlainTextEdit.NoWrap) self.messages.setFont(QFont(GlobalData().skin.baseMonoFontFace)) self.messages.setReadOnly(True) self.messages.setMaximumBlockCount(MAX_LINES) # Default font size is good enough for most of the systems. # 12.0 might be good only in case of the XServer on PC (Xming). # self.messages.setFontPointSize( 12.0 ) # Buttons self.selectAllButton = QAction(PixmapCache().getIcon('selectall.png'), 'Select all', self) self.selectAllButton.triggered.connect(self.messages.selectAll) self.copyButton = QAction(PixmapCache().getIcon('copytoclipboard.png'), 'Copy to clipboard', self) self.copyButton.triggered.connect(self.messages.copy) spacer = QWidget() spacer.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) self.clearButton = QAction(PixmapCache().getIcon('trash.png'), 'Clear all', self) self.clearButton.triggered.connect(self.__clear) # Toolbar self.toolbar = QToolBar() self.toolbar.setOrientation(Qt.Vertical) self.toolbar.setMovable(False) self.toolbar.setAllowedAreas(Qt.LeftToolBarArea) self.toolbar.setIconSize(QSize(16, 16)) self.toolbar.setFixedWidth(28) self.toolbar.setContentsMargins(0, 0, 0, 0) self.toolbar.addAction(self.selectAllButton) self.toolbar.addAction(self.copyButton) self.toolbar.addWidget(spacer) self.toolbar.addAction(self.clearButton) # layout layout = QHBoxLayout() layout.setContentsMargins(0, 0, 0, 0) layout.setSpacing(0) layout.addWidget(self.toolbar) layout.addWidget(self.messages) self.setLayout(layout) return def __handleShowContextMenu(self, coord): """ Show the context menu """ self.__selectAllMenuItem.setEnabled(not self.__isEmpty) self.__copyMenuItem.setEnabled(self.__copyAvailable) self.__clearMenuItem.setEnabled(not self.__isEmpty) self.__menu.popup(QCursor.pos()) return def __appendText(self, txt, isError): " Append the text " if len(txt) == 0: return self.__isEmpty = False cursor = self.messages.textCursor() cursor.movePosition(QTextCursor.End) self.messages.setTextCursor(cursor) if isError: self.messages.setCurrentCharFormat(self.cErrorFormat) else: self.messages.setCurrentCharFormat(self.cNormalFormat) self.messages.insertPlainText(txt) self.messages.insertPlainText('\n') self.messages.ensureCursorVisible() self.__updateToolbarButtons() return def appendMessage(self, txt): " Append the regular message " self.__appendText(txt, False) #QApplication.processEvents() return def appendError(self, txt): " Append the error message " self.__appendText(txt, True) #QApplication.processEvents() return def append(self, txt): " Decides what the message is - error or not - and append it then " if txt.startswith( 'CRITICAL' ) or \ txt.startswith( 'ERROR' ) or \ txt.startswith( 'WARNING' ): self.appendError(txt) else: self.appendMessage(txt) return def __updateToolbarButtons(self): " Contextually updates toolbar buttons " self.selectAllButton.setEnabled(not self.__isEmpty) self.copyButton.setEnabled(self.__copyAvailable) self.clearButton.setEnabled(not self.__isEmpty) return def __clear(self): " Triggers when the clear function is selected " self.__isEmpty = True self.__copyAvailable = False self.messages.clear() self.__updateToolbarButtons() return def __onCopyAvailable(self, isAvailable): " Triggers on the copyAvailable signal " self.__copyAvailable = isAvailable self.__updateToolbarButtons() return def getText(self): " Provides the content as a plain text " return self.messages.toPlainText()
def _update_client_tab(self): print '[_update_client_tab]' self.pre_selected_client_name = self.cur_selected_client_name self._widget.tabWidget.clear() for k in self._graph._client_info_list.values(): main_widget=QWidget() ver_layout=QVBoxLayout(main_widget) ver_layout.setContentsMargins (9,9,9,9) ver_layout.setSizeConstraint (ver_layout.SetDefaultConstraint) #button layout sub_widget=QWidget() sub_widget.setAccessibleName('sub_widget') btn_grid_layout=QGridLayout(sub_widget) btn_grid_layout.setContentsMargins (9,9,9,9) btn_grid_layout.setColumnStretch (1, 0) btn_grid_layout.setRowStretch (2, 0) invite_btn=QPushButton("Invite") platform_info_btn=QPushButton("Get Platform Info") status_btn=QPushButton("Get Status") start_app_btn=QPushButton("Start App") stop_app_btn=QPushButton("Stop App") invite_btn.clicked.connect(lambda: self._start_service(self._widget.tabWidget.tabText(self._widget.tabWidget.currentIndex()),"invite")) platform_info_btn.clicked.connect(lambda: self._start_service(self._widget.tabWidget.tabText(self._widget.tabWidget.currentIndex()),"platform_info")) status_btn.clicked.connect(lambda: self._start_service(self._widget.tabWidget.tabText(self._widget.tabWidget.currentIndex()),"status")) start_app_btn.clicked.connect(lambda: self._start_service(self._widget.tabWidget.tabText(self._widget.tabWidget.currentIndex()),"start_app")) stop_app_btn.clicked.connect(lambda: self._start_service(self._widget.tabWidget.tabText(self._widget.tabWidget.currentIndex()),"stop_app")) btn_grid_layout.addWidget(invite_btn) btn_grid_layout.addWidget(platform_info_btn) btn_grid_layout.addWidget(status_btn) btn_grid_layout.addWidget(start_app_btn) btn_grid_layout.addWidget(stop_app_btn) ver_layout.addWidget(sub_widget) #client information layout context_label = QLabel() context_label.setText("Client information") ver_layout.addWidget(context_label) app_context_widget=QPlainTextEdit() app_context_widget.setObjectName(k["name"]+'_'+'app_context_widget') app_context_widget.setAccessibleName('app_context_widget') app_context_widget.appendHtml(k["app_context"]) app_context_widget.setReadOnly(True) cursor = app_context_widget.textCursor() cursor.movePosition(QTextCursor.Start,QTextCursor.MoveAnchor,0) app_context_widget.setTextCursor(cursor) ver_layout.addWidget(app_context_widget) #service layout context_label = QLabel() context_label.setText("Service result") ver_layout.addWidget(context_label) services_text_widget=QPlainTextEdit() services_text_widget.setObjectName(k["name"]+'_'+'services_text_widget') services_text_widget.setReadOnly(True) cursor = services_text_widget.textCursor() cursor.movePosition(QTextCursor.Start,QTextCursor.MoveAnchor,0) services_text_widget.setTextCursor(cursor) ver_layout.addWidget(services_text_widget) # new icon path="" if k["is_new"]==True: path=os.path.join(os.path.dirname(os.path.abspath(__file__)),"../../resources/images/new.gif") #add tab self._widget.tabWidget.addTab(main_widget,QIcon(path), k["name"]); #set previous selected tab for k in range(self._widget.tabWidget.count()): tab_text=self._widget.tabWidget.tabText(k) if tab_text == self.pre_selected_client_name: self._widget.tabWidget.setCurrentIndex(k)
class LogViewer( QWidget ): """ The log (+stdout, +stderr) viewer widget """ def __init__( self, parent = None ): QWidget.__init__( self, parent ) self.__isEmpty = True self.__copyAvailable = False self.clearButton = None self.messages = None self.copyButton = None self.selectAllButton = None self.__createLayout( parent ) # create the context menu self.__menu = QMenu( self ) self.__selectAllMenuItem = self.__menu.addAction( PixmapCache().getIcon( 'selectall.png' ), 'Select All', self.messages.selectAll ) self.__copyMenuItem = self.__menu.addAction( PixmapCache().getIcon( 'copytoclipboard.png' ), 'Copy', self.messages.copy ) self.__menu.addSeparator() self.__clearMenuItem = self.__menu.addAction( PixmapCache().getIcon( 'trash.png' ), 'Clear', self.__clear ) self.messages.setContextMenuPolicy( Qt.CustomContextMenu ) self.messages.customContextMenuRequested.connect( self.__handleShowContextMenu ) self.messages.copyAvailable.connect( self.__onCopyAvailable ) self.cNormalFormat = self.messages.currentCharFormat() self.cErrorFormat = self.messages.currentCharFormat() self.cErrorFormat.setForeground( QBrush( QColor( Qt.red ) ) ) self.__updateToolbarButtons() return def __createLayout( self, parent ): " Helper to create the viewer layout " # Messages list area self.messages = QPlainTextEdit( parent ) self.messages.setLineWrapMode( QPlainTextEdit.NoWrap ) self.messages.setFont( QFont( GlobalData().skin.baseMonoFontFace ) ) self.messages.setReadOnly( True ) self.messages.setMaximumBlockCount( MAX_LINES ) # Default font size is good enough for most of the systems. # 12.0 might be good only in case of the XServer on PC (Xming). # self.messages.setFontPointSize( 12.0 ) # Buttons self.selectAllButton = QAction( PixmapCache().getIcon( 'selectall.png' ), 'Select all', self ) self.selectAllButton.triggered.connect( self.messages.selectAll ) self.copyButton = QAction( PixmapCache().getIcon( 'copytoclipboard.png' ), 'Copy to clipboard', self ) self.copyButton.triggered.connect( self.messages.copy ) spacer = QWidget() spacer.setSizePolicy( QSizePolicy.Expanding, QSizePolicy.Expanding ) self.clearButton = QAction( PixmapCache().getIcon( 'trash.png' ), 'Clear all', self ) self.clearButton.triggered.connect( self.__clear ) # Toolbar self.toolbar = QToolBar() self.toolbar.setOrientation( Qt.Vertical ) self.toolbar.setMovable( False ) self.toolbar.setAllowedAreas( Qt.LeftToolBarArea ) self.toolbar.setIconSize( QSize( 16, 16 ) ) self.toolbar.setFixedWidth( 28 ) self.toolbar.setContentsMargins( 0, 0, 0, 0 ) self.toolbar.addAction( self.selectAllButton ) self.toolbar.addAction( self.copyButton ) self.toolbar.addWidget( spacer ) self.toolbar.addAction( self.clearButton ) # layout layout = QHBoxLayout() layout.setContentsMargins( 0, 0, 0, 0 ) layout.setSpacing( 0 ) layout.addWidget( self.toolbar ) layout.addWidget( self.messages ) self.setLayout( layout ) return def __handleShowContextMenu( self, coord ): """ Show the context menu """ self.__selectAllMenuItem.setEnabled( not self.__isEmpty ) self.__copyMenuItem.setEnabled( self.__copyAvailable ) self.__clearMenuItem.setEnabled( not self.__isEmpty ) self.__menu.popup( QCursor.pos() ) return def __appendText( self, txt, isError ): " Append the text " if len( txt ) == 0: return self.__isEmpty = False cursor = self.messages.textCursor() cursor.movePosition( QTextCursor.End ) self.messages.setTextCursor( cursor ) if isError: self.messages.setCurrentCharFormat( self.cErrorFormat ) else: self.messages.setCurrentCharFormat( self.cNormalFormat ) self.messages.insertPlainText( txt ) self.messages.insertPlainText( '\n' ) self.messages.ensureCursorVisible() self.__updateToolbarButtons() return def appendMessage( self, txt ): " Append the regular message " self.__appendText( txt, False ) #QApplication.processEvents() return def appendError( self, txt ): " Append the error message " self.__appendText( txt, True ) #QApplication.processEvents() return def append( self, txt ): " Decides what the message is - error or not - and append it then " if txt.startswith( 'CRITICAL' ) or \ txt.startswith( 'ERROR' ) or \ txt.startswith( 'WARNING' ): self.appendError( txt ) else: self.appendMessage( txt ) return def __updateToolbarButtons( self ): " Contextually updates toolbar buttons " self.selectAllButton.setEnabled( not self.__isEmpty ) self.copyButton.setEnabled( self.__copyAvailable ) self.clearButton.setEnabled( not self.__isEmpty ) return def __clear( self ): " Triggers when the clear function is selected " self.__isEmpty = True self.__copyAvailable = False self.messages.clear() self.__updateToolbarButtons() return def __onCopyAvailable( self, isAvailable ): " Triggers on the copyAvailable signal " self.__copyAvailable = isAvailable self.__updateToolbarButtons() return def getText( self ): " Provides the content as a plain text " return self.messages.toPlainText()