Beispiel #1
0
 def clear(self):
     """ Deletes all items in the TreeView
     """
     #logging.debug(__name__ + ": clear")
     self._itemDict = {}
     self._firstItem = None
     QTreeWidget.clear(self)
Beispiel #2
0
    def mousePressEvent(self, event):
        index = self.indexAt(event.pos())
        if index.isValid():
	  item = self.itemAt(event.pos())
	  if event.button() == Qt.RightButton:
	    self.copyMenu.popup(QCursor.pos())
	QTreeWidget.mousePressEvent(self, event)
    def __init__(self, state_index=list()):
        QTreeWidget.__init__(self)

        self.header().setHidden(True)
        self.setSelectionMode(QTreeWidget.SingleSelection)
        self.setAnimated(True)

        self._actualProject = None
        #self._projects -> key: [Item, folderStructure]
        self._projects = {}
        self._loading_items = {}
        self._thread_execution = {}
        self.__enableCloseNotification = True
        self._fileWatcher = NinjaFileSystemWatcher
        self._refresh_projects_queue = []
        self._timer_running = False

        self.header().setHorizontalScrollMode(QAbstractItemView.ScrollPerPixel)
        self.header().setResizeMode(0, QHeaderView.ResizeToContents)
        self.header().setStretchLastSection(False)

        self.setContextMenuPolicy(Qt.CustomContextMenu)
        self.connect(self, SIGNAL(
            "customContextMenuRequested(const QPoint &)"),
            self._menu_context_tree)
        self.connect(self, SIGNAL("itemClicked(QTreeWidgetItem *, int)"),
            self._open_file)
        self.connect(self._fileWatcher, SIGNAL("fileChanged(int, QString)"),
            self._refresh_project_by_path)
        self.itemExpanded.connect(self._item_expanded)
        self.itemCollapsed.connect(self._item_collapsed)
        self.mute_signals = False
        self.state_index = list()
        self._folding_menu = FoldingContextMenu(self)
Beispiel #4
0
 def songKeyPressEvent(self, event):
     if event.matches(QKeySequence.Delete):
         self.__removeSong()
     elif event.key() == Qt.Key_Escape:
         self.songList.setCurrentRow(-1)
     else:
         QTreeWidget.keyPressEvent(self.songList, event)
    def __init__( self, debugger, parent = None ):
        QTreeWidget.__init__( self, parent )

        self.setRootIsDecorated( True )
        self.setAlternatingRowColors( True )
        self.setUniformRowHeights( True )
        self.setItemDelegate( NoOutlineHeightDelegate( 4 ) )

        self.setSelectionBehavior( QAbstractItemView.SelectRows )

        self.setHeaderLabels( [ "Name", "Value", "Type" ] )
        header = self.header()
        header.setSortIndicator( 0, Qt.AscendingOrder )
        header.setSortIndicatorShown( True )
        header.setClickable( True )
        header.setStretchLastSection( True )

        self.itemExpanded.connect( self.__expandItemSignal )
        self.itemCollapsed.connect( self.collapseItem )

        self.resortEnabled = True
        self.openItems = []
        self.framenr = 0
        self.__debugger = debugger

        # Ugly filtering support
        self.__hideMCFFilter = False
        self.__scopeFilter = 0  # Global and local
        self.__filterIsSet = False
        self.__textFilters = []
        self.__textFiltersCount = 0

        self.setSortingEnabled( True )
        return
 def mousePressEvent(self, mouseEvent):
     QTreeWidget.mousePressEvent(self, mouseEvent)
     #        http://doc.qt.nokia.com/4.7-snapshot/dnd.html
     if mouseEvent.button() != Qt.LeftButton:
         return
     if self._selectedExperiment():
         self.dragStartPosition = mouseEvent.pos()
    def keyPressEvent(self, event):
        """ 
        Обрабатываем нажатия на кнопки вверх и вниз так, чтобы перескакивать на следующую запись
        мимо категорий. Запрещаем использование кнопок вправо и влево
        
        """
        ourEvent = (event.key() == Qt.Key_Down or
                    event.key() == Qt.Key_Up or
                    event.key() == Qt.Key_Left or
                    event.key() == Qt.Key_Right)
        if not ourEvent:
            QTreeWidget.keyPressEvent(self, event)
            return

        curItem = self.currentItem()
        if event.key() == Qt.Key_Down:
            nextItem = self._getNextNonCategoryItem(curItem)
            if nextItem:
                self.setCurrentItem(nextItem)
        elif event.key() == Qt.Key_Up:
            nextItem = self._getPreviousNonCategoryItem(curItem)
            if nextItem:
                self.setCurrentItem(nextItem)
            elif self.topLevelItemCount() > 0:
                # Дошли до верха списка и нужно прокрутить до самого верха
                self.scrollToItem(self.topLevelItem(0))
Beispiel #8
0
 def __init__(self, parent):
     QTreeWidget.__init__(self, parent)
     self.name = "Modules"
     self.tm = TaskManager()
     self.loader = loader.loader()
     self.setupUi(self)
     self.initTreeModule()
    def __init__(self):
        QTreeWidget.__init__(self)

        self.header().setHidden(True)
        self.setSelectionMode(QTreeWidget.SingleSelection)
        self.setAnimated(True)

        self._actualProject = None
        #self._projects -> key: [Item, folderStructure]
        self._projects = {}
        self.__enableCloseNotification = True
        self._fileWatcher = QFileSystemWatcher()

        self.header().setHorizontalScrollMode(QAbstractItemView.ScrollPerPixel)
        self.header().setResizeMode(0, QHeaderView.ResizeToContents)
        self.header().setStretchLastSection(False)

        self.setContextMenuPolicy(Qt.CustomContextMenu)
        self.connect(self, SIGNAL(
            "customContextMenuRequested(const QPoint &)"),
            self._menu_context_tree)
        self.connect(self, SIGNAL("itemClicked(QTreeWidgetItem *, int)"),
            self._open_file)
        self.connect(self._fileWatcher, SIGNAL("directoryChanged(QString)"),
            self._refresh_project_by_path)
    def __init__( self, parent ):
        QTreeWidget.__init__( self, parent )

        self.pyQGisApp = parent
        self.canvas = None
        self.layers = self.getLayerSet()

        self.bMousePressedFlag = False
        self.itemBeingMoved = None

        # QTreeWidget properties
        self.setSortingEnabled( False )
        self.setDragEnabled( False )
        self.setAutoScroll( False )
        #self.setVerticalScrollMode( QAbstractItemView.ScrollPerPixel )
        self.setHeaderHidden( True )
        self.setRootIsDecorated( True )
        self.setContextMenuPolicy( Qt.CustomContextMenu )

        self.connect( self, SIGNAL( "customContextMenuRequested(QPoint)" ),
            self.showMenu )
        self.connect( QgsMapLayerRegistry.instance(), SIGNAL("layerWasAdded(QgsMapLayer *)"),
            self.addLayerToLegend )
        self.connect( QgsMapLayerRegistry.instance(), SIGNAL( "removedAll()" ),
            self.removeAll )
        self.connect( self, SIGNAL( "itemChanged(QTreeWidgetItem *,int)" ),
            self.updateLayerStatus )
        self.connect( self, SIGNAL( "currentItemChanged(QTreeWidgetItem *, QTreeWidgetItem *)" ),
            self.currentItemChanged )
Beispiel #11
0
    def __init__(self):
        QTreeWidget.__init__(self)
        self.header().setHidden(True)
        self.setSelectionMode(self.SingleSelection)
        self.setAnimated(True)
        self.header().setHorizontalScrollMode(QAbstractItemView.ScrollPerPixel)
        self.header().setResizeMode(0, QHeaderView.ResizeToContents)
        self.header().setStretchLastSection(False)
        self.actualSymbols = ('', {})
        self.docstrings = {}
        self.collapsedItems = {}

        self.connect(self, SIGNAL("itemClicked(QTreeWidgetItem *, int)"),
            self._go_to_definition)
        self.connect(self, SIGNAL("itemActivated(QTreeWidgetItem *, int)"),
            self._go_to_definition)
        self.setContextMenuPolicy(Qt.CustomContextMenu)
        self.connect(self,
            SIGNAL("customContextMenuRequested(const QPoint &)"),
            self._menu_context_tree)
        self.connect(self, SIGNAL("itemCollapsed(QTreeWidgetItem *)"),
            self._item_collapsed)
        self.connect(self, SIGNAL("itemExpanded(QTreeWidgetItem *)"),
            self._item_expanded)

        IDE.register_service('symbols_explorer', self)
        ExplorerContainer.register_tab(translations.TR_TAB_SYMBOLS, self)
Beispiel #12
0
 def keyHandler(self, event):
     if not self.edit_mode \
     and event.key() == Qt.Key_Delete:
         self.deleteEvent()
         event.accept()
         return
     QTreeWidget.keyPressEvent(self.container, event)
Beispiel #13
0
    def __init__( self, parent = None ):
        QTreeWidget.__init__( self, parent )

        self.setRootIsDecorated( False )
        self.setItemsExpandable( False )
        self.setSortingEnabled( True )

        self.__headerItem = QTreeWidgetItem( [ "", "File name", "Line",
                                               "Description" ] )

        self.__headerItem.setIcon( 0,
                                   PixmapCache().getIcon("todocompleted.png") )
        self.setHeaderItem( self.__headerItem )

        self.header().setSortIndicator( 1, Qt.AscendingOrder )
        self.__resizeColumns()

        self.todoItems = []

        self.setContextMenuPolicy( Qt.CustomContextMenu )
        self.connect( self,
                      SIGNAL( "customContextMenuRequested(const QPoint &)" ),
                      self.__showContextMenu )
        self.connect( self,
                      SIGNAL( "itemActivated(QTreeWidgetItem *, int)" ),
                      self.__todoItemActivated )
        return
Beispiel #14
0
	def __init__(self, parent=None, TreeFileName=DefaultTreeFileName):
		QTreeWidget.__init__(self, parent)
		self.parent = parent
		self.setGeometry(0,0, self.parent.width(), self.parent.height())
		self.setColumnCount(2)
		self.setColumnWidth(0,270)
		#self.header().setStretchLastSection(False)
		#self.resizeColumnToContents(1)
		headerTitles = QStringList()
		headerTitles.append(QString("Parameter"))
		headerTitles.append(QString("Value"))
		self.setHeaderLabels(headerTitles)
		self.setEditTriggers(QTreeWidget.DoubleClicked|QTreeWidget.EditKeyPressed)
		self.rootItems = []
		self.currentItemChanged.connect(self.visit)
		self.itemDoubleClicked.connect(self.edit_)
		self.editing = None
		self.expandAll()
		self.ScenarioName = ''
		self.NodeDescriptions = dict()  # textual parameter descriptions
		self.ParamScenario = dict()  # name of corresponding scenario for parameters
		self.changed = False
		self.ApplicationPath = ''
		self.TreeFileName = TreeFileName
		self.RunCfgFileName = DefaultCfgFileName
		self.load()
		self.parent.setWindowTitle(self.NodeValue('Title').replace('_',' ') + ' ' + DefaultTtitle)
 def __init__(self, controller, parent = None):
     '''
     Constructor - calls parent class constructor
     '''
     QTreeWidget.__init__(self, parent)
     if parent!=None:
         self.parentController = parent
Beispiel #16
0
 def __init__(self,parent = None):
     QTreeWidget.__init__(self,parent)
     self.setColumnCount(1)
     self.setHeaderLabel("Explorer")
     self.projects = []
     self.header().setStretchLastSection(False)
     self.header().setResizeMode(QHeaderView.ResizeToContents)
Beispiel #17
0
 def __init__(self,parent = None):
     QTreeWidget.__init__(self,parent)
     self.setColumnCount(1)
     self.header().close()
     self.header().setStretchLastSection(False)
     self.header().setResizeMode(QHeaderView.ResizeToContents)
     self.mainClass = None
 def scrollTo( self, index, hint = QAbstractItemView.EnsureVisible ):
     """ Disables horizontal scrolling when a row is clicked.
         Found here: http://qt-project.org/faq/answer/how_can_i_disable_autoscroll_when_selecting_a_partially_displayed_column_in
     """
     oldValue = self.horizontalScrollBar().value()
     QTreeWidget.scrollTo( self, index, hint )
     self.horizontalScrollBar().setValue( oldValue )
     return
 def __init__(self, hide_parent_element = False):
     """Constructor."""
     QTreeWidget.__init__(self)
     self._content_provider = None
     self._label_providers = {}
     # index table to lookup treeview items associated with model objects.
     self.__indextable = []
     self._hide_parent = hide_parent_element
    def clear( self ):
        " Resets everything "
        self.resortEnabled = True
        self.openItems = []
        self.framenr = 0

        QTreeWidget.clear( self )
        return
Beispiel #21
0
 def __init__(self):
     QTreeWidget.__init__(self)
     self.setHeaderLabels((self.tr('Description'), self.tr('Shortcut')))
     #columns width
     self.setColumnWidth(0, 175)
     self.header().setStretchLastSection(True)
     self.setSortingEnabled(True)
     self.sortByColumn(0, Qt.AscendingOrder)
Beispiel #22
0
 def keyPressEvent( self, event ):
     " Handles the key press events "
     if event.key() == Qt.Key_Escape:
         self.escapePressed.emit()
         event.accept()
     else:
         QTreeWidget.keyPressEvent( self, event )
     return
Beispiel #23
0
 def __init__(self):
     QTreeWidget.__init__(self)
     self.setHeaderLabels((self.tr('File'), self.tr('Line')))
     self.header().setHorizontalScrollMode(QAbstractItemView.ScrollPerPixel)
     self.header().setResizeMode(0, QHeaderView.ResizeToContents)
     self.header().setResizeMode(1, QHeaderView.ResizeToContents)
     self.header().setStretchLastSection(False)
     self.sortByColumn(0, Qt.AscendingOrder)
Beispiel #24
0
 def __init__(self, parent):
     QTreeWidget.__init__(self, parent)
     self.setItemsExpandable(True)
     self.setColumnCount(1)
     self.connect(self, SIGNAL('itemActivated(QTreeWidgetItem*,int)'),
                  self.activated)
     # Setup context menu
     self.menu = QMenu(self)
     self.common_actions = self.setup_common_actions()
    def leaveEvent(self, event):
        " Triggered when the cursor leaves the find results tree "
        global inside
        inside = False

        QApplication.processEvents()
        hideSearchTooltip()
        QTreeWidget.leaveEvent(self, event)
        return
Beispiel #26
0
 def __init__(self):
     QTreeWidget.__init__(self)
     self.setHeaderLabels((translations.TR_PROJECT_DESCRIPTION,
         translations.TR_SHORTCUT))
     #columns width
     self.setColumnWidth(0, 175)
     self.header().setStretchLastSection(True)
     self.setSortingEnabled(True)
     self.sortByColumn(0, Qt.AscendingOrder)
Beispiel #27
0
    def changeEvent(self, event):
        """ Search for a language change event

        This event have to call retranslateUi to change interface language on
        the fly.
        """
        if event.type() == QEvent.LanguageChange:
            self.retranslateUi(self)
        else:
            QTreeWidget.changeEvent(self, event)
Beispiel #28
0
	def keyPressEvent(self, e):
##		if e.key() in [Qt.Key_Escape]:
##			self.parent.close()		
		if e.key() in [Qt.Key_F2, Qt.Key_Space]:
			if self.editing is not None:
				#print "Error: already editing an item"
				pass
			else:
				self.edit_(self.currentItem(),0)
		QTreeWidget.keyPressEvent(self,e)
 def __init__(self, parent=None): 
     QTreeWidget.__init__(self, parent) 
     self.setWindowTitle('TreeWidget Context Menu') 
     self.header().setHidden(True) 
     self.setGeometry(320, 320, 320, 320) 
     for index in '12345': 
         parent = QTreeWidgetItem(self, ['Parent %s' % index]) 
         for item in 'ABCDE': 
             QTreeWidgetItem(parent, ['Child %s%s' % (index, item)]) 
         parent.setExpanded(True) 
 def __init__(self, parent=None):
     QTreeWidget.__init__(self, parent)
     
     self.singleOverlaySelection = True
     
     self.header().close()
     self.setSortingEnabled(True)
     self.installEventFilter(self)
     self.spacePressed.connect(self.spacePressedTreewidget)
     self.itemChanged.connect(self.treeItemChanged)
Beispiel #31
0
class NetworkArgs(QtHelper.EnhancedQDialog, Logger.ClassLogger):
    """
    Network arguments dialog
    """
    def __init__(self, dataArgs, parent=None):
        """
        Dialog to fill arguments for the network probe

        @param dataArgs: 
        @type dataArgs: 

        @param parent: 
        @type parent:
        """
        super(NetworkArgs, self).__init__(parent)
        self.dataArgs = dataArgs
        self.createDialog()
        self.createConnections()
        self.loadDefaultData()

    def createDialog(self):
        """
        Create qt dialog
        """
        mainLayout = QHBoxLayout()

        paramLayout = QHBoxLayout()
        paramLayout.addWidget(QLabel("Interface:"))
        self.intComboBox = QComboBox()
        self.intComboBox.setEditable(1)
        self.intComboBox.addItems(
            ['any', 'eth0', 'eth1', 'eth2', 'eth3', 'eth4', 'lo0'])
        paramLayout.addWidget(self.intComboBox)
        paramLayout.addWidget(QLabel("Filter:"))
        self.filterEdit = QLineEdit()
        paramLayout.addWidget(self.filterEdit)

        dataLayout = QVBoxLayout()
        self.labelHelp = QLabel(
            "Network interface to dump:\nIf the interface name does not exist in the list\nplease to edit the combox list to change it."
        )

        self.listBox = QTreeWidget(self)
        self.listBox.setIndentation(0)

        self.labels = [self.tr("Interface"), self.tr("Filter")]
        self.listBox.setHeaderLabels(self.labels)

        dataLayout.addWidget(self.labelHelp)
        dataLayout.addLayout(paramLayout)
        dataLayout.addWidget(self.listBox)

        buttonLayout = QVBoxLayout()
        self.addButton = QPushButton("Add", self)
        self.delButton = QPushButton("Remove", self)
        self.delButton.setEnabled(False)
        self.editButton = QPushButton("Edit", self)
        self.editButton.setEnabled(False)
        self.clearButton = QPushButton("Clear", self)
        self.okButton = QPushButton("Ok", self)
        self.cancelButton = QPushButton("Cancel", self)
        buttonLayout.addWidget(self.addButton)
        buttonLayout.addWidget(self.delButton)
        buttonLayout.addWidget(self.editButton)
        buttonLayout.addWidget(self.clearButton)
        buttonLayout.addWidget(self.okButton)
        buttonLayout.addWidget(self.cancelButton)

        mainLayout.addLayout(dataLayout)
        mainLayout.addLayout(buttonLayout)

        self.setLayout(mainLayout)

        self.setWindowTitle("Network Probe > Arguments")

    def createConnections(self):
        """
        Create qt connections
        """
        self.okButton.clicked.connect(self.accept)
        self.cancelButton.clicked.connect(self.reject)
        self.addButton.clicked.connect(self.addItem)
        self.delButton.clicked.connect(self.delItem)
        self.editButton.clicked.connect(self.editItem)
        self.clearButton.clicked.connect(self.clearList)
        self.listBox.itemClicked.connect(self.onItemSelected)

    def clearList(self):
        """
        Clear the list
        """
        self.listBox.clear()

    def onItemSelected(self, itm, row):
        """
        Called when an item is selected
        """
        self.delButton.setEnabled(True)
        self.editButton.setEnabled(True)

    def editItem(self):
        """
        Edit item
        """
        self.delButton.setEnabled(False)
        self.editButton.setEnabled(False)
        # retrieve value to put it in the line edit and then remove item
        model = self.listBox.model()
        for selectedItem in self.listBox.selectedItems():
            qIndex = self.listBox.indexFromItem(selectedItem)
            eth = selectedItem.dataNet['interface']
            flt = selectedItem.dataNet['filter']
            self.filterEdit.setText(flt)
            self.intComboBox.setEditText(eth)
            model.removeRow(qIndex.row())

    def delItem(self):
        """
        Delete item
        """
        self.delButton.setEnabled(False)
        self.editButton.setEnabled(False)
        # remove item
        model = self.listBox.model()
        for selectedItem in self.listBox.selectedItems():
            qIndex = self.listBox.indexFromItem(selectedItem)
            model.removeRow(qIndex.row())

    def addItem(self):
        """
        Add item
        """
        eth = self.intComboBox.currentText()
        if eth != '':
            flt = self.filterEdit.text()
            tpl = {'interface': str(eth), 'filter': str(flt)}
            newParam = NetItem(data=tpl, parent=self.listBox)
            self.listBox.resizeColumnToContents(0)

    def loadDefaultData(self):
        """
        Load the default data
        """
        try:
            if len(self.dataArgs) == 0:
                return
            datObj = eval(str(self.dataArgs))
            if 'interfaces' in datObj:
                for eth in datObj['interfaces']:
                    newParam = NetItem(data=eth, parent=self.listBox)
        except Exception as e:
            self.error("unable to load the default data: %s" % e)

    def getArgs(self):
        """
        Returns arguments
        Example list of files: {'interfaces': [ {'interface':'any', 'filter':''} ] }
        """
        listEth = []
        # iterate all items in a QListWidget
        root = self.listBox.invisibleRootItem()
        child_count = root.childCount()
        for i in xrange(child_count):
            itm = root.child(i)
            listEth.append(eval(str(itm.dataNet)))
        ret = {'interfaces': listEth}
        if len(listEth) == 0:
            ret = ''
        return str(ret)
Beispiel #32
0
class XConsoleEdit(XLoggerWidget):
    __designer_icon__ = projexui.resources.find('img/ui/console.png')

    def __init__(self, parent):
        super(XConsoleEdit, self).__init__(parent)

        self.setLogger(logging.getLogger())

        # create custom properties
        self._completerTree = None
        self._commandStack = []
        self._highlighter = XConsoleHighlighter(self.document())

        # set properties
        font = QFont('Courier New')
        font.setPointSize(9)
        self.setFont(font)
        self.setReadOnly(False)
        self.waitForInput()
        metrics = QFontMetrics(font)
        self.setTabStopWidth(4 * metrics.width(' '))

        # create connections
        XStream.stdout().messageWritten.connect(self.information)
        XStream.stderr().messageWritten.connect(self.error)

    def __del__(self):
        XStream.stdout().messageWritten.disconnect(self.information)
        XStream.stderr().messageWritten.disconnect(self.error)

    def acceptCompletion(self):
        """
        Accepts the current completion and inserts the code into the edit.
        
        :return     <bool> accepted
        """
        tree = self._completerTree
        if not tree:
            return False

        tree.hide()

        item = tree.currentItem()
        if not item:
            return False

        # clear the previously typed code for the block
        cursor = self.textCursor()
        text = cursor.block().text()
        col = cursor.columnNumber()
        end = col

        while col:
            col -= 1
            if text[col] == '.':
                col += 1
                break

        # insert the current text
        cursor.setPosition(cursor.position() - (end - col), cursor.KeepAnchor)
        cursor.removeSelectedText()
        self.insertPlainText(item.text(0))
        return True

    def applyCommand(self):
        """
        Applies the current line of code as an interactive python command.
        """
        # grab the command from the current line
        block = self.textCursor().block().text()
        match = INPUT_EXPR.match(projex.text.toUtf8(block))

        # if there is no command, then wait for the input
        if not match:
            self.waitForInput()
            return

        self.executeCommand(match.group(2).rstrip(), match.group(1).strip())

    def cancelCompletion(self):
        """
        Cancels the current completion.
        """
        if (self._completerTree):
            self._completerTree.hide()

    def clear(self):
        """
        Clears the current text and starts a new input line.
        """
        super(XConsoleEdit, self).clear()
        self.waitForInput()

    def closeEvent(self, event):
        """
        Disconnects from the stderr/stdout on close.
        
        :param      event | <QCloseEvent>
        """
        if (self.clearOnClose()):
            XStream.stdout().messageWritten.disconnect(self.information)
            XStream.stderr().messageWritten.disconnect(self.error)

        super(XConsoleEdit, self).closeEvent(event)

    def completerTree(self):
        """
        Returns the completion tree for this instance.
        
        :return     <QTreeWidget>
        """
        if (not self._completerTree):
            self._completerTree = QTreeWidget(self)
            self._completerTree.setWindowFlags(Qt.Popup)
            self._completerTree.setAlternatingRowColors(True)
            self._completerTree.installEventFilter(self)
            self._completerTree.itemClicked.connect(self.acceptCompletion)
            self._completerTree.setRootIsDecorated(False)
            self._completerTree.header().hide()

        return self._completerTree

    def eventFilter(self, obj, event):
        """
        Filters particular events for a given QObject through this class. \
        Will use this to intercept events to the completer tree widget while \
        filtering.
        
        :param      obj     | <QObject>
                    event   | <QEvent>
        
        :return     <bool> consumed
        """
        if (not obj == self._completerTree):
            return False

        if (event.type() != event.KeyPress):
            return False

        if (event.key() == Qt.Key_Escape):
            QToolTip.hideText()
            self.cancelCompletion()
            return False

        elif (event.key() in (Qt.Key_Enter, Qt.Key_Return, Qt.Key_Tab)):
            self.acceptCompletion()
            return False

        elif (event.key() in (Qt.Key_Up, Qt.Key_Down)):

            return False

        else:
            self.keyPressEvent(event)

            # update the completer
            cursor = self.textCursor()
            text = projex.text.toUtf8(cursor.block().text())
            text = text[:cursor.columnNumber()].split(' ')[-1]
            text = text.split('.')[-1]

            self._completerTree.blockSignals(True)
            self._completerTree.setUpdatesEnabled(False)

            self._completerTree.setCurrentItem(None)

            for i in range(self._completerTree.topLevelItemCount()):
                item = self._completerTree.topLevelItem(i)
                if projex.text.toUtf8(item.text(0)).startswith(text):
                    self._completerTree.setCurrentItem(item)
                    break

            self._completerTree.blockSignals(False)
            self._completerTree.setUpdatesEnabled(True)

            return True

    def executeCommand(self, command, mode='>>>'):
        """
        Executes the inputed command in the global scope.
        
        :param      command | <unicode>
        
        :return     <variant>
        """
        # check to see if we're starting a new line
        if mode == '...' and not command.strip():
            command = '\n'.join(self._commandStack)

        elif command.endswith(':') or mode == '...':
            self._commandStack.append(command)
            self.insertPlainText('\n... ')
            return

        # if we're not at the end of the console, then add it to the end
        elif not self.textCursor().atEnd():
            self.waitForInput()
            self.insertPlainText(command)
            return

        self._commandStack = []

        # insert a new line
        self.insertPlainText('\n')
        cmdresult = None

        try:
            cmdresult = eval(command, __main__.__dict__, __main__.__dict__)
        except SyntaxError:
            exec(command) in __main__.__dict__, __main__.__dict__

        # print the resulting commands
        if cmdresult != None:
            self.information(projex.text.toUtf8(cmdresult))

        self.waitForInput()

    def highlighter(self):
        """
        Returns the console highlighter for this widget.
        
        :return     <XConsoleHighlighter>
        """
        return self._highlighter

    def gotoHome(self):
        """
        Navigates to the home position for the edit.
        """
        mode = QTextCursor.MoveAnchor

        # select the home
        if QApplication.instance().keyboardModifiers() == Qt.ShiftModifier:
            mode = QTextCursor.KeepAnchor

        cursor = self.textCursor()
        block = projex.text.toUtf8(cursor.block().text())

        cursor.movePosition(QTextCursor.StartOfBlock, mode)
        if (block.startswith('>>> ')):
            cursor.movePosition(QTextCursor.Right, mode, 4)

        self.setTextCursor(cursor)

    def keyPressEvent(self, event):
        """
        Overloads the key press event to control keystroke modifications for \
        the console widget.
        
        :param      event | <QKeyEvent>
        """
        # enter || return keys will apply the command
        if event.key() in (Qt.Key_Return, Qt.Key_Enter):
            self.applyCommand()

        # home key will move the cursor to the home position
        elif event.key() == Qt.Key_Home:
            self.gotoHome()

        elif event.key() in (Qt.Key_Backspace, Qt.Key_Delete):
            super(XConsoleEdit, self).keyPressEvent(event)

            # update the completer
            cursor = self.textCursor()
            text = projex.text.toUtf8(cursor.block().text())
            text = text[:cursor.columnNumber()].split(' ')[-1]

            if not '.' in text:
                self.cancelCompletion()

        # period key will trigger a completion popup
        elif event.key() == Qt.Key_Period:
            self.startCompletion()
            super(XConsoleEdit, self).keyPressEvent(event)

        # space, tab, backspace and delete will cancel the completion
        elif event.key() == Qt.Key_Space:
            self.cancelCompletion()
            super(XConsoleEdit, self).keyPressEvent(event)

        # left parenthesis will start method help
        elif event.key() == Qt.Key_ParenLeft:
            self.cancelCompletion()
            self.showMethodToolTip()
            super(XConsoleEdit, self).keyPressEvent(event)

        # otherwise, handle the event like normal
        else:
            super(XConsoleEdit, self).keyPressEvent(event)

    def objectAtCursor(self):
        """
        Returns the python object that the text is representing.
        
        :return     <object> || None
        """

        # determine the text block
        cursor = self.textCursor()
        text = projex.text.toUtf8(cursor.block().text())
        col = cursor.columnNumber()
        end = col

        while (col):
            col -= 1
            if (re.match('[^a-zA-Z\._\(\)]', text[col])):
                break

        symbol = text[col:end].rstrip('.(')
        try:
            return eval(symbol, __main__.__dict__, __main__.__dict__)
        except:
            return None

    def showMethodToolTip(self):
        """
        Pops up a tooltip message with the help for the object under the \
        cursor.
        
        :return     <bool> success
        """
        self.cancelCompletion()

        obj = self.objectAtCursor()
        if (not obj):
            return False

        docs = inspect.getdoc(obj)
        if (not docs):
            return False

        # determine the cursor position
        rect = self.cursorRect()
        cursor = self.textCursor()
        point = QPoint(rect.left(), rect.top() + 18)

        QToolTip.showText(self.mapToGlobal(point), docs, self)

        return True

    def startCompletion(self):
        """
        Starts a new completion popup for the current object.
        
        :return     <bool> success
        """
        # add the top level items
        tree = self.completerTree()
        tree.clear()

        # make sure we have a valid object
        obj = self.objectAtCursor()
        if (obj is None):
            return False

        # determine the cursor position
        rect = self.cursorRect()
        cursor = self.textCursor()
        point = QPoint(rect.left(), rect.top() + 18)

        try:
            o_keys = obj.__dir__()
        except (AttributeError, TypeError):
            o_keys = dir(obj)

        keys = [key for key in sorted(o_keys) if not key.startswith('_')]
        if (not keys):
            return False

        for key in keys:
            tree.addTopLevelItem(QTreeWidgetItem([key]))

        tree.move(self.mapToGlobal(point))
        tree.show()

        return True

    def waitForInput(self):
        """
        Inserts a new input command into the console editor.
        """
        if (self.isReadOnly()):
            return

        self.moveCursor(QTextCursor.End)

        if (self.textCursor().block().text() == '>>> '):
            return

        # if there is already text on the line, then start a new line
        newln = '>>> '
        if projex.text.toUtf8(self.textCursor().block().text()):
            newln = '\n' + newln

        # insert the text
        self.setCurrentMode('standard')
        self.insertPlainText(newln)
        self.scrollToEnd()

        self._blankCache = ''
Beispiel #33
0
class TreeSymbolsWidget(QDialog):
    """Class of Dialog for Tree Symbols"""
    def __init__(self, parent=None):
        super(TreeSymbolsWidget, self).__init__(parent,
                                                Qt.WindowStaysOnTopHint)
        vbox = QVBoxLayout(self)
        vbox.setContentsMargins(0, 0, 0, 0)
        vbox.setSpacing(0)
        self.tree = QTreeWidget()
        vbox.addWidget(self.tree)
        self.tree.header().setHidden(True)
        self.tree.setSelectionMode(self.tree.SingleSelection)
        self.tree.setAnimated(True)
        self.tree.header().setHorizontalScrollMode(
            QAbstractItemView.ScrollPerPixel)
        self.tree.header().setResizeMode(0, QHeaderView.ResizeToContents)
        self.tree.header().setStretchLastSection(False)
        self.actualSymbols = ('', {})
        self.docstrings = {}
        self.collapsedItems = {}

        self.connect(self, SIGNAL("itemClicked(QTreeWidgetItem *, int)"),
                     self._go_to_definition)
        self.connect(self, SIGNAL("itemActivated(QTreeWidgetItem *, int)"),
                     self._go_to_definition)
        self.tree.setContextMenuPolicy(Qt.CustomContextMenu)
        self.connect(self,
                     SIGNAL("customContextMenuRequested(const QPoint &)"),
                     self._menu_context_tree)
        self.connect(self, SIGNAL("itemCollapsed(QTreeWidgetItem *)"),
                     self._item_collapsed)
        self.connect(self, SIGNAL("itemExpanded(QTreeWidgetItem *)"),
                     self._item_expanded)

        IDE.register_service('symbols_explorer', self)
        ExplorerContainer.register_tab(translations.TR_TAB_SYMBOLS, self)

    def install_tab(self):
        """Connect signals for goingdown"""
        ide = IDE.get_service('ide')
        self.connect(ide, SIGNAL("goingDown()"), self.close)

    def _menu_context_tree(self, point):
        """Context menu"""
        index = self.tree.indexAt(point)
        if not index.isValid():
            return

        menu = QMenu(self)
        f_all = menu.addAction(translations.TR_FOLD_ALL)
        u_all = menu.addAction(translations.TR_UNFOLD_ALL)
        menu.addSeparator()
        u_class = menu.addAction(translations.TR_UNFOLD_CLASSES)
        u_class_method = menu.addAction(
            translations.TR_UNFOLD_CLASSES_AND_METHODS)
        u_class_attr = menu.addAction(
            translations.TR_UNFOLD_CLASSES_AND_ATTRIBUTES)
        menu.addSeparator()
        #save_state = menu.addAction(self.tr("Save State"))

        self.connect(f_all, SIGNAL("triggered()"),
                     lambda: self.tree.collapseAll())
        self.connect(u_all, SIGNAL("triggered()"),
                     lambda: self.tree.expandAll())
        self.connect(u_class, SIGNAL("triggered()"), self._unfold_class)
        self.connect(u_class_method, SIGNAL("triggered()"),
                     self._unfold_class_method)
        self.connect(u_class_attr, SIGNAL("triggered()"),
                     self._unfold_class_attribute)
        #self.connect(save_state, SIGNAL("triggered()"),
        #self._save_symbols_state)

        menu.exec_(QCursor.pos())

    def _get_classes_root(self):
        """Return the root of classes"""
        class_root = None
        for i in range(self.tree.topLevelItemCount()):
            item = self.tree.topLevelItem(i)
            if item.isClass and not item.isClickable:
                class_root = item
                break
        return class_root

    def _unfold_class(self):
        """Method to Unfold Classes"""
        self.tree.collapseAll()
        classes_root = self._get_classes_root()
        if not classes_root:
            return

        classes_root.setExpanded(True)

    def _unfold_class_method(self):
        """Method to Unfold Methods"""
        self.tree.expandAll()
        classes_root = self._get_classes_root()
        if not classes_root:
            return
        #for each class!
        for i in range(classes_root.childCount()):
            class_item = classes_root.child(i)
            #for each attribute or functions
            for j in range(class_item.childCount()):
                item = class_item.child(j)
                #METHODS ROOT!!
                if not item.isMethod and not item.isClickable:
                    item.setExpanded(False)
                    break

    def _unfold_class_attribute(self):
        """Method to Unfold Attributes"""
        self.tree.expandAll()
        classes_root = self._get_classes_root()
        if not classes_root:
            return
        #for each class!
        for i in range(classes_root.childCount()):
            class_item = classes_root.child(i)
            #for each attribute or functions
            for j in range(class_item.childCount()):
                item = class_item.child(j)
                #ATTRIBUTES ROOT!!
                if not item.isAttribute and not item.isClickable:
                    item.setExpanded(False)
                    break

    def _save_symbols_state(self):
        """Method to Save a persistent Symbols state"""
        #filename = self.actualSymbols[0]
        #TODO: persist self.collapsedItems[filename] in QSettings
        pass

    def _get_expand(self, item):
        """
        Returns True or False to be used as setExpanded() with the items
        It method is based on the click that the user made in the tree
        """
        name = self._get_unique_name(item)
        filename = self.actualSymbols[0]
        collapsed_items = self.collapsedItems.get(filename, [])
        can_check = (not item.isClickable) or item.isClass or item.isMethod
        if can_check and name in collapsed_items:
            return False
        return True

    @staticmethod
    def _get_unique_name(item):
        """
        Returns a string used as unique name
        """
        # className_Attributes/className_Functions
        parent = item.parent()
        if parent:
            return "%s_%s" % (parent.text(0), item.text(0))
        return "_%s" % item.text(0)

    def update_symbols_tree(self, symbols, filename='', parent=None):
        """Method to Update the symbols on the Tree"""
        TIP = "{} {}"
        if not parent:
            if filename == self.actualSymbols[0] and \
                    self.actualSymbols[1] and not symbols:
                return

            if symbols == self.actualSymbols[1]:
                # Nothing new then return
                return

            # we have new symbols refresh it
            self.tree.clear()
            self.actualSymbols = (filename, symbols)
            self.docstrings = symbols.get('docstrings', {})
            parent = self.tree
        if 'attributes' in symbols:
            globalAttribute = ItemTree(parent, [translations.TR_ATTRIBUTES])
            globalAttribute.isClickable = False
            globalAttribute.isAttribute = True
            globalAttribute.setExpanded(self._get_expand(globalAttribute))
            globalAttribute.setToolTip(
                0,
                TIP.format(len(symbols['attributes']),
                           translations.TR_ATTRIBUTES))
            for glob in sorted(symbols['attributes']):
                globItem = ItemTree(globalAttribute, [glob],
                                    lineno=symbols['attributes'][glob])
                globItem.isAttribute = True
                globItem.setIcon(0, QIcon(":img/attribute"))
                globItem.setExpanded(self._get_expand(globItem))

        if 'functions' in symbols and symbols['functions']:
            functionsItem = ItemTree(parent, [translations.TR_FUNCTIONS])
            functionsItem.isClickable = False
            functionsItem.isMethod = True
            functionsItem.setExpanded(self._get_expand(functionsItem))
            functionsItem.setToolTip(
                0,
                TIP.format(len(symbols['functions']),
                           translations.TR_FUNCTIONS))
            for func in sorted(symbols['functions']):
                item = ItemTree(functionsItem, [func],
                                lineno=symbols['functions'][func]['lineno'])
                tooltip = self.create_tooltip(
                    func, symbols['functions'][func]['lineno'])
                item.isMethod = True
                item.setIcon(0, QIcon(":img/function"))
                item.setToolTip(0, tooltip)
                item.setExpanded(self._get_expand(item))
                self.update_symbols_tree(
                    symbols['functions'][func]['functions'], parent=item)
        if 'classes' in symbols and symbols['classes']:
            classItem = ItemTree(parent, [translations.TR_CLASSES])
            classItem.isClickable = False
            classItem.isClass = True
            classItem.setExpanded(self._get_expand(classItem))
            classItem.setToolTip(
                0, TIP.format(len(symbols['classes']),
                              translations.TR_CLASSES))
            for claz in sorted(symbols['classes']):
                line_number = symbols['classes'][claz]['lineno']
                item = ItemTree(classItem, [claz], lineno=line_number)
                item.isClass = True
                tooltip = self.create_tooltip(claz, line_number)
                item.setToolTip(0, tooltip)
                item.setIcon(0, QIcon(":img/class"))
                item.setExpanded(self._get_expand(item))
                self.update_symbols_tree(symbols['classes'][claz]['members'],
                                         parent=item)

    def _go_to_definition(self, item):
        """Takes and item object and goes to definition on the editor"""
        main_container = IDE.get_service('main_container')
        if item.isClickable and main_container:
            main_container.editor_go_to_line(item.lineno - 1)

    def create_tooltip(self, name, lineno):
        """Takes a name and line number and returns a tooltip"""
        doc = self.docstrings.get(lineno, None)
        if doc is None:
            doc = ''
        else:
            doc = '\n' + doc
        tooltip = name + doc
        return tooltip

    def _item_collapsed(self, item):
        """When item collapsed"""
        super(TreeSymbolsWidget, self).collapseItem(item)

        can_check = (not item.isClickable) or item.isClass or item.isMethod
        if can_check:
            n = self._get_unique_name(item)
            filename = self.actualSymbols[0]
            self.collapsedItems.setdefault(filename, [])
            if not n in self.collapsedItems[filename]:
                self.collapsedItems[filename].append(n)

    def _item_expanded(self, item):
        """When item expanded"""
        super(TreeSymbolsWidget, self).expandItem(item)

        n = self._get_unique_name(item)
        filename = self.actualSymbols[0]
        if n in self.collapsedItems.get(filename, []):
            self.collapsedItems[filename].remove(n)
            if not len(self.collapsedItems[filename]):
                # no more items, free space
                del self.collapsedItems[filename]

    def clean(self):
        """
        Reset the tree and reset attributes
        """
        self.tree.clear()
        self.collapsedItems = {}

    def reject(self):
        if self.parent() is None:
            self.emit(SIGNAL("dockWidget(PyQt_PyObject)"), self)

    def closeEvent(self, event):
        """On Close event handling"""
        self.emit(SIGNAL("dockWidget(PyQt_PyObject)"), self)
        event.ignore()
Beispiel #34
0
class PluginWidget(QWidget):
    def __init__(self, parent=None):
        QWidget.__init__(self, parent)

        self.pluginMetadata = {}

        # Main layout
        self.mainLayout = QVBoxLayout()
        self.setLayout(self.mainLayout)

        # Define size used for the underlines
        self.underlineSize = QSize()
        self.underlineSize.setHeight(1)

        # Define font used for headers
        self.font = QFont()
        self.font.setPointSize(11)
        self.font.setBold(True)
        self.font.setUnderline(True)

        # Plugins Description
        self.pluginDescription = QLabel()
        self.pluginDescription.setText(
            "Click a plugin to see more information." +
            " Plugins can be configured from the Recording tab. \n")
        self.pluginDescription.setWordWrap(True)

        # Plugins GroupBox
        self.pluginLayout = QVBoxLayout()
        self.pluginGroupBox = QGroupBox(
            "Plugins extend the functionality of Freeseer")
        self.pluginGroupBox.setLayout(self.pluginLayout)
        self.pluginLayout.insertWidget(0, self.pluginDescription)
        self.mainLayout.insertWidget(0, self.pluginGroupBox)

        # Plugins list
        self.list = QTreeWidget()
        self.list.setHeaderHidden(True)
        self.list.headerItem().setText(0, "1")
        self.pluginLayout.insertWidget(1, self.list)

        # Details
        self.detailPane = QGroupBox()
        self.detailLayout = QVBoxLayout()
        self.detailPane.setLayout(self.detailLayout)
        self.detailPaneDesc = QLabel()
        self.detailPaneDesc.setWordWrap(True)
        self.detailLayout.addWidget(self.detailPaneDesc)
        self.pluginLayout.insertWidget(2, self.detailPane)

        self.list.itemSelectionChanged.connect(self.treeViewSelect)

    def treeViewSelect(self):
        item = self.list.currentItem()
        key = str(item.text(0))
        if key in self.pluginMetadata.keys():
            self.showDetails(key)
        else:
            self.hideDetails()

    def showDetails(self, key):
        self.detailPane.setTitle(key)
        self.detailPaneDesc.setText(self.pluginMetadata[key])
        self.detailPane.show()

    def hideDetails(self):
        self.detailPane.hide()

    def getWidgetPlugin(self, plugin, plugin_category, plugman):
        plugin_name = plugin.plugin_object.get_name()
        item = QTreeWidgetItem()

        # Display Plugin's meta data in a tooltip
        pluginDetails = """
        <table>
        <tr>
            <td>Name: </td>
            <td><b>%(name)s</b></td>
        </tr>
        <tr>
            <td>Version: </td>
            <td><b>%(version)s</b></td>
        <tr>
            <td>Author: </td>
            <td><b>%(author)s</b></td>
        </tr>
        <tr>
            <td>Website: </td>
            <td><b>%(website)s</b></td>
        </tr>
        <tr>
            <td>Description: </td>
            <td><b>%(description)s</b></td>
        </tr>
        </table>
        """ % {
            "name": plugin.name,
            "version": plugin.version,
            "author": plugin.author,
            "website": plugin.website,
            "description": plugin.description
        }

        # put the details in the hash table
        self.pluginMetadata[plugin_name] = pluginDetails

        item.setText(0, plugin_name)
        return item
Beispiel #35
0
class AddToProject(QDialog):
    def __init__(self, pathProjects, parent=None):
        #pathProjects must be a list
        QDialog.__init__(self, parent)
        self.setWindowTitle(self.tr("Add File to Project"))
        self.pathSelected = ''
        vbox = QVBoxLayout(self)

        self._tree = QTreeWidget()
        self._tree.header().setHidden(True)
        self._tree.setSelectionMode(QTreeWidget.SingleSelection)
        self._tree.setAnimated(True)
        vbox.addWidget(self._tree)
        hbox = QHBoxLayout()
        btnAdd = QPushButton(self.tr("Add here!"))
        btnCancel = QPushButton(self.tr("Cancel"))
        hbox.addWidget(btnCancel)
        hbox.addWidget(btnAdd)
        vbox.addLayout(hbox)
        #load folders
        self._root = None
        self._loading_items = {}
        self.loading_projects(pathProjects)
        self._thread_execution = ThreadExecution(self._thread_load_projects,
                                                 args=[pathProjects])
        self.connect(self._thread_execution, SIGNAL("finished()"),
                     self._callback_load_project)
        self._thread_execution.start()

        self.connect(btnCancel, SIGNAL("clicked()"), self.close)
        self.connect(btnAdd, SIGNAL("clicked()"), self._select_path)

    def loading_projects(self, projects):
        for project in projects:
            loadingItem = LoadingItem()
            item = loadingItem.add_item_to_tree(project,
                                                self._tree,
                                                parent=self)
            self._loading_items[project] = item

    def _thread_load_projects(self, projects):
        structures = []
        for pathProject in projects:
            folderStructure = file_manager.open_project(pathProject)
            structures.append((folderStructure, pathProject))
        self._thread_execution.storage_values = structures

    def _callback_load_project(self):
        structures = self._thread_execution.storage_values
        for structure, path in structures:
            item = self._loading_items.pop(path, None)
            if item is not None:
                index = self._tree.indexOfTopLevelItem(item)
                self._tree.takeTopLevelItem(index)
            self._load_project(structure, path)

    def _select_path(self):
        item = self._tree.currentItem()
        if item:
            self.pathSelected = unicode(item.toolTip(0))
            self.close()

    def _load_project(self, folderStructure, folder):
        if not folder:
            return

        name = file_manager.get_basename(folder)
        item = QTreeWidgetItem(self._tree)
        item.setText(0, name)
        item.setToolTip(0, folder)
        item.setIcon(0, QIcon(resources.IMAGES['tree-folder']))
        if folderStructure[folder][1] is not None:
            folderStructure[folder][1].sort()
        self._load_folder(folderStructure, folder, item)
        item.setExpanded(True)
        self._root = item

    def _load_folder(self, folderStructure, folder, parentItem):
        items = folderStructure[folder]

        if items[1] is not None:
            items[1].sort()
        for _file in items[1]:
            if _file.startswith('.'):
                continue
            subfolder = QTreeWidgetItem(parentItem)
            subfolder.setText(0, _file)
            subfolder.setToolTip(0, os.path.join(folder, _file))
            subfolder.setIcon(0, QIcon(resources.IMAGES['tree-folder']))
            self._load_folder(folderStructure, os.path.join(folder, _file),
                              subfolder)
Beispiel #36
0
class StepKwMultiClassifications(WizardStep, FORM_CLASS):
    """InaSAFE Wizard Step Multi Classifications."""
    def __init__(self, parent=None):
        """Constructor for the tab.

        :param parent: widget to use as parent (Wizard Dialog).
        :type parent: QWidget
        """
        WizardStep.__init__(self, parent)
        self.exposures = []
        self.exposure_labels = []
        self.exposure_combo_boxes = []
        self.exposure_edit_buttons = []
        self.mode = CHOOSE_MODE

        self.layer_purpose = None
        self.layer_mode = None

        # Store the current representative state of the UI.
        # self.classifications = {}
        self.value_maps = {}
        self.thresholds = {}

        # Temporary attributes
        self.threshold_classes = OrderedDict()
        self.active_exposure = None

        self.list_unique_values = None
        self.tree_mapping_widget = None

        # GUI, good for testing
        self.save_button = None

        # Has default threshold
        # Trick for EQ raster for population #3853
        self.use_default_thresholds = False
        # Index of the special case exposure classification
        self.special_case_index = None

    def is_ready_to_next_step(self):
        """Check if the step is complete.

        :returns: True if new step may be enabled.
        :rtype: bool
        """
        # Still editing
        if self.mode == EDIT_MODE:
            return False
        for combo_box in self.exposure_combo_boxes:
            # Enable if there is one that has classification
            if combo_box.currentIndex() > 0:
                return True
        # Trick for EQ raster for population #3853
        if self.use_default_thresholds:
            return True
        return False

    def get_next_step(self):
        """Find the proper step when user clicks the Next button.

        :returns: The step to be switched to.
        :rtype: WizardStep instance or None
        """
        if self.layer_purpose != layer_purpose_aggregation:
            subcategory = self.parent.step_kw_subcategory.\
                selected_subcategory()
        else:
            subcategory = {'key': None}

        if is_raster_layer(self.parent.layer):
            return self.parent.step_kw_source

        # Check if it can go to inasafe field step
        inasafe_fields = get_non_compulsory_fields(self.layer_purpose['key'],
                                                   subcategory['key'])

        if not skip_inasafe_field(self.parent.layer, inasafe_fields):
            return self.parent.step_kw_inasafe_fields

        # Check if it can go to inasafe default field step
        default_inasafe_fields = get_fields(self.layer_purpose['key'],
                                            subcategory['key'],
                                            replace_null=True,
                                            in_group=False)
        if default_inasafe_fields:
            return self.parent.step_kw_default_inasafe_fields

        # Any other case
        return self.parent.step_kw_source

    def set_wizard_step_description(self):
        """Set the text for description."""
        subcategory = self.parent.step_kw_subcategory.selected_subcategory()
        field = self.parent.step_kw_field.selected_fields()
        is_raster = is_raster_layer(self.parent.layer)

        if is_raster:
            if self.layer_mode == layer_mode_continuous:
                text_label = multiple_continuous_hazard_classifications_raster
            else:
                text_label = multiple_classified_hazard_classifications_raster
            # noinspection PyAugmentAssignment
            text_label = text_label % (subcategory['name'],
                                       self.layer_purpose['name'])
        else:
            if self.layer_mode == layer_mode_continuous:
                text_label = multiple_continuous_hazard_classifications_vector
            else:
                text_label = multiple_classified_hazard_classifications_vector
            # noinspection PyAugmentAssignment
            text_label = text_label % (subcategory['name'],
                                       self.layer_purpose['name'], field)

        self.multi_classifications_label.setText(text_label)

    def setup_left_panel(self):
        """Setup the UI for left panel.

        Generate all exposure, combobox, and edit button.
        """
        hazard = self.parent.step_kw_subcategory.selected_subcategory()
        left_panel_heading = QLabel(tr('Classifications'))
        left_panel_heading.setFont(big_font)
        self.left_layout.addWidget(left_panel_heading)

        inner_left_layout = QGridLayout()

        row = 0
        for exposure in exposure_all:
            special_case = False
            # Filter out unsupported exposure for the hazard
            if exposure in hazard['disabled_exposures']:
                # Remove from the storage if the exposure is disabled
                if self.layer_mode == layer_mode_continuous:
                    if exposure['key'] in self.thresholds:
                        self.thresholds.pop(exposure['key'])
                else:
                    if exposure['key'] in self.value_maps:
                        self.value_maps.pop(exposure['key'])
                continue
            # Trick for EQ raster for population #3853
            if exposure == exposure_population and hazard == hazard_earthquake:
                if is_raster_layer(self.parent.layer):
                    if self.layer_mode == layer_mode_continuous:
                        self.use_default_thresholds = True
                        special_case = True
                        # Set classification for EQ Raster for Population
                        self.thresholds[exposure_population['key']] = {
                            earthquake_mmi_scale['key']: {
                                'classes':
                                default_classification_thresholds(
                                    earthquake_mmi_scale),
                                'active':
                                True
                            }
                        }

            # Add label
            # Hazard on Exposure Classifications
            label = tr(
                '{hazard_name} on {exposure_name} Classifications').format(
                    hazard_name=hazard['name'], exposure_name=exposure['name'])
            exposure_label = QLabel(label)

            # Add combo box
            exposure_combo_box = QComboBox()
            hazard_classifications = hazard.get('classifications')
            exposure_combo_box.addItem(tr('No classifications'))
            exposure_combo_box.setItemData(0, None, Qt.UserRole)

            current_index = 0
            i = 0
            # Iterate through all available hazard classifications
            for hazard_classification in hazard_classifications:
                # Skip if the classification is not for the exposure
                if 'exposures' in hazard_classification:
                    if exposure not in hazard_classification['exposures']:
                        continue
                exposure_combo_box.addItem(hazard_classification['name'])
                exposure_combo_box.setItemData(i + 1, hazard_classification,
                                               Qt.UserRole)
                if self.layer_mode == layer_mode_continuous:
                    current_hazard_classifications = self.thresholds.get(
                        exposure['key'])
                else:
                    current_hazard_classifications = self.value_maps.get(
                        exposure['key'])
                if current_hazard_classifications:
                    current_hazard_classification = \
                        current_hazard_classifications.get(
                            hazard_classification['key'])
                    if current_hazard_classification:
                        is_active = current_hazard_classification.get('active')
                        if is_active:
                            current_index = i + 1
                i += 1
            # Set current classification
            exposure_combo_box.setCurrentIndex(current_index)

            # Add edit button
            exposure_edit_button = QPushButton(tr('Edit'))

            # For special case. Raster EQ on Population.
            if special_case:
                mmi_index = exposure_combo_box.findText(
                    earthquake_mmi_scale['name'])
                exposure_combo_box.setCurrentIndex(mmi_index)
                exposure_combo_box.setEnabled(False)
                exposure_edit_button.setEnabled(False)
                tool_tip_message = tr(
                    'InaSAFE use default classification for Raster Earthquake '
                    'hazard on population.')
                exposure_label.setToolTip(tool_tip_message)
                exposure_combo_box.setToolTip(tool_tip_message)
                exposure_edit_button.setToolTip(tool_tip_message)

            else:
                if current_index == 0:
                    # Disable if there is no classification chosen.
                    exposure_edit_button.setEnabled(False)
                exposure_edit_button.clicked.connect(
                    partial(self.edit_button_clicked,
                            edit_button=exposure_edit_button,
                            exposure_combo_box=exposure_combo_box,
                            exposure=exposure))
                exposure_combo_box.currentIndexChanged.connect(
                    partial(self.classifications_combo_box_changed,
                            exposure=exposure,
                            exposure_combo_box=exposure_combo_box,
                            edit_button=exposure_edit_button))

            # Arrange in layout
            inner_left_layout.addWidget(exposure_label, row, 0)
            inner_left_layout.addWidget(exposure_combo_box, row, 1)
            inner_left_layout.addWidget(exposure_edit_button, row, 2)

            # Adding to step's attribute
            self.exposures.append(exposure)
            self.exposure_combo_boxes.append(exposure_combo_box)
            self.exposure_edit_buttons.append(exposure_edit_button)
            self.exposure_labels.append(label)
            if special_case:
                self.special_case_index = len(self.exposures) - 1

            row += 1

        self.left_layout.addLayout(inner_left_layout)
        # To push the inner_left_layout up
        self.left_layout.addStretch(1)

    # noinspection PyUnusedLocal
    def edit_button_clicked(self, edit_button, exposure_combo_box, exposure):
        """Method to handle when an edit button is clicked.

        :param edit_button: The edit button.
        :type edit_button: QPushButton

        :param exposure_combo_box: The combo box of the exposure, contains
            list of classifications.
        :type exposure_combo_box: QComboBox

        :param exposure: Exposure definition.
        :type exposure: dict
        """
        # Note(IS): Do not change the text of edit button for now until we
        # have better behaviour.
        classification = self.get_classification(exposure_combo_box)

        if self.mode == CHOOSE_MODE:
            # Change mode
            self.mode = EDIT_MODE
            # Set active exposure
            self.active_exposure = exposure
            # Disable all edit button
            for exposure_edit_button in self.exposure_edit_buttons:
                exposure_edit_button.setEnabled(False)
            # Except one that was clicked
            # edit_button.setEnabled(True)
            # Disable all combo box
            for exposure_combo_box in self.exposure_combo_boxes:
                exposure_combo_box.setEnabled(False)
            # Change the edit button to cancel
            # edit_button.setText(tr('Cancel'))

            # Clear right panel
            clear_layout(self.right_layout)
            # Show edit threshold or value mapping
            if self.layer_mode == layer_mode_continuous:
                self.setup_thresholds_panel(classification)
            else:
                self.setup_value_mapping_panels(classification)
            self.add_buttons(classification)

        elif self.mode == EDIT_MODE:
            # Behave the same as cancel button clicked.
            self.cancel_button_clicked()

        self.parent.pbnNext.setEnabled(self.is_ready_to_next_step())

    def show_current_state(self):
        """Setup the UI for QTextEdit to show the current state."""
        right_panel_heading = QLabel(tr('Status'))
        right_panel_heading.setFont(big_font)
        right_panel_heading.setSizePolicy(QSizePolicy.Maximum,
                                          QSizePolicy.Maximum)
        self.right_layout.addWidget(right_panel_heading)

        message = m.Message()
        if self.layer_mode == layer_mode_continuous:
            title = tr('Thresholds')
        else:
            title = tr('Value maps')

        message.add(m.Heading(title, **INFO_STYLE))

        for i in range(len(self.exposures)):
            message.add(m.Text(self.exposure_labels[i]))

            classification = self.get_classification(
                self.exposure_combo_boxes[i])
            if self.layer_mode == layer_mode_continuous:
                thresholds = self.thresholds.get(self.exposures[i]['key'])
                if not thresholds or not classification:
                    message.add(m.Paragraph(tr('No classifications set.')))
                    continue
                table = m.Table(
                    style_class='table table-condensed table-striped')
                header = m.Row()
                header.add(m.Cell(tr('Class name')))
                header.add(m.Cell(tr('Minimum')))
                header.add(m.Cell(tr('Maximum')))
                table.add(header)
                classes = classification.get('classes')
                # Sort by value, put the lowest first
                classes = sorted(classes, key=lambda k: k['value'])
                for the_class in classes:
                    threshold = thresholds[classification['key']]['classes'][
                        the_class['key']]
                    row = m.Row()
                    row.add(m.Cell(the_class['name']))
                    row.add(m.Cell(threshold[0]))
                    row.add(m.Cell(threshold[1]))
                    table.add(row)
            else:
                value_maps = self.value_maps.get(self.exposures[i]['key'])
                if not value_maps or not classification:
                    message.add(m.Paragraph(tr('No classifications set.')))
                    continue
                table = m.Table(
                    style_class='table table-condensed table-striped')
                header = m.Row()
                header.add(m.Cell(tr('Class name')))
                header.add(m.Cell(tr('Value')))
                table.add(header)
                classes = classification.get('classes')
                # Sort by value, put the lowest first
                classes = sorted(classes, key=lambda k: k['value'])
                for the_class in classes:
                    value_map = value_maps[
                        classification['key']]['classes'].get(
                            the_class['key'], [])
                    row = m.Row()
                    row.add(m.Cell(the_class['name']))
                    row.add(m.Cell(', '.join([str(v) for v in value_map])))
                    table.add(row)
            message.add(table)

        # status_text_edit = QTextBrowser(None)
        status_text_edit = QWebView(None)
        status_text_edit.setSizePolicy(QSizePolicy.Ignored,
                                       QSizePolicy.Ignored)

        status_text_edit.page().mainFrame().setScrollBarPolicy(
            Qt.Horizontal, Qt.ScrollBarAlwaysOff)
        html_string = html_header() + message.to_html() + html_footer()
        status_text_edit.setHtml(html_string)
        self.right_layout.addWidget(status_text_edit)

    def set_widgets(self):
        """Set widgets on the Multi classification step."""
        self.clear()
        self.layer_mode = self.parent.step_kw_layermode.selected_layermode()
        self.layer_purpose = self.parent.step_kw_purpose.selected_purpose()
        self.set_current_state()

        # Set the step description
        self.set_wizard_step_description()

        # Set the left panel
        self.setup_left_panel()

        # Set the right panel, for the beginning show the viewer
        self.show_current_state()

    def clear(self):
        """Clear current state."""
        self.exposures = []
        self.exposure_labels = []
        self.exposure_combo_boxes = []
        self.exposure_edit_buttons = []
        self.mode = CHOOSE_MODE

        self.layer_purpose = None
        self.layer_mode = None
        self.special_case_index = None

        self.value_maps = {}
        self.thresholds = {}

        # Temporary attributes
        self.threshold_classes = OrderedDict()
        self.active_exposure = None

        self.list_unique_values = None
        self.tree_mapping_widget = None

        clear_layout(self.left_layout)
        clear_layout(self.right_layout)

    def get_current_state(self):
        """Obtain current classification and value map / threshold."""
        def clean_state(dictionary):
            """Clean dictionary from bad value.

            :param dictionary: Dictionary of value maps or thresholds.
            :type dictionary: dict

            :returns: Clean state.
            :rtype: dict
            """
            clean_dictionary = {
                k: v
                for k, v in dictionary.items() if isinstance(v, dict)
            }

            return clean_dictionary

        if self.layer_mode == layer_mode_continuous:
            output = {'thresholds': clean_state(self.thresholds)}
            key = 'thresholds'
        else:
            output = {'value_maps': clean_state(self.value_maps)}
            key = 'value_maps'

        # Clean non existing hazard class key
        empty_exposure_classifications = []
        for the_exposure, the_hazard_classifications in output[key].items():
            for the_hazard_classification in the_hazard_classifications.\
                    keys():
                invalid_classifications = []
                if not definition(the_hazard_classification):
                    invalid_classifications.append(the_hazard_classification)
                for invalid_classification in invalid_classifications:
                    the_hazard_classifications.pop(invalid_classification)
            if not the_hazard_classifications:
                empty_exposure_classifications.append(the_exposure)

        for empty_exposure_classification in empty_exposure_classifications:
            output[key].pop(empty_exposure_classification)

        return output

    @staticmethod
    def get_classification(combo_box):
        """Helper to obtain the classification from a combo box.

        :param combo_box: A classification combo box.
        :type combo_box: QComboBox.

        :returns: Classification definitions.
        :rtype: dict
        """
        return combo_box.itemData(combo_box.currentIndex(), Qt.UserRole)

    def setup_thresholds_panel(self, classification):
        """Setup threshold panel in the right panel.

        :param classification: Classification definition.
        :type classification: dict
        """
        # Set text in the label
        layer_purpose = self.parent.step_kw_purpose.selected_purpose()
        layer_subcategory = self.parent.step_kw_subcategory.\
            selected_subcategory()

        if is_raster_layer(self.parent.layer):
            statistics = self.parent.layer.dataProvider().bandStatistics(
                1, QgsRasterBandStats.All, self.parent.layer.extent(), 0)
            description_text = continuous_raster_question % (
                layer_purpose['name'], layer_subcategory['name'],
                classification['name'], statistics.minimumValue,
                statistics.maximumValue)
        else:
            field_name = self.parent.step_kw_field.selected_fields()
            field_index = self.parent.layer.fieldNameIndex(field_name)
            min_value_layer = self.parent.layer.minimumValue(field_index)
            max_value_layer = self.parent.layer.maximumValue(field_index)
            description_text = continuous_vector_question % (
                layer_purpose['name'], layer_subcategory['name'], field_name,
                classification['name'], min_value_layer, max_value_layer)

        # Set description
        description_label = QLabel(description_text)
        description_label.setWordWrap(True)
        self.right_layout.addWidget(description_label)

        if self.thresholds:
            thresholds = self.thresholds
        else:
            thresholds = self.parent.get_existing_keyword('thresholds')
        selected_unit = self.parent.step_kw_unit.selected_unit()['key']

        self.threshold_classes = OrderedDict()
        classes = classification.get('classes')
        # Sort by value, put the lowest first
        classes = sorted(classes, key=lambda the_key: the_key['value'])

        grid_layout_thresholds = QGridLayout()

        for i, the_class in enumerate(classes):
            class_layout = QHBoxLayout()

            # Class label
            class_label = QLabel(the_class['name'])

            # Min label
            min_label = QLabel(tr('Min >'))

            # Min value as double spin
            min_value_input = QDoubleSpinBox()
            # TODO(IS) We can set the min and max depends on the unit, later
            min_value_input.setMinimum(0)
            min_value_input.setMaximum(999999)

            if thresholds.get(self.active_exposure['key']):
                exposure_thresholds = thresholds.get(
                    self.active_exposure['key'])
                if exposure_thresholds.get(classification['key']):
                    exposure_thresholds_classifications = exposure_thresholds\
                        .get(classification['key'])
                    min_value_input.setValue(
                        exposure_thresholds_classifications['classes'][
                            the_class['key']][0])
                else:
                    default_min = the_class['numeric_default_min']
                    if isinstance(default_min, dict):
                        default_min = the_class['numeric_default_min'][
                            selected_unit]
                    min_value_input.setValue(default_min)
            else:
                default_min = the_class['numeric_default_min']
                if isinstance(default_min, dict):
                    default_min = the_class['numeric_default_min'][
                        selected_unit]
                min_value_input.setValue(default_min)
            min_value_input.setSingleStep(0.1)

            # Max label
            max_label = QLabel(tr('Max <='))

            # Max value as double spin
            max_value_input = QDoubleSpinBox()
            # TODO(IS) We can set the min and max depends on the unit, later
            max_value_input.setMinimum(0)
            max_value_input.setMaximum(999999)
            if thresholds.get(self.active_exposure['key']):
                exposure_thresholds = thresholds.get(
                    self.active_exposure['key'])
                if exposure_thresholds.get(classification['key']):
                    exposure_thresholds_classifications = exposure_thresholds \
                        .get(classification['key'])
                    max_value_input.setValue(
                        exposure_thresholds_classifications['classes'][
                            the_class['key']][1])
                else:
                    default_max = the_class['numeric_default_max']
                    if isinstance(default_max, dict):
                        default_max = the_class['numeric_default_max'][
                            selected_unit]
                    max_value_input.setValue(default_max)
            else:
                default_max = the_class['numeric_default_max']
                if isinstance(default_max, dict):
                    default_max = the_class['numeric_default_max'][
                        selected_unit]
                max_value_input.setValue(default_max)
            max_value_input.setSingleStep(0.1)

            # Add to class_layout
            class_layout.addWidget(min_label)
            class_layout.addWidget(min_value_input)
            class_layout.addWidget(max_label)
            class_layout.addWidget(max_value_input)

            class_layout.setStretch(0, 1)
            class_layout.setStretch(1, 2)
            class_layout.setStretch(2, 1)
            class_layout.setStretch(3, 2)

            # Add to grid_layout
            grid_layout_thresholds.addWidget(class_label, i, 0)
            grid_layout_thresholds.addLayout(class_layout, i, 1)

            self.threshold_classes[the_class['key']] = [
                min_value_input, max_value_input
            ]

        grid_layout_thresholds.setColumnStretch(0, 1)
        grid_layout_thresholds.setColumnStretch(0, 2)

        def min_max_changed(double_spin_index, mode):
            """Slot when min or max value change.

            :param double_spin_index: The index of the double spin.
            :type double_spin_index: int

            :param mode: The flag to indicate the min or max value.
            :type mode: int
            """
            if mode == MAX_VALUE_MODE:
                current_max_value = self.threshold_classes.values(
                )[double_spin_index][1]
                target_min_value = self.threshold_classes.values()[
                    double_spin_index + 1][0]
                if current_max_value.value() != target_min_value.value():
                    target_min_value.setValue(current_max_value.value())
            elif mode == MIN_VALUE_MODE:
                current_min_value = self.threshold_classes.values(
                )[double_spin_index][0]
                target_max_value = self.threshold_classes.values()[
                    double_spin_index - 1][1]
                if current_min_value.value() != target_max_value.value():
                    target_max_value.setValue(current_min_value.value())

        # Set behaviour
        for k, v in self.threshold_classes.items():
            index = self.threshold_classes.keys().index(k)
            if index < len(self.threshold_classes) - 1:
                # Max value changed
                v[1].valueChanged.connect(
                    partial(min_max_changed,
                            double_spin_index=index,
                            mode=MAX_VALUE_MODE))
            if index > 0:
                # Min value
                v[0].valueChanged.connect(
                    partial(min_max_changed,
                            double_spin_index=index,
                            mode=MIN_VALUE_MODE))

        grid_layout_thresholds.setSpacing(0)

        self.right_layout.addLayout(grid_layout_thresholds)

    def add_buttons(self, classification):
        """Helper to setup 3 buttons.

        :param classification: The current classification.
        :type classification: dict
        """
        # Note(IS): Until we have good behaviour, we will disable load
        # default and cancel button.
        # Add 3 buttons: Load default, Cancel, Save
        # load_default_button = QPushButton(tr('Load Default'))
        # cancel_button = QPushButton(tr('Cancel'))
        self.save_button = QPushButton(tr('Save'))

        # Action for buttons
        # cancel_button.clicked.connect(self.cancel_button_clicked)
        self.save_button.clicked.connect(
            partial(self.save_button_clicked, classification=classification))

        button_layout = QHBoxLayout()
        # button_layout.addWidget(load_default_button)
        button_layout.addStretch(1)
        # button_layout.addWidget(cancel_button)
        button_layout.addWidget(self.save_button)

        button_layout.setStretch(0, 3)
        button_layout.setStretch(1, 1)
        # button_layout.setStretch(2, 1)
        # button_layout.setStretch(3, 1)

        self.right_layout.addLayout(button_layout)

    def setup_value_mapping_panels(self, classification):
        """Setup value mapping panel in the right panel.

        :param classification: Classification definition.
        :type classification: dict
        """
        # Set text in the label
        layer_purpose = self.parent.step_kw_purpose.selected_purpose()
        layer_subcategory = self.parent.step_kw_subcategory. \
            selected_subcategory()

        if is_raster_layer(self.parent.layer):
            description_text = classify_raster_question % (
                layer_subcategory['name'], layer_purpose['name'],
                classification['name'])

            dataset = gdal.Open(self.parent.layer.source(), GA_ReadOnly)
            active_band = self.parent.step_kw_band_selector.selected_band()
            unique_values = numpy.unique(
                numpy.array(dataset.GetRasterBand(active_band).ReadAsArray()))
            field_type = 0
            # Convert datatype to a json serializable type
            if numpy.issubdtype(unique_values.dtype, float):
                unique_values = [float(i) for i in unique_values]
            else:
                unique_values = [int(i) for i in unique_values]
        else:
            field = self.parent.step_kw_field.selected_fields()
            field_index = self.parent.layer.dataProvider().fields(). \
                indexFromName(field)
            field_type = self.parent.layer.dataProvider(). \
                fields()[field_index].type()
            description_text = classify_vector_question % (
                layer_subcategory['name'], layer_purpose['name'],
                classification['name'], field.upper())
            unique_values = self.parent.layer.uniqueValues(field_index)

        # Set description
        description_label = QLabel(description_text)
        description_label.setWordWrap(True)
        self.right_layout.addWidget(description_label)

        self.list_unique_values = QListWidget()
        self.list_unique_values.setDragDropMode(QAbstractItemView.DragDrop)
        self.list_unique_values.setDefaultDropAction(Qt.MoveAction)

        self.tree_mapping_widget = QTreeWidget()
        self.tree_mapping_widget.setDragDropMode(QAbstractItemView.DragDrop)
        self.tree_mapping_widget.setDefaultDropAction(Qt.MoveAction)
        self.tree_mapping_widget.header().hide()

        self.tree_mapping_widget.itemChanged.connect(
            self.update_dragged_item_flags)

        value_mapping_layout = QHBoxLayout()
        value_mapping_layout.addWidget(self.list_unique_values)
        value_mapping_layout.addWidget(self.tree_mapping_widget)

        self.right_layout.addLayout(value_mapping_layout)

        default_classes = classification['classes']

        # Assign unique values to classes (according to default)
        unassigned_values = list()
        assigned_values = dict()
        for default_class in default_classes:
            assigned_values[default_class['key']] = list()
        for unique_value in unique_values:
            if unique_value is None or isinstance(unique_value,
                                                  QPyNullVariant):
                # Don't classify features with NULL value
                continue
            # Capitalization of the value and removing '_' (raw OSM data).
            value_as_string = unicode(unique_value).upper().replace('_', ' ')
            assigned = False
            for default_class in default_classes:
                if 'string_defaults' in default_class:
                    condition_1 = (field_type > 9 and value_as_string in [
                        c.upper() for c in default_class['string_defaults']
                    ])
                else:
                    condition_1 = False
                condition_2 = (
                    field_type < 10 and 'numeric_default_min' in default_class
                    and 'numeric_default_max' in default_class
                    and (default_class['numeric_default_min'] <= unique_value <
                         default_class['numeric_default_max']))
                if condition_1 or condition_2:
                    assigned_values[default_class['key']] += [unique_value]
                    assigned = True
            if not assigned:
                # add to unassigned values list otherwise
                unassigned_values += [unique_value]
        self.populate_classified_values(unassigned_values, assigned_values,
                                        default_classes,
                                        self.list_unique_values,
                                        self.tree_mapping_widget)

        # Current value map for exposure and classification
        available_classifications = self.value_maps.get(
            self.active_exposure['key'])
        if not available_classifications:
            return
        # Get active one
        current_classification = available_classifications.get(
            classification['key'])
        if not current_classification:
            return
        current_value_map = current_classification.get('classes')
        if not current_value_map:
            return

        unassigned_values = list()
        assigned_values = dict()
        for default_class in default_classes:
            assigned_values[default_class['key']] = list()
        for unique_value in unique_values:
            if unique_value is None or isinstance(unique_value,
                                                  QPyNullVariant):
                # Don't classify features with NULL value
                continue
            # check in value map
            assigned = False
            for key, value_list in current_value_map.items():
                if unique_value in value_list and key in assigned_values:
                    assigned_values[key] += [unique_value]
                    assigned = True
            if not assigned:
                unassigned_values += [unique_value]
        self.populate_classified_values(unassigned_values, assigned_values,
                                        default_classes,
                                        self.list_unique_values,
                                        self.tree_mapping_widget)

    # noinspection PyMethodMayBeStatic
    def update_dragged_item_flags(self, item):
        """Fix the drop flag after the item is dropped.

        Check if it looks like an item dragged from QListWidget
        to QTreeWidget and disable the drop flag.
        For some reasons the flag is set when dragging.

        :param item: Item which is dragged.
        :type item: QTreeWidgetItem

        .. note:: This is a slot executed when the item change.
        """
        if int(item.flags() & Qt.ItemIsDropEnabled) \
                and int(item.flags() & Qt.ItemIsDragEnabled):
            item.setFlags(item.flags() & ~Qt.ItemIsDropEnabled)

    @staticmethod
    def populate_classified_values(unassigned_values, assigned_values,
                                   default_classes, list_unique_values,
                                   tree_mapping_widget):
        """Populate lstUniqueValues and treeClasses.from the parameters.

        :param unassigned_values: List of values that haven't been assigned
            to a class. It will be put in list_unique_values.
        :type unassigned_values: list

        :param assigned_values: Dictionary with class as the key and list of
            value as the value of the dictionary. It will be put in
            tree_mapping_widget.
        :type assigned_values: dict

        :param default_classes: Default classes from unit.
        :type default_classes: list

        :param list_unique_values: List Widget for unique values
        :type list_unique_values: QListWidget

        :param tree_mapping_widget: Tree Widget for classifying.
        :type tree_mapping_widget: QTreeWidget
        """
        # Populate the unique values list
        list_unique_values.clear()
        list_unique_values.setSelectionMode(
            QAbstractItemView.ExtendedSelection)
        for value in unassigned_values:
            value_as_string = value is not None and unicode(value) or 'NULL'
            list_item = QListWidgetItem(list_unique_values)
            list_item.setFlags(Qt.ItemIsEnabled | Qt.ItemIsSelectable
                               | Qt.ItemIsDragEnabled)
            list_item.setData(Qt.UserRole, value)
            list_item.setText(value_as_string)
            list_unique_values.addItem(list_item)
        # Populate assigned values tree
        tree_mapping_widget.clear()
        bold_font = QFont()
        bold_font.setItalic(True)
        bold_font.setBold(True)
        bold_font.setWeight(75)
        tree_mapping_widget.invisibleRootItem().setFlags(Qt.ItemIsEnabled)
        for default_class in default_classes:
            # Create branch for class
            tree_branch = QTreeWidgetItem(tree_mapping_widget)
            tree_branch.setFlags(Qt.ItemIsDropEnabled | Qt.ItemIsEnabled)
            tree_branch.setExpanded(True)
            tree_branch.setFont(0, bold_font)
            if 'name' in default_class:
                default_class_name = default_class['name']
            else:
                default_class_name = default_class['key']
            tree_branch.setText(0, default_class_name)
            tree_branch.setData(0, Qt.UserRole, default_class['key'])
            if 'description' in default_class:
                tree_branch.setToolTip(0, default_class['description'])
            # Assign known values
            for value in assigned_values[default_class['key']]:
                string_value = value is not None and unicode(value) or 'NULL'
                tree_leaf = QTreeWidgetItem(tree_branch)
                tree_leaf.setFlags(Qt.ItemIsEnabled | Qt.ItemIsSelectable
                                   | Qt.ItemIsDragEnabled)
                tree_leaf.setData(0, Qt.UserRole, value)
                tree_leaf.setText(0, string_value)

    def cancel_button_clicked(self):
        """Action for cancel button clicked."""
        # Change mode
        self.mode = CHOOSE_MODE
        # Enable all edit buttons and combo boxes
        for i in range(len(self.exposures)):
            if i == self.special_case_index:
                self.exposure_edit_buttons[i].setEnabled(False)
                self.exposure_combo_boxes[i].setEnabled(False)
                continue
            if self.get_classification(self.exposure_combo_boxes[i]):
                self.exposure_edit_buttons[i].setEnabled(True)
            else:
                self.exposure_edit_buttons[i].setEnabled(False)
            # self.exposure_edit_buttons[i].setText(tr('Edit'))
            self.exposure_combo_boxes[i].setEnabled(True)

        # Clear right panel
        clear_layout(self.right_layout)
        # Show current state
        self.show_current_state()
        # Unset active exposure
        self.active_exposure = None

        self.parent.pbnNext.setEnabled(self.is_ready_to_next_step())

    def save_button_clicked(self, classification):
        """Action for save button clicked.

        :param classification: The classification that being edited.
        :type classification: dict
        """
        # Save current edit
        if self.layer_mode == layer_mode_continuous:
            thresholds = self.get_threshold()
            classification_class = {'classes': thresholds, 'active': True}
            if self.thresholds.get(self.active_exposure['key']):
                # Set other class to not active
                for current_classification in self.thresholds.get(
                        self.active_exposure['key']).values():
                    current_classification['active'] = False
            else:
                self.thresholds[self.active_exposure['key']] = {}

            self.thresholds[self.active_exposure['key']][
                classification['key']] = classification_class
        else:
            value_maps = self.get_value_map()
            classification_class = {'classes': value_maps, 'active': True}
            if self.value_maps.get(self.active_exposure['key']):
                # Set other class to not active
                for current_classification in self.value_maps.get(
                        self.active_exposure['key']).values():
                    current_classification['active'] = False
            else:
                self.value_maps[self.active_exposure['key']] = {}

            self.value_maps[self.active_exposure['key']][
                classification['key']] = classification_class
        # Back to choose mode
        self.cancel_button_clicked()

    def get_threshold(self):
        """Return threshold based on current state."""
        value_map = dict()
        for key, value in self.threshold_classes.items():
            value_map[key] = [
                value[0].value(),
                value[1].value(),
            ]
        return value_map

    def get_value_map(self):
        """Obtain the value-to-class mapping set by user.

        :returns: The complete mapping as a dict of lists.
        :rtype: dict
        """
        value_map = {}
        tree_clone = self.tree_mapping_widget.invisibleRootItem().clone()
        for tree_branch in tree_clone.takeChildren():
            value_list = []
            for tree_leaf in tree_branch.takeChildren():
                value_list += [tree_leaf.data(0, Qt.UserRole)]
            if value_list:
                value_map[tree_branch.data(0, Qt.UserRole)] = value_list
        return value_map

    def set_current_state(self):
        """"Helper to set the state of the step from current keywords."""
        if not self.thresholds:
            self.thresholds = self.parent.get_existing_keyword('thresholds')
        if not self.value_maps:
            self.value_maps = self.parent.get_existing_keyword('value_maps')

    def classifications_combo_box_changed(self, index, exposure,
                                          exposure_combo_box, edit_button):
        """Action when classification combo box changed.

        :param index: The index of the combo box.
        :type index: int

        :param exposure: The exposure associated with the combo box.
        :type exposure: dict

        :param exposure_combo_box: Combo box for the classification.
        :type exposure_combo_box: QComboBox

        :param edit_button: The edit button associate with combo box.
        :type edit_button: QPushButton
        """
        # Disable button if it's no classification
        edit_button.setEnabled(bool(index))

        classification = self.get_classification(exposure_combo_box)
        self.activate_classification(exposure, classification)
        clear_layout(self.right_layout)
        self.show_current_state()

        self.parent.pbnNext.setEnabled(self.is_ready_to_next_step())

        # Open edit panel directly
        edit_button.click()

    def activate_classification(self, exposure, classification=None):
        """Set active to True for classification for the exposure.

        If classification = None, all classification set active = False.

        :param exposure: Exposure definition.
        :type exposure: dict

        :param classification: Classification definition.
        :type classification: dict
        """
        if self.layer_mode == layer_mode_continuous:
            selected_unit = self.parent.step_kw_unit.selected_unit()['key']
            target = self.thresholds.get(exposure['key'])
            if target is None:
                self.thresholds[exposure['key']] = {}
            target = self.thresholds.get(exposure['key'])
        else:
            selected_unit = None
            target = self.value_maps.get(exposure['key'])
            if target is None:
                self.value_maps[exposure['key']] = {}
            target = self.value_maps.get(exposure['key'])

        if classification is not None:
            if classification['key'] not in target:
                if self.layer_mode == layer_mode_continuous:
                    default_classes = default_classification_thresholds(
                        classification, selected_unit)
                    target[classification['key']] = {
                        'classes': default_classes,
                        'active': True
                    }
                else:
                    default_classes = default_classification_value_maps(
                        classification)
                    target[classification['key']] = {
                        'classes': default_classes,
                        'active': True
                    }
                return

        for classification_key, value in target.items():
            if classification is None:
                value['active'] = False
                continue

            if classification_key == classification['key']:
                value['active'] = True
            else:
                value['active'] = False

    @property
    def step_name(self):
        """Get the human friendly name for the wizard step.

        :returns: The name of the wizard step.
        :rtype: str
        """
        return tr('Multi Classification Step')

    def help_content(self):
        """Return the content of help for this step wizard.

            We only needs to re-implement this method in each wizard step.

        :returns: A message object contains help.
        :rtype: m.Message
        """
        message = m.Message()
        message.add(
            m.Paragraph(
                tr('In this wizard step: {step_name}, you will be able to set the '
                   'classification that you will use per exposure type. You can also '
                   'set the threshold or value map for each classification.').
                format(step_name=self.step_name)))
        return message
Beispiel #37
0
    def setup_value_mapping_panels(self, classification):
        """Setup value mapping panel in the right panel.

        :param classification: Classification definition.
        :type classification: dict
        """
        # Set text in the label
        layer_purpose = self.parent.step_kw_purpose.selected_purpose()
        layer_subcategory = self.parent.step_kw_subcategory. \
            selected_subcategory()

        if is_raster_layer(self.parent.layer):
            description_text = classify_raster_question % (
                layer_subcategory['name'], layer_purpose['name'],
                classification['name'])

            dataset = gdal.Open(self.parent.layer.source(), GA_ReadOnly)
            active_band = self.parent.step_kw_band_selector.selected_band()
            unique_values = numpy.unique(
                numpy.array(dataset.GetRasterBand(active_band).ReadAsArray()))
            field_type = 0
            # Convert datatype to a json serializable type
            if numpy.issubdtype(unique_values.dtype, float):
                unique_values = [float(i) for i in unique_values]
            else:
                unique_values = [int(i) for i in unique_values]
        else:
            field = self.parent.step_kw_field.selected_fields()
            field_index = self.parent.layer.dataProvider().fields(). \
                indexFromName(field)
            field_type = self.parent.layer.dataProvider(). \
                fields()[field_index].type()
            description_text = classify_vector_question % (
                layer_subcategory['name'], layer_purpose['name'],
                classification['name'], field.upper())
            unique_values = self.parent.layer.uniqueValues(field_index)

        # Set description
        description_label = QLabel(description_text)
        description_label.setWordWrap(True)
        self.right_layout.addWidget(description_label)

        self.list_unique_values = QListWidget()
        self.list_unique_values.setDragDropMode(QAbstractItemView.DragDrop)
        self.list_unique_values.setDefaultDropAction(Qt.MoveAction)

        self.tree_mapping_widget = QTreeWidget()
        self.tree_mapping_widget.setDragDropMode(QAbstractItemView.DragDrop)
        self.tree_mapping_widget.setDefaultDropAction(Qt.MoveAction)
        self.tree_mapping_widget.header().hide()

        self.tree_mapping_widget.itemChanged.connect(
            self.update_dragged_item_flags)

        value_mapping_layout = QHBoxLayout()
        value_mapping_layout.addWidget(self.list_unique_values)
        value_mapping_layout.addWidget(self.tree_mapping_widget)

        self.right_layout.addLayout(value_mapping_layout)

        default_classes = classification['classes']

        # Assign unique values to classes (according to default)
        unassigned_values = list()
        assigned_values = dict()
        for default_class in default_classes:
            assigned_values[default_class['key']] = list()
        for unique_value in unique_values:
            if unique_value is None or isinstance(unique_value,
                                                  QPyNullVariant):
                # Don't classify features with NULL value
                continue
            # Capitalization of the value and removing '_' (raw OSM data).
            value_as_string = unicode(unique_value).upper().replace('_', ' ')
            assigned = False
            for default_class in default_classes:
                if 'string_defaults' in default_class:
                    condition_1 = (field_type > 9 and value_as_string in [
                        c.upper() for c in default_class['string_defaults']
                    ])
                else:
                    condition_1 = False
                condition_2 = (
                    field_type < 10 and 'numeric_default_min' in default_class
                    and 'numeric_default_max' in default_class
                    and (default_class['numeric_default_min'] <= unique_value <
                         default_class['numeric_default_max']))
                if condition_1 or condition_2:
                    assigned_values[default_class['key']] += [unique_value]
                    assigned = True
            if not assigned:
                # add to unassigned values list otherwise
                unassigned_values += [unique_value]
        self.populate_classified_values(unassigned_values, assigned_values,
                                        default_classes,
                                        self.list_unique_values,
                                        self.tree_mapping_widget)

        # Current value map for exposure and classification
        available_classifications = self.value_maps.get(
            self.active_exposure['key'])
        if not available_classifications:
            return
        # Get active one
        current_classification = available_classifications.get(
            classification['key'])
        if not current_classification:
            return
        current_value_map = current_classification.get('classes')
        if not current_value_map:
            return

        unassigned_values = list()
        assigned_values = dict()
        for default_class in default_classes:
            assigned_values[default_class['key']] = list()
        for unique_value in unique_values:
            if unique_value is None or isinstance(unique_value,
                                                  QPyNullVariant):
                # Don't classify features with NULL value
                continue
            # check in value map
            assigned = False
            for key, value_list in current_value_map.items():
                if unique_value in value_list and key in assigned_values:
                    assigned_values[key] += [unique_value]
                    assigned = True
            if not assigned:
                unassigned_values += [unique_value]
        self.populate_classified_values(unassigned_values, assigned_values,
                                        default_classes,
                                        self.list_unique_values,
                                        self.tree_mapping_widget)
Beispiel #38
0
 def mousePressEvent(self, event):
     if event.button() == Qt.RightButton:
         return
     else:
         QTreeWidget.mousePressEvent(self, event)
Beispiel #39
0
class GmApp(QMainWindow):
    def __init__(self):
        super(QMainWindow, self).__init__()

        self.setWindowTitle("GuloMail by GulonSoft")
        self.setWindowIcon(QIcon("g-square.png"))

        self.createActions()
        self.createStatusBar()
        self.createMenus()
        self.createToolbars()
        self.createWidgets()
        self.createLayouts()

    def createActions(self):
        self.newAction = QAction("&New",
                                 self,
                                 shortcut=QKeySequence.New,
                                 statusTip="New")
        self.sendReceiveAction = QAction("Send / &Receive",
                                         self,
                                         shortcut="F9",
                                         statusTip="Send / Receive")
        self.printAction = QAction("&Print...",
                                   self,
                                   shortcut="Ctrl+P",
                                   statusTip="Print")
        self.quitAction = QAction("&Quit",
                                  self,
                                  shortcut="Ctrl+Q",
                                  statusTip="Quit",
                                  triggered=self.close)

        self.copyAction = QAction("&Copy",
                                  self,
                                  statusTip="Copy",
                                  shortcut=QKeySequence.Copy)
        self.deleteAction = QAction("&Delete",
                                    self,
                                    statusTip="Delete Message")

        self.nextAction = QAction("Next &Unread Message",
                                  self,
                                  shortcut="Ctrl+]",
                                  statusTip="Next unread message")
        self.previousAction = QAction("P&revious Unread Message",
                                      self,
                                      shortcut="Ctrl+[",
                                      statusTip="Previous unread message")
        self.replyAction = QAction("&Reply",
                                   self,
                                   shortcut="Ctrl+R",
                                   statusTip="Reply to sender",
                                   triggered=self.reply)
        self.replyToAllAction = QAction("Reply to &All",
                                        self,
                                        shortcut="Ctrl+Shift+R",
                                        statusTip="Reply to all",
                                        triggered=self.replyToAll)
        self.forwardAction = QAction("&Forward",
                                     self,
                                     shortcut="Ctrl+F",
                                     statusTip="Forward")
        self.junkAction = QAction("Junk",
                                  self,
                                  shortcut="Ctrl+J",
                                  statusTip="Mark as Junk")
        self.notJunkAction = QAction("Not junk",
                                     self,
                                     shortcut="Shift+Ctrl+J",
                                     statusTip="Mark as Not Junk")

        self.contentsAction = QAction("&Contents",
                                      self,
                                      statusTip="Help Contents",
                                      shortcut="F1",
                                      triggered=self.helpContents)
        self.aboutAction = QAction("&About",
                                   self,
                                   statusTip="About GuloMail",
                                   triggered=self.about)

        self.cancelAction = QAction("&Cancel", self, statusTip="Cancel")

    def createStatusBar(self):
        self.statusBar()

    def createMenus(self):
        self.fileMenu = self.menuBar().addMenu("&File")
        self.fileMenu.addAction(self.newAction)
        self.fileMenu.addAction(self.sendReceiveAction)
        self.fileMenu.addAction(self.printAction)
        self.fileMenu.addAction(self.quitAction)

        self.editMenu = self.menuBar().addMenu("&Edit")
        self.editMenu.addAction(self.copyAction)
        self.editMenu.addAction(self.deleteAction)

        self.viewMenu = self.menuBar().addMenu("&View")
        self.folderMenu = self.menuBar().addMenu("F&older")

        self.messageMenu = self.menuBar().addMenu("&Message")
        self.goToMenu = self.messageMenu.addMenu("&Go To")
        self.goToMenu.addAction(self.nextAction)
        self.goToMenu.addAction(self.previousAction)
        self.messageMenu.addAction(self.replyAction)
        self.messageMenu.addAction(self.replyToAllAction)
        self.messageMenu.addAction(self.forwardAction)
        self.markAsMenu = self.messageMenu.addMenu("Mar&k as...")
        self.markAsMenu.addAction(self.junkAction)
        self.markAsMenu.addAction(self.notJunkAction)

        self.searchMenu = self.menuBar().addMenu("&Search")

        self.helpMenu = self.menuBar().addMenu("&Help")
        self.helpMenu.addAction(self.contentsAction)
        self.helpMenu.addAction(self.aboutAction)

    def createToolbars(self):
        self.toolbar = self.addToolBar('Main Toolbar')
        self.toolbar.setMovable(False)
        self.toolbar.addAction(self.newAction)
        self.toolbar.addSeparator()
        self.toolbar.addAction(self.sendReceiveAction)
        self.toolbar.addSeparator()
        self.toolbar.addAction(self.replyAction)
        self.toolbar.addAction(self.replyToAllAction)
        self.toolbar.addAction(self.forwardAction)
        self.toolbar.addSeparator()
        self.toolbar.addAction(self.printAction)
        self.toolbar.addAction(self.deleteAction)
        self.toolbar.addAction(self.junkAction)
        self.toolbar.addAction(self.notJunkAction)
        self.toolbar.addAction(self.cancelAction)
        self.toolbar.addSeparator()
        self.toolbar.addAction(self.previousAction)
        self.toolbar.addAction(self.nextAction)

    def createWidgets(self):
        ## Message Table
        self.table = QTableView()
        self.table.setEditTriggers(QAbstractItemView.NoEditTriggers)
        self.table.setSelectionBehavior(QAbstractItemView.SelectRows)
        self.table.setGridStyle(Qt.NoPen)

        self.model = QStandardItemModel(8, 3, self)
        self.model.setHeaderData(0, Qt.Horizontal, "From")
        self.model.setHeaderData(1, Qt.Horizontal, "Subject")
        self.model.setHeaderData(2, Qt.Horizontal, "Received")

        self.table.setModel(self.model)
        self.selectionModel = QItemSelectionModel(self.model)
        self.selectionModel.SelectionFlag = 0x0020
        self.table.setSelectionModel(self.selectionModel)
        self.table.horizontalHeader().setStretchLastSection(True)
        self.table.verticalHeader().setVisible(False)
        self.table.setSortingEnabled(True)
        self.table.setAlternatingRowColors(True)

        ## Folder Tree View
        self.folderTree = QTreeWidget()
        self.folderTree.setColumnCount(1)
        self.folderTree.setHeaderLabel(QString('Folders'))

        self.treeItem = QTreeWidgetItem()
        self.treeItem.setText(0, 'Folders')

        self.inbox = QTreeWidgetItem()
        self.inbox.setText(0, 'Inbox')

        self.deletedItems = QTreeWidgetItem()
        self.deletedItems.setText(0, 'Deleted Items')

        self.drafts = QTreeWidgetItem()
        self.drafts.setText(0, 'Drafts')

        self.junk = QTreeWidgetItem()
        self.junk.setText(0, 'Junk')

        self.outbox = QTreeWidgetItem()
        self.outbox.setText(0, 'Outbox')

        self.sent = QTreeWidgetItem()
        self.sent.setText(0, 'Sent')

        self.treeItem.addChild(self.inbox)
        self.treeItem.addChild(self.deletedItems)
        self.treeItem.addChild(self.drafts)
        self.treeItem.addChild(self.junk)
        self.treeItem.addChild(self.outbox)
        self.treeItem.addChild(self.sent)

        self.folderTree.addTopLevelItem(self.treeItem)
        self.folderTree.expandAll()
        self.folderTree.setAnimated(True)

        self.folderTree.setMaximumWidth(150)

        ## Temp. placeholders
        self.textEdit = QTextEdit()
        self.textEdit2 = QTextEdit()

    def createLayouts(self):
        self.mainSplitter = QSplitter()
        self.setCentralWidget(self.mainSplitter)

        self.mainSplitter.addWidget(self.folderTree)

        self.messageSplitter = QSplitter(Qt.Vertical)
        self.messageSplitter.addWidget(self.table)
        self.messageSplitter.addWidget(self.textEdit2)

        self.mainSplitter.addWidget(self.messageSplitter)

    def helpContents(self):
        print "Help"

    def reply(self):
        print "Reply"

    def replyToAll(self):
        print "Reply To All"

    def about(self):
        text = QString("GuloMail v0.1\n\n")
        text.append(
            "GuloMail is a freeware email client written in Python using PyQt4 (Python bindings for Nokia's Qt)\n\n"
        )
        text.append(QChar(0x00A9))
        text.append("GulonSoft 2010\nhttp://www.gulon.co.uk/")
        QMessageBox.about(self, "About GuloMail", text)
Beispiel #40
0
    def __init__(self, *args, **kwargs):
        super(ShortcutManagerDlg, self).__init__(*args, **kwargs)
        self.setWindowTitle("Shortcut Preferences")
        self.setMinimumWidth(500)
        self.setMinimumHeight(500)

        mgr = ShortcutManager()  # Singleton

        scrollWidget = QWidget(parent=self)
        tempLayout = QVBoxLayout(scrollWidget)
        scrollWidget.setSizePolicy(QSizePolicy.Expanding,
                                   QSizePolicy.Expanding)

        treeWidget = QTreeWidget(parent=scrollWidget)
        treeWidget.setHeaderLabels(["Action", "Shortcut"])
        treeWidget.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred)
        treeWidget.setColumnWidth(0, 300)
        treeWidget.setColumnWidth(1, 50)

        # Create a LineEdit for each shortcut,
        # and keep track of them in a dict
        shortcutEdits = collections.OrderedDict()
        for group, shortcutDict in mgr.shortcuts.items():
            groupItem = QTreeWidgetItem(treeWidget, QStringList(group))
            ListOfActions = set()
            for i, (shortcut, (desc, obj)) in enumerate(shortcutDict.items()):
                if desc in ListOfActions:
                    continue
                edit = QLineEdit(str(shortcut.key().toString()))
                shortcutEdits[shortcut] = edit
                item = QTreeWidgetItem(groupItem, QStringList(desc))
                item.setText(0, desc)
                ListOfActions.add(desc)
                treeWidget.setItemWidget(item, 1, edit)

        tempLayout.addWidget(treeWidget)

        # Add ok and cancel buttons
        buttonLayout = QHBoxLayout()
        cancelButton = QPushButton("Cancel")
        cancelButton.clicked.connect(self.reject)
        okButton = QPushButton("OK")
        okButton.clicked.connect(self.accept)
        okButton.setDefault(True)
        buttonLayout.addSpacerItem(QSpacerItem(10, 0, QSizePolicy.Expanding))
        buttonLayout.addWidget(cancelButton)
        buttonLayout.addWidget(okButton)
        tempLayout.addLayout(buttonLayout)

        scroll = QScrollArea(parent=self)
        scroll.setWidget(scrollWidget)
        scroll.setWidgetResizable(True)
        scroll.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred)
        dlgLayout = QVBoxLayout()
        dlgLayout.addWidget(scroll)
        self.setLayout(dlgLayout)

        # Show the window
        result = self.exec_()

        # If the user didn't hit "cancel", apply his changes to the manager's shortcuts
        if result == QDialog.Accepted:
            for shortcut, edit in shortcutEdits.items():
                oldKey = str(shortcut.key().toString()).lower()
                newKey = str(edit.text()).lower()

                if oldKey != newKey and newKey != "":
                    # Before we add this shortcut to our dict, disable any other shortcuts it replaces
                    conflicting_shortcuts = mgr._findExistingShortcuts(newKey)
                    for conflicted in conflicting_shortcuts:
                        conflicted.setKey(QKeySequence(""))
                        shortcutEdits[conflicted].setText("")
                    shortcut.setKey(QKeySequence(newKey))

                # Make sure the tooltips get updated.
                mgr.updateToolTip(shortcut)
            mgr.storeToPreferences()
Beispiel #41
0
    def createWidgets(self):
        ## Message Table
        self.table = QTableView()
        self.table.setEditTriggers(QAbstractItemView.NoEditTriggers)
        self.table.setSelectionBehavior(QAbstractItemView.SelectRows)
        self.table.setGridStyle(Qt.NoPen)

        self.model = QStandardItemModel(8, 3, self)
        self.model.setHeaderData(0, Qt.Horizontal, "From")
        self.model.setHeaderData(1, Qt.Horizontal, "Subject")
        self.model.setHeaderData(2, Qt.Horizontal, "Received")

        self.table.setModel(self.model)
        self.selectionModel = QItemSelectionModel(self.model)
        self.selectionModel.SelectionFlag = 0x0020
        self.table.setSelectionModel(self.selectionModel)
        self.table.horizontalHeader().setStretchLastSection(True)
        self.table.verticalHeader().setVisible(False)
        self.table.setSortingEnabled(True)
        self.table.setAlternatingRowColors(True)

        ## Folder Tree View
        self.folderTree = QTreeWidget()
        self.folderTree.setColumnCount(1)
        self.folderTree.setHeaderLabel(QString('Folders'))

        self.treeItem = QTreeWidgetItem()
        self.treeItem.setText(0, 'Folders')

        self.inbox = QTreeWidgetItem()
        self.inbox.setText(0, 'Inbox')

        self.deletedItems = QTreeWidgetItem()
        self.deletedItems.setText(0, 'Deleted Items')

        self.drafts = QTreeWidgetItem()
        self.drafts.setText(0, 'Drafts')

        self.junk = QTreeWidgetItem()
        self.junk.setText(0, 'Junk')

        self.outbox = QTreeWidgetItem()
        self.outbox.setText(0, 'Outbox')

        self.sent = QTreeWidgetItem()
        self.sent.setText(0, 'Sent')

        self.treeItem.addChild(self.inbox)
        self.treeItem.addChild(self.deletedItems)
        self.treeItem.addChild(self.drafts)
        self.treeItem.addChild(self.junk)
        self.treeItem.addChild(self.outbox)
        self.treeItem.addChild(self.sent)

        self.folderTree.addTopLevelItem(self.treeItem)
        self.folderTree.expandAll()
        self.folderTree.setAnimated(True)

        self.folderTree.setMaximumWidth(150)

        ## Temp. placeholders
        self.textEdit = QTextEdit()
        self.textEdit2 = QTextEdit()
Beispiel #42
0
    def __init__(self, parent=None, signalManager=None, name="KEGG Pathways"):
        OWWidget.__init__(self, parent, signalManager, name, wantGraph=True)
        self.inputs = [("Examples", Orange.data.Table, self.SetData),
                       ("Reference", Orange.data.Table, self.SetRefData)]
        self.outputs = [("Selected Examples", Orange.data.Table),
                        ("Unselected Examples", Orange.data.Table)]
        self.organismIndex = 0
        self.geneAttrIndex = 0
        self.autoCommit = False
        self.autoResize = True
        self.useReference = False
        self.useAttrNames = 0
        self.showOrthology = True

        self.loadSettings()

        self.organismCodes = []
        self._changedFlag = False

        self.controlArea.setMaximumWidth(250)
        box = OWGUI.widgetBox(self.controlArea, "Info")
        self.infoLabel = OWGUI.widgetLabel(box, "No data on input\n")

        # Organism selection.
        box = OWGUI.widgetBox(self.controlArea, "Organism")
        self.organismComboBox = OWGUI.comboBox(
            box, self, "organismIndex",
            items=[],
            callback=self.Update,
            addSpace=True,
            debuggingEnabled=0,
            tooltip="Select the organism of the input genes")

        # Selection of genes attribute
        box = OWGUI.widgetBox(self.controlArea, "Gene attribute")
        self.geneAttrCandidates = VariableListModel(parent=self)
        self.geneAttrCombo = OWGUI.comboBox(
            box, self, "geneAttrIndex", callback=self.Update)
        self.geneAttrCombo.setModel(self.geneAttrCandidates)

        OWGUI.checkBox(box, self, "useAttrNames",
                       "Use variable names",
                       disables=[(-1, self.geneAttrCombo)],
                       callback=self.Update)

        self.geneAttrCombo.setDisabled(bool(self.useAttrNames))

        OWGUI.separator(self.controlArea)

        OWGUI.checkBox(self.controlArea, self, "useReference",
                       "From signal",
                       box="Reference",
                       callback=self.Update)

        OWGUI.separator(self.controlArea)

        OWGUI.checkBox(self.controlArea, self, "showOrthology",
                       "Show pathways in full orthology",
                       box="Orthology",
                       callback=self.UpdateListView)

        OWGUI.checkBox(self.controlArea, self, "autoResize",
                       "Resize to fit",
                       box="Image",
                       callback=self.UpdatePathwayViewTransform)

        box = OWGUI.widgetBox(self.controlArea, "Cache Control")

        OWGUI.button(box, self, "Clear cache",
                     callback=self.ClearCache,
                     tooltip="Clear all locally cached KEGG data.")

        OWGUI.separator(self.controlArea)

        box = OWGUI.widgetBox(self.controlArea, "Selection")
        cb = OWGUI.checkBox(box, self, "autoCommit", "Commit on update")
        button = OWGUI.button(box, self, "Commit", callback=self.Commit,
                              default=True)
        OWGUI.setStopper(self, button, cb, "_changedFlag", self.Commit)

        OWGUI.rubber(self.controlArea)

        spliter = QSplitter(Qt.Vertical, self.mainArea)
        self.pathwayView = PathwayView(self, spliter)
        self.pathwayView.scene().selectionChanged.connect(
            self._onSelectionChanged
        )
        self.mainArea.layout().addWidget(spliter)

        self.listView = QTreeWidget(spliter)
        spliter.addWidget(self.listView)

        self.listView.setAllColumnsShowFocus(1)
        self.listView.setColumnCount(4)
        self.listView.setHeaderLabels(["Pathway", "P value",
                                       "Genes", "Reference"])

        self.listView.setSelectionMode(QTreeWidget.SingleSelection)

        self.listView.setSortingEnabled(True)

        self.listView.setMaximumHeight(200)

        self.connect(self.listView,
                     SIGNAL("itemSelectionChanged()"),
                     self.UpdatePathwayView)

        self.connect(self.graphButton,
                     SIGNAL("clicked()"),
                     self.saveGraph)

        select = QAction(
            "Select All", self,
            shortcut=QKeySequence.SelectAll
        )
        select.triggered.connect(self.selectAll)
        self.addAction(select)

        self.data = None
        self.refData = None

        self.resize(800, 600)

        self.connect(self,
                     SIGNAL("widgetStateChanged(QString, int, QString)"),
                     self.onStateChange)

        self.has_new_data = False
        self.has_new_reference_set = False

        self._executor = ThreadExecutor()
        self.setEnabled(False)
        self.setBlocking(True)
        QTimer.singleShot(0, self._initialize)
        self.infoLabel.setText("Fetching organism definitions\n")
Beispiel #43
0
    def __createLayout(self, action, title, files):
        """ Creates the dialog layout """

        self.resize(400, 300)
        self.setSizeGripEnabled(True)

        # Top level layout
        layout = QVBoxLayout(self)

        # Pixmap and the message
        topLayout = QHBoxLayout()
        pixmap = QLabel()
        pixmap.setPixmap(PixmapCache().getPixmap('warning.png'))
        topLayout.addWidget(pixmap)
        hSpacer = QWidget()
        hSpacer.setFixedSize(15, 15)
        topLayout.addWidget(hSpacer)
        message = QLabel( "All the project files must be " \
                          "saved before start debugging" )
        message.setAlignment(Qt.AlignHCenter | Qt.AlignVCenter)
        message.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        message.setWordWrap(True)
        topLayout.addWidget(message)
        layout.addLayout(topLayout)

        vSpacer = QWidget()
        vSpacer.setFixedSize(15, 15)
        layout.addWidget(vSpacer)

        layout.addWidget(QLabel(title + ":"))
        filesList = QTreeWidget()
        filesList.setRootIsDecorated(False)
        filesList.setAlternatingRowColors(True)
        filesList.setUniformRowHeights(True)
        filesList.setItemsExpandable(False)
        filesList.setItemDelegate(NoOutlineHeightDelegate(4))
        filesList.setSelectionMode(QAbstractItemView.NoSelection)
        filesList.setHeaderHidden(True)
        for item in files:
            fileName = item[0]
            fileItem = QTreeWidgetItem([fileName])
            fileType = detectFileType(fileName)
            fileItem.setIcon(0, getFileIcon(fileType))
            if fileType in [PythonFileType, Python3FileType]:
                infoSrc = GlobalData().briefModinfoCache
                info = infoSrc.get(fileName)
                if info.docstring is not None:
                    fileItem.setToolTip(0, info.docstring.text)
                else:
                    fileItem.setToolTip(0, "")
            filesList.addTopLevelItem(fileItem)
        layout.addWidget(filesList)

        # Buttons at the bottom
        buttonBox = QDialogButtonBox()
        buttonBox.setOrientation(Qt.Horizontal)
        buttonBox.setStandardButtons(QDialogButtonBox.Cancel)
        continueButton = buttonBox.addButton(action,
                                             QDialogButtonBox.ActionRole)
        continueButton.setDefault(True)
        layout.addWidget(buttonBox)

        continueButton.clicked.connect(self.accept)
        buttonBox.rejected.connect(self.close)
        continueButton.setFocus()
        return
Beispiel #44
0
class OWKEGGPathwayBrowser(OWWidget):
    settingsList = ["organismIndex", "geneAttrIndex", "autoCommit",
                    "autoResize", "useReference", "useAttrNames",
                    "showOrthology"]

    contextHandlers = {
        "": DomainContextHandler(
            "",
            [ContextField("organismIndex",
                          DomainContextHandler.Required +
                          DomainContextHandler.IncludeMetaAttributes),
             ContextField("geneAttrIndex",
                          DomainContextHandler.Required +
                          DomainContextHandler.IncludeMetaAttributes),
             ContextField("useAttrNames",
                          DomainContextHandler.Required +
                          DomainContextHandler.IncludeMetaAttributes)]
        )
    }

    def __init__(self, parent=None, signalManager=None, name="KEGG Pathways"):
        OWWidget.__init__(self, parent, signalManager, name, wantGraph=True)
        self.inputs = [("Examples", Orange.data.Table, self.SetData),
                       ("Reference", Orange.data.Table, self.SetRefData)]
        self.outputs = [("Selected Examples", Orange.data.Table),
                        ("Unselected Examples", Orange.data.Table)]
        self.organismIndex = 0
        self.geneAttrIndex = 0
        self.autoCommit = False
        self.autoResize = True
        self.useReference = False
        self.useAttrNames = 0
        self.showOrthology = True

        self.loadSettings()

        self.organismCodes = []
        self._changedFlag = False

        self.controlArea.setMaximumWidth(250)
        box = OWGUI.widgetBox(self.controlArea, "Info")
        self.infoLabel = OWGUI.widgetLabel(box, "No data on input\n")

        # Organism selection.
        box = OWGUI.widgetBox(self.controlArea, "Organism")
        self.organismComboBox = OWGUI.comboBox(
            box, self, "organismIndex",
            items=[],
            callback=self.Update,
            addSpace=True,
            debuggingEnabled=0,
            tooltip="Select the organism of the input genes")

        # Selection of genes attribute
        box = OWGUI.widgetBox(self.controlArea, "Gene attribute")
        self.geneAttrCandidates = VariableListModel(parent=self)
        self.geneAttrCombo = OWGUI.comboBox(
            box, self, "geneAttrIndex", callback=self.Update)
        self.geneAttrCombo.setModel(self.geneAttrCandidates)

        OWGUI.checkBox(box, self, "useAttrNames",
                       "Use variable names",
                       disables=[(-1, self.geneAttrCombo)],
                       callback=self.Update)

        self.geneAttrCombo.setDisabled(bool(self.useAttrNames))

        OWGUI.separator(self.controlArea)

        OWGUI.checkBox(self.controlArea, self, "useReference",
                       "From signal",
                       box="Reference",
                       callback=self.Update)

        OWGUI.separator(self.controlArea)

        OWGUI.checkBox(self.controlArea, self, "showOrthology",
                       "Show pathways in full orthology",
                       box="Orthology",
                       callback=self.UpdateListView)

        OWGUI.checkBox(self.controlArea, self, "autoResize",
                       "Resize to fit",
                       box="Image",
                       callback=self.UpdatePathwayViewTransform)

        box = OWGUI.widgetBox(self.controlArea, "Cache Control")

        OWGUI.button(box, self, "Clear cache",
                     callback=self.ClearCache,
                     tooltip="Clear all locally cached KEGG data.")

        OWGUI.separator(self.controlArea)

        box = OWGUI.widgetBox(self.controlArea, "Selection")
        cb = OWGUI.checkBox(box, self, "autoCommit", "Commit on update")
        button = OWGUI.button(box, self, "Commit", callback=self.Commit,
                              default=True)
        OWGUI.setStopper(self, button, cb, "_changedFlag", self.Commit)

        OWGUI.rubber(self.controlArea)

        spliter = QSplitter(Qt.Vertical, self.mainArea)
        self.pathwayView = PathwayView(self, spliter)
        self.pathwayView.scene().selectionChanged.connect(
            self._onSelectionChanged
        )
        self.mainArea.layout().addWidget(spliter)

        self.listView = QTreeWidget(spliter)
        spliter.addWidget(self.listView)

        self.listView.setAllColumnsShowFocus(1)
        self.listView.setColumnCount(4)
        self.listView.setHeaderLabels(["Pathway", "P value",
                                       "Genes", "Reference"])

        self.listView.setSelectionMode(QTreeWidget.SingleSelection)

        self.listView.setSortingEnabled(True)

        self.listView.setMaximumHeight(200)

        self.connect(self.listView,
                     SIGNAL("itemSelectionChanged()"),
                     self.UpdatePathwayView)

        self.connect(self.graphButton,
                     SIGNAL("clicked()"),
                     self.saveGraph)

        select = QAction(
            "Select All", self,
            shortcut=QKeySequence.SelectAll
        )
        select.triggered.connect(self.selectAll)
        self.addAction(select)

        self.data = None
        self.refData = None

        self.resize(800, 600)

        self.connect(self,
                     SIGNAL("widgetStateChanged(QString, int, QString)"),
                     self.onStateChange)

        self.has_new_data = False
        self.has_new_reference_set = False

        self._executor = ThreadExecutor()
        self.setEnabled(False)
        self.setBlocking(True)
        QTimer.singleShot(0, self._initialize)
        self.infoLabel.setText("Fetching organism definitions\n")

    def _initialize(self):
        # First try to import slumber to see if we can even use the
        # kegg module.
        try:
            import slumber
        except ImportError:
            QMessageBox.warning(self,
                "'slumber' library required.",
                '<p>Please install '
                '<a href="http://pypi.python.org/pypi/slumber">slumber</a> '
                'library to use KEGG Pathways widget.</p>'
            )
            self.infoLabel.setText(
                '<p>Please install '
                '<a href="http://pypi.python.org/pypi/slumber">slumber</a> '
                'library to use KEGG Pathways widget.</p>'
            )
            self.error(0, "Missing slumber/requests library")
            return

        progress = methodinvoke(self, "setProgress", (float,))

        def get_genome():
            """Return a KEGGGenome with the common org entries precached."""
            genome = kegg.KEGGGenome()

            essential = genome.essential_organisms()
            common = genome.common_organisms()
            # Remove duplicates of essential from common.
            # (essential + common list as defined here will be used in the
            # GUI.)
            common = [c for c in common if c not in essential]

            # TODO: Add option to specify additional organisms not
            # in the common list.

            keys = map(genome.org_code_to_entry_key, essential + common)

            genome.pre_cache(keys, progress_callback=progress)
            return (keys, genome)

        self._genomeTask = task = Task(function=get_genome)
        task.finished.connect(self._initializeOrganisms)

        self.progressBarInit()
        self._executor.submit(task)

    def _initializeOrganisms(self):
        self.progressBarFinished()
        try:
            keys, genome = self._genomeTask.result()
        except Exception as err:
            self.error(0, str(err))
            return

        entries = [genome[key] for key in keys]
        items = [entry.definition for entry in entries]
        codes = [entry.organism_code for entry in entries]

        self.organismCodes = codes
        self.organismComboBox.clear()
        self.organismComboBox.addItems(items)
        self.organismComboBox.setCurrentIndex(self.organismIndex)

        self.setEnabled(True)
        self.setBlocking(False)
        self.infoLabel.setText("No data on input\n")

    def Clear(self):
        """
        Clear the widget state.
        """
        self.queryGenes = []
        self.referenceGenes = []
        self.genes = {}
        self.uniqueGenesDict = {}
        self.revUniqueGenesDict = {}
        self.pathways = {}
        self.org = None
        self.geneAttrCandidates[:] = []

        self.infoLabel.setText("No data on input\n")
        self.listView.clear()
        self.pathwayView.SetPathway(None)

        self.send("Selected Examples", None)
        self.send("Unselected Examples", None)

    def SetData(self, data=None):
        self.closeContext()
        self.data = data
        self.warning(0)
        self.error(0)
        self.information(0)

        if data is not None:
            vars = data.domain.variables + data.domain.getmetas().values()
            vars = [var for var in vars
                    if isinstance(var, (Orange.feature.String,
                                        Orange.feature.Discrete))]
            self.geneAttrCandidates[:] = vars

            # Try to guess the gene name variable
            names_lower = [v.name.lower() for v in vars]
            scores = [(name == "gene", "gene" in name)
                      for name in names_lower]
            imax, _ = max(enumerate(scores), key=itemgetter(1))
            self.geneAttrIndex = imax

            taxid = data_hints.get_hint(data, "taxid", None)
            if taxid:
                try:
                    code = kegg.from_taxid(taxid)
                    self.organismIndex = self.organismCodes.index(code)
                except Exception as ex:
                    print ex, taxid

            self.useAttrNames = data_hints.get_hint(data, "genesinrows",
                                                    self.useAttrNames)

            self.openContext("", data)
        else:
            self.Clear()

        self.has_new_data = True

    def SetRefData(self, data=None):
        self.refData = data
        self.information(1)

        self.has_new_reference_set = True

    def handleNewSignals(self):
        if self.has_new_data or (self.has_new_reference_set and \
                                 self.useReference):
            self.Update()

            self.has_new_data = False
            self.has_new_reference_set = False

    def UpdateListView(self):
        self.bestPValueItem = None
        self.listView.clear()
        if not self.data:
            return

        allPathways = self.org.pathways()
        allRefPathways = kegg.pathways("map")

        items = []
        kegg_pathways = kegg.KEGGPathways()

        org_code = self.organismCodes[min(self.organismIndex,
                                          len(self.organismCodes) - 1)]

        if self.showOrthology:
            self.koOrthology = kegg.KEGGBrite("ko00001")
            self.listView.setRootIsDecorated(True)
            path_ids = set([s[-5:] for s in self.pathways.keys()])

            def _walkCollect(koEntry):
                num = koEntry.title[:5] if koEntry.title else None
                if num in path_ids:
                    return ([koEntry] +
                            reduce(lambda li, c: li + _walkCollect(c),
                                   [child for child in koEntry.entries],
                                   []))
                else:
                    c = reduce(lambda li, c: li + _walkCollect(c),
                               [child for child in koEntry.entries],
                               [])
                    return c + (c and [koEntry] or [])

            allClasses = reduce(lambda li1, li2: li1 + li2,
                                [_walkCollect(c) for c in self.koOrthology],
                                [])

            def _walkCreate(koEntry, lvItem):
                item = QTreeWidgetItem(lvItem)
                id = "path:" + org_code + koEntry.title[:5]

                if koEntry.title[:5] in path_ids:
                    p = kegg_pathways.get_entry(id)
                    if p is None:
                        # In case the genesets still have obsolete entries
                        name = koEntry.title
                    else:
                        name = p.name
                    genes, p_value, ref = self.pathways[id]
                    item.setText(0, name)
                    item.setText(1, "%.5f" % p_value)
                    item.setText(2, "%i of %i" % (len(genes), len(self.genes)))
                    item.setText(3, "%i of %i" % (ref, len(self.referenceGenes)))
                    item.pathway_id = id if p is not None else None
                else:
                    if id in allPathways:
                        text = kegg_pathways.get_entry(id).name
                    else:
                        text = koEntry.title
                    item.setText(0, text)

                    if id in allPathways:
                        item.pathway_id = id
                    elif "path:map" + koEntry.title[:5] in allRefPathways:
                        item.pathway_id = "path:map" + koEntry.title[:5]
                    else:
                        item.pathway_id = None

                for child in koEntry.entries:
                    if child in allClasses:
                        _walkCreate(child, item)

            for koEntry in self.koOrthology:
                if koEntry in allClasses:
                    _walkCreate(koEntry, self.listView)

            self.listView.update()
        else:
            self.listView.setRootIsDecorated(False)
            pathways = self.pathways.items()
            pathways.sort(lambda a, b: cmp(a[1][1], b[1][1]))

            for id, (genes, p_value, ref) in pathways:
                item = QTreeWidgetItem(self.listView)
                item.setText(0, kegg_pathways.get_entry(id).name)
                item.setText(1, "%.5f" % p_value)
                item.setText(2, "%i of %i" % (len(genes), len(self.genes)))
                item.setText(3, "%i of %i" % (ref, len(self.referenceGenes)))
                item.pathway_id = id
                items.append(item)

        self.bestPValueItem = items and items[0] or None
        self.listView.expandAll()
        for i in range(4):
            self.listView.resizeColumnToContents(i)

        if self.bestPValueItem:
            index = self.listView.indexFromItem(self.bestPValueItem)
            self.listView.selectionModel().select(
                index, QItemSelectionModel.ClearAndSelect
            )

    def UpdatePathwayView(self):
        items = self.listView.selectedItems()

        if len(items) > 0:
            item = items[0]
        else:
            item = None

        self.Commit()
        item = item or self.bestPValueItem
        if not item or not item.pathway_id:
            self.pathwayView.SetPathway(None)
            return

        def get_kgml_and_image(pathway_id):
            """Return an initialized KEGGPathway with pre-cached data"""
            p = kegg.KEGGPathway(pathway_id)
            p._get_kgml()  # makes sure the kgml file is downloaded
            p._get_image_filename()  # makes sure the image is downloaded
            return (pathway_id, p)

        self.setEnabled(False)
        self._pathwayTask = Task(
            function=lambda: get_kgml_and_image(item.pathway_id)
        )
        self._pathwayTask.finished.connect(self._onPathwayTaskFinshed)
        self._executor.submit(self._pathwayTask)

    def _onPathwayTaskFinshed(self):
        self.setEnabled(True)
        pathway_id, self.pathway = self._pathwayTask.result()
        self.pathwayView.SetPathway(
            self.pathway,
            self.pathways.get(pathway_id, [[]])[0]
        )

    def UpdatePathwayViewTransform(self):
        self.pathwayView.updateTransform()

    def Update(self):
        """
        Update (recompute enriched pathways) the widget state.
        """
        if not self.data:
            return

        self.error(0)
        self.information(0)

        # XXX: Check data in setData, do not even alow this to be executed if
        # data has no genes
        try:
            genes = self.GeneNamesFromData(self.data)
        except ValueError:
            self.error(0, "Cannot extract gene names from input.")
            genes = []

        if not self.useAttrNames and any("," in gene for gene in genes):
            genes = reduce(add, (split_and_strip(gene, ",")
                                 for gene in genes),
                           [])
            self.information(0,
                             "Separators detected in input gene names. "
                             "Assuming multiple genes per instance.")
        self.queryGenes = genes

        self.information(1)
        reference = None
        if self.useReference and self.refData:
            reference = self.GeneNamesFromData(self.refData)
            if not self.useAttrNames \
                    and any("," in gene for gene in reference):
                reference = reduce(add, (split_and_strip(gene, ",")
                                         for gene in reference),
                                   [])
                self.information(1,
                                 "Separators detected in reference gene "
                                 "names. Assuming multiple genes per "
                                 "instance.")

        org_code = self.SelectedOrganismCode()

        def run_enrichment(org_code, genes, reference=None, progress=None):
            org = kegg.KEGGOrganism(org_code)
            if reference is None:
                reference = org.get_genes()

            # Map 'genes' and 'reference' sets to unique KEGG identifiers
            unique_genes, _, _ = org.get_unique_gene_ids(set(genes))
            unique_ref_genes, _, _ = org.get_unique_gene_ids(set(reference))

            taxid = kegg.to_taxid(org.org_code)
            # Map the taxid back to standard 'common' taxids
            # (as used by 'geneset') if applicable
            r_tax_map = dict((v, k) for k, v in
                             kegg.KEGGGenome.TAXID_MAP.items())
            if taxid in r_tax_map:
                taxid = r_tax_map[taxid]

            # We use the kegg pathway gene sets provided by 'geneset' for
            # the enrichment calculation.

            # Ensure we are using the latest genesets
            # TODO: ?? Is updating the index enough?
            serverfiles.update(geneset.sfdomain, "index.pck")
            kegg_gs_collections = geneset.collections(
                (("KEGG", "pathways"), taxid)
            )
            pathways = pathway_enrichment(
                kegg_gs_collections, unique_genes.keys(),
                unique_ref_genes.keys(),
                callback=progress
            )
            # Ensure that pathway entries are pre-cached for later use in the
            # list/tree view
            kegg_pathways = kegg.KEGGPathways()
            kegg_pathways.pre_cache(
                pathways.keys(), progress_callback=progress
            )

            return pathways, org, unique_genes, unique_ref_genes

        self.progressBarInit()
        self.setEnabled(False)
        self.infoLabel.setText("Retrieving...\n")

        progress = methodinvoke(self, "setProgress", (float,))
        self._enrichTask = Task(
            function=lambda:
                run_enrichment(org_code, genes, reference, progress)
        )
        self._enrichTask.finished.connect(self._onEnrichTaskFinished)
        self._executor.submit(self._enrichTask)

    def _onEnrichTaskFinished(self):
        self.setEnabled(True)
        self.setBlocking(False)

        self.progressBarFinished()
        try:
            pathways, org, unique_genes, unique_ref_genes = \
                self._enrichTask.result()
        except Exception:
            raise

        self.org = org
        self.genes = unique_genes.keys()
        self.uniqueGenesDict = unique_genes
        self.revUniqueGenesDict = dict([(val, key) for key, val in
                                        self.uniqueGenesDict.items()])
        self.referenceGenes = unique_ref_genes.keys()
        self.pathways = pathways

        if not self.pathways:
            self.warning(0, "No enriched pathways found.")
        else:
            self.warning(0)

        count = len(set(self.queryGenes))
        self.infoLabel.setText(
            "%i unique gene names on input\n"
            "%i (%.1f%%) genes names matched" %
            (count, len(unique_genes),
             100.0 * len(unique_genes) / count if count else 0.0)
        )

        self.UpdateListView()

    @pyqtSlot(float)
    def setProgress(self, value):
        self.progressBarValue = value

    def GeneNamesFromData(self, data):
        """
        Extract and return gene names from `data`.
        """
        if self.useAttrNames:
            genes = [str(v.name).strip() for v in data.domain.attributes]
        elif self.geneAttrCandidates:
            index = min(self.geneAttrIndex, len(self.geneAttrCandidates) - 1)
            geneAttr = self.geneAttrCandidates[index]
            genes = [str(e[geneAttr]) for e in data
                     if not e[geneAttr].isSpecial()]
        else:
            raise ValueError("No gene names in data.")
        return genes

    def SelectedOrganismCode(self):
        """
        Return the selected organism code.
        """
        return self.organismCodes[min(self.organismIndex,
                                      len(self.organismCodes) - 1)]

    def selectAll(self):
        """
        Select all items in the pathway view.
        """
        changed = False
        scene = self.pathwayView.scene()
        with disconnected(scene.selectionChanged, self._onSelectionChanged):
            for item in scene.items():
                if item.flags() & QGraphicsItem.ItemIsSelectable and \
                        not item.isSelected():
                    item.setSelected(True)
                    changed = True
        if changed:
            self._onSelectionChanged()

    def _onSelectionChanged(self):
        # Item selection in the pathwayView/scene has changed
        if self.autoCommit:
            self.Commit()
        else:
            self._changedFlag = True

    def Commit(self):
        if self.data:
            selectedItems = self.pathwayView.scene().selectedItems()
            selectedGenes = reduce(set.union, [item.marked_objects
                                               for item in selectedItems],
                                   set())

            if self.useAttrNames:
                selectedVars = [self.data.domain[self.uniqueGenesDict[gene]]
                                for gene in selectedGenes]
                newDomain = Orange.data.Domain(selectedVars, 0)
                data = Orange.data.Table(newDomain, self.data)
                self.send("Selected Examples", data)
            elif self.geneAttrCandidates:
                geneAttr = self.geneAttrCandidates[min(self.geneAttrIndex,
                                                       len(self.geneAttrCandidates) - 1)]
                selectedExamples = []
                otherExamples = []
                for ex in self.data:
                    names = [self.revUniqueGenesDict.get(name, None)
                             for name in split_and_strip(str(ex[geneAttr]), ",")]
                    if any(name and name in selectedGenes for name in names):
                        selectedExamples.append(ex)
                    else:
                        otherExamples.append(ex)

                if selectedExamples:
                    selectedExamples = Orange.data.Table(selectedExamples)
                else:
                    selectedExamples = None

                if otherExamples:
                    otherExamples = Orange.data.Table(otherExamples)
                else:
                    otherExamples = None

                self.send("Selected Examples", selectedExamples)
                self.send("Unselected Examples", otherExamples)
        else:
            self.send("Selected Examples", None)
            self.send("Unselected Examples", None)

    def ClearCache(self):
        from ..kegg import caching
        try:
            caching.clear_cache()
        except Exception, ex:
            QMessageBox.warning(self, "Cache clear", ex.args[0])
Beispiel #45
0
 def event(self, event):
     if (event.type() == QEvent.KeyPress) and (event.key() == Qt.Key_Space):
         self.emit(SIGNAL("spacePressed"))
         return True
     return QTreeWidget.event(self, event)
Beispiel #46
0
class PluginsDialog(QDialog):
    " Codimension plugins dialog "

    def __init__(self, pluginManager, parent=None):
        QDialog.__init__(self, parent)
        self.setWindowTitle("Plugin Manager")

        self.__pluginManager = pluginManager
        self.__configFuncs = {}  # int -> callable

        self.__createLayout()
        self.__populate()

        self.__pluginsView.setFocus()
        self.__inItemChange = False
        return

    def __createLayout(self):
        " Creates the dialog layout "
        self.resize(640, 480)
        self.setSizeGripEnabled(True)

        layout = QVBoxLayout()

        # Plugins list
        self.__pluginsView = QTreeWidget()
        self.__pluginsView.setAlternatingRowColors(True)
        self.__pluginsView.setRootIsDecorated(False)
        self.__pluginsView.setItemsExpandable(False)
        self.__pluginsView.setSortingEnabled(True)
        self.__pluginsView.setItemDelegate(NoOutlineHeightDelegate(4))
        self.__pluginsView.setUniformRowHeights(True)

        # Alert | system/user | Enable | Name | Version
        self.__pluginsHeader = QTreeWidgetItem(
            ["", "", "", "Name", "Version", ""])
        self.__pluginsView.setHeaderItem(self.__pluginsHeader)
        self.__pluginsView.header().setSortIndicator(NAME_COL,
                                                     Qt.AscendingOrder)
        self.connect(self.__pluginsView, SIGNAL("itemSelectionChanged()"),
                     self.__pluginSelectionChanged)
        self.connect(self.__pluginsView,
                     SIGNAL("itemChanged(QTreeWidgetItem*,int)"),
                     self.__onItemChanged)

        layout.addWidget(self.__pluginsView)

        # Detailed information
        detailsLabel = QLabel("Detailed information")
        layout.addWidget(detailsLabel)
        self.__details = QTreeWidget()
        self.__details.setAlternatingRowColors(False)
        self.__details.setRootIsDecorated(False)
        self.__details.setItemsExpandable(False)
        self.__details.setSortingEnabled(False)
        self.__details.setItemDelegate(NoOutlineHeightDelegate(4))
        self.__details.setUniformRowHeights(True)

        detailsHeader = QTreeWidgetItem(["", ""])
        self.__details.setHeaderItem(detailsHeader)
        self.__details.setHeaderHidden(True)

        metrics = QFontMetrics(self.__details.font())
        rect = metrics.boundingRect("X")
        self.__details.setFixedHeight(rect.height() * 6 + 5)
        layout.addWidget(self.__details)

        # Errors/warnings
        errorsLabel = QLabel("Errors / warnings")
        layout.addWidget(errorsLabel)
        self.__errorsText = QTextEdit()
        self.__errorsText.setReadOnly(True)
        self.__errorsText.setAcceptRichText(False)
        metrics = QFontMetrics(self.__errorsText.font())
        rect = metrics.boundingRect("X")
        self.__errorsText.setFixedHeight(rect.height() * 4 + 5)
        layout.addWidget(self.__errorsText)

        # Buttons box
        buttonBox = QDialogButtonBox(self)
        buttonBox.setOrientation(Qt.Horizontal)
        buttonBox.setStandardButtons(QDialogButtonBox.Ok)
        self.__OKButton = buttonBox.button(QDialogButtonBox.Ok)
        self.__OKButton.setDefault(True)
        self.connect(buttonBox, SIGNAL("accepted()"), self.close)
        self.connect(buttonBox, SIGNAL("rejected()"), self.close)
        layout.addWidget(buttonBox)

        self.setLayout(layout)
        return

    def __createConfigButton(self):
        " Creates a configure button for a plugin "
        button = SettingsButton()
        self.connect(button, SIGNAL('CustomClick'), self.onPluginSettings)
        return button

    def __populate(self):
        " Populates the list with the plugins "
        index = 0

        for category in self.__pluginManager.activePlugins:
            for cdmPlugin in self.__pluginManager.activePlugins[category]:
                newItem = PluginItem(self.__pluginManager, cdmPlugin, True,
                                     category)
                self.__pluginsView.addTopLevelItem(newItem)
                settingsButton = self.__createConfigButton()

                try:
                    configFunction = cdmPlugin.getObject().getConfigFunction()
                    if configFunction is None:
                        settingsButton.setToolTip(
                            "Plugin does not need configuring")
                        settingsButton.setEnabled(False)
                    else:
                        settingsButton.setToolTip("Click to configure")
                        settingsButton.setEnabled(True)
                        self.__configFuncs[index] = configFunction
                        settingsButton.index = index
                        index += 1
                except Exception:
                    settingsButton.setToolTip(
                        "Bad plugin interface. No "
                        "configuration function received.")
                    settingsButton.setEnabled(False)

                self.__pluginsView.setItemWidget(newItem, SETTINGS_COL,
                                                 settingsButton)

        for category in self.__pluginManager.inactivePlugins:
            for cdmPlugin in self.__pluginManager.inactivePlugins[category]:
                newItem = PluginItem(self.__pluginManager, cdmPlugin, False,
                                     category)
                self.__pluginsView.addTopLevelItem(newItem)
                settingsButton = self.__createConfigButton()

                try:
                    configFunction = cdmPlugin.getObject().getConfigFunction()
                    if configFunction is None:
                        settingsButton.setToolTip(
                            "Plugin does not need configuring")
                        settingsButton.setEnabled(False)
                    else:
                        settingsButton.setToolTip(
                            "Enable plugin and then click to configure")
                        settingsButton.setEnabled(False)
                        self.__configFuncs[index] = configFunction
                        settingsButton.index = index
                        index += 1
                except:
                    settingsButton.setToolTip(
                        "Bad plugin interface. No "
                        "configuration function received.")
                    settingsButton.setEnabled(False)

                self.__pluginsView.setItemWidget(newItem, SETTINGS_COL,
                                                 settingsButton)

        for cdmPlugin in self.__pluginManager.unknownPlugins:
            newItem = PluginItem(self.__pluginManager, cdmPlugin, False, None)
            self.__pluginsView.addTopLevelItem(newItem)
            settingsButton = self.__createConfigButton()
            settingsButton.setToolTip("Unknown plugins are not configurable")
            settingsButton.setEnabled(False)
            self.__pluginsView.setItemWidget(newItem, SETTINGS_COL,
                                             settingsButton)

        self.__sortPlugins()
        self.__resizePlugins()
        return

    def __sortPlugins(self):
        " Sorts the plugins table "
        self.__pluginsView.sortItems(
            self.__pluginsView.sortColumn(),
            self.__pluginsView.header().sortIndicatorOrder())
        return

    def __resizePlugins(self):
        " Resizes the plugins table "
        self.__pluginsView.header().setStretchLastSection(False)
        self.__pluginsView.header().resizeSections(
            QHeaderView.ResizeToContents)
        self.__pluginsView.header().resizeSection(STATE_COL, 28)
        self.__pluginsView.header().setResizeMode(STATE_COL, QHeaderView.Fixed)
        self.__pluginsView.header().resizeSection(CONFLICT_COL, 28)
        self.__pluginsView.header().setResizeMode(CONFLICT_COL,
                                                  QHeaderView.Fixed)
        self.__pluginsView.header().resizeSection(TYPE_COL, 28)
        self.__pluginsView.header().setResizeMode(TYPE_COL, QHeaderView.Fixed)

        self.__pluginsView.header().setResizeMode(VERSION_COL,
                                                  QHeaderView.Stretch)
        self.__pluginsView.header().resizeSection(SETTINGS_COL, 24)
        self.__pluginsView.header().setResizeMode(SETTINGS_COL,
                                                  QHeaderView.Fixed)
        return

    def __pluginSelectionChanged(self):
        " Triggered when an item is selected "
        selected = list(self.__pluginsView.selectedItems())
        if selected:
            self.__updateDetails(selected[0])
        else:
            self.__updateDetails(None)
        return

    def __updateDetails(self, item):
        " Updates the content of the details and the error boxes "
        self.__details.clear()
        self.__errorsText.setText("")

        if item is None:
            return

        self.__details.addTopLevelItem(
            QTreeWidgetItem(["Author", item.plugin.getAuthor()]))
        self.__details.addTopLevelItem(
            QTreeWidgetItem(["Path",
                             os.path.normpath(item.plugin.getPath())]))
        self.__details.addTopLevelItem(
            QTreeWidgetItem(["Description",
                             item.plugin.getDescription()]))
        self.__details.addTopLevelItem(
            QTreeWidgetItem(["Web site", item.plugin.getWebsite()]))

        copyright = item.plugin.getCopyright()
        if copyright is not None:
            if copyright.lower() != "unknown":
                self.__details.addTopLevelItem(
                    QTreeWidgetItem(["Copyright", copyright]))

        for name in item.plugin.getDetails():
            value = item.plugin.getDetails()[name]
            self.__details.addTopLevelItem(QTreeWidgetItem([name, value]))

        self.__errorsText.setText(item.plugin.conflictMessage)
        return

    def __onItemChanged(self, item, column):
        " Triggered when an item is changed "

        if self.__inItemChange:
            return

        if item.active:
            self.__inItemChange = True
            item.plugin.disable()
            item.active = False

            settingsButton = self.__pluginsView.itemWidget(item, SETTINGS_COL)
            settingsButton.setEnabled(False)
            if settingsButton.index != -1:
                settingsButton.setToolTip(
                    "Enable plugin and then click to configure")

            if item.category in self.__pluginManager.inactivePlugins:
                self.__pluginManager.inactivePlugins[item.category].append(
                    item.plugin)
            else:
                self.__pluginManager.inactivePlugins[item.category] = [
                    item.plugin
                ]
            self.__pluginManager.activePlugins[item.category].remove(
                item.plugin)
            self.__pluginManager.saveDisabledPlugins()
            self.__inItemChange = False
            self.__pluginManager.sendPluginDeactivated(item.plugin)
            return

        self.__inItemChange = True
        message = self.__pluginManager.checkConflict(item.plugin)
        if message is not None:
            item.setCheckState(STATE_COL, Qt.Unchecked)
            self.__errorsText.setText(message)
            self.__inItemChange = False
            return

        try:
            item.plugin.enable()
            item.active = True
            if item.category in self.__pluginManager.activePlugins:
                self.__pluginManager.activePlugins[item.category].append(
                    item.plugin)
            else:
                self.__pluginManager.activePlugins[item.category] = [
                    item.plugin
                ]
            self.__pluginManager.inactivePlugins[item.category].remove(
                item.plugin)
            self.__pluginManager.saveDisabledPlugins()
            self.__errorsText.setText("")
            item.setIcon(CONFLICT_COL, PixmapCache().getIcon('empty.png'))
            item.setToolTip(CONFLICT_COL, "")

            settingsButton = self.__pluginsView.itemWidget(item, SETTINGS_COL)
            if settingsButton.index != -1:
                settingsButton.setToolTip("Click to configure")
                settingsButton.setEnabled(True)
            self.__pluginManager.sendPluginActivated(item.plugin)
        except:
            item.setCheckState(STATE_COL, Qt.Unchecked)
            self.__errorsText.setText(
                "Error activating the plugin - exception is generated")

        self.__inItemChange = False
        return

    def onPluginSettings(self, index):
        " Triggered when a configuring function is called "
        if index not in self.__configFuncs:
            return

        try:
            self.__configFuncs[index]()
        except Exception, exc:
            logging.error("Error calling the plugin configuration function. "
                          "Message: " + str(exc))
        return
Beispiel #47
0
 def mousePressEvent(self, event):
     """ Mouse press event to manage the layers drag """
     if ( event.button() == Qt.LeftButton ):
         self.lastPressPos = event.pos()
         self.bMousePressedFlag = True
     QTreeWidget.mousePressEvent( self, event )
Beispiel #48
0
    def __createLayout(self):
        " Creates the dialog layout "
        self.resize(640, 480)
        self.setSizeGripEnabled(True)

        layout = QVBoxLayout()

        # Plugins list
        self.__pluginsView = QTreeWidget()
        self.__pluginsView.setAlternatingRowColors(True)
        self.__pluginsView.setRootIsDecorated(False)
        self.__pluginsView.setItemsExpandable(False)
        self.__pluginsView.setSortingEnabled(True)
        self.__pluginsView.setItemDelegate(NoOutlineHeightDelegate(4))
        self.__pluginsView.setUniformRowHeights(True)

        # Alert | system/user | Enable | Name | Version
        self.__pluginsHeader = QTreeWidgetItem(
            ["", "", "", "Name", "Version", ""])
        self.__pluginsView.setHeaderItem(self.__pluginsHeader)
        self.__pluginsView.header().setSortIndicator(NAME_COL,
                                                     Qt.AscendingOrder)
        self.connect(self.__pluginsView, SIGNAL("itemSelectionChanged()"),
                     self.__pluginSelectionChanged)
        self.connect(self.__pluginsView,
                     SIGNAL("itemChanged(QTreeWidgetItem*,int)"),
                     self.__onItemChanged)

        layout.addWidget(self.__pluginsView)

        # Detailed information
        detailsLabel = QLabel("Detailed information")
        layout.addWidget(detailsLabel)
        self.__details = QTreeWidget()
        self.__details.setAlternatingRowColors(False)
        self.__details.setRootIsDecorated(False)
        self.__details.setItemsExpandable(False)
        self.__details.setSortingEnabled(False)
        self.__details.setItemDelegate(NoOutlineHeightDelegate(4))
        self.__details.setUniformRowHeights(True)

        detailsHeader = QTreeWidgetItem(["", ""])
        self.__details.setHeaderItem(detailsHeader)
        self.__details.setHeaderHidden(True)

        metrics = QFontMetrics(self.__details.font())
        rect = metrics.boundingRect("X")
        self.__details.setFixedHeight(rect.height() * 6 + 5)
        layout.addWidget(self.__details)

        # Errors/warnings
        errorsLabel = QLabel("Errors / warnings")
        layout.addWidget(errorsLabel)
        self.__errorsText = QTextEdit()
        self.__errorsText.setReadOnly(True)
        self.__errorsText.setAcceptRichText(False)
        metrics = QFontMetrics(self.__errorsText.font())
        rect = metrics.boundingRect("X")
        self.__errorsText.setFixedHeight(rect.height() * 4 + 5)
        layout.addWidget(self.__errorsText)

        # Buttons box
        buttonBox = QDialogButtonBox(self)
        buttonBox.setOrientation(Qt.Horizontal)
        buttonBox.setStandardButtons(QDialogButtonBox.Ok)
        self.__OKButton = buttonBox.button(QDialogButtonBox.Ok)
        self.__OKButton.setDefault(True)
        self.connect(buttonBox, SIGNAL("accepted()"), self.close)
        self.connect(buttonBox, SIGNAL("rejected()"), self.close)
        layout.addWidget(buttonBox)

        self.setLayout(layout)
        return
Beispiel #49
0
class PythonConsoleWidget(QWidget):
    def __init__(self, parent=None):
        QWidget.__init__(self, parent)
        self.setWindowTitle(
            QCoreApplication.translate("PythonConsole", "Python Console"))

        self.settings = QSettings()

        self.shell = ShellScintilla(self)
        self.setFocusProxy(self.shell)
        self.shellOut = ShellOutputScintilla(self)
        self.tabEditorWidget = EditorTabWidget(self)

        ##------------ UI -------------------------------

        self.splitterEditor = QSplitter(self)
        self.splitterEditor.setOrientation(Qt.Horizontal)
        self.splitterEditor.setHandleWidth(6)
        self.splitterEditor.setChildrenCollapsible(True)

        self.shellOutWidget = QWidget(self)
        self.shellOutWidget.setLayout(QVBoxLayout())
        self.shellOutWidget.layout().setContentsMargins(0, 0, 0, 0)
        self.shellOutWidget.layout().addWidget(self.shellOut)

        self.splitter = QSplitter(self.splitterEditor)
        self.splitter.setOrientation(Qt.Vertical)
        self.splitter.setHandleWidth(3)
        self.splitter.setChildrenCollapsible(False)
        self.splitter.addWidget(self.shellOutWidget)
        self.splitter.addWidget(self.shell)

        #self.splitterEditor.addWidget(self.tabEditorWidget)

        self.splitterObj = QSplitter(self.splitterEditor)
        self.splitterObj.setHandleWidth(3)
        self.splitterObj.setOrientation(Qt.Horizontal)
        #self.splitterObj.setSizes([0, 0])
        #self.splitterObj.setStretchFactor(0, 1)

        self.widgetEditor = QWidget(self.splitterObj)
        self.widgetFind = QWidget(self)

        self.listClassMethod = QTreeWidget(self.splitterObj)
        self.listClassMethod.setColumnCount(2)
        objInspLabel = QCoreApplication.translate("PythonConsole",
                                                  "Object Inspector")
        self.listClassMethod.setHeaderLabels([objInspLabel, ''])
        self.listClassMethod.setColumnHidden(1, True)
        self.listClassMethod.setAlternatingRowColors(True)

        #self.splitterEditor.addWidget(self.widgetEditor)
        #self.splitterObj.addWidget(self.listClassMethod)
        #self.splitterObj.addWidget(self.widgetEditor)

        # Hide side editor on start up
        self.splitterObj.hide()
        self.listClassMethod.hide()
        # Hide search widget on start up
        self.widgetFind.hide()

        sizes = self.splitter.sizes()
        self.splitter.setSizes(sizes)

        ##----------------Restore Settings------------------------------------

        self.restoreSettingsConsole()

        ##------------------Toolbar Editor-------------------------------------

        ## Action for Open File
        openFileBt = QCoreApplication.translate("PythonConsole", "Open file")
        self.openFileButton = QAction(self)
        self.openFileButton.setCheckable(False)
        self.openFileButton.setEnabled(True)
        self.openFileButton.setIcon(
            QgsApplication.getThemeIcon("console/iconOpenConsole.png"))
        self.openFileButton.setMenuRole(QAction.PreferencesRole)
        self.openFileButton.setIconVisibleInMenu(True)
        self.openFileButton.setToolTip(openFileBt)
        self.openFileButton.setText(openFileBt)

        openExtEditorBt = QCoreApplication.translate(
            "PythonConsole", "Open in external editor")
        self.openInEditorButton = QAction(self)
        self.openInEditorButton.setCheckable(False)
        self.openInEditorButton.setEnabled(True)
        self.openInEditorButton.setIcon(
            QgsApplication.getThemeIcon("console/iconShowEditorConsole.png"))
        self.openInEditorButton.setMenuRole(QAction.PreferencesRole)
        self.openInEditorButton.setIconVisibleInMenu(True)
        self.openInEditorButton.setToolTip(openExtEditorBt)
        self.openInEditorButton.setText(openExtEditorBt)
        ## Action for Save File
        saveFileBt = QCoreApplication.translate("PythonConsole", "Save")
        self.saveFileButton = QAction(self)
        self.saveFileButton.setCheckable(False)
        self.saveFileButton.setEnabled(False)
        self.saveFileButton.setIcon(
            QgsApplication.getThemeIcon("console/iconSaveConsole.png"))
        self.saveFileButton.setMenuRole(QAction.PreferencesRole)
        self.saveFileButton.setIconVisibleInMenu(True)
        self.saveFileButton.setToolTip(saveFileBt)
        self.saveFileButton.setText(saveFileBt)
        ## Action for Save File As
        saveAsFileBt = QCoreApplication.translate("PythonConsole",
                                                  "Save As...")
        self.saveAsFileButton = QAction(self)
        self.saveAsFileButton.setCheckable(False)
        self.saveAsFileButton.setEnabled(True)
        self.saveAsFileButton.setIcon(
            QgsApplication.getThemeIcon("console/iconSaveAsConsole.png"))
        self.saveAsFileButton.setMenuRole(QAction.PreferencesRole)
        self.saveAsFileButton.setIconVisibleInMenu(True)
        self.saveAsFileButton.setToolTip(saveAsFileBt)
        self.saveAsFileButton.setText(saveAsFileBt)
        ## Action Cut
        cutEditorBt = QCoreApplication.translate("PythonConsole", "Cut")
        self.cutEditorButton = QAction(self)
        self.cutEditorButton.setCheckable(False)
        self.cutEditorButton.setEnabled(True)
        self.cutEditorButton.setIcon(
            QgsApplication.getThemeIcon("console/iconCutEditorConsole.png"))
        self.cutEditorButton.setMenuRole(QAction.PreferencesRole)
        self.cutEditorButton.setIconVisibleInMenu(True)
        self.cutEditorButton.setToolTip(cutEditorBt)
        self.cutEditorButton.setText(cutEditorBt)
        ## Action Copy
        copyEditorBt = QCoreApplication.translate("PythonConsole", "Copy")
        self.copyEditorButton = QAction(self)
        self.copyEditorButton.setCheckable(False)
        self.copyEditorButton.setEnabled(True)
        self.copyEditorButton.setIcon(
            QgsApplication.getThemeIcon("console/iconCopyEditorConsole.png"))
        self.copyEditorButton.setMenuRole(QAction.PreferencesRole)
        self.copyEditorButton.setIconVisibleInMenu(True)
        self.copyEditorButton.setToolTip(copyEditorBt)
        self.copyEditorButton.setText(copyEditorBt)
        ## Action Paste
        pasteEditorBt = QCoreApplication.translate("PythonConsole", "Paste")
        self.pasteEditorButton = QAction(self)
        self.pasteEditorButton.setCheckable(False)
        self.pasteEditorButton.setEnabled(True)
        self.pasteEditorButton.setIcon(
            QgsApplication.getThemeIcon("console/iconPasteEditorConsole.png"))
        self.pasteEditorButton.setMenuRole(QAction.PreferencesRole)
        self.pasteEditorButton.setIconVisibleInMenu(True)
        self.pasteEditorButton.setToolTip(pasteEditorBt)
        self.pasteEditorButton.setText(pasteEditorBt)
        ## Action Run Script (subprocess)
        runScriptEditorBt = QCoreApplication.translate("PythonConsole",
                                                       "Run script")
        self.runScriptEditorButton = QAction(self)
        self.runScriptEditorButton.setCheckable(False)
        self.runScriptEditorButton.setEnabled(True)
        self.runScriptEditorButton.setIcon(
            QgsApplication.getThemeIcon("console/iconRunScriptConsole.png"))
        self.runScriptEditorButton.setMenuRole(QAction.PreferencesRole)
        self.runScriptEditorButton.setIconVisibleInMenu(True)
        self.runScriptEditorButton.setToolTip(runScriptEditorBt)
        self.runScriptEditorButton.setText(runScriptEditorBt)
        ## Action Run Script (subprocess)
        commentEditorBt = QCoreApplication.translate("PythonConsole",
                                                     "Comment")
        self.commentEditorButton = QAction(self)
        self.commentEditorButton.setCheckable(False)
        self.commentEditorButton.setEnabled(True)
        self.commentEditorButton.setIcon(
            QgsApplication.getThemeIcon(
                "console/iconCommentEditorConsole.png"))
        self.commentEditorButton.setMenuRole(QAction.PreferencesRole)
        self.commentEditorButton.setIconVisibleInMenu(True)
        self.commentEditorButton.setToolTip(commentEditorBt)
        self.commentEditorButton.setText(commentEditorBt)
        ## Action Run Script (subprocess)
        uncommentEditorBt = QCoreApplication.translate("PythonConsole",
                                                       "Uncomment")
        self.uncommentEditorButton = QAction(self)
        self.uncommentEditorButton.setCheckable(False)
        self.uncommentEditorButton.setEnabled(True)
        self.uncommentEditorButton.setIcon(
            QgsApplication.getThemeIcon(
                "console/iconUncommentEditorConsole.png"))
        self.uncommentEditorButton.setMenuRole(QAction.PreferencesRole)
        self.uncommentEditorButton.setIconVisibleInMenu(True)
        self.uncommentEditorButton.setToolTip(uncommentEditorBt)
        self.uncommentEditorButton.setText(uncommentEditorBt)
        ## Action for Object browser
        objList = QCoreApplication.translate("PythonConsole",
                                             "Object Inspector")
        self.objectListButton = QAction(self)
        self.objectListButton.setCheckable(True)
        self.objectListButton.setEnabled(
            self.settings.value("pythonConsole/enableObjectInsp",
                                False,
                                type=bool))
        self.objectListButton.setIcon(
            QgsApplication.getThemeIcon("console/iconClassBrowserConsole.png"))
        self.objectListButton.setMenuRole(QAction.PreferencesRole)
        self.objectListButton.setIconVisibleInMenu(True)
        self.objectListButton.setToolTip(objList)
        self.objectListButton.setText(objList)
        ## Action for Find text
        findText = QCoreApplication.translate("PythonConsole", "Find Text")
        self.findTextButton = QAction(self)
        self.findTextButton.setCheckable(True)
        self.findTextButton.setEnabled(True)
        self.findTextButton.setIcon(
            QgsApplication.getThemeIcon("console/iconSearchEditorConsole.png"))
        self.findTextButton.setMenuRole(QAction.PreferencesRole)
        self.findTextButton.setIconVisibleInMenu(True)
        self.findTextButton.setToolTip(findText)
        self.findTextButton.setText(findText)

        ##----------------Toolbar Console-------------------------------------

        ## Action Show Editor
        showEditor = QCoreApplication.translate("PythonConsole", "Show editor")
        self.showEditorButton = QAction(self)
        self.showEditorButton.setEnabled(True)
        self.showEditorButton.setCheckable(True)
        self.showEditorButton.setIcon(
            QgsApplication.getThemeIcon("console/iconShowEditorConsole.png"))
        self.showEditorButton.setMenuRole(QAction.PreferencesRole)
        self.showEditorButton.setIconVisibleInMenu(True)
        self.showEditorButton.setToolTip(showEditor)
        self.showEditorButton.setText(showEditor)
        ## Action for Clear button
        clearBt = QCoreApplication.translate("PythonConsole", "Clear console")
        self.clearButton = QAction(self)
        self.clearButton.setCheckable(False)
        self.clearButton.setEnabled(True)
        self.clearButton.setIcon(
            QgsApplication.getThemeIcon("console/iconClearConsole.png"))
        self.clearButton.setMenuRole(QAction.PreferencesRole)
        self.clearButton.setIconVisibleInMenu(True)
        self.clearButton.setToolTip(clearBt)
        self.clearButton.setText(clearBt)
        ## Action for settings
        optionsBt = QCoreApplication.translate("PythonConsole", "Settings")
        self.optionsButton = QAction(self)
        self.optionsButton.setCheckable(False)
        self.optionsButton.setEnabled(True)
        self.optionsButton.setIcon(
            QgsApplication.getThemeIcon("console/iconSettingsConsole.png"))
        self.optionsButton.setMenuRole(QAction.PreferencesRole)
        self.optionsButton.setIconVisibleInMenu(True)
        self.optionsButton.setToolTip(optionsBt)
        self.optionsButton.setText(optionsBt)
        ## Action menu for class
        actionClassBt = QCoreApplication.translate("PythonConsole",
                                                   "Import Class")
        self.actionClass = QAction(self)
        self.actionClass.setCheckable(False)
        self.actionClass.setEnabled(True)
        self.actionClass.setIcon(
            QgsApplication.getThemeIcon("console/iconClassConsole.png"))
        self.actionClass.setMenuRole(QAction.PreferencesRole)
        self.actionClass.setIconVisibleInMenu(True)
        self.actionClass.setToolTip(actionClassBt)
        self.actionClass.setText(actionClassBt)
        ## Import Processing class
        loadProcessingBt = QCoreApplication.translate(
            "PythonConsole", "Import Processing class")
        self.loadProcessingButton = QAction(self)
        self.loadProcessingButton.setCheckable(False)
        self.loadProcessingButton.setEnabled(True)
        self.loadProcessingButton.setIcon(
            QgsApplication.getThemeIcon("console/iconProcessingConsole.png"))
        self.loadProcessingButton.setMenuRole(QAction.PreferencesRole)
        self.loadProcessingButton.setIconVisibleInMenu(True)
        self.loadProcessingButton.setToolTip(loadProcessingBt)
        self.loadProcessingButton.setText(loadProcessingBt)
        ## Import QtCore class
        loadQtCoreBt = QCoreApplication.translate("PythonConsole",
                                                  "Import PyQt.QtCore class")
        self.loadQtCoreButton = QAction(self)
        self.loadQtCoreButton.setCheckable(False)
        self.loadQtCoreButton.setEnabled(True)
        self.loadQtCoreButton.setIcon(
            QgsApplication.getThemeIcon("console/iconQtCoreConsole.png"))
        self.loadQtCoreButton.setMenuRole(QAction.PreferencesRole)
        self.loadQtCoreButton.setIconVisibleInMenu(True)
        self.loadQtCoreButton.setToolTip(loadQtCoreBt)
        self.loadQtCoreButton.setText(loadQtCoreBt)
        ## Import QtGui class
        loadQtGuiBt = QCoreApplication.translate("PythonConsole",
                                                 "Import PyQt.QtGui class")
        self.loadQtGuiButton = QAction(self)
        self.loadQtGuiButton.setCheckable(False)
        self.loadQtGuiButton.setEnabled(True)
        self.loadQtGuiButton.setIcon(
            QgsApplication.getThemeIcon("console/iconQtGuiConsole.png"))
        self.loadQtGuiButton.setMenuRole(QAction.PreferencesRole)
        self.loadQtGuiButton.setIconVisibleInMenu(True)
        self.loadQtGuiButton.setToolTip(loadQtGuiBt)
        self.loadQtGuiButton.setText(loadQtGuiBt)
        ## Action for Run script
        runBt = QCoreApplication.translate("PythonConsole", "Run command")
        self.runButton = QAction(self)
        self.runButton.setCheckable(False)
        self.runButton.setEnabled(True)
        self.runButton.setIcon(
            QgsApplication.getThemeIcon("console/iconRunConsole.png"))
        self.runButton.setMenuRole(QAction.PreferencesRole)
        self.runButton.setIconVisibleInMenu(True)
        self.runButton.setToolTip(runBt)
        self.runButton.setText(runBt)
        ## Help action
        helpBt = QCoreApplication.translate("PythonConsole", "Help")
        self.helpButton = QAction(self)
        self.helpButton.setCheckable(False)
        self.helpButton.setEnabled(True)
        self.helpButton.setIcon(
            QgsApplication.getThemeIcon("console/iconHelpConsole.png"))
        self.helpButton.setMenuRole(QAction.PreferencesRole)
        self.helpButton.setIconVisibleInMenu(True)
        self.helpButton.setToolTip(helpBt)
        self.helpButton.setText(helpBt)

        self.toolBar = QToolBar()
        self.toolBar.setEnabled(True)
        self.toolBar.setFocusPolicy(Qt.NoFocus)
        self.toolBar.setContextMenuPolicy(Qt.DefaultContextMenu)
        self.toolBar.setLayoutDirection(Qt.LeftToRight)
        self.toolBar.setIconSize(QSize(16, 16))
        self.toolBar.setMovable(False)
        self.toolBar.setFloatable(False)
        self.toolBar.addAction(self.clearButton)
        self.toolBar.addAction(self.actionClass)
        self.toolBar.addAction(self.runButton)
        self.toolBar.addSeparator()
        self.toolBar.addAction(self.showEditorButton)
        self.toolBar.addSeparator()
        self.toolBar.addAction(self.optionsButton)
        self.toolBar.addAction(self.helpButton)

        self.toolBarEditor = QToolBar()
        self.toolBarEditor.setEnabled(False)
        self.toolBarEditor.setFocusPolicy(Qt.NoFocus)
        self.toolBarEditor.setContextMenuPolicy(Qt.DefaultContextMenu)
        self.toolBarEditor.setLayoutDirection(Qt.LeftToRight)
        self.toolBarEditor.setIconSize(QSize(16, 16))
        self.toolBarEditor.setMovable(False)
        self.toolBarEditor.setFloatable(False)
        self.toolBarEditor.addAction(self.openFileButton)
        self.toolBarEditor.addAction(self.openInEditorButton)
        self.toolBarEditor.addSeparator()
        self.toolBarEditor.addAction(self.saveFileButton)
        self.toolBarEditor.addAction(self.saveAsFileButton)
        self.toolBarEditor.addSeparator()
        self.toolBarEditor.addAction(self.runScriptEditorButton)
        self.toolBarEditor.addSeparator()
        self.toolBarEditor.addAction(self.findTextButton)
        self.toolBarEditor.addSeparator()
        self.toolBarEditor.addAction(self.cutEditorButton)
        self.toolBarEditor.addAction(self.copyEditorButton)
        self.toolBarEditor.addAction(self.pasteEditorButton)
        self.toolBarEditor.addSeparator()
        self.toolBarEditor.addAction(self.commentEditorButton)
        self.toolBarEditor.addAction(self.uncommentEditorButton)
        self.toolBarEditor.addSeparator()
        self.toolBarEditor.addAction(self.objectListButton)

        ## Menu Import Class
        self.classMenu = QMenu()
        self.classMenu.addAction(self.loadProcessingButton)
        self.classMenu.addAction(self.loadQtCoreButton)
        self.classMenu.addAction(self.loadQtGuiButton)
        cM = self.toolBar.widgetForAction(self.actionClass)
        cM.setMenu(self.classMenu)
        cM.setPopupMode(QToolButton.InstantPopup)

        self.widgetButton = QWidget()
        sizePolicy = QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Preferred)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(
            self.widgetButton.sizePolicy().hasHeightForWidth())
        self.widgetButton.setSizePolicy(sizePolicy)

        self.widgetButtonEditor = QWidget(self.widgetEditor)
        sizePolicy = QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Preferred)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(
            self.widgetButtonEditor.sizePolicy().hasHeightForWidth())
        self.widgetButtonEditor.setSizePolicy(sizePolicy)

        sizePolicy = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(
            self.shellOut.sizePolicy().hasHeightForWidth())
        self.shellOut.setSizePolicy(sizePolicy)

        self.shellOut.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded)
        self.shell.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded)

        ##------------ Layout -------------------------------

        self.mainLayout = QGridLayout(self)
        self.mainLayout.setMargin(0)
        self.mainLayout.setSpacing(0)
        self.mainLayout.addWidget(self.widgetButton, 0, 0, 1, 1)
        self.mainLayout.addWidget(self.splitterEditor, 0, 1, 1, 1)

        self.shellOutWidget.layout().insertWidget(0, self.toolBar)

        self.layoutEditor = QGridLayout(self.widgetEditor)
        self.layoutEditor.setMargin(0)
        self.layoutEditor.setSpacing(0)
        self.layoutEditor.addWidget(self.toolBarEditor, 0, 1, 1, 1)
        self.layoutEditor.addWidget(self.widgetButtonEditor, 1, 0, 2, 1)
        self.layoutEditor.addWidget(self.tabEditorWidget, 1, 1, 1, 1)
        self.layoutEditor.addWidget(self.widgetFind, 2, 1, 1, 1)

        ## Layout for the find widget
        self.layoutFind = QGridLayout(self.widgetFind)
        self.layoutFind.setContentsMargins(0, 0, 0, 0)
        self.lineEditFind = QgsFilterLineEdit()
        placeHolderTxt = QCoreApplication.translate("PythonConsole",
                                                    "Enter text to find...")

        if pyqtconfig.Configuration().qt_version >= 0x40700:
            self.lineEditFind.setPlaceholderText(placeHolderTxt)
        else:
            self.lineEditFind.setToolTip(placeHolderTxt)
        self.findNextButton = QToolButton()
        self.findNextButton.setEnabled(False)
        toolTipfindNext = QCoreApplication.translate("PythonConsole",
                                                     "Find Next")
        self.findNextButton.setToolTip(toolTipfindNext)
        self.findNextButton.setIcon(
            QgsApplication.getThemeIcon(
                "console/iconSearchNextEditorConsole.png"))
        self.findNextButton.setIconSize(QSize(24, 24))
        self.findNextButton.setAutoRaise(True)
        self.findPrevButton = QToolButton()
        self.findPrevButton.setEnabled(False)
        toolTipfindPrev = QCoreApplication.translate("PythonConsole",
                                                     "Find Previous")
        self.findPrevButton.setToolTip(toolTipfindPrev)
        self.findPrevButton.setIcon(
            QgsApplication.getThemeIcon(
                "console/iconSearchPrevEditorConsole.png"))
        self.findPrevButton.setIconSize(QSize(24, 24))
        self.findPrevButton.setAutoRaise(True)
        self.caseSensitive = QCheckBox()
        caseSensTr = QCoreApplication.translate("PythonConsole",
                                                "Case Sensitive")
        self.caseSensitive.setText(caseSensTr)
        self.wholeWord = QCheckBox()
        wholeWordTr = QCoreApplication.translate("PythonConsole", "Whole Word")
        self.wholeWord.setText(wholeWordTr)
        self.wrapAround = QCheckBox()
        self.wrapAround.setChecked(True)
        wrapAroundTr = QCoreApplication.translate("PythonConsole",
                                                  "Wrap Around")
        self.wrapAround.setText(wrapAroundTr)
        self.layoutFind.addWidget(self.lineEditFind, 0, 1, 1, 1)
        self.layoutFind.addWidget(self.findPrevButton, 0, 2, 1, 1)
        self.layoutFind.addWidget(self.findNextButton, 0, 3, 1, 1)
        self.layoutFind.addWidget(self.caseSensitive, 0, 4, 1, 1)
        self.layoutFind.addWidget(self.wholeWord, 0, 5, 1, 1)
        self.layoutFind.addWidget(self.wrapAround, 0, 6, 1, 1)

        ##------------ Add first Tab in Editor -------------------------------

        #self.tabEditorWidget.newTabEditor(tabName='first', filename=None)

        ##------------ Signal -------------------------------

        self.findTextButton.toggled.connect(self.findTextEditor)
        self.objectListButton.toggled.connect(self.toggleObjectListWidget)
        self.commentEditorButton.triggered.connect(self.commentCode)
        self.uncommentEditorButton.triggered.connect(self.uncommentCode)
        self.runScriptEditorButton.triggered.connect(self.runScriptEditor)
        self.cutEditorButton.triggered.connect(self.cutEditor)
        self.copyEditorButton.triggered.connect(self.copyEditor)
        self.pasteEditorButton.triggered.connect(self.pasteEditor)
        self.showEditorButton.toggled.connect(self.toggleEditor)
        self.clearButton.triggered.connect(self.shellOut.clearConsole)
        self.optionsButton.triggered.connect(self.openSettings)
        self.loadProcessingButton.triggered.connect(self.processing)
        self.loadQtCoreButton.triggered.connect(self.qtCore)
        self.loadQtGuiButton.triggered.connect(self.qtGui)
        self.runButton.triggered.connect(self.shell.entered)
        self.openFileButton.triggered.connect(self.openScriptFile)
        self.openInEditorButton.triggered.connect(self.openScriptFileExtEditor)
        self.saveFileButton.triggered.connect(self.saveScriptFile)
        self.saveAsFileButton.triggered.connect(self.saveAsScriptFile)
        self.helpButton.triggered.connect(self.openHelp)
        self.connect(self.listClassMethod,
                     SIGNAL('itemClicked(QTreeWidgetItem*, int)'),
                     self.onClickGoToLine)
        self.lineEditFind.returnPressed.connect(self._findText)
        self.findNextButton.clicked.connect(self._findNext)
        self.findPrevButton.clicked.connect(self._findPrev)
        self.lineEditFind.textChanged.connect(self._textFindChanged)

    def _findText(self):
        self.tabEditorWidget.currentWidget().newEditor.findText(True)

    def _findNext(self):
        self.tabEditorWidget.currentWidget().newEditor.findText(True)

    def _findPrev(self):
        self.tabEditorWidget.currentWidget().newEditor.findText(False)

    def _textFindChanged(self):
        if self.lineEditFind.text():
            self.findNextButton.setEnabled(True)
            self.findPrevButton.setEnabled(True)
        else:
            self.lineEditFind.setStyleSheet('')
            self.findNextButton.setEnabled(False)
            self.findPrevButton.setEnabled(False)

    def onClickGoToLine(self, item, column):
        tabEditor = self.tabEditorWidget.currentWidget().newEditor
        if item.text(1) == 'syntaxError':
            check = tabEditor.syntaxCheck(fromContextMenu=False)
            if check and not tabEditor.isReadOnly():
                self.tabEditorWidget.currentWidget().save()
            return
        linenr = int(item.text(1))
        itemName = str(item.text(0))
        charPos = itemName.find(' ')
        if charPos != -1:
            objName = itemName[0:charPos]
        else:
            objName = itemName
        tabEditor.goToLine(objName, linenr)

    def processing(self):
        self.shell.commandConsole('processing')

    def qtCore(self):
        self.shell.commandConsole('qtCore')

    def qtGui(self):
        self.shell.commandConsole('qtGui')

    def toggleEditor(self, checked):
        self.splitterObj.show() if checked else self.splitterObj.hide()
        if not self.tabEditorWidget:
            self.tabEditorWidget.enableToolBarEditor(checked)
            self.tabEditorWidget.restoreTabsOrAddNew()

    def toggleObjectListWidget(self, checked):
        self.listClassMethod.show() if checked else self.listClassMethod.hide()

    def findTextEditor(self, checked):
        self.widgetFind.show() if checked else self.widgetFind.hide()

    def pasteEditor(self):
        self.tabEditorWidget.currentWidget().newEditor.paste()

    def cutEditor(self):
        self.tabEditorWidget.currentWidget().newEditor.cut()

    def copyEditor(self):
        self.tabEditorWidget.currentWidget().newEditor.copy()

    def runScriptEditor(self):
        self.tabEditorWidget.currentWidget().newEditor.runScriptCode()

    def commentCode(self):
        self.tabEditorWidget.currentWidget().newEditor.commentEditorCode(True)

    def uncommentCode(self):
        self.tabEditorWidget.currentWidget().newEditor.commentEditorCode(False)

    def openScriptFileExtEditor(self):
        tabWidget = self.tabEditorWidget.currentWidget()
        path = tabWidget.path
        import subprocess
        try:
            subprocess.Popen([os.environ['EDITOR'], path])
        except KeyError:
            QDesktopServices.openUrl(QUrl.fromLocalFile(path))

    def openScriptFile(self):
        lastDirPath = self.settings.value("pythonConsole/lastDirPath",
                                          QDir.homePath())
        openFileTr = QCoreApplication.translate("PythonConsole", "Open File")
        fileList = QFileDialog.getOpenFileNames(self, openFileTr, lastDirPath,
                                                "Script file (*.py)")
        if fileList:
            for pyFile in fileList:
                for i in range(self.tabEditorWidget.count()):
                    tabWidget = self.tabEditorWidget.widget(i)
                    if tabWidget.path == pyFile:
                        self.tabEditorWidget.setCurrentWidget(tabWidget)
                        break
                else:
                    tabName = QFileInfo(pyFile).fileName()
                    self.tabEditorWidget.newTabEditor(tabName, pyFile)

                    lastDirPath = QFileInfo(pyFile).path()
                    self.settings.setValue("pythonConsole/lastDirPath", pyFile)
                    self.updateTabListScript(pyFile, action='append')

    def saveScriptFile(self):
        tabWidget = self.tabEditorWidget.currentWidget()
        try:
            tabWidget.save()
        except (IOError, OSError) as error:
            msgText = QCoreApplication.translate(
                'PythonConsole',
                'The file <b>{0}</b> could not be saved. Error: {1}').format(
                    tabWidget.path, error.strerror)
            self.callWidgetMessageBarEditor(msgText, 2, False)

    def saveAsScriptFile(self, index=None):
        tabWidget = self.tabEditorWidget.currentWidget()
        if not index:
            index = self.tabEditorWidget.currentIndex()
        if not tabWidget.path:
            fileName = self.tabEditorWidget.tabText(index) + '.py'
            folder = self.settings.value("pythonConsole/lastDirPath",
                                         QDir.home())
            pathFileName = os.path.join(folder, fileName)
            fileNone = True
        else:
            pathFileName = tabWidget.path
            fileNone = False
        saveAsFileTr = QCoreApplication.translate("PythonConsole",
                                                  "Save File As")
        filename = QFileDialog.getSaveFileName(self, saveAsFileTr,
                                               pathFileName,
                                               "Script file (*.py)")
        if filename:
            try:
                tabWidget.save(filename)
            except (IOError, OSError) as error:
                msgText = QCoreApplication.translate(
                    'PythonConsole',
                    'The file <b>{0}</b> could not be saved. Error: {1}'
                ).format(tabWidget.path, error.strerror)
                self.callWidgetMessageBarEditor(msgText, 2, False)
                if fileNone:
                    tabWidget.path = None
                else:
                    tabWidget.path = pathFileName
                return

            if not fileNone:
                self.updateTabListScript(pathFileName, action='remove')

    def openHelp(self):
        QgsContextHelp.run("PythonConsole")

    def openSettings(self):
        if optionsDialog(self).exec_():
            self.shell.refreshSettingsShell()
            self.shellOut.refreshSettingsOutput()
            self.tabEditorWidget.refreshSettingsEditor()

    def callWidgetMessageBar(self, text):
        self.shellOut.widgetMessageBar(iface, text)

    def callWidgetMessageBarEditor(self, text, level, timed):
        self.tabEditorWidget.widgetMessageBar(iface, text, level, timed)

    def updateTabListScript(self, script, action=None):
        if action == 'remove':
            self.tabListScript.remove(script)
        elif action == 'append':
            if not self.tabListScript:
                self.tabListScript = []
            if script not in self.tabListScript:
                self.tabListScript.append(script)
        else:
            self.tabListScript = []
        self.settings.setValue("pythonConsole/tabScripts", self.tabListScript)

    def saveSettingsConsole(self):
        self.settings.setValue("pythonConsole/splitterConsole",
                               self.splitter.saveState())
        self.settings.setValue("pythonConsole/splitterObj",
                               self.splitterObj.saveState())
        self.settings.setValue("pythonConsole/splitterEditor",
                               self.splitterEditor.saveState())

        self.shell.writeHistoryFile(True)

    def restoreSettingsConsole(self):
        storedTabScripts = self.settings.value("pythonConsole/tabScripts", [])
        self.tabListScript = storedTabScripts
        self.splitter.restoreState(
            self.settings.value("pythonConsole/splitterConsole", QByteArray()))
        self.splitterEditor.restoreState(
            self.settings.value("pythonConsole/splitterEditor", QByteArray()))
        self.splitterObj.restoreState(
            self.settings.value("pythonConsole/splitterObj", QByteArray()))
Beispiel #50
0
    def __init__(self, parent=None):
        QWidget.__init__(self, parent)
        self.setWindowTitle(
            QCoreApplication.translate("PythonConsole", "Python Console"))

        self.settings = QSettings()

        self.shell = ShellScintilla(self)
        self.setFocusProxy(self.shell)
        self.shellOut = ShellOutputScintilla(self)
        self.tabEditorWidget = EditorTabWidget(self)

        ##------------ UI -------------------------------

        self.splitterEditor = QSplitter(self)
        self.splitterEditor.setOrientation(Qt.Horizontal)
        self.splitterEditor.setHandleWidth(6)
        self.splitterEditor.setChildrenCollapsible(True)

        self.shellOutWidget = QWidget(self)
        self.shellOutWidget.setLayout(QVBoxLayout())
        self.shellOutWidget.layout().setContentsMargins(0, 0, 0, 0)
        self.shellOutWidget.layout().addWidget(self.shellOut)

        self.splitter = QSplitter(self.splitterEditor)
        self.splitter.setOrientation(Qt.Vertical)
        self.splitter.setHandleWidth(3)
        self.splitter.setChildrenCollapsible(False)
        self.splitter.addWidget(self.shellOutWidget)
        self.splitter.addWidget(self.shell)

        #self.splitterEditor.addWidget(self.tabEditorWidget)

        self.splitterObj = QSplitter(self.splitterEditor)
        self.splitterObj.setHandleWidth(3)
        self.splitterObj.setOrientation(Qt.Horizontal)
        #self.splitterObj.setSizes([0, 0])
        #self.splitterObj.setStretchFactor(0, 1)

        self.widgetEditor = QWidget(self.splitterObj)
        self.widgetFind = QWidget(self)

        self.listClassMethod = QTreeWidget(self.splitterObj)
        self.listClassMethod.setColumnCount(2)
        objInspLabel = QCoreApplication.translate("PythonConsole",
                                                  "Object Inspector")
        self.listClassMethod.setHeaderLabels([objInspLabel, ''])
        self.listClassMethod.setColumnHidden(1, True)
        self.listClassMethod.setAlternatingRowColors(True)

        #self.splitterEditor.addWidget(self.widgetEditor)
        #self.splitterObj.addWidget(self.listClassMethod)
        #self.splitterObj.addWidget(self.widgetEditor)

        # Hide side editor on start up
        self.splitterObj.hide()
        self.listClassMethod.hide()
        # Hide search widget on start up
        self.widgetFind.hide()

        sizes = self.splitter.sizes()
        self.splitter.setSizes(sizes)

        ##----------------Restore Settings------------------------------------

        self.restoreSettingsConsole()

        ##------------------Toolbar Editor-------------------------------------

        ## Action for Open File
        openFileBt = QCoreApplication.translate("PythonConsole", "Open file")
        self.openFileButton = QAction(self)
        self.openFileButton.setCheckable(False)
        self.openFileButton.setEnabled(True)
        self.openFileButton.setIcon(
            QgsApplication.getThemeIcon("console/iconOpenConsole.png"))
        self.openFileButton.setMenuRole(QAction.PreferencesRole)
        self.openFileButton.setIconVisibleInMenu(True)
        self.openFileButton.setToolTip(openFileBt)
        self.openFileButton.setText(openFileBt)

        openExtEditorBt = QCoreApplication.translate(
            "PythonConsole", "Open in external editor")
        self.openInEditorButton = QAction(self)
        self.openInEditorButton.setCheckable(False)
        self.openInEditorButton.setEnabled(True)
        self.openInEditorButton.setIcon(
            QgsApplication.getThemeIcon("console/iconShowEditorConsole.png"))
        self.openInEditorButton.setMenuRole(QAction.PreferencesRole)
        self.openInEditorButton.setIconVisibleInMenu(True)
        self.openInEditorButton.setToolTip(openExtEditorBt)
        self.openInEditorButton.setText(openExtEditorBt)
        ## Action for Save File
        saveFileBt = QCoreApplication.translate("PythonConsole", "Save")
        self.saveFileButton = QAction(self)
        self.saveFileButton.setCheckable(False)
        self.saveFileButton.setEnabled(False)
        self.saveFileButton.setIcon(
            QgsApplication.getThemeIcon("console/iconSaveConsole.png"))
        self.saveFileButton.setMenuRole(QAction.PreferencesRole)
        self.saveFileButton.setIconVisibleInMenu(True)
        self.saveFileButton.setToolTip(saveFileBt)
        self.saveFileButton.setText(saveFileBt)
        ## Action for Save File As
        saveAsFileBt = QCoreApplication.translate("PythonConsole",
                                                  "Save As...")
        self.saveAsFileButton = QAction(self)
        self.saveAsFileButton.setCheckable(False)
        self.saveAsFileButton.setEnabled(True)
        self.saveAsFileButton.setIcon(
            QgsApplication.getThemeIcon("console/iconSaveAsConsole.png"))
        self.saveAsFileButton.setMenuRole(QAction.PreferencesRole)
        self.saveAsFileButton.setIconVisibleInMenu(True)
        self.saveAsFileButton.setToolTip(saveAsFileBt)
        self.saveAsFileButton.setText(saveAsFileBt)
        ## Action Cut
        cutEditorBt = QCoreApplication.translate("PythonConsole", "Cut")
        self.cutEditorButton = QAction(self)
        self.cutEditorButton.setCheckable(False)
        self.cutEditorButton.setEnabled(True)
        self.cutEditorButton.setIcon(
            QgsApplication.getThemeIcon("console/iconCutEditorConsole.png"))
        self.cutEditorButton.setMenuRole(QAction.PreferencesRole)
        self.cutEditorButton.setIconVisibleInMenu(True)
        self.cutEditorButton.setToolTip(cutEditorBt)
        self.cutEditorButton.setText(cutEditorBt)
        ## Action Copy
        copyEditorBt = QCoreApplication.translate("PythonConsole", "Copy")
        self.copyEditorButton = QAction(self)
        self.copyEditorButton.setCheckable(False)
        self.copyEditorButton.setEnabled(True)
        self.copyEditorButton.setIcon(
            QgsApplication.getThemeIcon("console/iconCopyEditorConsole.png"))
        self.copyEditorButton.setMenuRole(QAction.PreferencesRole)
        self.copyEditorButton.setIconVisibleInMenu(True)
        self.copyEditorButton.setToolTip(copyEditorBt)
        self.copyEditorButton.setText(copyEditorBt)
        ## Action Paste
        pasteEditorBt = QCoreApplication.translate("PythonConsole", "Paste")
        self.pasteEditorButton = QAction(self)
        self.pasteEditorButton.setCheckable(False)
        self.pasteEditorButton.setEnabled(True)
        self.pasteEditorButton.setIcon(
            QgsApplication.getThemeIcon("console/iconPasteEditorConsole.png"))
        self.pasteEditorButton.setMenuRole(QAction.PreferencesRole)
        self.pasteEditorButton.setIconVisibleInMenu(True)
        self.pasteEditorButton.setToolTip(pasteEditorBt)
        self.pasteEditorButton.setText(pasteEditorBt)
        ## Action Run Script (subprocess)
        runScriptEditorBt = QCoreApplication.translate("PythonConsole",
                                                       "Run script")
        self.runScriptEditorButton = QAction(self)
        self.runScriptEditorButton.setCheckable(False)
        self.runScriptEditorButton.setEnabled(True)
        self.runScriptEditorButton.setIcon(
            QgsApplication.getThemeIcon("console/iconRunScriptConsole.png"))
        self.runScriptEditorButton.setMenuRole(QAction.PreferencesRole)
        self.runScriptEditorButton.setIconVisibleInMenu(True)
        self.runScriptEditorButton.setToolTip(runScriptEditorBt)
        self.runScriptEditorButton.setText(runScriptEditorBt)
        ## Action Run Script (subprocess)
        commentEditorBt = QCoreApplication.translate("PythonConsole",
                                                     "Comment")
        self.commentEditorButton = QAction(self)
        self.commentEditorButton.setCheckable(False)
        self.commentEditorButton.setEnabled(True)
        self.commentEditorButton.setIcon(
            QgsApplication.getThemeIcon(
                "console/iconCommentEditorConsole.png"))
        self.commentEditorButton.setMenuRole(QAction.PreferencesRole)
        self.commentEditorButton.setIconVisibleInMenu(True)
        self.commentEditorButton.setToolTip(commentEditorBt)
        self.commentEditorButton.setText(commentEditorBt)
        ## Action Run Script (subprocess)
        uncommentEditorBt = QCoreApplication.translate("PythonConsole",
                                                       "Uncomment")
        self.uncommentEditorButton = QAction(self)
        self.uncommentEditorButton.setCheckable(False)
        self.uncommentEditorButton.setEnabled(True)
        self.uncommentEditorButton.setIcon(
            QgsApplication.getThemeIcon(
                "console/iconUncommentEditorConsole.png"))
        self.uncommentEditorButton.setMenuRole(QAction.PreferencesRole)
        self.uncommentEditorButton.setIconVisibleInMenu(True)
        self.uncommentEditorButton.setToolTip(uncommentEditorBt)
        self.uncommentEditorButton.setText(uncommentEditorBt)
        ## Action for Object browser
        objList = QCoreApplication.translate("PythonConsole",
                                             "Object Inspector")
        self.objectListButton = QAction(self)
        self.objectListButton.setCheckable(True)
        self.objectListButton.setEnabled(
            self.settings.value("pythonConsole/enableObjectInsp",
                                False,
                                type=bool))
        self.objectListButton.setIcon(
            QgsApplication.getThemeIcon("console/iconClassBrowserConsole.png"))
        self.objectListButton.setMenuRole(QAction.PreferencesRole)
        self.objectListButton.setIconVisibleInMenu(True)
        self.objectListButton.setToolTip(objList)
        self.objectListButton.setText(objList)
        ## Action for Find text
        findText = QCoreApplication.translate("PythonConsole", "Find Text")
        self.findTextButton = QAction(self)
        self.findTextButton.setCheckable(True)
        self.findTextButton.setEnabled(True)
        self.findTextButton.setIcon(
            QgsApplication.getThemeIcon("console/iconSearchEditorConsole.png"))
        self.findTextButton.setMenuRole(QAction.PreferencesRole)
        self.findTextButton.setIconVisibleInMenu(True)
        self.findTextButton.setToolTip(findText)
        self.findTextButton.setText(findText)

        ##----------------Toolbar Console-------------------------------------

        ## Action Show Editor
        showEditor = QCoreApplication.translate("PythonConsole", "Show editor")
        self.showEditorButton = QAction(self)
        self.showEditorButton.setEnabled(True)
        self.showEditorButton.setCheckable(True)
        self.showEditorButton.setIcon(
            QgsApplication.getThemeIcon("console/iconShowEditorConsole.png"))
        self.showEditorButton.setMenuRole(QAction.PreferencesRole)
        self.showEditorButton.setIconVisibleInMenu(True)
        self.showEditorButton.setToolTip(showEditor)
        self.showEditorButton.setText(showEditor)
        ## Action for Clear button
        clearBt = QCoreApplication.translate("PythonConsole", "Clear console")
        self.clearButton = QAction(self)
        self.clearButton.setCheckable(False)
        self.clearButton.setEnabled(True)
        self.clearButton.setIcon(
            QgsApplication.getThemeIcon("console/iconClearConsole.png"))
        self.clearButton.setMenuRole(QAction.PreferencesRole)
        self.clearButton.setIconVisibleInMenu(True)
        self.clearButton.setToolTip(clearBt)
        self.clearButton.setText(clearBt)
        ## Action for settings
        optionsBt = QCoreApplication.translate("PythonConsole", "Settings")
        self.optionsButton = QAction(self)
        self.optionsButton.setCheckable(False)
        self.optionsButton.setEnabled(True)
        self.optionsButton.setIcon(
            QgsApplication.getThemeIcon("console/iconSettingsConsole.png"))
        self.optionsButton.setMenuRole(QAction.PreferencesRole)
        self.optionsButton.setIconVisibleInMenu(True)
        self.optionsButton.setToolTip(optionsBt)
        self.optionsButton.setText(optionsBt)
        ## Action menu for class
        actionClassBt = QCoreApplication.translate("PythonConsole",
                                                   "Import Class")
        self.actionClass = QAction(self)
        self.actionClass.setCheckable(False)
        self.actionClass.setEnabled(True)
        self.actionClass.setIcon(
            QgsApplication.getThemeIcon("console/iconClassConsole.png"))
        self.actionClass.setMenuRole(QAction.PreferencesRole)
        self.actionClass.setIconVisibleInMenu(True)
        self.actionClass.setToolTip(actionClassBt)
        self.actionClass.setText(actionClassBt)
        ## Import Processing class
        loadProcessingBt = QCoreApplication.translate(
            "PythonConsole", "Import Processing class")
        self.loadProcessingButton = QAction(self)
        self.loadProcessingButton.setCheckable(False)
        self.loadProcessingButton.setEnabled(True)
        self.loadProcessingButton.setIcon(
            QgsApplication.getThemeIcon("console/iconProcessingConsole.png"))
        self.loadProcessingButton.setMenuRole(QAction.PreferencesRole)
        self.loadProcessingButton.setIconVisibleInMenu(True)
        self.loadProcessingButton.setToolTip(loadProcessingBt)
        self.loadProcessingButton.setText(loadProcessingBt)
        ## Import QtCore class
        loadQtCoreBt = QCoreApplication.translate("PythonConsole",
                                                  "Import PyQt.QtCore class")
        self.loadQtCoreButton = QAction(self)
        self.loadQtCoreButton.setCheckable(False)
        self.loadQtCoreButton.setEnabled(True)
        self.loadQtCoreButton.setIcon(
            QgsApplication.getThemeIcon("console/iconQtCoreConsole.png"))
        self.loadQtCoreButton.setMenuRole(QAction.PreferencesRole)
        self.loadQtCoreButton.setIconVisibleInMenu(True)
        self.loadQtCoreButton.setToolTip(loadQtCoreBt)
        self.loadQtCoreButton.setText(loadQtCoreBt)
        ## Import QtGui class
        loadQtGuiBt = QCoreApplication.translate("PythonConsole",
                                                 "Import PyQt.QtGui class")
        self.loadQtGuiButton = QAction(self)
        self.loadQtGuiButton.setCheckable(False)
        self.loadQtGuiButton.setEnabled(True)
        self.loadQtGuiButton.setIcon(
            QgsApplication.getThemeIcon("console/iconQtGuiConsole.png"))
        self.loadQtGuiButton.setMenuRole(QAction.PreferencesRole)
        self.loadQtGuiButton.setIconVisibleInMenu(True)
        self.loadQtGuiButton.setToolTip(loadQtGuiBt)
        self.loadQtGuiButton.setText(loadQtGuiBt)
        ## Action for Run script
        runBt = QCoreApplication.translate("PythonConsole", "Run command")
        self.runButton = QAction(self)
        self.runButton.setCheckable(False)
        self.runButton.setEnabled(True)
        self.runButton.setIcon(
            QgsApplication.getThemeIcon("console/iconRunConsole.png"))
        self.runButton.setMenuRole(QAction.PreferencesRole)
        self.runButton.setIconVisibleInMenu(True)
        self.runButton.setToolTip(runBt)
        self.runButton.setText(runBt)
        ## Help action
        helpBt = QCoreApplication.translate("PythonConsole", "Help")
        self.helpButton = QAction(self)
        self.helpButton.setCheckable(False)
        self.helpButton.setEnabled(True)
        self.helpButton.setIcon(
            QgsApplication.getThemeIcon("console/iconHelpConsole.png"))
        self.helpButton.setMenuRole(QAction.PreferencesRole)
        self.helpButton.setIconVisibleInMenu(True)
        self.helpButton.setToolTip(helpBt)
        self.helpButton.setText(helpBt)

        self.toolBar = QToolBar()
        self.toolBar.setEnabled(True)
        self.toolBar.setFocusPolicy(Qt.NoFocus)
        self.toolBar.setContextMenuPolicy(Qt.DefaultContextMenu)
        self.toolBar.setLayoutDirection(Qt.LeftToRight)
        self.toolBar.setIconSize(QSize(16, 16))
        self.toolBar.setMovable(False)
        self.toolBar.setFloatable(False)
        self.toolBar.addAction(self.clearButton)
        self.toolBar.addAction(self.actionClass)
        self.toolBar.addAction(self.runButton)
        self.toolBar.addSeparator()
        self.toolBar.addAction(self.showEditorButton)
        self.toolBar.addSeparator()
        self.toolBar.addAction(self.optionsButton)
        self.toolBar.addAction(self.helpButton)

        self.toolBarEditor = QToolBar()
        self.toolBarEditor.setEnabled(False)
        self.toolBarEditor.setFocusPolicy(Qt.NoFocus)
        self.toolBarEditor.setContextMenuPolicy(Qt.DefaultContextMenu)
        self.toolBarEditor.setLayoutDirection(Qt.LeftToRight)
        self.toolBarEditor.setIconSize(QSize(16, 16))
        self.toolBarEditor.setMovable(False)
        self.toolBarEditor.setFloatable(False)
        self.toolBarEditor.addAction(self.openFileButton)
        self.toolBarEditor.addAction(self.openInEditorButton)
        self.toolBarEditor.addSeparator()
        self.toolBarEditor.addAction(self.saveFileButton)
        self.toolBarEditor.addAction(self.saveAsFileButton)
        self.toolBarEditor.addSeparator()
        self.toolBarEditor.addAction(self.runScriptEditorButton)
        self.toolBarEditor.addSeparator()
        self.toolBarEditor.addAction(self.findTextButton)
        self.toolBarEditor.addSeparator()
        self.toolBarEditor.addAction(self.cutEditorButton)
        self.toolBarEditor.addAction(self.copyEditorButton)
        self.toolBarEditor.addAction(self.pasteEditorButton)
        self.toolBarEditor.addSeparator()
        self.toolBarEditor.addAction(self.commentEditorButton)
        self.toolBarEditor.addAction(self.uncommentEditorButton)
        self.toolBarEditor.addSeparator()
        self.toolBarEditor.addAction(self.objectListButton)

        ## Menu Import Class
        self.classMenu = QMenu()
        self.classMenu.addAction(self.loadProcessingButton)
        self.classMenu.addAction(self.loadQtCoreButton)
        self.classMenu.addAction(self.loadQtGuiButton)
        cM = self.toolBar.widgetForAction(self.actionClass)
        cM.setMenu(self.classMenu)
        cM.setPopupMode(QToolButton.InstantPopup)

        self.widgetButton = QWidget()
        sizePolicy = QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Preferred)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(
            self.widgetButton.sizePolicy().hasHeightForWidth())
        self.widgetButton.setSizePolicy(sizePolicy)

        self.widgetButtonEditor = QWidget(self.widgetEditor)
        sizePolicy = QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Preferred)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(
            self.widgetButtonEditor.sizePolicy().hasHeightForWidth())
        self.widgetButtonEditor.setSizePolicy(sizePolicy)

        sizePolicy = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(
            self.shellOut.sizePolicy().hasHeightForWidth())
        self.shellOut.setSizePolicy(sizePolicy)

        self.shellOut.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded)
        self.shell.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded)

        ##------------ Layout -------------------------------

        self.mainLayout = QGridLayout(self)
        self.mainLayout.setMargin(0)
        self.mainLayout.setSpacing(0)
        self.mainLayout.addWidget(self.widgetButton, 0, 0, 1, 1)
        self.mainLayout.addWidget(self.splitterEditor, 0, 1, 1, 1)

        self.shellOutWidget.layout().insertWidget(0, self.toolBar)

        self.layoutEditor = QGridLayout(self.widgetEditor)
        self.layoutEditor.setMargin(0)
        self.layoutEditor.setSpacing(0)
        self.layoutEditor.addWidget(self.toolBarEditor, 0, 1, 1, 1)
        self.layoutEditor.addWidget(self.widgetButtonEditor, 1, 0, 2, 1)
        self.layoutEditor.addWidget(self.tabEditorWidget, 1, 1, 1, 1)
        self.layoutEditor.addWidget(self.widgetFind, 2, 1, 1, 1)

        ## Layout for the find widget
        self.layoutFind = QGridLayout(self.widgetFind)
        self.layoutFind.setContentsMargins(0, 0, 0, 0)
        self.lineEditFind = QgsFilterLineEdit()
        placeHolderTxt = QCoreApplication.translate("PythonConsole",
                                                    "Enter text to find...")

        if pyqtconfig.Configuration().qt_version >= 0x40700:
            self.lineEditFind.setPlaceholderText(placeHolderTxt)
        else:
            self.lineEditFind.setToolTip(placeHolderTxt)
        self.findNextButton = QToolButton()
        self.findNextButton.setEnabled(False)
        toolTipfindNext = QCoreApplication.translate("PythonConsole",
                                                     "Find Next")
        self.findNextButton.setToolTip(toolTipfindNext)
        self.findNextButton.setIcon(
            QgsApplication.getThemeIcon(
                "console/iconSearchNextEditorConsole.png"))
        self.findNextButton.setIconSize(QSize(24, 24))
        self.findNextButton.setAutoRaise(True)
        self.findPrevButton = QToolButton()
        self.findPrevButton.setEnabled(False)
        toolTipfindPrev = QCoreApplication.translate("PythonConsole",
                                                     "Find Previous")
        self.findPrevButton.setToolTip(toolTipfindPrev)
        self.findPrevButton.setIcon(
            QgsApplication.getThemeIcon(
                "console/iconSearchPrevEditorConsole.png"))
        self.findPrevButton.setIconSize(QSize(24, 24))
        self.findPrevButton.setAutoRaise(True)
        self.caseSensitive = QCheckBox()
        caseSensTr = QCoreApplication.translate("PythonConsole",
                                                "Case Sensitive")
        self.caseSensitive.setText(caseSensTr)
        self.wholeWord = QCheckBox()
        wholeWordTr = QCoreApplication.translate("PythonConsole", "Whole Word")
        self.wholeWord.setText(wholeWordTr)
        self.wrapAround = QCheckBox()
        self.wrapAround.setChecked(True)
        wrapAroundTr = QCoreApplication.translate("PythonConsole",
                                                  "Wrap Around")
        self.wrapAround.setText(wrapAroundTr)
        self.layoutFind.addWidget(self.lineEditFind, 0, 1, 1, 1)
        self.layoutFind.addWidget(self.findPrevButton, 0, 2, 1, 1)
        self.layoutFind.addWidget(self.findNextButton, 0, 3, 1, 1)
        self.layoutFind.addWidget(self.caseSensitive, 0, 4, 1, 1)
        self.layoutFind.addWidget(self.wholeWord, 0, 5, 1, 1)
        self.layoutFind.addWidget(self.wrapAround, 0, 6, 1, 1)

        ##------------ Add first Tab in Editor -------------------------------

        #self.tabEditorWidget.newTabEditor(tabName='first', filename=None)

        ##------------ Signal -------------------------------

        self.findTextButton.toggled.connect(self.findTextEditor)
        self.objectListButton.toggled.connect(self.toggleObjectListWidget)
        self.commentEditorButton.triggered.connect(self.commentCode)
        self.uncommentEditorButton.triggered.connect(self.uncommentCode)
        self.runScriptEditorButton.triggered.connect(self.runScriptEditor)
        self.cutEditorButton.triggered.connect(self.cutEditor)
        self.copyEditorButton.triggered.connect(self.copyEditor)
        self.pasteEditorButton.triggered.connect(self.pasteEditor)
        self.showEditorButton.toggled.connect(self.toggleEditor)
        self.clearButton.triggered.connect(self.shellOut.clearConsole)
        self.optionsButton.triggered.connect(self.openSettings)
        self.loadProcessingButton.triggered.connect(self.processing)
        self.loadQtCoreButton.triggered.connect(self.qtCore)
        self.loadQtGuiButton.triggered.connect(self.qtGui)
        self.runButton.triggered.connect(self.shell.entered)
        self.openFileButton.triggered.connect(self.openScriptFile)
        self.openInEditorButton.triggered.connect(self.openScriptFileExtEditor)
        self.saveFileButton.triggered.connect(self.saveScriptFile)
        self.saveAsFileButton.triggered.connect(self.saveAsScriptFile)
        self.helpButton.triggered.connect(self.openHelp)
        self.connect(self.listClassMethod,
                     SIGNAL('itemClicked(QTreeWidgetItem*, int)'),
                     self.onClickGoToLine)
        self.lineEditFind.returnPressed.connect(self._findText)
        self.findNextButton.clicked.connect(self._findNext)
        self.findPrevButton.clicked.connect(self._findPrev)
        self.lineEditFind.textChanged.connect(self._textFindChanged)