예제 #1
0
class CurvePanel(QListView):
    def __init__(self, curve_source):
        QListView.__init__(self)
        self.curve_source = curve_source
        self.setViewMode(QListView.IconMode)
        self.setIconSize(QSize(64,64))
        self.model = QStandardItemModel()
        for curve in curve_source._curves:
            self.add_curve(curve)
        self.setModel(self.model)
        self.setWrapping(True)
        self.show()

    def edit(self, index, trigger, event):
        if trigger == QAbstractItemView.DoubleClicked:
            item = self.model.item(index.row())
            curve = item.curve
            print curve.name()
            return True
        else:
            return False

    def add_new_curve(self):
        pass
    
    def add_curve(self, curve):
        name = curve.name()
        plot = self._create_plot(name)
        item = PlotItem(plot)
        item.curve = curve
        self.model.appendRow(item)

    def _create_plot(self, xcurve_name):
        index = self.curve_source.index()
        return Plot.of(xcurve_name, index.name()).from_(self.curve_source)
예제 #2
0
    def getSampleModel(spl, flags='peak', **kw):
        from gui.MetBaseGui import MSStandardItem
        if flags not in ('peak', 'cluster', 'id'):
            return
        model = QStandardItemModel()
        if flags == 'peak':
            from utils.misc import Hot
            areas = [peak.area for peak in spl.rawPeaks.ipeaks()]
            mxInt = max(areas)
            model.setHorizontalHeaderLabels(MSSample.peakModelLabel)

            for i, peak in enumerate(spl.rawPeaks.ipeaks()):
                model.setItem(i, 0, MSStandardItem(str(peak.mass())))
                model.item(i, 0).setBackground(
                    QBrush(Hot._get_color(areas[i] / mxInt, True, alpha=0.5)))

                model.setItem(i, 1, MSStandardItem(str(peak.rt)))
                model.item(i, 1).setBackground(
                    QBrush(Hot._get_color(areas[i] / mxInt, True, alpha=0.5)))

                model.setItem(i, 2, MSStandardItem(str(peak.area)))
                model.item(i, 2).setBackground(
                    QBrush(Hot._get_color(areas[i] / mxInt, True, alpha=0.5)))

                model.setItem(i, 3, MSStandardItem(str(peak.sn)))
                model.item(i, 3).setBackground(
                    QBrush(Hot._get_color(areas[i] / mxInt, True, alpha=0.5)))

                model.setItem(i, 4, MSStandardItem(str(peak.r_coef)))
                model.item(i, 4).setBackground(
                    QBrush(Hot._get_color(areas[i] / mxInt, True, alpha=0.5)))

        elif flags == 'cluster':
            model.setHorizontalHeaderLabels(MSSample.clusterModelLabel)
            for i, peak in enumerate(spl.mappedPeaks.ipeaks()):
                model.setItem(i, 0, MSStandardItem(str(peak.mass())))
                model.setItem(i, 1, MSStandardItem(str(peak.rt)))
                model.setItem(i, 2, MSStandardItem(str(peak.area)))
                info_iso = ""
                info_frag = ""
                for iso in peak.isoCluster:
                    info_iso += '%s/%s\t' % (str(iso.mass()), str(iso.rt))
                for add in peak.fragCluster:
                    info_frag += '%s/%s\t' % (str(add.mass()), str(add.rt))
                model.setItem(i, 3, MSStandardItem(info_iso))
                model.setItem(i, 4, MSStandardItem(info_frag))
        return model
예제 #3
0
파일: util.py 프로젝트: jmechnich/qmpc
class DataModel(object):
    def __init__(self):
        super(DataModel,self).__init__()
        self.servers     = QStandardItemModel(0,3)
        self.selected    = ''
        self.autoconnect = False
        
    def loadSettings(self):
        settings = QSettings()
        servers = settings.value("servers", None)
        self.servers.clear()
        if servers:
            for s in servers:
                self.servers.appendRow([QStandardItem(str(i)) for i in s])
        self.selected    =  str(settings.value("selected",    self.selected))
        self.autoconnect = int(settings.value("autoconnect", self.autoconnect))
        
    def saveSettings(self):
        settings = QSettings()
        servers = []
        if self.servers:
            for row in xrange(self.servers.rowCount()):
                entry = []
                for col in xrange(self.servers.columnCount()):
                    entry += [self.servers.item(row,col).text()]
                servers += [entry]
        if len(servers):
            settings.setValue("servers", servers)
        else:
            settings.setValue("servers", None)
        settings.setValue("selected",     str(self.selected))
        settings.setValue("autoconnect", int(self.autoconnect))

    def selectedServer(self):
        selectedServer = []
        if self.selected:
            result = self.servers.findItems( self.selected)
            if len(result):
                mi = result[0]
                row = mi.row()
                for col in xrange(self.servers.columnCount()):
                    selectedServer += [self.servers.item(row,col).text()]
        return selectedServer
예제 #4
0
    def getSampleModel(spl, flags='peak', **kw):
        from gui.MetBaseGui import MSStandardItem
        if flags not in ('peak', 'cluster', 'id'):
            return
        model = QStandardItemModel()
        if flags=='peak':
            from utils.misc import Hot
            areas=[peak.area for peak in spl.rawPeaks.ipeaks()]
            mxInt=max(areas)
            model.setHorizontalHeaderLabels(MSSample.peakModelLabel)

            for i, peak in enumerate(spl.rawPeaks.ipeaks()):
                model.setItem(i, 0, MSStandardItem(str(peak.mass())))
                model.item(i, 0).setBackground(QBrush(Hot._get_color(areas[i]/mxInt, True, alpha=0.5)))

                model.setItem(i, 1, MSStandardItem(str(peak.rt)))
                model.item(i, 1).setBackground(QBrush(Hot._get_color(areas[i]/mxInt, True, alpha=0.5)))

                model.setItem(i, 2, MSStandardItem(str(peak.area)))
                model.item(i, 2).setBackground(QBrush(Hot._get_color(areas[i]/mxInt, True, alpha=0.5)))

                model.setItem(i, 3, MSStandardItem(str(peak.sn)))
                model.item(i, 3).setBackground(QBrush(Hot._get_color(areas[i]/mxInt, True, alpha=0.5)))

                model.setItem(i, 4, MSStandardItem(str(peak.r_coef)))
                model.item(i, 4).setBackground(QBrush(Hot._get_color(areas[i]/mxInt, True, alpha=0.5)))

        elif flags=='cluster':
            model.setHorizontalHeaderLabels(MSSample.clusterModelLabel)
            for i, peak in enumerate(spl.mappedPeaks.ipeaks()):
                model.setItem(i, 0, MSStandardItem(str(peak.mass())))
                model.setItem(i, 1, MSStandardItem(str(peak.rt)))
                model.setItem(i, 2, MSStandardItem(str(peak.area)))
                info_iso ="";info_frag=""
                for iso in peak.isoCluster:
                    info_iso += '%s/%s\t'%(str(iso.mass()),str(iso.rt))
                for add in peak.fragCluster:
                    info_frag += '%s/%s\t'%(str(add.mass()),str(add.rt))
                model.setItem(i, 3, MSStandardItem(info_iso))
                model.setItem(i, 4, MSStandardItem(info_frag))
        return model
예제 #5
0
class ListViewWindow(QtGui.QWidget):
    def __init__(self):
        super(ListViewWindow, self).__init__()
        # ui_full_path = find_file_in_product('list_ui_widget.ui')
        ui_full_path = find_resource_in_pkg('list_window.ui')
        self.ui = uic.loadUi(ui_full_path, self)
        self.model = QStandardItemModel()
        self._mouse_button = None
        self.listView.setModel(self.model)

        # self.show()
        self.listView.clicked.connect(self.item_clicked)
        # self.listView.doubleClicked.connect(self.handle_right_click)
        self.minimized = True
        self.click_handler = None
        self.right_click_handler = None
        self.list_view_mouse_pressed = self.listView.mousePressEvent
        self.listView.mousePressEvent = self.mousePressEvent

    #     self.ui.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
    #     self.ui.connect(self.ui, QtCore.SIGNAL("customContextMenuRequested(QPoint)"),
    #                                      self.on_context)
    #
    # def on_context(self, point):
    #     # Create a menu
    #     menu = QtGui.QMenu("Menu", self)
    #     menu.addAction(self.mAction1)
    #     menu.addAction(self.mAction2)
    #     # Show the context menu.
    #     menu.exec_(self.view.mapToGlobal(point))

    def item_clicked(self, index):
        row_text = str(self.model.item(index.row()).text())
        # mouse_buttons = QtGui.qApp.mouseButtons()
        # print int(mouse_buttons)
        if self._mouse_button == QtCore.Qt.RightButton:
            if self.right_click_handler:
                self.right_click_handler(row_text)
        elif not (self.click_handler is None):
            self.click_handler(row_text)

    # def handle_right_click(self, index):
    #     row_text = str(self.model.item(index.row()).text())
    #     if self.right_click_handler:
    #         self.right_click_handler(row_text)

    def set_click_handler(self, callback_func):
        self.click_handler = callback_func

    def mousePressEvent(self, event):
        self._mouse_button = event.button()
        self.list_view_mouse_pressed(event)
예제 #6
0
파일: TaskbarIcon.py 프로젝트: weijia/ufs
class ApplicationList(QtGui.QWidget, MinimizeOnClose):
    def __init__(self):
        super(ApplicationList, self).__init__()
        ui_full_path = fileTools.findFileInProduct('app_list.ui')
        self.ui = uic.loadUi(ui_full_path, self)
        self.model = QStandardItemModel()
        '''
        item = QStandardItem('Hello world')
        item1 = QStandardItem('Hello world1')
        item.setCheckState(Qt.Checked)
        item.setCheckable(True)
        item1.setCheckState(Qt.Checked)
        item1.setCheckable(True)
        self.model.appendRow(item)
        self.model.appendRow(item1)
        '''
        self.listView.setModel(self.model)
        '''
        self.connect(self.listView.selectionModel(),  
                     QtCore.SIGNAL("selectionChanged(QItemSelection, QItemSelection)"),  
                     self.store_current_selection) 
        '''
        self.show()
        self.listView.clicked.connect(self.item_clicked)
    def item_clicked(self, index):
        self.callback_func(str(self.model.item(index.row()).text()))
    '''
    #---------------------------------------------------------------------------
    def store_current_selection(self, newSelection, oldSelection):
        indexes = newSelection.indexes()

        for index in indexes:

            text = u"(%i,%i)" % (index.row(), index.column())
            #self.model.setData(index, text)
            #print text
            #print self.model.item(index.row()).text()
            self.callback_func(str(self.model.item(index.row()).text())
    '''
    def set_callback(self, callback_func):
        self.callback_func = callback_func
    def initListView(self):
        """Init status table"""
        # List Box model
        model = QStandardItemModel()

        # Init list objects
        for i, frame in enumerate(self.task.videoLabelHandler.files):
            item = QStandardItem(frame + "\t{0} Objects".format(len(self.task.videoLabelHandler.objects)))
            item.setCheckState(Qt.Checked)
            item.setCheckable(True)
            model.appendRow(item)

        if self.segmentation_mode:
            model.item(0).setEnabled(False)
        else:
            model.item(i).setCheckState(Qt.Unchecked)
            model.item(i).setEnabled(False)

        # Set model
        self.view.setModel(model)
예제 #8
0
class STRPartyListView(QListView):
    """
    A widget for listing and selecting STR party entities.
    .. versionadded:: 1.5
    """
    party_selected = pyqtSignal(QStandardItem)
    party_deselected = pyqtSignal(QStandardItem)

    def __init__(self, parent=None, profile=None, social_tenure=None):
        super(STRPartyListView, self).__init__(parent)

        self._model = QStandardItemModel(self)
        self._model.setColumnCount(1)
        self.setModel(self._model)
        self.setEditTriggers(QAbstractItemView.NoEditTriggers)
        self._model.itemChanged.connect(self._on_item_changed)

        self._profile = profile
        if not self._profile is None:
            self._load_profile_entities()

        self._social_tenure = social_tenure
        if not self._social_tenure is None:
            self.select_parties(self._social_tenure.parties)

    def _on_item_changed(self, item):
        # Emit signals when an item has been (de)selected.
        if item.checkState() == Qt.Checked:
            self.party_selected.emit(item)
        elif item.checkState() == Qt.Unchecked:
            self.party_deselected.emit(item)

    @property
    def profile(self):
        """
        :return: Returns the current profile object in the configuration.
        :rtype: Profile
        """
        return self._profile

    @profile.setter
    def profile(self, profile):
        """
        Sets the current profile object in the configuration.
        :param profile: Profile object.
        :type profile: Profile
        """
        self._profile = profile
        self._load_profile_entities()

    @property
    def social_tenure(self):
        """
        :return: Returns the profile's social tenure entity.
        :rtype: SocialTenure
        """
        return self._social_tenure

    @social_tenure.setter
    def social_tenure(self, social_tenure):
        """
        Set the social_tenure entity.
        :param social_tenure: A profile's social tenure entity.
        :type social_tenure: SocialTenure
        """
        self._social_tenure = social_tenure
        self.select_parties(self._social_tenure.parties)

    def _load_profile_entities(self):
        # Reset view
        self.clear()

        # Populate entity items in the view
        for e in self._profile.user_entities():
            self._add_entity(e)

    def _add_entity(self, party):
        # Add entity item to view
        item = QStandardItem(QIcon(':/plugins/stdm/images/icons/table.png'),
                             party.short_name)
        item.setCheckable(True)
        item.setCheckState(Qt.Unchecked)

        self._model.appendRow(item)

    def select_parties(self, parties):
        """
        Checks party entities in the view and emit the party_selected
        signal for each item selected.
        :param parties: Collection of STR party entities.
        :type parties: list
        """
        # Clear selection
        self.clear_selection()

        for p in parties:
            name = p.short_name
            self.select_party(name)

    def parties(self):
        """
        :return: Returns a list of selected party names.
        :rtype: list
        """
        selected_items = []

        for i in range(self._model.rowCount()):
            item = self._model.item(i)
            if item.checkState() == Qt.Checked:
                selected_items.append(item.text())

        return selected_items

    def clear(self):
        """
        Remove all party items in the view.
        """
        self._model.clear()
        self._model.setColumnCount(1)

    def clear_selection(self):
        """
        Uncheck all items in the view.
        """
        for i in range(self._model.rowCount()):
            item = self._model.item(i)
            if item.checkState() == Qt.Checked:
                item.setCheckState(Qt.Unchecked)

    def select_party(self, name):
        """
        Selects a party entity with the given short name.
        :param name: Entity short name
        :type name: str
        """
        items = self._model.findItems(name)
        if len(items) > 0:
            item = items[0]
            if item.checkState() == Qt.Unchecked:
                item.setCheckState(Qt.Checked)

    def deselect_party(self, name):
        """
        Deselects a party entity with the given short name.
        :param name: Entity short name
        :type name: str
        """
        items = self._model.findItems(name)
        if len(items) > 0:
            item = items[0]
            if item.checkState() == Qt.Checked:
                item.setCheckState(Qt.Unchecked)
예제 #9
0
class LogDialog(QDialog):
    """LogDialog for the Freeseer project.

    It is the dialog window for the log.
    There is an instance for every FreeseerApp.
    It has a LogHandler which calls LogDialog's
    message() method when a new log message is received.
    The call to message() causes a call to add_entry()
    which adds the information to a new row in the table.
    """

    def __init__(self, parent=None):
        super(LogDialog, self).__init__(parent)

        self.resize(800, 500)

        self.app = QApplication.instance()

        icon = QIcon()
        icon.addPixmap(QPixmap(_fromUtf8(":/freeseer/logo.png")), QIcon.Normal, QIcon.Off)
        self.setWindowIcon(icon)

        layout = QVBoxLayout()
        self.setLayout(layout)

        self.level = 0
        self.handler = LogHandler()

        self.table_model = QStandardItemModel(0, 5)
        header_names = ["Date", "Level", "Module", "Message", "LevelNo"]
        date_column = header_names.index("Date")
        level_column = header_names.index("Level")
        module_column = header_names.index("Module")
        self.level_num_column = header_names.index("LevelNo")
        self.table_model.setHorizontalHeaderLabels(header_names)

        self.table_view = QTableView()
        self.table_view.setModel(self.table_model)
        self.table_view.horizontalHeader().setStretchLastSection(True)
        self.table_view.setColumnWidth(date_column, 125)
        self.table_view.setColumnWidth(level_column, 60)
        self.table_view.setColumnWidth(module_column, 250)
        self.table_view.setColumnHidden(self.level_num_column, True)
        self.table_view.setShowGrid(False)
        self.table_view.horizontalHeader().setClickable(False)
        self.table_view.verticalHeader().hide()
        self.table_view.setStyleSheet("""Qtable_view::item {
            border-bottom: 1px solid lightgrey;
            selection-background-color: white;
            selection-color: black;
            }""")

        top_panel = QHBoxLayout()
        self.log_levels = ["Debug", "Info", "Warning", "Error"]
        self.level_colors = ["#3E4C85", "#269629", "#B0AB21", "#B32020"]

        self.levels_label = QLabel("Filter Level: ")
        self.levels_label.setStyleSheet("QLabel { font-weight: bold }")
        self.current_level_label = QLabel(self.log_levels[0])
        self.current_level_label.setStyleSheet("QLabel {{ color: {} }}".format(self.level_colors[0]))
        self.clear_button = QPushButton("Clear Log")
        self.levels_slider = QSlider(Qt.Horizontal)
        self.levels_slider.setStyleSheet("""
        QSlider::handle:horizontal {
            background: qlineargradient(x1:0, y1:0, x2:1, y2:1,
                stop:0 #FFFFFF, stop:1 #E3E3E3);
            border: 1px solid #707070;
            width: 10px;
            margin-top: -4px;
            margin-bottom: -4px;
            border-radius: 4px;
        }

        QSlider::handle:horizontal:hover {
            background: qlineargradient(x1:0, y1:0, x2:1, y2:1,
                stop:0 #DEDEDE, stop:1 #C9C9C9);
            border: 1px solid #4F4F4F;
            border-radius: 4px;
        }

        QSlider::sub-page:horizontal {
            background: qlineargradient(x1: 0, y1: 0,    x2: 0, y2: 1,
                stop: 0 #BFBFBF, stop: 1 #9E9E9E);
            background: qlineargradient(x1: 0, y1: 0.2, x2: 1, y2: 1,
                stop: 0 #9E9E9E, stop: 1 #858585);
            border: 1px solid #777;
            height: 10px;
            border-radius: 4px;
        }

        QSlider::add-page:horizontal {
            background: #fff;
            border: 1px solid #707070;
            height: 10px;
            border-radius: 4px;
        }""")
        self.levels_slider.setRange(0, len(self.log_levels) - 1)
        self.levels_slider.setTickPosition(QSlider.TicksBelow)
        self.levels_slider.setTickInterval(1)

        top_panel.addSpacerItem(QSpacerItem(10, 0))
        top_panel.addWidget(self.levels_label, 3)
        top_panel.addWidget(self.current_level_label, 2)
        top_panel.addWidget(self.levels_slider, 8)
        top_panel.addSpacerItem(QSpacerItem(25, 0))
        top_panel.addWidget(self.clear_button, 10)

        layout.addLayout(top_panel)
        layout.addWidget(self.table_view)

        self.connect(self.clear_button, SIGNAL('clicked()'), functools.partial(self.table_model.setRowCount, 0))
        self.connect(self.levels_slider, SIGNAL('valueChanged(int)'), self.slider_set_level)

        self.setWindowTitle("Log")
        self.handler.add_listener(self)

    def __del__(self):
        self.handler.remove_listener(self)

    def retranslate(self):
        self.setWindowTitle(self.app.translate("LogDialog", "Log"))
        self.clear_button.setText(self.app.translate("LogDialog", "Clear Log"))
        self.levels_label.setText("{}: ".format(self.app.translate("LogDialog", "Filter Level")))

    def message(self, message):
        """Passes the log fields to add_entry()

        It is called by LogHandler when a log message is received"""
        self.add_entry(message["time"], message["level"], message["full_module_name"], message["message"], str(message["levelno"]))

    def add_entry(self, date, level, module, message, levelno):
        """Adds the given fields to a new row in the log table

        It is called by message() when a log message is received"""
        items = [QStandardItem(date), QStandardItem(level), QStandardItem(module), QStandardItem(message), QStandardItem(levelno)]
        for item in items:
            item.setEditable(False)
        self.table_model.appendRow(items)

    def slider_set_level(self, level):
        self.current_level_label.setText(self.log_levels[level])
        self.current_level_label.setStyleSheet("QLabel {{ color: {} }}".format(self.level_colors[level]))
        self.set_level(level + 1)

    def set_level(self, level):
        """Sets the current level of the LogDialog.

        Level is based on the selection made in the levels_combo_box.
        It hides all messages with a lower level."""
        self.level = level * 10
        for i in range(self.table_model.rowCount()):
            if int(str(self.table_model.item(i, self.level_num_column).text())) < self.level:
                self.table_view.setRowHidden(i, True)
            else:
                self.table_view.setRowHidden(i, False)
예제 #10
0
class SubPowerWidget(QWidget):
	"""
	@brief Zeigt alle Unterkräfte in einer Baumstruktur an.
	"""


	def __init__(self, template, character, parent=None):
		super(SubPowerWidget, self).__init__(parent)

		self.__storage = template
		self.__character = character

		self.__model = QStandardItemModel()
		# Das ungenutzte Model dient dazu, alle Unterkräfte aufzunehmen, die ich nicht darstellen möchte. Ist einfacher, als diese im View zu verstecken.
		self.__modelUnused = QStandardItemModel()

		self._layout = QVBoxLayout()
		self.setLayout( self._layout )

		self.__view = QTreeView()
		self.__view.setHeaderHidden(True)
		self.__view.setModel( self.__model)

		self._layout.addWidget(self.__view)

		self._typ = "Subpower"
		categories = self.__storage.categories(self._typ)

		self.__items = {}

		self.__rootItem = QStandardItem()
		self.__rootItem = self.__model.invisibleRootItem()

		self.__rootItemUnused = QStandardItem()
		self.__rootItemUnused = self.__modelUnused.invisibleRootItem()

		for item in categories:
			categoryItem = QStandardItem(item)
			self.__rootItem.appendRow(categoryItem)

			## Ich benötige diese Items auch im ungenutzten Model.
			categoryItemUnused = QStandardItem(item)
			self.__rootItemUnused.appendRow(categoryItemUnused)
			
			traitList = list( self.__character.traits[self._typ][item].items() )
			traitList.sort()
			for trait in traitList:
				traitItem = QStandardItem(trait[1].name)
				traitItem.setCheckable(True)
				## Unhashable Type
				self.__items[trait[1]] = traitItem
				categoryItem.appendRow(traitItem)

				## Funktioniert mit PySide nicht:
				#trait[1].availableChanged.connect(traitItem.setEnabled)
				## Funktioniert auch mit PySide:
				trait[1].availableChanged.connect(
					lambda enable, item=traitItem: item.setEnabled(enable)
				)
				trait[1].valueChanged.connect(
					lambda val, trait=trait[1], item=traitItem: self.__setItemValue(trait, item)
				)

		self.__model.itemChanged.connect(self.__getItemValue)
		self.__character.speciesChanged.connect(self.hideOrShowToolPage)
		self.__character.breedChanged.connect(self.hideOrShowToolPage)
		self.__character.factionChanged.connect(self.hideOrShowToolPage)


	def __setItemValue(self, trait, item):
		"""
		Setzt den Wert der Angezeigten Items.
		"""

		if trait.value == 0:
			item.setCheckState(Qt.Unchecked)
		elif trait.value == 1:
			item.setCheckState(Qt.PartiallyChecked)
		else:
			item.setCheckState(Qt.Checked)


	def __getItemValue(self, item):
		"""
		Setzt den Wert der Eigenschaft im Speicher.
		"""

		for trait in self.__items.items():
			if id(trait[1]) == id(item):
				trait[0].value = item.checkState()
				break


	def hideOrShowToolPage(self, res):
		"""
		Alle Eigenschaften, die nicht zur Verfügung stehen, werden verborgen, indem sie in ein anderes Model verschoben werden.

		\bug Möglicher Fehler in PySide: Der Aufruf von QStandardItem.model() führt beim Beenden des Programms zu einem Segmentation Fault.
		"""

		# Versteckt alle Unterkräfte, die zu gewähltem Charakter nicht passen.
		for item in self.__items.items():
			if (
				(
					item[0].species and
					item[0].species != self.__character.species
				) or (
					item[0].only and
					self.__character.breed not in item[0].only and
					self.__character.faction not in item[0].only
				)
			):
				#self.__view.setRowHidden(item[1].index().row(), item[1].parent().index(), True)
				#Debug.debug(item[1].model())
				## Hier wird beispielsweise besagter Aufruf getätigt, der zu einem segfault führt.
				if item[1].model() == self.__model:
					parent = item[1].parent()
					itemUnused = parent.takeRow(item[1].index().row())
					parentUnused = self.__modelUnused.findItems(parent.text())[0]
					parentUnused.appendRow(itemUnused)
			else:
				#self.__view.setRowHidden(item[1].index().row(), item[1].parent().index(), False)
				if item[1].model() == self.__modelUnused:
					parent = item[1].parent()
					itemUsed = parent.takeRow(item[1].index().row())
					parentUsed = self.__model.findItems(parent.text())[0]
					parentUsed.appendRow(itemUsed)

		## Versteckt alle Elternzeilen, wenn sie keine Kinder enthalten.
		for i in range(self.__model.rowCount()):
			categoryItem = self.__model.item(i)
			if categoryItem.hasChildren():
				self.__view.setRowHidden(categoryItem.index().row(), self.__rootItem.index(), False)
			else:
				self.__view.setRowHidden(categoryItem.index().row(), self.__rootItem.index(), True)
예제 #11
0
class MSClusteringController(MSDialogController):
    """
    Class to Control the gui and the model for clustering
    
    """
    POS_ADDUCTS=path.normcase('config/databases/POS_ADDUCTS.csv'), \
                path.normcase('config/databases/POS_ADDUCTS_LOW_RES.csv')
    NEG_ADDUCTS=path.normcase('config/databases/NEG_ADDUCTS.csv'), \
                path.normcase('config/databases/NEG_ADDUCTS_LOW_RES.csv')
    FRAGMENTS=path.normcase('config/databases/FRAGMENTS.csv'), \
              path.normcase('config/databases/FRAGMENTS_LOW_RES.csv')
              
    def __init__(self, lspl, visu, creation):
        MSDialogController.__init__(self, lspl, visu, creation)
        self.polarity=1 #initialisation
        if not self.model:
            self.goodIdx = 0
        else:
            self.goodIdx = 0 if self.model[0].kind == 'HighRes' else 1
        
        self.populateTableViews(self.polarity)
        self.allAddsChecked = False
        self.allFragsChecked = False
        QObject.connect(self.view.posmode, SIGNAL('toggled(bool)'), self.updatePolarity)
        QObject.connect(self.view.checkAllAdds, SIGNAL('clicked()'), self.checkAdds)
        QObject.connect(self.view.checkAllFrags, SIGNAL('clicked()'), self.checkFrags)
        
        self.view.exec_()
    
    
    def getFragAddData(self, polarity=1):
        """parsing adducts and fragments files"""
        frags=self.readData(self.FRAGMENTS[self.goodIdx])
        if not polarity:
            adds=self.readData(self.NEG_ADDUCTS[self.goodIdx])
        elif polarity:
            adds=self.readData(self.POS_ADDUCTS[self.goodIdx])
        return frags, adds
    
    
    def readData(self, file_):
        """read data from databases files"""
        def fragData(line, d):
            d[(s[0], s[1], str(1))]= False
            
        def addData(line, d):
            d[(s[0], s[-1].rstrip(), s[1])]= False
        
        routine=None
        if file_ in (self.POS_ADDUCTS+self.NEG_ADDUCTS):
            routine=addData
        elif file_ in self.FRAGMENTS:
            routine=fragData
        else:
            print ("Error reading adducts and fragments files")
            return
        res=OrderedDict()        
        with open(file_) as f:
            for i in range (2):
                l=f.readline()
            while l!="":
                s=l.split(',')
                routine(l, res)
                l=f.readline()
        return res
    
    
    def checkAdds(self):
        for i in xrange(self.adductsModel.rowCount()):
            #data = self.adductsModel.item(i,0).text()
            item = self.adductsModel.item(i,0)
            if self.allAddsChecked:
                item.setCheckState(0)
                self.view.checkAllAdds.setText('Check All')
            else:
                item.setCheckState(2)
                self.view.checkAllAdds.setText('UnCheck All')
        self.allAddsChecked = not self.allAddsChecked
                   
    def checkFrags(self):
        for i in xrange(self.fragsModel.rowCount()):
            #data = self.fragsModel.item(i,0).text()
            item = self.fragsModel.item(i,0)
            if self.allFragsChecked:
                item.setCheckState(0)
                self.view.checkAllFrags.setText('Check All')
            else:
                item.setCheckState(2)
                self.view.checkAllFrags.setText('UnCheck All')
        self.allFragsChecked = not self.allFragsChecked
        
        
    def populateTableViews(self, polarity):
        frags, adds = self.getFragAddData(polarity)
        self.adductsModel, self.fragsModel = QStandardItemModel(), QStandardItemModel()
        self.adductsModel.setHorizontalHeaderLabels(["Adducts(name, mass, nmol)"])
        self.fragsModel.setHorizontalHeaderLabels(["Fragments(name, mass, nmol)"])
        
        for i, adduct in enumerate(adds.keys()):
            item =QStandardItem(', '.join(map(str, adduct)))
            item.setCheckable(True)
            if adds[adduct]:
                item.setCheckState(2)
            else:
                item.setCheckState(0)
            self.adductsModel.setItem(i, 0, item)
        self.view.adductsTable.setModel(self.adductsModel)
        
        for i, frag in enumerate(frags.keys()):
            item = QStandardItem(', '.join(map(str, frag)))
            item.setCheckable(True)
            if frags[frag]:
                item.setCheckState(2)
            else:
                item.setCheckState(0)
            self.fragsModel.setItem(i, 0, item)
        self.view.fragTable.setModel(self.fragsModel)
    
    def getFragsAndAdductsToCheck(self):
        frags, adducts={}, {}
        for i in range(self.fragsModel.rowCount()):
            data = self.fragsModel.item(i,0).text()
            item = self.fragsModel.item(i,0)
            if item.checkState():
                frags[tuple([str(x) for x in data.split(', ')])]= True
            else:
                frags[tuple([str(x) for x in data.split(', ')])]= False
                
        for i in range(self.adductsModel.rowCount()):
            data = self.adductsModel.item(i,0).text()
            item = self.adductsModel.item(i,0)
            if item.checkState():
                adducts[tuple([str(x) for x in data.split(', ')])]= True
            else:
                adducts[tuple([str(x) for x in data.split(', ')])]= False

        checkMasses=OrderedDict()        
        for frag in frags.keys():
            if frags[frag]:
                checkMasses[(float(frag[1]), float(frag[2]))] = frag[0]
        for add in adducts.keys():
            if adducts[add]:
                if self.polarity:#positive polarity
                    checkMasses[(-float(add[1]), float(add[2]))] = add[0]
                elif not self.polarity:#negative polarity
                    checkMasses[(float(add[1]), float(add[2]))] = add[0]
        return checkMasses
    

    def updatePolarity(self, boolean):
        self.polarity = 1 if boolean else 0#positive, negative
        self.populateTableViews(self.polarity)
    
    
    def getParameters(self):
        """classical getParameters (model) function"""
        
        self.parameters["rtError"] = self.view.lineEdit_2.value()
        self.parameters["clusterLength"] = self.view.lineEdit_3.value()
        self.parameters["idmsLength"] =tuple([float(x) for x in self.view.lineEdit_4.text().split('-')])
        self.parameters["badPeaks"] = self.view.lineEdit_5.isChecked()
        #self.parameters["useCorr"] = self.view.check.isChecked()
        self.parameters["gap"]=self.view.spinBox.value()
        self.parameters["resolveConflicts"]=self.view.lineEdit_6.isChecked()
        self.parameters["frags"]=self.getFragsAndAdductsToCheck()
    
    
    def startTask(self):
        """
        Main Function (model function) Clustering
        
        """
        MSDialogController.startTask(self)
        #qApp.instance().view.showInStatusBar("Clustering Step...Please Wait..",  5000)
        self.task = MSClusterThread(self.sampleList, **self.parameters)
        QObject.connect(self.view, SIGNAL('destroyed(QObject *)'), self.task.begin)
        #self.connect(self.view, SIGNAL('destroyed(QObject *)'), self.setViewToNone)
        QObject.connect(self.task, SIGNAL("started()"),qApp.instance().view.to_determined_mode)
        QObject.connect(self.task, SIGNAL('update_pb'), qApp.instance().view.updateProgressBar)
        #QObject.connect(self.task, SIGNAL("finished()"),qApp.instance().view.to_determined_mode)
        QObject.connect(self.task, SIGNAL("finished()"), self.setModels)
        #print "about to close"
        self.view.close()
        #print "closed"
        #self.task.begin()
    
    def setModels(self):#, sampleList):
        """
        closing function of the process
        
        """
        qApp.instance().view.showInformationMessage("Clustering done", "Clustering Done succesfully !")
        qApp.instance().view.tabWidget.setCurrentIndex(2)
        

    
    def _initialize(self):
        """initialization of the parameters"""
        
        self.view.lineEdit_2.setValue(6.)
        self.view.lineEdit_3.setValue(6)
        self.view.lineEdit_4.setText("0-0")
        #self.view.lineEdit_5.setText("10.")
        self.view.decrOrder.setChecked(True)
        self.view.lineEdit_6.setChecked(True)
        self.view.spinBox.setValue(0)
예제 #12
0
class ModelAtrributesView(QListView):
    """
    Custom QListView implementation that displays checkable model attributes.
    """
    def __init__(self,parent=None,dataModel = None):
        QListView.__init__(self, parent)
        
        self._dataModel = dataModel
        self._selectedDisplayMapping = OrderedDict()
        self._modelDisplayMapping = OrderedDict()
        self._attrModel = QStandardItemModel(self)
        
    def dataModel(self):
        """
        Returns the data model instance.
        """
        return self._dataModel
    
    def setDataModel(self,dataModel):
        """
        Sets the data model. Should be a callable class rather than the class.
        instance.
        """
        if callable(dataModel):
            self._dataModel = dataModel
            
        else:
            self._dataModel = dataModel.__class__
    
    def modelDisplayMapping(self):
        """
        Returns the column name and display name collection.
        """
        return self._modelDisplayMapping
    
    def setModelDisplayMapping(self, dataMapping):
        """
        Sets the mapping dictionary for the table object
        """
        if dataMapping != None:
            self._modelDisplayMapping=dataMapping

    def load(self, sort=False):
        """
        Load the model's attributes into the list view.
        """
        if self._dataModel == None:
            return
        
        try:
            self._loadAttrs(self._dataModel.displayMapping(), sort)
        except AttributeError:
            #Ignore error if model does not contain the displayMapping static method
            pass

    def load_mapping(self, mapping, sort=False):
        """
        Load collection containing column name and corresponding display name.
        """
        self._modelDisplayMapping = mapping

        self._loadAttrs(mapping, sort)

    def sort(self):
        """
        Sorts display name in ascending order.
        """
        self._attrModel.sort(0)
        
    def _loadAttrs(self, attrMapping, sort=False):
        """
        Loads display mapping into the list view.
        Specify to sort display names in ascending order once items have been
        added to the model.
        """
        self._attrModel.clear()
        self._attrModel.setColumnCount(2)
        
        for attrName,displayName in attrMapping.iteritems():
            #Exclude row ID in the list, other unique identifier attributes in the model can be used
            if attrName != "id":
                displayNameItem = QStandardItem(displayName)
                displayNameItem.setCheckable(True)
                attrNameItem = QStandardItem(attrName)
                
                self._attrModel.appendRow([displayNameItem,attrNameItem])
            
        self.setModel(self._attrModel)

        if sort:
            self._attrModel.sort(0)
        
    def selectedMappings(self):
        """
        Return a dictionary of field names and their corresponding display values.
        """
        selectedAttrs = {}
        
        for i in range(self._attrModel.rowCount()):
            displayNameItem = self._attrModel.item(i,0)
            
            if displayNameItem.checkState() == Qt.Checked:
                attrNameItem = self._attrModel.item(i,1)  
                selectedAttrs[attrNameItem.text()] = displayNameItem.text()
        
        return selectedAttrs
예제 #13
0
class OWConfusionMatrix(widget.OWWidget):
    """Confusion matrix widget"""

    name = "Confusion Matrix"
    description = "Display a confusion matrix constructed from " \
                  "the results of classifier evaluations."
    icon = "icons/ConfusionMatrix.svg"
    priority = 1001

    inputs = [("Evaluation Results", Orange.evaluation.Results, "set_results")]
    outputs = [("Selected Data", Orange.data.Table)]

    quantities = [
        "Number of instances", "Proportion of predicted",
        "Proportion of actual"
    ]

    settingsHandler = settings.ClassValuesContextHandler()

    selected_learner = settings.Setting([0], schema_only=True)
    selection = settings.ContextSetting(set())
    selected_quantity = settings.Setting(0)
    append_predictions = settings.Setting(True)
    append_probabilities = settings.Setting(False)
    autocommit = settings.Setting(True)

    UserAdviceMessages = [
        widget.Message(
            "Clicking on cells or in headers outputs the corresponding "
            "data instances", "click_cell")
    ]

    def __init__(self):
        super().__init__()

        self.data = None
        self.results = None
        self.learners = []
        self.headers = []

        box = gui.vBox(self.controlArea, "Learners")

        self.learners_box = gui.listBox(box,
                                        self,
                                        "selected_learner",
                                        "learners",
                                        callback=self._learner_changed)
        box = gui.vBox(self.controlArea, "Show")

        gui.comboBox(box,
                     self,
                     "selected_quantity",
                     items=self.quantities,
                     callback=self._update)

        box = gui.vBox(self.controlArea, "Select")

        gui.button(box,
                   self,
                   "Select Correct",
                   callback=self.select_correct,
                   autoDefault=False)
        gui.button(box,
                   self,
                   "Select Misclassified",
                   callback=self.select_wrong,
                   autoDefault=False)
        gui.button(box,
                   self,
                   "Clear Selection",
                   callback=self.select_none,
                   autoDefault=False)

        self.outputbox = box = gui.vBox(self.controlArea, "Output")
        gui.checkBox(box,
                     self,
                     "append_predictions",
                     "Predictions",
                     callback=self._invalidate)
        gui.checkBox(box,
                     self,
                     "append_probabilities",
                     "Probabilities",
                     callback=self._invalidate)

        gui.auto_commit(self.controlArea, self, "autocommit", "Send Selected",
                        "Send Automatically")

        grid = QGridLayout()

        self.tablemodel = QStandardItemModel(self)
        view = self.tableview = QTableView(
            editTriggers=QTableView.NoEditTriggers)
        view.setModel(self.tablemodel)
        view.horizontalHeader().hide()
        view.verticalHeader().hide()
        view.horizontalHeader().setMinimumSectionSize(60)
        view.selectionModel().selectionChanged.connect(self._invalidate)
        view.setShowGrid(False)
        view.setItemDelegate(BorderedItemDelegate(Qt.white))
        view.clicked.connect(self.cell_clicked)
        grid.addWidget(view, 0, 0)
        self.mainArea.layout().addLayout(grid)

    def sizeHint(self):
        """Initial size"""
        return QSize(750, 490)

    def _item(self, i, j):
        return self.tablemodel.item(i, j) or QStandardItem()

    def _set_item(self, i, j, item):
        self.tablemodel.setItem(i, j, item)

    def _init_table(self, nclasses):
        item = self._item(0, 2)
        item.setData("Predicted", Qt.DisplayRole)
        item.setTextAlignment(Qt.AlignCenter)
        item.setFlags(Qt.NoItemFlags)

        self._set_item(0, 2, item)
        item = self._item(2, 0)
        item.setData("Actual", Qt.DisplayRole)
        item.setTextAlignment(Qt.AlignHCenter | Qt.AlignBottom)
        item.setFlags(Qt.NoItemFlags)
        self.tableview.setItemDelegateForColumn(0, gui.VerticalItemDelegate())
        self._set_item(2, 0, item)
        self.tableview.setSpan(0, 2, 1, nclasses)
        self.tableview.setSpan(2, 0, nclasses, 1)

        font = self.tablemodel.invisibleRootItem().font()
        bold_font = QFont(font)
        bold_font.setBold(True)

        for i in (0, 1):
            for j in (0, 1):
                item = self._item(i, j)
                item.setFlags(Qt.NoItemFlags)
                self._set_item(i, j, item)

        for p, label in enumerate(self.headers):
            for i, j in ((1, p + 2), (p + 2, 1)):
                item = self._item(i, j)
                item.setData(label, Qt.DisplayRole)
                item.setFont(bold_font)
                item.setTextAlignment(Qt.AlignRight | Qt.AlignVCenter)
                item.setFlags(Qt.ItemIsEnabled)
                if p < len(self.headers) - 1:
                    item.setData("br"[j == 1], BorderRole)
                    item.setData(QColor(192, 192, 192), BorderColorRole)
                self._set_item(i, j, item)

        hor_header = self.tableview.horizontalHeader()
        if len(' '.join(self.headers)) < 120:
            hor_header.setResizeMode(QHeaderView.ResizeToContents)
        else:
            hor_header.setDefaultSectionSize(60)
        self.tablemodel.setRowCount(nclasses + 3)
        self.tablemodel.setColumnCount(nclasses + 3)

    def set_results(self, results):
        """Set the input results."""

        prev_sel_learner = self.selected_learner.copy()
        self.clear()
        self.warning()
        self.closeContext()

        data = None
        if results is not None and results.data is not None:
            data = results.data

        if data is not None and not data.domain.has_discrete_class:
            self.warning("Confusion Matrix cannot show regression results.")

        self.results = results
        self.data = data

        if data is not None:
            class_values = data.domain.class_var.values
        elif results is not None:
            raise NotImplementedError

        if results is None:
            self.report_button.setDisabled(True)
        else:
            self.report_button.setDisabled(False)

            nmodels = results.predicted.shape[0]
            self.headers = class_values + \
                           [unicodedata.lookup("N-ARY SUMMATION")]

            # NOTE: The 'learner_names' is set in 'Test Learners' widget.
            if hasattr(results, "learner_names"):
                self.learners = results.learner_names
            else:
                self.learners = [
                    "Learner #{}".format(i + 1) for i in range(nmodels)
                ]

            self._init_table(len(class_values))
            self.openContext(data.domain.class_var)
            if not prev_sel_learner or prev_sel_learner[0] >= len(
                    self.learners):
                self.selected_learner[:] = [0]
            else:
                self.selected_learner[:] = prev_sel_learner
            self._update()
            self._set_selection()
            self.unconditional_commit()

    def clear(self):
        """Reset the widget, clear controls"""
        self.results = None
        self.data = None
        self.tablemodel.clear()
        self.headers = []
        # Clear learners last. This action will invoke `_learner_changed`
        self.learners = []

    def select_correct(self):
        """Select the diagonal elements of the matrix"""
        selection = QItemSelection()
        n = self.tablemodel.rowCount()
        for i in range(2, n):
            index = self.tablemodel.index(i, i)
            selection.select(index, index)
        self.tableview.selectionModel().select(
            selection, QItemSelectionModel.ClearAndSelect)

    def select_wrong(self):
        """Select the off-diagonal elements of the matrix"""
        selection = QItemSelection()
        n = self.tablemodel.rowCount()
        for i in range(2, n):
            for j in range(i + 1, n):
                index = self.tablemodel.index(i, j)
                selection.select(index, index)
                index = self.tablemodel.index(j, i)
                selection.select(index, index)
        self.tableview.selectionModel().select(
            selection, QItemSelectionModel.ClearAndSelect)

    def select_none(self):
        """Reset selection"""
        self.tableview.selectionModel().clear()

    def cell_clicked(self, model_index):
        """Handle cell click event"""
        i, j = model_index.row(), model_index.column()
        if not i or not j:
            return
        n = self.tablemodel.rowCount()
        index = self.tablemodel.index
        selection = None
        if i == j == 1 or i == j == n - 1:
            selection = QItemSelection(index(2, 2), index(n - 1, n - 1))
        elif i in (1, n - 1):
            selection = QItemSelection(index(2, j), index(n - 1, j))
        elif j in (1, n - 1):
            selection = QItemSelection(index(i, 2), index(i, n - 1))

        if selection is not None:
            self.tableview.selectionModel().select(
                selection, QItemSelectionModel.ClearAndSelect)

    def commit(self):
        """Output data instances corresponding to selected cells"""
        if self.results is not None and self.data is not None \
                and self.selected_learner:
            indices = self.tableview.selectedIndexes()
            indices = {(ind.row() - 2, ind.column() - 2) for ind in indices}
            actual = self.results.actual
            learner_name = self.learners[self.selected_learner[0]]
            predicted = self.results.predicted[self.selected_learner[0]]
            selected = [
                i for i, t in enumerate(zip(actual, predicted)) if t in indices
            ]
            row_indices = self.results.row_indices[selected]

            extra = []
            class_var = self.data.domain.class_var
            metas = self.data.domain.metas

            if self.append_predictions:
                predicted = numpy.array(predicted[selected], dtype=object)
                extra.append(predicted.reshape(-1, 1))
                var = Orange.data.DiscreteVariable(
                    "{}({})".format(class_var.name, learner_name),
                    class_var.values)
                metas = metas + (var, )

            if self.append_probabilities and \
                    self.results.probabilities is not None:
                probs = self.results.probabilities[self.selected_learner[0],
                                                   selected]
                extra.append(numpy.array(probs, dtype=object))
                pvars = [
                    Orange.data.ContinuousVariable("p({})".format(value))
                    for value in class_var.values
                ]
                metas = metas + tuple(pvars)

            X = self.data.X[row_indices]
            Y = self.data.Y[row_indices]
            M = self.data.metas[row_indices]
            row_ids = self.data.ids[row_indices]

            M = numpy.hstack((M, ) + tuple(extra))
            domain = Orange.data.Domain(self.data.domain.attributes,
                                        self.data.domain.class_vars, metas)
            data = Orange.data.Table.from_numpy(domain, X, Y, M)
            data.ids = row_ids
            data.name = learner_name

        else:
            data = None

        self.send("Selected Data", data)

    def _invalidate(self):
        indices = self.tableview.selectedIndexes()
        self.selection = {(ind.row() - 2, ind.column() - 2) for ind in indices}
        self.commit()

    def _set_selection(self):
        selection = QItemSelection()
        index = self.tableview.model().index
        for row, col in self.selection:
            sel = index(row + 2, col + 2)
            selection.select(sel, sel)
        self.tableview.selectionModel().select(
            selection, QItemSelectionModel.ClearAndSelect)

    def _learner_changed(self):
        self._update()
        self._set_selection()
        self.commit()

    def _update(self):
        def _isinvalid(x):
            return isnan(x) or isinf(x)

        # Update the displayed confusion matrix
        if self.results is not None and self.selected_learner:
            cmatrix = confusion_matrix(self.results, self.selected_learner[0])
            colsum = cmatrix.sum(axis=0)
            rowsum = cmatrix.sum(axis=1)
            n = len(cmatrix)
            diag = numpy.diag_indices(n)

            colors = cmatrix.astype(numpy.double)
            colors[diag] = 0
            if self.selected_quantity == 0:
                normalized = cmatrix.astype(numpy.int)
                formatstr = "{}"
                div = numpy.array([colors.max()])
            else:
                if self.selected_quantity == 1:
                    normalized = 100 * cmatrix / colsum
                    div = colors.max(axis=0)
                else:
                    normalized = 100 * cmatrix / rowsum[:, numpy.newaxis]
                    div = colors.max(axis=1)[:, numpy.newaxis]
                formatstr = "{:2.1f} %"
            div[div == 0] = 1
            colors /= div
            colors[diag] = normalized[diag] / normalized[diag].max()

            for i in range(n):
                for j in range(n):
                    val = normalized[i, j]
                    col_val = colors[i, j]
                    item = self._item(i + 2, j + 2)
                    item.setData(
                        "NA" if _isinvalid(val) else formatstr.format(val),
                        Qt.DisplayRole)
                    bkcolor = QColor.fromHsl(
                        [0, 240][i == j], 160,
                        255 if _isinvalid(col_val) else int(255 -
                                                            30 * col_val))
                    item.setData(QBrush(bkcolor), Qt.BackgroundRole)
                    item.setData("trbl", BorderRole)
                    item.setToolTip("actual: {}\npredicted: {}".format(
                        self.headers[i], self.headers[j]))
                    item.setTextAlignment(Qt.AlignRight | Qt.AlignVCenter)
                    item.setFlags(Qt.ItemIsEnabled | Qt.ItemIsSelectable)
                    self._set_item(i + 2, j + 2, item)

            bold_font = self.tablemodel.invisibleRootItem().font()
            bold_font.setBold(True)

            def _sum_item(value, border=""):
                item = QStandardItem()
                item.setData(value, Qt.DisplayRole)
                item.setTextAlignment(Qt.AlignRight | Qt.AlignVCenter)
                item.setFlags(Qt.ItemIsEnabled)
                item.setFont(bold_font)
                item.setData(border, BorderRole)
                item.setData(QColor(192, 192, 192), BorderColorRole)
                return item

            for i in range(n):
                self._set_item(n + 2, i + 2, _sum_item(int(colsum[i]), "t"))
                self._set_item(i + 2, n + 2, _sum_item(int(rowsum[i]), "l"))
            self._set_item(n + 2, n + 2, _sum_item(int(rowsum.sum())))

    def send_report(self):
        """Send report"""
        if self.results is not None and self.selected_learner:
            self.report_table(
                "Confusion matrix for {} (showing {})".format(
                    self.learners[self.selected_learner[0]],
                    self.quantities[self.selected_quantity].lower()),
                self.tableview)
예제 #14
0
class ObstacleTable(QSortFilterProxyModel):

    MocMultiplier = 1
    SelectionMode = SelectionModeType.Automatic

    def __init__(self, surfacesList, fileWriter=None):
        QSortFilterProxyModel.__init__(self)
        ObstacleTable.SelectionMode = SelectionModeType.Automatic
        self.manualPolygon = None
        self.surfacesList = surfacesList
        self.surfaceType = None
        self.source = QStandardItemModel()
        self.setSourceModel(self.source)
        #         tableView.hideColumn(self.IndexObjectId)
        #         tableView.hideColumn(self.IndexLayerId)
        #         tableView.hideColumn(self.IndexX)
        #         tableView.hideColumn(self.IndexY)
        #         tableView.hideColumn(self.IndexLat)
        #         tableView.hideColumn(self.IndexLon)
        #         tableView.hideColumn(self.IndexSurface)
        self.hideColumnLabels = [
            ObstacleTableColumnType.ObjectId, ObstacleTableColumnType.LayerId,
            ObstacleTableColumnType.X, ObstacleTableColumnType.Y,
            ObstacleTableColumnType.Lat, ObstacleTableColumnType.Lon,
            ObstacleTableColumnType.Surface
        ]

        self.fixedColumnLabels = [
            ObstacleTableColumnType.ObjectId, ObstacleTableColumnType.LayerId,
            ObstacleTableColumnType.Name, ObstacleTableColumnType.X,
            ObstacleTableColumnType.Y, ObstacleTableColumnType.Lat,
            ObstacleTableColumnType.Lon, ObstacleTableColumnType.AltM,
            ObstacleTableColumnType.AltFt, ObstacleTableColumnType.TreesM,
            ObstacleTableColumnType.TreesFt
        ]

        self.IndexObjectId = 0
        self.IndexLayerId = 1
        self.IndexName = 2
        self.IndexX = 3
        self.IndexY = 4
        self.IndexLat = 5
        self.IndexLon = 6
        self.IndexAltM = 7
        self.IndexAltFt = 8
        self.IndexTreesM = 9
        self.IndexTreesFt = 10
        self.IndexOcaM = -1
        self.IndexOcaFt = -1
        self.IndexOchM = -1
        self.IndexOchFt = -1
        self.IndexObstArea = -1
        self.IndexDistInSecM = -1
        self.IndexMocAppliedM = -1
        self.IndexMocAppliedFt = -1
        self.IndexMocMultiplier = -1
        self.IndexMocReqM = -1
        self.IndexMocReqFt = -1
        self.IndexDoM = -1
        self.IndexDrM = -1
        self.IndexDzM = -1
        self.IndexDxM = -1
        self.IndexDsocM = -1
        self.IndexHeightLossM = -1
        self.IndexHeightLossFt = -1
        self.IndexAcAltM = -1
        self.IndexAcAltFt = -1
        self.IndexAltReqM = -1
        self.IndexAltReqFt = -1
        self.IndexCritical = -1
        self.IndexMACG = -1
        self.IndexPDG = -1
        self.IndexSurfAltM = -1
        self.IndexSurfAltFt = -1
        self.IndexDifferenceM = -1
        self.IndexDifferenceFt = -1
        self.IndexIlsX = -1
        self.IndexIlsY = -1
        self.IndexEqAltM = -1
        self.IndexEqAltFt = -1
        self.IndexSurfaceName = -1
        self.IndexDisregardable = -1
        self.IndexCloseIn = -1
        self.IndexTag = -1
        self.IndexSurface = -1
        self.IndexArea = -1
        self.IndexHLAppliedM = -1
        self.setHeaderLabels()
        self.setFilterKeyColumn(self.IndexSurface)
        self.setSortRole(Qt.UserRole + 1)
        self.layoutChanged.connect(self.setVerticalHeader)
        self.btnLocate = None
        self.tblObstacles = None

    def FilterDisregardableObstacles(self, state):
        if state:
            self.setFilterKeyColumn(self.IndexDisregardable)
            self.setFilterFixedString("Yes")
            self.setFilterKeyColumn(self.IndexSurface)

    def setSurfaceType(self, surfaceType):
        self.surfaceType = surfaceType

    def setFilterFixedString(self, filterString):
        QSortFilterProxyModel.setFilterFixedString(self, filterString)
        self.setVerticalHeader()
        if self.btnLocate != None and self.tblObstacles != None:
            selectedIndexes = self.tblObstacles.selectedIndexes()
            if len(selectedIndexes) == 0:
                self.btnLocate.setEnabled(False)
            else:
                self.btnLocate.setEnabled(True)

    def setLocateBtn(self, btnLocate):
        self.btnLocate = btnLocate
        self.btnLocate.setEnabled(False)
        self.btnLocate.clicked.connect(self.btnLocateClicked)

    def btnLocateClicked(self):
        if self.tblObstacles == None:
            return
        selectedIndexes = self.tblObstacles.selectedIndexes()
        self.locate(selectedIndexes)

    def tblObstaclesClicked(self, idx):
        if len(self.tblObstacles.selectedIndexes()) > 0:
            self.btnLocate.setEnabled(True)

    def setTableView(self, tblObstacles):
        self.tblObstacles = tblObstacles
        self.tblObstacles.setSelectionBehavior(QAbstractItemView.SelectRows)
        self.tblObstacles.setSortingEnabled(True)
        self.tblObstacles.clicked.connect(self.tblObstaclesClicked)
        self.tblObstacles.verticalHeader().sectionClicked.connect(
            self.tblObstaclesClicked)
        pass

    def setHeaderLabels(self):
        #         print self.setHeaderData(1, Qt.Vertical, 1, Qt.DisplayRole)
        pass

    def setVerticalHeader(self):
        for i in range(self.rowCount()):
            self.setHeaderData(i, Qt.Vertical, i + 1, Qt.DisplayRole)

    def setHiddenColumns(self, tableView):
        tableView.hideColumn(self.IndexObjectId)
        tableView.hideColumn(self.IndexLayerId)
        tableView.hideColumn(self.IndexX)
        tableView.hideColumn(self.IndexY)
        tableView.hideColumn(self.IndexLat)
        tableView.hideColumn(self.IndexLon)
        tableView.hideColumn(self.IndexSurface)

    def getExtentForLocate(self, sourceRow):
        extent = None
        surfaceType = None
        if self.IndexSurface < 0:
            surfaceType = self.surfaceType
        else:
            surfaceType = self.source.item(sourceRow, self.IndexSurface).text()
        surfaceLayers = QgisHelper.getSurfaceLayers(self.surfaceType)
        for sfLayer in surfaceLayers:
            lId = sfLayer.name()
            if lId.contains(surfaceType):
                extent = sfLayer.extent()
                break
        return extent

    def clear(self):
        self.source.clear()
        self.source.setHorizontalHeaderLabels(self.fixedColumnLabels)
#         self.setHeaderLabels()

    def locate(self, selectedRowIndexes):
        if selectedRowIndexes == None or len(selectedRowIndexes) <= 0:
            return
        sourceRow = self.mapToSource(selectedRowIndexes[0]).row()
        objectId = int(self.source.item(sourceRow, self.IndexObjectId).text())
        layerId = self.source.item(sourceRow, self.IndexLayerId).text()
        QgisHelper.selectFeature(layerId, objectId)
        layer = QgsMapLayerRegistry.instance().mapLayer(layerId)
        crs = define._canvas.mapSettings().destinationCrs()
        if crs.mapUnits() == QGis.Meters:
            x = float(self.source.item(sourceRow, self.IndexX).text())
            y = float(self.source.item(sourceRow, self.IndexY).text())
            extent = QgsRectangle(x - 350, y - 350, x + 350, y + 350)
        else:
            x, result1 = self.source.item(sourceRow,
                                          self.IndexLon).data().toDouble()
            y, result2 = self.source.item(sourceRow,
                                          self.IndexLat).data().toDouble()
            extent = QgsRectangle(x - 0.005, y - 0.005, x + 0.005, y + 0.005)
        point = QgsPoint(x, y)
        # extent = self.getExtentForLocate(sourceRow)

        if extent is None:
            return

        QgisHelper.zoomExtent(point, extent, 2)
        pass

    def loadObstacles(self, surfaceLayers):
        if self.source.rowCount() > 0:
            self.source.clear()
            self.source.setHorizontalHeaderLabels(self.fixedColumnLabels)
        demEvaluateAg = None
        existingDemFlag = False
        obstacleLayersDEM = QgisHelper.getSurfaceLayers(SurfaceTypes.DEM)
        obstacleLayers = QgisHelper.getSurfaceLayers(SurfaceTypes.Obstacles)
        if obstacleLayersDEM != None and len(obstacleLayersDEM) > 0:
            if QMessageBox.question(
                    None, "Question",
                    "Do you want to use DEM for evaluating Obstacle?",
                    QMessageBox.Yes | QMessageBox.No) == QMessageBox.Yes:
                self.loadObstaclesDEM(obstacleLayersDEM, surfaceLayers)
        if obstacleLayers != None and len(obstacleLayers) > 0:
            #             if QMessageBox.question(None, "Question", "Do you want to use DEM for evaluating Obstacle?", QMessageBox.Yes | QMessageBox.No) == QMessageBox.No:
            self.loadObstaclesVector(obstacleLayers, surfaceLayers)
        return True

    def loadObstaclesDEM(self, obstacleLayersDEM, surfaceLayers):
        progressMessageBar = define._messagBar.createMessage(
            "Loading DEM Obstacles...")
        self.progress = QProgressBar()
        self.progress.setAlignment(Qt.AlignLeft | Qt.AlignVCenter)
        progressMessageBar.layout().addWidget(self.progress)
        define._messagBar.pushWidget(progressMessageBar,
                                     define._messagBar.INFO)
        maxium = 0
        offset = 0.0
        self.progress.setValue(0)
        wCount = 0
        hCount = 0
        for ly in obstacleLayersDEM:
            demDataProvider = ly.dataProvider()
            boundDem = demDataProvider.extent()
            xMin = boundDem.xMinimum()
            xMax = boundDem.xMaximum()
            yMin = boundDem.yMinimum()
            yMax = boundDem.yMaximum()
            bound = QgisHelper.getIntersectExtent(
                ly, QgsGeometry.fromRect(boundDem), surfaceLayers)
            #             boundGeom = QgsGeometry.fromRect(bound)
            if bound == None:
                continue
            block = ly.dataProvider().block(0, ly.extent(), ly.width(),
                                            ly.height())
            xMinimum = ly.dataProvider().extent().xMinimum()
            yMaximum = ly.dataProvider().extent().yMaximum()
            yMinimum = ly.dataProvider().extent().yMinimum()
            xMaximum = ly.dataProvider().extent().xMaximum()

            xOffSet = ly.extent().width() / ly.width()
            yOffSet = ly.extent().height() / ly.height()
            offset = xOffSet
            if bound.xMinimum() < xMinimum:
                wStartNumber = 0
                xStartValue = xMinimum
            else:
                wStartNumber = int((bound.xMinimum() - xMinimum) / xOffSet)
                xStartValue = bound.xMinimum()
            if yMaximum < bound.yMaximum():
                hStartNumber = 0
                yStartValue = yMaximum
            else:
                hStartNumber = int((yMaximum - bound.yMaximum()) / yOffSet)
                yStartValue = bound.yMaximum()

            if bound.xMaximum() > xMaximum:
                xEndValue = xMaximum
            else:
                xEndValue = bound.xMaximum()
            if yMinimum > bound.yMinimum():
                yEndValue = yMinimum
            else:
                yEndValue = bound.yMinimum()
            wCount = int(math.fabs(xEndValue - xStartValue) / xOffSet)
            hCount = int(math.fabs(yEndValue - yStartValue) / yOffSet)

            pixelCount = hCount
            maxium += pixelCount

        cellSizeWnd = cellsizeWnd(offset, wCount * hCount, maxium * 0.04)
        cellSizeWnd.setWindowTitle("Input Cell Size")
        result = cellSizeWnd.exec_()
        cellRate = 1
        if result == 1:
            offset = cellSizeWnd.cellsize
            maxium = cellSizeWnd.cellCount + 2
            cellRate = cellSizeWnd.cellRate


#             print cellSizeWnd.textedit1.text()

        if maxium == 0:
            return False
        self.progress.setMaximum(maxium)

        trees = define._treesDEM
        tolerance = define._toleranceDEM

        for obstacleLayer in obstacleLayersDEM:
            obstacleUnits = obstacleLayer.crs().mapUnits()
            demDataProvider = obstacleLayer.dataProvider()
            boundDem = demDataProvider.extent()
            bound = QgisHelper.getIntersectExtent(
                obstacleLayer, QgsGeometry.fromRect(boundDem), surfaceLayers)
            if bound == None:
                continue
            boundGeom = QgsGeometry.fromRect(bound)
            if not boundGeom.intersects(QgsGeometry.fromRect(boundDem)):
                continue
            block = obstacleLayer.dataProvider().block(1,
                                                       obstacleLayer.extent(),
                                                       obstacleLayer.width(),
                                                       obstacleLayer.height())
            xMinimum = obstacleLayer.extent().xMinimum()
            yMaximum = obstacleLayer.extent().yMaximum()
            yMinimum = obstacleLayer.extent().yMinimum()
            xMaximum = obstacleLayer.extent().xMaximum()

            xOffSet = obstacleLayer.extent().width() / obstacleLayer.width()
            yOffSet = obstacleLayer.extent().height() / obstacleLayer.height()

            if bound.xMinimum() < xMinimum:
                hStartNumber = 0
                xStartValue = xMinimum
            else:
                hStartNumber = int((bound.xMinimum() - xMinimum) / xOffSet)
                xStartValue = bound.xMinimum()
            if yMaximum < bound.yMaximum():
                wStartNumber = 0
                yStartValue = yMaximum
            else:
                wStartNumber = int((yMaximum - bound.yMaximum()) / yOffSet)
                yStartValue = bound.yMaximum()

            if bound.xMaximum() > xMaximum:
                xEndValue = xMaximum
            else:
                xEndValue = bound.xMaximum()
            if yMinimum > bound.yMinimum():
                yEndValue = yMinimum
            else:
                yEndValue = bound.yMinimum()
            wCount = int(math.fabs(xEndValue - xStartValue) / offset)
            hCount = int(math.fabs(yEndValue - yStartValue) / offset)

            xPixelWidth = 0.0
            yPixelWidth = 0.0
            featureID = 0
            # i = 0
            # k = 0
            # altitudeList = []
            # self.progress.setValue(0)
            # while i  <=  hCount - 1:
            #     j = 0
            #     while j <= wCount - 1:
            #         if block.isNoData(j * int(cellRate) + wStartNumber, i* int(cellRate) + hStartNumber):
            #             self.progress.setValue(k)
            #             QApplication.processEvents()
            #             j += 1
            #             k += 1
            #             altitudeList.append(None)
            #             continue
            #         altitude = block.value(j * int(cellRate) + wStartNumber, i * int(cellRate) + hStartNumber)
            #         altitudeList.append(altitude)
            #         self.progress.setValue(k)
            #         QApplication.processEvents()
            #         j += 1
            #         k += 1
            #     i += 1

            i = 0
            k = 0
            name = "DEM"
            semiXoffset = xOffSet / 2
            semiYoffset = yOffSet / 2
            while i <= hCount - 1:
                j = 0
                while j <= wCount - 1:
                    if block.isNoData(j * cellRate + wStartNumber,
                                      i * cellRate + hStartNumber):
                        self.progress.setValue(k)
                        QApplication.processEvents()
                        j += 1
                        k += 1
                        continue
                    altitude = block.value(j * cellRate + wStartNumber,
                                           i * cellRate + hStartNumber)
                    # # if block.isNoData(j * int(cellRate) + wStartNumber, i* int(cellRate) + hStartNumber):
                    # #     j += 1
                    # #     self.progress.setValue(self.progress.value() + 1)
                    # #     QApplication.processEvents()
                    # #     continue
                    # # altitude = block.value(j* int(cellRate) + wStartNumber, i* int(cellRate)+ hStartNumber)
                    # altitude = altitudeList[k]
                    # if altitude == None:
                    #     self.progress.setValue(k)
                    #     QApplication.processEvents()
                    #     j += 1
                    #     k += 1
                    #     continue

                    point = QgsPoint(
                        xStartValue + (i * cellRate) * xOffSet + semiXoffset,
                        yStartValue - (j * cellRate - 1) * yOffSet -
                        semiYoffset)
                    position = Point3D()
                    positionDegree = Point3D()

                    if define._canvas.mapUnits() == QGis.Meters:
                        if define._canvas.mapSettings().destinationCrs(
                        ) != obstacleLayer.crs():
                            position = QgisHelper.CrsTransformPoint(
                                point.x(), point.y(), obstacleLayer.crs(),
                                define._canvas.mapSettings().destinationCrs(),
                                altitude)
                        else:
                            position = Point3D(point.x(), point.y(), altitude)
                    else:
                        if define._canvas.mapSettings().destinationCrs(
                        ) != obstacleLayer.crs():
                            positionDegree = QgisHelper.CrsTransformPoint(
                                point.x(), point.y(), obstacleLayer.crs(),
                                define._canvas.mapSettings().destinationCrs(),
                                altitude)
                        else:
                            positionDegree = Point3D(point.x(), point.y(),
                                                     altitude)
                    obstacle = Obstacle(name, position, obstacleLayer.id(),
                                        featureID, None, trees,
                                        ObstacleTable.MocMultiplier, tolerance)
                    obstacle.positionDegree = positionDegree
                    if self.manualPolygon != None:
                        if not self.manualPolygon.contains(obstacle.Position):
                            continue
                    self.checkObstacle(obstacle)
                    self.progress.setValue(k)
                    QApplication.processEvents()
                    j += 1
                    featureID += 1
                    k += 1
                i += 1
        self.progress.setValue(maxium)
        define._messagBar.hide()
        self.manualPolygon = None

    def loadObstaclesVector(self, obstacleLayers, surfaceLayers):
        progressMessageBar = define._messagBar.createMessage(
            "Loading Vector Obstacles...")
        self.progress = QProgressBar()
        self.progress.setAlignment(Qt.AlignLeft | Qt.AlignVCenter)
        progressMessageBar.layout().addWidget(self.progress)
        define._messagBar.pushWidget(progressMessageBar,
                                     define._messagBar.INFO)
        maxium = 0
        self.progress.setValue(0)
        for ly in obstacleLayers:
            maxium += ly.featureCount()

        if maxium == 0:
            return False
        self.progress.setMaximum(maxium)

        for obstacleLayer in obstacleLayers:
            obstacleUnits = obstacleLayer.crs().mapUnits()
            features = QgisHelper.getFeaturesInLayerExtent(
                define._canvas, obstacleLayer, surfaceLayers,
                SelectionModeType.Automatic)
            #             print len(features)
            for feature in features:
                name = feature.attribute("Name").toString()
                altitude = feature.attribute("Altitude").toFloat()[0]
                trees = define._trees
                tolerance = define._tolerance
                point = feature.geometry().asPoint()
                position = Point3D()
                positionDegree = Point3D()
                if define._canvas.mapUnits() == QGis.Meters:
                    if define._canvas.mapSettings().destinationCrs(
                    ) != obstacleLayer.crs():
                        position = QgisHelper.CrsTransformPoint(
                            point.x(), point.y(), obstacleLayer.crs(),
                            define._canvas.mapSettings().destinationCrs(),
                            altitude)
                    else:
                        position = Point3D(point.x(), point.y(), altitude)
                else:
                    if define._canvas.mapSettings().destinationCrs(
                    ) != obstacleLayer.crs():
                        positionDegree = QgisHelper.CrsTransformPoint(
                            point.x(), point.y(), obstacleLayer.crs(),
                            define._canvas.mapSettings().destinationCrs(),
                            altitude)
                    else:
                        positionDegree = Point3D(point.x(), point.y(),
                                                 altitude)
                featureId = feature.id()
                layerId = obstacleLayer.id()
                obstacle = Obstacle(name, position, layerId, featureId, None,
                                    trees, ObstacleTable.MocMultiplier,
                                    tolerance)
                obstacle.positionDegree = positionDegree
                #                 obstacle.positionDegree = positionDegree
                self.checkObstacle(obstacle)
                self.progress.setValue(self.progress.value() + 1)
                QApplication.processEvents()
            QApplication.processEvents()
        self.progress.setValue(maxium)
        define._messagBar.hide()
        self.manualPolygon = None

    def addObstacleToModel(self, obstacle, checkResult=None):
        standardItemList = []
        # obstacle.positionDegree = QgisHelper.Meter2Degree(obstacle.Position.x(), obstacle.Position.y())
        standardItem = QStandardItem(str(obstacle.featureId))
        standardItem.setData(obstacle.featureId)
        standardItemList.append(standardItem)

        standardItem = QStandardItem(str(obstacle.layerId))
        standardItem.setData(obstacle.layerId)
        standardItemList.append(standardItem)

        standardItem = QStandardItem(str(obstacle.name))
        standardItem.setData(obstacle.name)
        standardItemList.append(standardItem)

        standardItem = QStandardItem(str(obstacle.Position.x()))
        standardItem.setData(obstacle.Position.x())
        standardItemList.append(standardItem)

        standardItem = QStandardItem(str(obstacle.Position.y()))
        standardItem.setData(obstacle.Position.y())
        standardItemList.append(standardItem)

        value = QVariant(QgisHelper.strDegree(obstacle.positionDegree.y()))
        standardItem = QStandardItem(value.toString())
        standardItem.setData(obstacle.positionDegree.y())
        standardItemList.append(standardItem)
        strV = QgisHelper.strDegree(obstacle.positionDegree.y())

        value = QVariant(QgisHelper.strDegree(obstacle.positionDegree.x()))
        standardItem = QStandardItem(value.toString())
        standardItem.setData(obstacle.positionDegree.x())
        standardItemList.append(standardItem)

        standardItem = QStandardItem(str(obstacle.Position.z()))
        standardItem.setData(obstacle.Position.z())
        standardItemList.append(standardItem)

        standardItem = QStandardItem(
            str(Unit.ConvertMeterToFeet(obstacle.Position.z())))
        standardItem.setData(Unit.ConvertMeterToFeet(obstacle.Position.z()))
        standardItemList.append(standardItem)

        standardItem = QStandardItem(str(obstacle.trees))
        standardItem.setData(obstacle.trees)
        standardItemList.append(standardItem)

        standardItem = QStandardItem(
            str(Unit.ConvertMeterToFeet(obstacle.trees)))
        standardItem.setData(Unit.ConvertMeterToFeet(obstacle.trees))
        standardItemList.append(standardItem)

        #         for i in range(len(standardItemList), self.source.columnCount()):
        #             standardItemList.append(QStandardItem("None"))

        self.source.appendRow(standardItemList)

        standardItem = QStandardItem(str(obstacle.mocMultiplier))
        standardItem.setData(obstacle.mocMultiplier)
        self.source.setItem(self.source.rowCount() - 1,
                            self.IndexMocMultiplier, standardItem)

    def checkObstacle(self, obstacle):
        pass

    def CompareObstacleRows(self, newRow, row, ignore):
        pass

    def method_0(self, obstacle_0):
        colCount = self.columnCount()
        objectId = range(colCount)

        objectId[0] = (obstacle_0.featureId)
        objectId[1] = (obstacle_0.name)
        objectId[2] = (obstacle_0.position.x())
        objectId[3] = (obstacle_0.position.y())
        objectId[4] = (obstacle_0.Position.z())
        position = obstacle_0.position
        objectId[6] = (Unit.ConvertMeterToFeet(position.z()))
        objectId[7] = (obstacle_0.trees)
        objectId[8] = (Unit.ConvertMeterToFeet(obstacle_0.Trees))
        if (self.IndexMocMultiplier > -1):
            objectId[self.IndexMocMultiplier] = obstacle_0.MocMultiplier

        return objectId

    def method_1(self, object_0):
        pass
예제 #15
0
class SetupDialog(QDialog, Ui_SetupDialog):
    """
        Function and Event handling class for the Ui_SetupDialog.
    """
    def __init__(self, parent):
        QDialog.__init__(self, parent)

        self._gui_logger = GUILogger("GUILogger", logging.INFO)
        self._gui_job = None
        EventLogger.add_logger(self._gui_logger)

        # FIXME better way to find interval and uids in tree_widget?!
        self.__tree_interval_tooltip = "Update interval in seconds"
        self.__tree_uid_tooltip = "UID cannot be empty"
        self.data_logger_thread = None
        self.tab_debug_warning = False

        self.device_dialog = None

        self.host_infos = None
        self.last_host = None
        self.host_index_changing = None

        self.setupUi(self)

        self.model_data = QStandardItemModel(self)
        self.model_data.setHorizontalHeaderLabels(
            ['Time', 'Name', 'UID', 'Var', 'Raw', 'Unit'])
        self.table_data.setModel(self.model_data)
        self.table_data.setColumnWidth(0, 160)
        self.table_data.setColumnWidth(1, 170)
        self.table_data.setColumnWidth(2, 50)
        self.table_data.setColumnWidth(3, 110)
        self.table_data.setColumnWidth(4, 70)
        self.table_data.setColumnWidth(5, 100)

        self.model_devices = QStandardItemModel(self)
        self.model_devices.setHorizontalHeaderLabels(['Device', 'Value'])
        self.tree_devices.setModel(self.model_devices)
        self.tree_devices.setColumnWidth(0, 300)

        self.widget_initialization()

        self.btn_start_logging.setIcon(
            QIcon(load_pixmap('data_logger/start-icon.png')))

        timestamp = int(time.time())
        self.edit_csv_file_name.setText(
            os.path.join(get_home_path(),
                         'logger_data_{0}.csv'.format(timestamp)))
        self.edit_log_file_name.setText(
            os.path.join(get_home_path(),
                         'logger_debug_{0}.log'.format(timestamp)))

        self.combo_data_time_format.addItem(
            utils.timestamp_to_de(timestamp) + ' (DD.MM.YYYY HH:MM:SS)', 'de')
        self.combo_data_time_format.addItem(
            utils.timestamp_to_us(timestamp) + ' (MM/DD/YYYY HH:MM:SS)', 'us')
        self.combo_data_time_format.addItem(
            utils.timestamp_to_iso(timestamp) + ' (ISO 8601)', 'iso')
        self.combo_data_time_format.addItem(
            utils.timestamp_to_unix(timestamp) + ' (Unix)', 'unix')

        self.combo_debug_time_format.addItem(
            utils.timestamp_to_de(timestamp) + ' (DD.MM.YYYY HH:MM:SS)', 'de')
        self.combo_debug_time_format.addItem(
            utils.timestamp_to_us(timestamp) + ' (MM/DD/YYYY HH:MM:SS)', 'us')
        self.combo_debug_time_format.addItem(
            utils.timestamp_to_iso(timestamp) + ' (ISO 8601)', 'iso')
        self.combo_debug_time_format.addItem(
            utils.timestamp_to_unix(timestamp) + ' (Unix)', 'unix')

        self.combo_log_level.addItem('Debug', 'debug')
        self.combo_log_level.addItem('Info', 'info')
        self.combo_log_level.addItem('Warning', 'warning')
        self.combo_log_level.addItem('Error', 'error')
        self.combo_log_level.addItem('Critical', 'critical')
        self.combo_log_level.setCurrentIndex(0)  # debug

        self.combo_debug_level.addItem('Debug', logging.DEBUG)
        self.combo_debug_level.addItem('Info', logging.INFO)
        self.combo_debug_level.addItem('Warning', logging.WARNING)
        self.combo_debug_level.addItem('Error', logging.ERROR)
        self.combo_debug_level.addItem('Critical', logging.CRITICAL)
        self.combo_debug_level.setCurrentIndex(1)  # info

        self.update_ui_state()

    def update_ui_state(self):
        data_to_csv_file = self.check_data_to_csv_file.isChecked()
        debug_to_log_file = self.check_debug_to_log_file.isChecked()

        self.label_csv_file_name.setVisible(data_to_csv_file)
        self.edit_csv_file_name.setVisible(data_to_csv_file)
        self.btn_browse_csv_file_name.setVisible(data_to_csv_file)

        self.label_log_file_name.setVisible(debug_to_log_file)
        self.edit_log_file_name.setVisible(debug_to_log_file)
        self.btn_browse_log_file_name.setVisible(debug_to_log_file)
        self.label_log_level.setVisible(debug_to_log_file)
        self.combo_log_level.setVisible(debug_to_log_file)

    def widget_initialization(self):
        """
            Sets default values for some widgets
        """
        # Login data
        self.host_info_initialization()

        self.signal_initialization()

    def signal_initialization(self):
        """
            Init of all important Signals and connections.
        """
        # Buttons
        self.btn_start_logging.clicked.connect(self.btn_start_logging_clicked)
        self.btn_save_config.clicked.connect(self.btn_save_config_clicked)
        self.btn_load_config.clicked.connect(self.btn_load_config_clicked)
        self.check_data_to_csv_file.stateChanged.connect(self.update_ui_state)
        self.check_debug_to_log_file.stateChanged.connect(self.update_ui_state)
        self.btn_browse_csv_file_name.clicked.connect(
            self.btn_browse_csv_file_name_clicked)
        self.btn_browse_log_file_name.clicked.connect(
            self.btn_browse_log_file_name_clicked)
        self.btn_clear_debug.clicked.connect(self.btn_clear_debug_clicked)
        self.combo_debug_level.currentIndexChanged.connect(
            self.combo_debug_level_changed)
        self.btn_add_device.clicked.connect(self.btn_add_device_clicked)
        self.btn_remove_device.clicked.connect(self.btn_remove_device_clicked)
        self.btn_remove_all_devices.clicked.connect(
            self.btn_remove_all_devices_clicked)

        self.tab_widget.currentChanged.connect(self.tab_reset_warning)
        self.btn_clear_data.clicked.connect(self.btn_clear_data_clicked)

        self.connect(self._gui_logger,
                     QtCore.SIGNAL(GUILogger.SIGNAL_NEW_MESSAGE),
                     self.add_debug_message)
        self.connect(self._gui_logger,
                     QtCore.SIGNAL(GUILogger.SIGNAL_NEW_MESSAGE_TAB_HIGHLIGHT),
                     self.highlight_debug_tab)

        self.combo_host.currentIndexChanged.connect(self._host_index_changed)
        self.spin_port.valueChanged.connect(self._port_changed)

    def host_info_initialization(self):
        """
            initialize host by getting information out of brickv.config
        """
        self.host_infos = config.get_host_infos(config.HOST_INFO_COUNT)
        self.host_index_changing = True

        for host_info in self.host_infos:
            self.combo_host.addItem(host_info.host)

        self.last_host = None
        self.combo_host.setCurrentIndex(0)
        self.spin_port.setValue(self.host_infos[0].port)
        self.host_index_changing = False

    def btn_start_logging_clicked(self):
        """
            Start/Stop of the logging process
        """
        if (self.data_logger_thread
                is not None) and (not self.data_logger_thread.stopped):
            self.btn_start_logging.clicked.disconnect()

            self.data_logger_thread.stop()
            self._reset_stop()

        elif self.data_logger_thread is None:
            from brickv.data_logger import main

            self._gui_job = GuiDataJob(name="GuiData-Writer")
            self.connect(self._gui_job,
                         QtCore.SIGNAL(GuiDataJob.SIGNAL_NEW_DATA),
                         self.table_add_row)

            self.data_logger_thread = main.main(
                None, GuiConfigHandler.create_config(self), self._gui_job)

            if self.data_logger_thread is not None:
                self.btn_start_logging.setText("Stop Logging")
                self.btn_start_logging.setIcon(
                    QIcon(load_pixmap('data_logger/stop-icon.png')))
                self.tab_devices.setEnabled(False)
                self.tab_setup.setEnabled(False)
                self.tab_widget.setCurrentIndex(
                    self.tab_widget.indexOf(self.tab_data))
                self.tab_reset_warning()

    def _reset_stop(self):
        self.tab_devices.setEnabled(True)
        self.tab_setup.setEnabled(True)
        self.btn_start_logging.setText("Start Logging")
        self.btn_start_logging.setIcon(
            QIcon(load_pixmap('data_logger/start-icon.png')))

        self.disconnect(self._gui_job,
                        QtCore.SIGNAL(GuiDataJob.SIGNAL_NEW_DATA),
                        self.table_add_row)
        self.data_logger_thread = None
        self._gui_job = None

        self.btn_start_logging.clicked.connect(self.btn_start_logging_clicked)

    def btn_save_config_clicked(self):
        filename = get_save_file_name(get_main_window(), 'Save Config',
                                      get_home_path(), 'JSON Files (*.json)')

        if len(filename) == 0:
            return

        if not filename.lower().endswith('.json'):
            filename += '.json'

        config = GuiConfigHandler.create_config(self)

        if not save_config(config, filename):
            QMessageBox.warning(
                get_main_window(), 'Save Config',
                'Could not save config to file! See Debug tab for details.',
                QMessageBox.Ok)

    def btn_load_config_clicked(self):
        filename = get_open_file_name(get_main_window(), 'Load Config',
                                      get_home_path(), 'JSON Files (*.json)')

        if len(filename) == 0:
            return

        config = load_and_validate_config(filename)

        if config == None:
            QMessageBox.warning(
                get_main_window(), 'Load Config',
                'Could not load config from file! See Debug tab for details.',
                QMessageBox.Ok)
            return

        self.update_setup_tab(config)
        self.update_devices_tab(config)

    def btn_browse_csv_file_name_clicked(self):
        if len(self.edit_csv_file_name.text()) > 0:
            last_dir = os.path.dirname(
                os.path.realpath(self.edit_csv_file_name.text()))
        else:
            last_dir = get_home_path()

        filename = get_save_file_name(get_main_window(), 'Choose CSV File',
                                      last_dir, "CSV Files (*.csv)")

        if len(filename) > 0:
            if not filename.lower().endswith('.csv'):
                filename += '.csv'

            self.edit_csv_file_name.setText(filename)

    def btn_browse_log_file_name_clicked(self):
        if len(self.edit_log_file_name.text()) > 0:
            last_dir = os.path.dirname(
                os.path.realpath(self.edit_log_file_name.text()))
        else:
            last_dir = get_home_path()

        filename = get_save_file_name(get_main_window(), 'Choose Log File',
                                      last_dir, "Log Files (*.log)")

        if len(filename) > 0:
            if not filename.lower().endswith('.log'):
                filename += '.log'

            self.edit_log_file_name.setText(filename)

    def btn_add_device_clicked(self):
        """
            Opens the DeviceDialog in Add-Mode.
        """
        if self.device_dialog is None:
            self.device_dialog = DeviceDialog(self)

        self.device_dialog.btn_refresh_clicked()
        self.device_dialog.show()

    def btn_remove_device_clicked(self):
        selection = self.tree_devices.selectionModel().selectedIndexes()

        while len(selection) > 0:
            index = selection[0]

            while index.parent() != self.model_devices.invisibleRootItem(
            ).index():
                index = index.parent()

            self.model_devices.removeRows(index.row(), 1)

            # get new selection, because row removal might invalid indices
            selection = self.tree_devices.selectionModel().selectedIndexes()

    def btn_remove_all_devices_clicked(self):
        self.model_devices.removeRows(0, self.model_devices.rowCount())

    def btn_clear_data_clicked(self):
        self.model_data.removeRows(0, self.model_data.rowCount())

    def tab_reset_warning(self):
        """
            Resets the Warning @ the debug tab.
        """
        if not self.tab_debug_warning or self.tab_widget.currentWidget(
        ).objectName() != self.tab_debug.objectName():
            return

        self.tab_debug_warning = False

        self.tab_set(self.tab_widget.indexOf(self.tab_debug),
                     self.palette().color(QPalette.WindowText), None)

    def combo_debug_level_changed(self):
        """
            Changes the log level dynamically.
        """
        self._gui_logger.level = self.combo_debug_level.itemData(
            self.combo_debug_level.currentIndex())

    def tab_set(self, tab_index, color, icon=None):
        """
            Sets the font Color and an icon, if given, at a specific tab.
        """
        from PyQt4.QtGui import QIcon

        self.tab_widget.tabBar().setTabTextColor(tab_index, color)
        if icon is not None:
            self.tab_widget.setTabIcon(tab_index, QIcon(icon))
        else:
            self.tab_widget.setTabIcon(tab_index, QIcon())

    def _host_index_changed(self, i):
        """
            Persists host information changes like in brickv.mainwindow
            Changes port if the host was changed
        """
        if i < 0:
            return

        self.host_index_changing = True
        self.spin_port.setValue(self.host_infos[i].port)
        self.host_index_changing = False

    def _port_changed(self, value):
        """
            Persists host information changes like in brickv.mainwindow
        """
        if self.host_index_changing:
            return

        i = self.combo_host.currentIndex()
        if i < 0:
            return

        self.host_infos[i].port = self.spin_port.value()

    def update_setup_tab(self, config):
        EventLogger.debug('Updating setup tab from config')

        self.combo_host.setEditText(config['hosts']['default']['name'])
        self.spin_port.setValue(config['hosts']['default']['port'])

        self.combo_data_time_format.setCurrentIndex(
            max(
                self.combo_data_time_format.findData(
                    config['data']['time_format']), 0))
        self.check_data_to_csv_file.setChecked(
            config['data']['csv']['enabled'])
        self.edit_csv_file_name.setText(
            config['data']['csv']['file_name'].decode('utf-8'))

        self.combo_debug_time_format.setCurrentIndex(
            max(
                self.combo_debug_time_format.findData(
                    config['debug']['time_format']), 0))
        self.check_debug_to_log_file.setChecked(
            config['debug']['log']['enabled'])
        self.edit_log_file_name.setText(
            config['debug']['log']['file_name'].decode('utf-8'))
        self.combo_log_level.setCurrentIndex(
            max(
                self.combo_debug_time_format.findData(
                    config['debug']['log']['level']), 0))

    def update_devices_tab(self, config):
        EventLogger.debug('Updating devices tab from config')

        self.model_devices.removeRows(0, self.model_data.rowCount())

        for device in config['devices']:
            self.add_device_to_tree(device)

    def add_device_to_tree(self, device):
        # check if device is already added
        if len(device['uid']) > 0:
            for row in range(self.model_devices.rowCount()):
                existing_name = self.model_devices.item(row, 0).text()
                exisitng_uid = self.tree_devices.indexWidget(
                    self.model_devices.item(row, 1).index()).text()

                if device['name'] == existing_name and device[
                        'uid'] == exisitng_uid:
                    EventLogger.info(
                        'Ignoring duplicate device "{0}" with UID "{1}"'.
                        format(device['name'], device['uid']))
                    return

        # add device
        name_item = QStandardItem(device['name'])
        uid_item = QStandardItem('')

        self.model_devices.appendRow([name_item, uid_item])

        edit_uid = QLineEdit()
        edit_uid.setPlaceholderText('Enter UID')
        edit_uid.setValidator(
            QRegExpValidator(QRegExp(
                '^[{0}]{{1,6}}$'.format(BASE58))))  # FIXME: use stricter logic
        edit_uid.setText(device['uid'])

        self.tree_devices.setIndexWidget(uid_item.index(), edit_uid)

        value_specs = device_specs[device['name']]['values']
        parent_item = QStandardItem('Values')

        name_item.appendRow([parent_item, QStandardItem('')])
        self.tree_devices.expand(parent_item.index())

        # add values
        for value_spec in value_specs:
            value_name_item = QStandardItem(value_spec['name'])
            value_interval_item = QStandardItem('')

            parent_item.appendRow([value_name_item, value_interval_item])

            spinbox_interval = QSpinBox()
            spinbox_interval.setRange(0, (1 << 31) - 1)
            spinbox_interval.setSingleStep(1)
            spinbox_interval.setValue(
                device['values'][value_spec['name']]['interval'])
            spinbox_interval.setSuffix(' seconds')

            self.tree_devices.setIndexWidget(value_interval_item.index(),
                                             spinbox_interval)

            if value_spec['subvalues'] != None:
                for subvalue_name in value_spec['subvalues']:
                    subvalue_name_item = QStandardItem(subvalue_name)
                    subvalue_check_item = QStandardItem('')

                    value_name_item.appendRow(
                        [subvalue_name_item, subvalue_check_item])

                    check_subvalue = QCheckBox()
                    check_subvalue.setChecked(device['values'][
                        value_spec['name']]['subvalues'][subvalue_name])

                    self.tree_devices.setIndexWidget(
                        subvalue_check_item.index(), check_subvalue)

        self.tree_devices.expand(name_item.index())

        # add options
        option_specs = device_specs[device['name']]['options']

        if option_specs != None:
            parent_item = QStandardItem('Options')

            name_item.appendRow([parent_item, QStandardItem('')])

            for option_spec in option_specs:
                option_name_item = QStandardItem(option_spec['name'])
                option_widget_item = QStandardItem('')

                parent_item.appendRow([option_name_item, option_widget_item])

                if option_spec['type'] == 'choice':
                    widget_option_value = QComboBox()

                    for option_value_spec in option_spec['values']:
                        widget_option_value.addItem(
                            option_value_spec[0].decode('utf-8'),
                            option_value_spec[1])

                    widget_option_value.setCurrentIndex(
                        widget_option_value.findText(device['options'][
                            option_spec['name']]['value'].decode('utf-8')))
                elif option_spec['type'] == 'int':
                    widget_option_value = QSpinBox()
                    widget_option_value.setRange(option_spec['minimum'],
                                                 option_spec['maximum'])
                    widget_option_value.setSuffix(option_spec['suffix'])
                    widget_option_value.setValue(
                        device['options'][option_spec['name']]['value'])
                elif option_spec['type'] == 'bool':
                    widget_option_value = QCheckBox()
                    widget_option_value.setChecked(
                        device['options'][option_spec['name']]['value'])

                self.tree_devices.setIndexWidget(option_widget_item.index(),
                                                 widget_option_value)

    def add_debug_message(self, message):
        self.text_debug.append(message)

        while self.text_debug.document().blockCount() > 1000:
            cursor = QTextCursor(self.text_debug.document().begin())
            cursor.select(QTextCursor.BlockUnderCursor)
            cursor.movePosition(QTextCursor.Right, QTextCursor.KeepAnchor)
            cursor.removeSelectedText()

        if self.checkbox_debug_auto_scroll.isChecked():
            self.text_debug.verticalScrollBar().setValue(
                self.text_debug.verticalScrollBar().maximum())

    def btn_clear_debug_clicked(self):
        self.text_debug.clear()

    def highlight_debug_tab(self):
        """
            SIGNAL function:
            Highlight the debug tab when an error occurs.
        """
        if not self.tab_debug_warning and self.tab_widget.currentWidget(
        ).objectName() != self.tab_debug.objectName():
            self.tab_debug_warning = True
            self.tab_set(
                self.tab_widget.indexOf(self.tab_debug), QColor(255, 0, 0),
                os.path.join(get_resources_path(), "warning-icon.png"))

    def table_add_row(self, csv_data):
        """
            SIGNAL function:
            Adds new CSV Data into the Table.
        """
        rows = self.model_data.rowCount()

        while rows >= 1000:
            self.model_data.removeRow(0)
            rows = self.model_data.rowCount()

        row_number = None

        if rows > 0:
            try:
                row_number = int(
                    self.model_data.headerData(rows - 1, Qt.Vertical))
            except ValueError:
                pass

        self.model_data.appendRow([
            QStandardItem(csv_data.timestamp),
            QStandardItem(csv_data.name),
            QStandardItem(csv_data.uid),
            QStandardItem(csv_data.var_name),
            QStandardItem(str(csv_data.raw_data)),
            QStandardItem(csv_data.var_unit.decode('utf-8'))
        ])

        if row_number != None:
            self.model_data.setHeaderData(rows, Qt.Vertical,
                                          str(row_number + 1))

        if self.checkbox_data_auto_scroll.isChecked():
            self.table_data.scrollToBottom()
예제 #16
0
class DefaultsDlg(QDialog, Ui_Dialog):
    """
    Class documentation goes here.
    """
    def __init__(self, defaults, parent=None):
        """
        Constructor
        
        @param parent reference to the parent widget (QWidget)
        """
        super().__init__(parent)
        self.setupUi(self)
        self.setAttribute(Qt.WA_DeleteOnClose)
        
        self.defaults = defaults
        
        self.fillScalars()
        self.fillPlots()
        self.fillCalculations()
        
    def updateDefaults(self):
        self.defaults['defaultScalars'] = self.setDefaultScalars()
        self.defaults['defaultPlots'] = self.setDefaultPlots()
        self.defaults['defaultCalculations'] = self.setDefaultCalculations()
        
    def fillScalars(self):
        scalars = [ 'absorbance (%)', 
                    'reflectance (%)', 
                    'transmittance (%)',
                    'absorbance (mA/cm²)',
                    'reflectance (mA/cm²)', 
                    'transmittance (mA/cm²)',
                    'generation',
                    'Jmax (mA/cm²)',
                    'absorption layerwise (%)',
                    'absorption layerwise (mA/cm²)', 
                    'collection layerwise (%)',
                    'collection layerwise (mA/cm²)', 
                    'calc. time (s)'
                    ]
                    
        self.scalarListModel = QStandardItemModel()
        scalarsToShow = self.defaults['defaultScalars']
        for value in scalars:                   
            item = QStandardItem(value)
            check = Qt.Checked if value in scalarsToShow else Qt.Unchecked
            item.setCheckState(check)
            item.setCheckable(True)
            self.scalarListModel.appendRow(item)
    
        self.scalarListView.setModel(self.scalarListModel)
        
    def setDefaultScalars(self):
        setVisible = []
        for row in range(self.scalarListModel.rowCount()):
            item = self.scalarListModel.item(row)                  
            if item.checkState() == Qt.Checked:
                setVisible.append(item.text())
                
        return setVisible
        
        
    def fillPlots(self):
        plots = [   'total A,R,T',              # requires calc [0]
                    'Ellipsometry',               # requires nothing
                    'absorption (layerwise)',   # requires calc [2]
                    'collection (layerwise)',   # requires calc [2]
                    'QE',                       # requires calc [2]
                    'reflection (interfacewise)', 
                    'generation'                # requires calc [3]
                    
                    
                ]
                    
        self.plotListModel = QStandardItemModel()
        plotsToShow = self.defaults['defaultPlots']
        for value in plots:                   
            item = QStandardItem(value)
            check = Qt.Checked if value in plotsToShow else Qt.Unchecked
            item.setCheckState(check)
            item.setCheckable(True)
            self.plotListModel.appendRow(item)
    
        self.plotListView.setModel(self.plotListModel)
        
    def setDefaultPlots(self):
        setVisible = []
        for row in range(self.plotListModel.rowCount()):
            item = self.plotListModel.item(row)                  
            if item.checkState() == Qt.Checked:
                setVisible.append(item.text())
                
        return setVisible
                
    def fillCalculations(self):
        self.calculations = ['Stack optics (A,R,T)',
                        'Ellipsometry', 
                        'Field intensity',
                        'Layerwise optics (absorption, collection, QE)', 
                        'Generation'
                        ]
                    
        self.calcListModel = QStandardItemModel()
        calculationsToShow = self.defaults['defaultCalculations']
        for value in self.calculations:                   
            item = QStandardItem(value)
            check = Qt.Checked if value in calculationsToShow else Qt.Unchecked
            item.setCheckState(check)
            item.setCheckable(True)
            #item.setEnabled(False)
            self.calcListModel.appendRow(item)
    
        self.calculationsListView.setModel(self.calcListModel)
        
    def setDefaultCalculations(self):
        for row in range(self.calcListModel.rowCount()):
            item = self.calcListModel.item(row)                  
            if item.checkState() == Qt.Checked:
                highestRow = row 
                
                
        setCalcOn = self.calculations[:highestRow+1]
                
        return setCalcOn
예제 #17
0
class SetupDialog(QDialog, Ui_SetupDialog):
    """
        Function and Event handling class for the Ui_SetupDialog.
    """

    def __init__(self, parent):
        QDialog.__init__(self, parent)

        self._gui_logger = GUILogger("GUILogger", logging.INFO)
        self._gui_job = None
        EventLogger.add_logger(self._gui_logger)

        # FIXME better way to find interval and uids in tree_widget?!
        self.__tree_interval_tooltip = "Update interval in seconds"
        self.__tree_uid_tooltip = "UID cannot be empty"
        self.data_logger_thread = None
        self.tab_debug_warning = False

        self.device_dialog = None

        self.host_infos = None
        self.last_host = None
        self.host_index_changing = None

        self.setupUi(self)

        self.model_data = QStandardItemModel(self)
        self.model_data.setHorizontalHeaderLabels(['Time', 'Name', 'UID', 'Var', 'Raw', 'Unit'])
        self.table_data.setModel(self.model_data)
        self.table_data.setColumnWidth(0, 160)
        self.table_data.setColumnWidth(1, 170)
        self.table_data.setColumnWidth(2, 50)
        self.table_data.setColumnWidth(3, 110)
        self.table_data.setColumnWidth(4, 70)
        self.table_data.setColumnWidth(5, 100)

        self.model_devices = QStandardItemModel(self)
        self.model_devices.setHorizontalHeaderLabels(['Device', 'Value'])
        self.tree_devices.setModel(self.model_devices)
        self.tree_devices.setColumnWidth(0, 300)

        self.widget_initialization()

        self.btn_start_logging.setIcon(QIcon(load_pixmap('data_logger/start-icon.png')))

        timestamp = int(time.time())
        self.edit_csv_file_name.setText(os.path.join(get_home_path(), 'logger_data_{0}.csv'.format(timestamp)))
        self.edit_log_file_name.setText(os.path.join(get_home_path(), 'logger_debug_{0}.log'.format(timestamp)))

        self.combo_data_time_format.addItem(utils.timestamp_to_de(timestamp) + ' (DD.MM.YYYY HH:MM:SS)', 'de')
        self.combo_data_time_format.addItem(utils.timestamp_to_us(timestamp) + ' (MM/DD/YYYY HH:MM:SS)', 'us')
        self.combo_data_time_format.addItem(utils.timestamp_to_iso(timestamp) + ' (ISO 8601)', 'iso')
        self.combo_data_time_format.addItem(utils.timestamp_to_unix(timestamp) + ' (Unix)', 'unix')

        self.combo_debug_time_format.addItem(utils.timestamp_to_de(timestamp) + ' (DD.MM.YYYY HH:MM:SS)', 'de')
        self.combo_debug_time_format.addItem(utils.timestamp_to_us(timestamp) + ' (MM/DD/YYYY HH:MM:SS)', 'us')
        self.combo_debug_time_format.addItem(utils.timestamp_to_iso(timestamp) + ' (ISO 8601)', 'iso')
        self.combo_debug_time_format.addItem(utils.timestamp_to_unix(timestamp) + ' (Unix)', 'unix')

        self.combo_log_level.addItem('Debug', 'debug')
        self.combo_log_level.addItem('Info', 'info')
        self.combo_log_level.addItem('Warning', 'warning')
        self.combo_log_level.addItem('Error', 'error')
        self.combo_log_level.addItem('Critical', 'critical')
        self.combo_log_level.setCurrentIndex(0) # debug

        self.combo_debug_level.addItem('Debug', logging.DEBUG)
        self.combo_debug_level.addItem('Info', logging.INFO)
        self.combo_debug_level.addItem('Warning', logging.WARNING)
        self.combo_debug_level.addItem('Error', logging.ERROR)
        self.combo_debug_level.addItem('Critical', logging.CRITICAL)
        self.combo_debug_level.setCurrentIndex(1) # info

        self.update_ui_state()

    def update_ui_state(self):
        data_to_csv_file = self.check_data_to_csv_file.isChecked()
        debug_to_log_file = self.check_debug_to_log_file.isChecked()

        self.label_csv_file_name.setVisible(data_to_csv_file)
        self.edit_csv_file_name.setVisible(data_to_csv_file)
        self.btn_browse_csv_file_name.setVisible(data_to_csv_file)

        self.label_log_file_name.setVisible(debug_to_log_file)
        self.edit_log_file_name.setVisible(debug_to_log_file)
        self.btn_browse_log_file_name.setVisible(debug_to_log_file)
        self.label_log_level.setVisible(debug_to_log_file)
        self.combo_log_level.setVisible(debug_to_log_file)

    def widget_initialization(self):
        """
            Sets default values for some widgets
        """
        # Login data
        self.host_info_initialization()

        self.signal_initialization()

    def signal_initialization(self):
        """
            Init of all important Signals and connections.
        """
        # Buttons
        self.btn_start_logging.clicked.connect(self.btn_start_logging_clicked)
        self.btn_save_config.clicked.connect(self.btn_save_config_clicked)
        self.btn_load_config.clicked.connect(self.btn_load_config_clicked)
        self.check_data_to_csv_file.stateChanged.connect(self.update_ui_state)
        self.check_debug_to_log_file.stateChanged.connect(self.update_ui_state)
        self.btn_browse_csv_file_name.clicked.connect(self.btn_browse_csv_file_name_clicked)
        self.btn_browse_log_file_name.clicked.connect(self.btn_browse_log_file_name_clicked)
        self.btn_clear_debug.clicked.connect(self.btn_clear_debug_clicked)
        self.combo_debug_level.currentIndexChanged.connect(self.combo_debug_level_changed)
        self.btn_add_device.clicked.connect(self.btn_add_device_clicked)
        self.btn_remove_device.clicked.connect(self.btn_remove_device_clicked)
        self.btn_remove_all_devices.clicked.connect(self.btn_remove_all_devices_clicked)

        self.tab_widget.currentChanged.connect(self.tab_reset_warning)
        self.btn_clear_data.clicked.connect(self.btn_clear_data_clicked)

        self.connect(self._gui_logger, QtCore.SIGNAL(GUILogger.SIGNAL_NEW_MESSAGE), self.add_debug_message)
        self.connect(self._gui_logger, QtCore.SIGNAL(GUILogger.SIGNAL_NEW_MESSAGE_TAB_HIGHLIGHT),
                     self.highlight_debug_tab)

        self.combo_host.currentIndexChanged.connect(self._host_index_changed)
        self.spin_port.valueChanged.connect(self._port_changed)

    def host_info_initialization(self):
        """
            initialize host by getting information out of brickv.config
        """
        self.host_infos = config.get_host_infos(config.HOST_INFO_COUNT)
        self.host_index_changing = True

        for host_info in self.host_infos:
            self.combo_host.addItem(host_info.host)

        self.last_host = None
        self.combo_host.setCurrentIndex(0)
        self.spin_port.setValue(self.host_infos[0].port)
        self.host_index_changing = False

    def btn_start_logging_clicked(self):
        """
            Start/Stop of the logging process
        """
        if (self.data_logger_thread is not None) and (not self.data_logger_thread.stopped):
            self.btn_start_logging.clicked.disconnect()

            self.data_logger_thread.stop()
            self._reset_stop()

        elif self.data_logger_thread is None:
            from brickv.data_logger import main

            self._gui_job = GuiDataJob(name="GuiData-Writer")
            self.connect(self._gui_job, QtCore.SIGNAL(GuiDataJob.SIGNAL_NEW_DATA), self.table_add_row)

            self.data_logger_thread = main.main(None, GuiConfigHandler.create_config(self), self._gui_job)

            if self.data_logger_thread is not None:
                self.btn_start_logging.setText("Stop Logging")
                self.btn_start_logging.setIcon(QIcon(load_pixmap('data_logger/stop-icon.png')))
                self.tab_devices.setEnabled(False)
                self.tab_setup.setEnabled(False)
                self.tab_widget.setCurrentIndex(self.tab_widget.indexOf(self.tab_data))
                self.tab_reset_warning()

    def _reset_stop(self):
        self.tab_devices.setEnabled(True)
        self.tab_setup.setEnabled(True)
        self.btn_start_logging.setText("Start Logging")
        self.btn_start_logging.setIcon(QIcon(load_pixmap('data_logger/start-icon.png')))

        self.disconnect(self._gui_job, QtCore.SIGNAL(GuiDataJob.SIGNAL_NEW_DATA), self.table_add_row)
        self.data_logger_thread = None
        self._gui_job = None

        self.btn_start_logging.clicked.connect(self.btn_start_logging_clicked)

    def btn_save_config_clicked(self):
        filename = get_save_file_name(get_main_window(), 'Save Config',
                                      get_home_path(), 'JSON Files (*.json)')

        if len(filename) == 0:
            return

        if not filename.lower().endswith('.json'):
            filename += '.json'

        config = GuiConfigHandler.create_config(self)

        if not save_config(config, filename):
            QMessageBox.warning(get_main_window(), 'Save Config',
                                'Could not save config to file! See Debug tab for details.',
                                QMessageBox.Ok)

    def btn_load_config_clicked(self):
        filename = get_open_file_name(get_main_window(), 'Load Config',
                                      get_home_path(), 'JSON Files (*.json)')

        if len(filename) == 0:
            return

        config = load_and_validate_config(filename)

        if config == None:
            QMessageBox.warning(get_main_window(), 'Load Config',
                                'Could not load config from file! See Debug tab for details.',
                                QMessageBox.Ok)
            return

        self.update_setup_tab(config)
        self.update_devices_tab(config)

    def btn_browse_csv_file_name_clicked(self):
        if len(self.edit_csv_file_name.text()) > 0:
            last_dir = os.path.dirname(os.path.realpath(self.edit_csv_file_name.text()))
        else:
            last_dir = get_home_path()

        filename = get_save_file_name(get_main_window(), 'Choose CSV File',
                                      last_dir, "CSV Files (*.csv)")

        if len(filename) > 0:
            if not filename.lower().endswith('.csv'):
                filename += '.csv'

            self.edit_csv_file_name.setText(filename)

    def btn_browse_log_file_name_clicked(self):
        if len(self.edit_log_file_name.text()) > 0:
            last_dir = os.path.dirname(os.path.realpath(self.edit_log_file_name.text()))
        else:
            last_dir = get_home_path()

        filename = get_save_file_name(get_main_window(), 'Choose Log File',
                                      last_dir, "Log Files (*.log)")

        if len(filename) > 0:
            if not filename.lower().endswith('.log'):
                filename += '.log'

            self.edit_log_file_name.setText(filename)

    def btn_add_device_clicked(self):
        """
            Opens the DeviceDialog in Add-Mode.
        """
        if self.device_dialog is None:
            self.device_dialog = DeviceDialog(self)

        self.device_dialog.btn_refresh_clicked()
        self.device_dialog.show()

    def btn_remove_device_clicked(self):
        selection = self.tree_devices.selectionModel().selectedIndexes()

        while len(selection) > 0:
            index = selection[0]

            while index.parent() != self.model_devices.invisibleRootItem().index():
                index = index.parent()

            self.model_devices.removeRows(index.row(), 1)

            # get new selection, because row removal might invalid indices
            selection = self.tree_devices.selectionModel().selectedIndexes()

    def btn_remove_all_devices_clicked(self):
        self.model_devices.removeRows(0, self.model_devices.rowCount())

    def btn_clear_data_clicked(self):
        self.model_data.removeRows(0, self.model_data.rowCount())

    def tab_reset_warning(self):
        """
            Resets the Warning @ the debug tab.
        """
        if not self.tab_debug_warning or self.tab_widget.currentWidget().objectName() != self.tab_debug.objectName():
            return

        self.tab_debug_warning = False

        self.tab_set(self.tab_widget.indexOf(self.tab_debug), self.palette().color(QPalette.WindowText), None)

    def combo_debug_level_changed(self):
        """
            Changes the log level dynamically.
        """
        self._gui_logger.level = self.combo_debug_level.itemData(self.combo_debug_level.currentIndex())

    def tab_set(self, tab_index, color, icon=None):
        """
            Sets the font Color and an icon, if given, at a specific tab.
        """
        from PyQt4.QtGui import QIcon

        self.tab_widget.tabBar().setTabTextColor(tab_index, color)
        if icon is not None:
            self.tab_widget.setTabIcon(tab_index, QIcon(icon))
        else:
            self.tab_widget.setTabIcon(tab_index, QIcon())

    def _host_index_changed(self, i):
        """
            Persists host information changes like in brickv.mainwindow
            Changes port if the host was changed
        """
        if i < 0:
            return

        self.host_index_changing = True
        self.spin_port.setValue(self.host_infos[i].port)
        self.host_index_changing = False

    def _port_changed(self, value):
        """
            Persists host information changes like in brickv.mainwindow
        """
        if self.host_index_changing:
            return

        i = self.combo_host.currentIndex()
        if i < 0:
            return

        self.host_infos[i].port = self.spin_port.value()

    def update_setup_tab(self, config):
        EventLogger.debug('Updating setup tab from config')

        self.combo_host.setEditText(config['hosts']['default']['name'])
        self.spin_port.setValue(config['hosts']['default']['port'])

        self.combo_data_time_format.setCurrentIndex(max(self.combo_data_time_format.findData(config['data']['time_format']), 0))
        self.check_data_to_csv_file.setChecked(config['data']['csv']['enabled'])
        self.edit_csv_file_name.setText(config['data']['csv']['file_name'].decode('utf-8'))

        self.combo_debug_time_format.setCurrentIndex(max(self.combo_debug_time_format.findData(config['debug']['time_format']), 0))
        self.check_debug_to_log_file.setChecked(config['debug']['log']['enabled'])
        self.edit_log_file_name.setText(config['debug']['log']['file_name'].decode('utf-8'))
        self.combo_log_level.setCurrentIndex(max(self.combo_debug_time_format.findData(config['debug']['log']['level']), 0))

    def update_devices_tab(self, config):
        EventLogger.debug('Updating devices tab from config')

        self.model_devices.removeRows(0, self.model_data.rowCount())

        for device in config['devices']:
            self.add_device_to_tree(device)

    def add_device_to_tree(self, device):
        # check if device is already added
        if len(device['uid']) > 0:
            for row in range(self.model_devices.rowCount()):
                existing_name = self.model_devices.item(row, 0).text()
                exisitng_uid = self.tree_devices.indexWidget(self.model_devices.item(row, 1).index()).text()

                if device['name'] == existing_name and device['uid'] == exisitng_uid:
                    EventLogger.info('Ignoring duplicate device "{0}" with UID "{1}"'
                                     .format(device['name'], device['uid']))
                    return

        # add device
        name_item = QStandardItem(device['name'])
        uid_item = QStandardItem('')

        self.model_devices.appendRow([name_item, uid_item])

        edit_uid = QLineEdit()
        edit_uid.setPlaceholderText('Enter UID')
        edit_uid.setValidator(QRegExpValidator(QRegExp('^[{0}]{{1,6}}$'.format(BASE58)))) # FIXME: use stricter logic
        edit_uid.setText(device['uid'])

        self.tree_devices.setIndexWidget(uid_item.index(), edit_uid)

        value_specs = device_specs[device['name']]['values']
        parent_item = QStandardItem('Values')

        name_item.appendRow([parent_item, QStandardItem('')])
        self.tree_devices.expand(parent_item.index())

        # add values
        for value_spec in value_specs:
            value_name_item = QStandardItem(value_spec['name'])
            value_interval_item = QStandardItem('')

            parent_item.appendRow([value_name_item, value_interval_item])

            spinbox_interval = QSpinBox()
            spinbox_interval.setRange(0, (1 << 31) - 1)
            spinbox_interval.setSingleStep(1)
            spinbox_interval.setValue(device['values'][value_spec['name']]['interval'])
            spinbox_interval.setSuffix(' seconds')

            self.tree_devices.setIndexWidget(value_interval_item.index(), spinbox_interval)

            if value_spec['subvalues'] != None:
                for subvalue_name in value_spec['subvalues']:
                    subvalue_name_item = QStandardItem(subvalue_name)
                    subvalue_check_item = QStandardItem('')

                    value_name_item.appendRow([subvalue_name_item, subvalue_check_item])

                    check_subvalue = QCheckBox()
                    check_subvalue.setChecked(device['values'][value_spec['name']]['subvalues'][subvalue_name])

                    self.tree_devices.setIndexWidget(subvalue_check_item.index(), check_subvalue)

        self.tree_devices.expand(name_item.index())

        # add options
        option_specs = device_specs[device['name']]['options']

        if option_specs != None:
            parent_item = QStandardItem('Options')

            name_item.appendRow([parent_item, QStandardItem('')])

            for option_spec in option_specs:
                option_name_item = QStandardItem(option_spec['name'])
                option_widget_item = QStandardItem('')

                parent_item.appendRow([option_name_item, option_widget_item])

                if option_spec['type'] == 'choice':
                    widget_option_value = QComboBox()

                    for option_value_spec in option_spec['values']:
                        widget_option_value.addItem(option_value_spec[0].decode('utf-8'), option_value_spec[1])

                    widget_option_value.setCurrentIndex(widget_option_value.findText(device['options'][option_spec['name']]['value'].decode('utf-8')))
                elif option_spec['type'] == 'int':
                    widget_option_value = QSpinBox()
                    widget_option_value.setRange(option_spec['minimum'], option_spec['maximum'])
                    widget_option_value.setSuffix(option_spec['suffix'])
                    widget_option_value.setValue(device['options'][option_spec['name']]['value'])
                elif option_spec['type'] == 'bool':
                    widget_option_value = QCheckBox()
                    widget_option_value.setChecked(device['options'][option_spec['name']]['value'])

                self.tree_devices.setIndexWidget(option_widget_item.index(), widget_option_value)

    def add_debug_message(self, message):
        self.text_debug.append(message)

        while self.text_debug.document().blockCount() > 1000:
            cursor = QTextCursor(self.text_debug.document().begin())
            cursor.select(QTextCursor.BlockUnderCursor)
            cursor.movePosition(QTextCursor.Right, QTextCursor.KeepAnchor)
            cursor.removeSelectedText()

        if self.checkbox_debug_auto_scroll.isChecked():
            self.text_debug.verticalScrollBar().setValue(self.text_debug.verticalScrollBar().maximum())

    def btn_clear_debug_clicked(self):
        self.text_debug.clear()

    def highlight_debug_tab(self):
        """
            SIGNAL function:
            Highlight the debug tab when an error occurs.
        """
        if not self.tab_debug_warning and self.tab_widget.currentWidget().objectName() != self.tab_debug.objectName():
            self.tab_debug_warning = True
            self.tab_set(self.tab_widget.indexOf(self.tab_debug), QColor(255, 0, 0),
                         os.path.join(get_resources_path(), "warning-icon.png"))

    def table_add_row(self, csv_data):
        """
            SIGNAL function:
            Adds new CSV Data into the Table.
        """
        rows = self.model_data.rowCount()

        while rows >= 1000:
            self.model_data.removeRow(0)
            rows = self.model_data.rowCount()

        row_number = None

        if rows > 0:
            try:
                row_number = int(self.model_data.headerData(rows - 1, Qt.Vertical))
            except ValueError:
                pass

        self.model_data.appendRow([QStandardItem(csv_data.timestamp),
                                   QStandardItem(csv_data.name),
                                   QStandardItem(csv_data.uid),
                                   QStandardItem(csv_data.var_name),
                                   QStandardItem(str(csv_data.raw_data)),
                                   QStandardItem(csv_data.var_unit.decode('utf-8'))])

        if row_number != None:
            self.model_data.setHeaderData(rows, Qt.Vertical, str(row_number + 1))

        if self.checkbox_data_auto_scroll.isChecked():
            self.table_data.scrollToBottom()
예제 #18
0
class OWConfusionMatrix(widget.OWWidget):
    name = "Confusion Matrix"
    description = "Display confusion matrix constructed from results " \
                  "of evaluation of classifiers."
    icon = "icons/ConfusionMatrix.svg"
    priority = 1001

    inputs = [("Evaluation Results", Orange.evaluation.Results, "set_results")]
    outputs = [("Selected Data", Orange.data.Table)]

    quantities = ["Number of instances",
                  "Proportion of predicted",
                  "Proportion of actual"]

    selected_learner = settings.Setting([])
    selected_quantity = settings.Setting(0)
    append_predictions = settings.Setting(True)
    append_probabilities = settings.Setting(False)
    autocommit = settings.Setting(True)

    UserAdviceMessages = [
        widget.Message(
                "Clicking on cells or in headers outputs the corresponding "
                "data instances",
                "click_cell")]

    def __init__(self):
        super().__init__()

        self.data = None
        self.results = None
        self.learners = []
        self.headers = []

        box = gui.widgetBox(self.controlArea, "Learners")

        self.learners_box = gui.listBox(
            box, self, "selected_learner", "learners",
            callback=self._learner_changed
        )
        box = gui.widgetBox(self.controlArea, "Show")

        gui.comboBox(box, self, "selected_quantity", items=self.quantities,
                     callback=self._update)

        box = gui.widgetBox(self.controlArea, "Select")

        gui.button(box, self, "Correct",
                   callback=self.select_correct, autoDefault=False)
        gui.button(box, self, "Misclassified",
                   callback=self.select_wrong, autoDefault=False)
        gui.button(box, self, "None",
                   callback=self.select_none, autoDefault=False)

        self.outputbox = box = gui.widgetBox(self.controlArea, "Output")
        gui.checkBox(box, self, "append_predictions",
                     "Predictions", callback=self._invalidate)
        gui.checkBox(box, self, "append_probabilities",
                     "Probabilities",
                     callback=self._invalidate)

        gui.auto_commit(self.controlArea, self, "autocommit",
                        "Send Data", "Auto send is on")

        grid = QGridLayout()

        self.tablemodel = QStandardItemModel(self)
        view = self.tableview = QTableView(
            editTriggers=QTableView.NoEditTriggers)
        view.setModel(self.tablemodel)
        view.horizontalHeader().hide()
        view.verticalHeader().hide()
        view.horizontalHeader().setMinimumSectionSize(60)
        view.selectionModel().selectionChanged.connect(self._invalidate)
        view.setShowGrid(False)
        view.clicked.connect(self.cell_clicked)
        grid.addWidget(view, 0, 0)
        self.mainArea.layout().addLayout(grid)

    def sizeHint(self):
        return QSize(750, 490)

    def _item(self, i, j):
        return self.tablemodel.item(i, j) or QStandardItem()

    def _set_item(self, i, j, item):
        self.tablemodel.setItem(i, j, item)

    def set_results(self, results):
        """Set the input results."""

        self.clear()
        self.warning([0, 1])

        data = None
        if results is not None:
            if results.data is not None:
                data = results.data

        if data is not None and not data.domain.has_discrete_class:
            data = None
            results = None
            self.warning(
                0, "Confusion Matrix cannot be used for regression results.")

        self.results = results
        self.data = data

        if data is not None:
            class_values = data.domain.class_var.values
        elif results is not None:
            raise NotImplementedError

        if results is not None:
            nmodels, ntests = results.predicted.shape
            self.headers = class_values + \
                           [unicodedata.lookup("N-ARY SUMMATION")]

            # NOTE: The 'learner_names' is set in 'Test Learners' widget.
            if hasattr(results, "learner_names"):
                self.learners = results.learner_names
            else:
                self.learners = ["Learner #%i" % (i + 1)
                                 for i in range(nmodels)]

            item = self._item(0, 2)
            item.setData("Predicted", Qt.DisplayRole)
            item.setTextAlignment(Qt.AlignCenter)
            item.setFlags(Qt.NoItemFlags)

            self._set_item(0, 2, item)
            item = self._item(2, 0)
            item.setData("Actual", Qt.DisplayRole)
            item.setTextAlignment(Qt.AlignHCenter | Qt.AlignBottom)
            item.setFlags(Qt.NoItemFlags)
            self.tableview.setItemDelegateForColumn(
                0, gui.VerticalItemDelegate())
            self._set_item(2, 0, item)
            self.tableview.setSpan(0, 2, 1, len(class_values))
            self.tableview.setSpan(2, 0, len(class_values), 1)

            for i in (0, 1):
                for j in (0, 1):
                    item = self._item(i, j)
                    item.setFlags(Qt.NoItemFlags)
                    self._set_item(i, j, item)

            for p, label in enumerate(self.headers):
                for i, j in ((1, p + 2), (p + 2, 1)):
                    item = self._item(i, j)
                    item.setData(label, Qt.DisplayRole)
                    item.setData(QBrush(QColor(208, 208, 208)),
                                 Qt.BackgroundColorRole)
                    item.setTextAlignment(Qt.AlignRight | Qt.AlignVCenter)
                    item.setFlags(Qt.ItemIsEnabled)
                    self._set_item(i, j, item)

            hor_header = self.tableview.horizontalHeader()
            if len(' '.join(self.headers)) < 120:
                hor_header.setResizeMode(QHeaderView.ResizeToContents)
            else:
                hor_header.setDefaultSectionSize(60)
            self.tablemodel.setRowCount(len(class_values) + 3)
            self.tablemodel.setColumnCount(len(class_values) + 3)
            self.selected_learner = [0]
            self._update()

    def clear(self):
        self.results = None
        self.data = None
        self.tablemodel.clear()
        self.headers = []
        # Clear learners last. This action will invoke `_learner_changed`
        # method
        self.learners = []

    def select_correct(self):
        selection = QItemSelection()
        n = self.tablemodel.rowCount()
        for i in range(2, n):
            index = self.tablemodel.index(i, i)
            selection.select(index, index)

        self.tableview.selectionModel().select(
            selection, QItemSelectionModel.ClearAndSelect
        )

    def select_wrong(self):
        selection = QItemSelection()
        n = self.tablemodel.rowCount()

        for i in range(2, n):
            for j in range(i + 1, n):
                index = self.tablemodel.index(i, j)
                selection.select(index, index)
                index = self.tablemodel.index(j, i)
                selection.select(index, index)

        self.tableview.selectionModel().select(
            selection, QItemSelectionModel.ClearAndSelect
        )

    def select_none(self):
        self.tableview.selectionModel().clear()

    def cell_clicked(self, model_index):
        i, j = model_index.row(), model_index.column()
        if not i or not j:
            return
        n = self.tablemodel.rowCount()
        index = self.tablemodel.index
        selection = None
        if i == j == 1 or i == j == n - 1:
            selection = QItemSelection(index(2, 2), index(n - 1, n - 1))
        elif i in (1, n - 1):
            selection = QItemSelection(index(2, j), index(n - 1, j))
        elif j in (1, n - 1):
            selection = QItemSelection(index(i, 2), index(i, n - 1))

        if selection is not None:
            self.tableview.selectionModel().select(
                selection, QItemSelectionModel.ClearAndSelect
            )

    def commit(self):
        if self.results is not None and self.data is not None \
                and self.selected_learner:
            indices = self.tableview.selectedIndexes()
            indices = {(ind.row() - 2, ind.column() - 2) for ind in indices}
            actual = self.results.actual
            selected_learner = self.selected_learner[0]
            learner_name = self.learners[selected_learner]
            predicted = self.results.predicted[selected_learner]
            selected = [i for i, t in enumerate(zip(actual, predicted))
                        if t in indices]
            row_indices = self.results.row_indices[selected]

            extra = []
            class_var = self.data.domain.class_var
            metas = self.data.domain.metas

            if self.append_predictions:
                predicted = numpy.array(predicted[selected], dtype=object)
                extra.append(predicted.reshape(-1, 1))
                var = Orange.data.DiscreteVariable(
                    "{}({})".format(class_var.name, learner_name),
                    class_var.values
                )
                metas = metas + (var,)

            if self.append_probabilities and \
                    self.results.probabilities is not None:
                probs = self.results.probabilities[selected_learner, selected]
                extra.append(numpy.array(probs, dtype=object))
                pvars = [Orange.data.ContinuousVariable("p({})".format(value))
                         for value in class_var.values]
                metas = metas + tuple(pvars)

            X = self.data.X[row_indices]
            Y = self.data.Y[row_indices]
            M = self.data.metas[row_indices]
            row_ids = self.data.ids[row_indices]

            M = numpy.hstack((M,) + tuple(extra))
            domain = Orange.data.Domain(
                self.data.domain.attributes,
                self.data.domain.class_vars,
                metas
            )
            data = Orange.data.Table.from_numpy(domain, X, Y, M)
            data.ids = row_ids
            data.name = learner_name

        else:
            data = None

        self.send("Selected Data", data)

    def _invalidate(self):
        self.commit()

    def _learner_changed(self):
        # The selected learner has changed
        indices = self.tableview.selectedIndexes()
        self._update()
        selection = QItemSelection()
        for sel in indices:
            selection.select(sel, sel)
        self.tableview.selectionModel().select(
            selection, QItemSelectionModel.ClearAndSelect
        )
        self.commit()

    def _update(self):
        # Update the displayed confusion matrix
        if self.results is not None and self.selected_learner:
            index = self.selected_learner[0]
            cmatrix = confusion_matrix(self.results, index)
            colsum = cmatrix.sum(axis=0)
            rowsum = cmatrix.sum(axis=1)
            total = rowsum.sum()

            if self.selected_quantity == 0:
                value = lambda i, j: int(cmatrix[i, j])
            elif self.selected_quantity == 1:
                value = lambda i, j: \
                    ("{:2.1f} %".format(100 * cmatrix[i, j] / colsum[i])
                     if colsum[i] else "N/A")
            elif self.selected_quantity == 2:
                value = lambda i, j: \
                    ("{:2.1f} %".format(100 * cmatrix[i, j] / rowsum[i])
                     if colsum[i] else "N/A")
            else:
                assert False

            for i, row in enumerate(cmatrix):
                for j, _ in enumerate(row):
                    item = self._item(i + 2, j + 2)
                    item.setData(value(i, j), Qt.DisplayRole)
                    item.setToolTip("actual: {}\npredicted: {}".format(
                        self.headers[i], self.headers[j]))
                    item.setTextAlignment(Qt.AlignRight | Qt.AlignVCenter)
                    item.setFlags(Qt.ItemIsEnabled | Qt.ItemIsSelectable)
                    self._set_item(i + 2, j + 2, item)

            model = self.tablemodel
            font = model.invisibleRootItem().font()
            bold_font = QFont(font)
            bold_font.setBold(True)

            def sum_item(value):
                item = QStandardItem()
                item.setData(value, Qt.DisplayRole)
                item.setTextAlignment(Qt.AlignRight | Qt.AlignVCenter)
                item.setFlags(Qt.ItemIsEnabled)
                item.setFont(bold_font)
                return item

            N = len(colsum)
            for i in range(N):
                model.setItem(N + 2, i + 2, sum_item(int(colsum[i])))
                model.setItem(i + 2, N + 2, sum_item(int(rowsum[i])))

            model.setItem(N + 2, N + 2, sum_item(int(total)))
예제 #19
0
파일: manager.py 프로젝트: NathanW2/qmap
class QMapManager(QDialog):
	def __init__(self, config, parent=None):
		QDialog.__init__(self, parent)
		curdir = os.path.abspath(os.path.dirname(__file__))
		PyQt4.uic.loadUi(os.path.join(curdir,'manager.ui'), self)
		self.model = QStandardItemModel()
		self.projectsmodel = QStandardItemModel()
		self.projectlist.setModel(self.projectsmodel)
		self.clientlist.setModel(self.model)
		self.clientlist.selectionModel().selectionChanged.connect(self.update)
		self.installbutton.pressed.connect(self.installToClient)
		self.mapper = QDataWidgetMapper()
		self.mapper.setModel(self.model)
		self.mapper.addMapping(self.installpath, 1)
		self.config = config
		self.populateProjects()
		self.populateClients()
		
	def installToClient(self):
		index = self.clientlist.selectionModel().currentIndex()
		item = self.model.itemFromIndex(index)
		print "Deploying to " + item.text()
		build.deployTargetByName(item.text())

	def update(self, selected, deselected ):
		index = selected.indexes()[0]
		self.mapper.setCurrentModelIndex(index)
		item = self.model.itemFromIndex(index)
		settings = item.data()

		for row in xrange(0,self.projectsmodel.rowCount()):
			index = self.projectsmodel.index(row, 0)
			item = self.projectsmodel.itemFromIndex(index)
			item.setCheckState(Qt.Unchecked)

		projects = settings['projects']
		
		for project in projects:
			if project == "All":
				i = 0
				while self.projectsmodel.item(i):
					item = self.projectsmodel.item(i)
					item.setCheckState(Qt.Checked)
					i += 1
				break
			
			projectitem = self.projectsmodel.findItems(project)[0]
		 	projectitem.setCheckState(Qt.Checked)
				
	def populateClients(self):
		row = 0
		for client, settings in self.config['clients'].iteritems():
			name = QStandardItem(client)
			name.setData(settings)
			path = QStandardItem(settings['path'])
			self.model.insertRow(row, [name, path])
			row += 1

	def populateProjects(self):
		row = 0
		for project in getProjects():
			projectitem = QStandardItem(project.name)
			projectitem.setCheckable(True)
			self.projectsmodel.insertRow(row, projectitem)
			row += 1
예제 #20
0
class DlgCharting(QDialog):
    def __init__(self, parent, data):
        QDialog.__init__(self, parent)
        self.ui = Ui_ChartingBase()
        self.ui.setupUi(self)

        self.setWindowTitle("Charting Tool 2")

        # self.ui.btnNext.clicked.connect(self.btnNext_clicked)
        self.ui.btnPrevious.clicked.connect(self.btnPrevious_clicked)
        self.ui.btnExit.clicked.connect(self.btnExit_clicked)

        self.ui.txtText1.textChanged.connect(self.txtText1_textChanged)
        self.ui.txtText2.textChanged.connect(self.txtText2_textChanged)
        self.ui.txtText3.textChanged.connect(self.txtText3_textChanged)
        self.ui.txtText4.textChanged.connect(self.txtText4_textChanged)
        self.ui.txtText5.textChanged.connect(self.txtText5_textChanged)
        self.ui.txtText6.textChanged.connect(self.txtText6_textChanged)
        self.ui.txtText7.textChanged.connect(self.txtText7_textChanged)
        self.ui.txtText8.textChanged.connect(self.txtText8_textChanged)
        self.ui.txtText9.textChanged.connect(self.txtText9_textChanged)
        self.ui.txtText10.textChanged.connect(self.txtText10_textChanged)
        self.ui.txtText11.textChanged.connect(self.txtText11_textChanged)
        self.ui.txtText12.textChanged.connect(self.txtText12_textChanged)
        self.ui.txtText13.textChanged.connect(self.txtText13_textChanged)

        # self.btnNextAndbtnPreviewSetEnabled()
        self.setDataDict = None
        self.parentDlg = parent
        self.pw = None
        self.stdModel = None
        self.data = data
        self.renderFlag = False
        self.changedComposerMap = None
        self.tableChangedValue = None
        self.straightCount = self.data["StraightCount"]
        self.catOfAcftCount = self.data["CatOfAcftCount"][0]

        self.rejected.connect(self.dlgRejected)

    def dlgRejected(self):
        self.parentDlg.show()

    def refreshData(self, data):
        self.data = data

    def txtText1_textChanged(self):
        self.txt1.setText(self.ui.txtText1.text())

    def txtText2_textChanged(self):
        self.txt2.setText(self.ui.txtText2.text())

    def txtText3_textChanged(self):
        self.txt3.setText(self.ui.txtText3.text())

    def txtText4_textChanged(self):
        self.txt4.setText(self.ui.txtText4.toPlainText())

    def txtText5_textChanged(self):
        self.txt5.setText(self.ui.txtText5.toPlainText())

    def txtText6_textChanged(self):
        self.txt6.setText(self.ui.txtText6.toPlainText())

    def txtText7_textChanged(self):
        try:
            self.txt7.setText(self.ui.txtText7.toPlainText())
        except:
            pass

    def txtText8_textChanged(self):
        self.txt8.setText(self.ui.txtText8.text())

    def txtText9_textChanged(self):
        self.txt9.setText(self.ui.txtText9.text())

    def txtText10_textChanged(self):
        self.txt10.setText(self.ui.txtText10.text())

    def txtText11_textChanged(self):
        self.txt11.setText(self.ui.txtText11.text())

    def txtText12_textChanged(self):
        self.txt12.setText(self.ui.txtText12.text())

    def txtText13_textChanged(self):
        self.txt13.setText(self.ui.txtText13.text())

    # def btnNextAndbtnPreviewSetEnabled(self):
    #     if self.ui.stackedWidget.currentIndex() == 0:
    #         self.ui.btnPrevious.setEnabled(False)
    #         self.ui.frame_2.setVisible(False)
    #         self.resize(100, 100)
    #
    #     else:
    #         self.ui.frame_2.setVisible(True)
    #         self.ui.btnPrevious.setEnabled(True)
    #     if self.ui.stackedWidget.currentIndex() == self.ui.stackedWidget.count() - 1:
    #         self.ui.btnNext.setEnabled(False)
    #     else:
    #         self.ui.btnNext.setEnabled(True)
    def btnExit_clicked(self):
        # comp = QgsComposer(self, define._canvas)
        # comp.show()
        self.setDataDict = dict()
        for key, val in self.data.iteritems():
            self.setDataDict.__setitem__(key, val)
        self.setDataDict.__setitem__("TextData", [
            self.ui.txtText1.text(),
            self.ui.txtText2.text(),
            self.ui.txtText3.text(),
            self.ui.txtText4.toPlainText(),
            self.ui.txtText5.toPlainText(),
            self.ui.txtText6.toPlainText(),
            self.ui.txtText7.toPlainText(),
            self.ui.txtText8.text(),
            self.ui.txtText9.text(),
            self.ui.txtText10.text(),
            self.ui.txtText11.text(),
            self.ui.txtText12.text(),
            self.ui.txtText13.text()
        ])
        # self.setDataDict.__setitem__("StraightCount", self.straightCount)
        # self.setDataDict.__setitem__("CatOfAcftCount", self.catOfAcftCount)
        comp = None
        if self.pw == None or not isinstance(self.pw, ComposerDlg):
            comp = self.composer(self.setDataDict)
        else:
            comp = self.composer(self.setDataDict, False)
        pwFlag = False

        if self.pw == None or not isinstance(self.pw, ComposerDlg):
            self.pw = ComposerDlg(self, comp, self.stdModel, self.setDataDict)
            pwFlag = True
        if not self.renderFlag:
            self.pw.show()
        if not pwFlag:
            self.pw.rePresent(comp, self.stdModel, self.setDataDict)
        self.renderFlag = False

    def showDlg(self):
        self.pw.hide()
        self.show()
        self.ui.txtText1.setText(self.txt1.text())
        self.ui.txtText2.setText(self.txt2.text())
        self.ui.txtText3.setText(self.txt3.text())
        self.ui.txtText4.setText(self.txt4.text())
        self.ui.txtText5.setText(self.txt5.text())
        self.ui.txtText6.setText(self.txt6.text())
        self.ui.txtText7.setText(self.txt7.text())
        self.ui.txtText8.setText(self.txt8.text())
        self.ui.txtText9.setText(self.txt9.text())
        self.ui.txtText10.setText(self.txt10.text())
        self.ui.txtText11.setText(self.txt11.text())
        self.ui.txtText12.setText(self.txt12.text())
        self.ui.txtText13.setText(self.txt13.text())

    # def btnNext_clicked(self):
    #     if self.ui.stackedWidget.currentIndex() + 1 < self.ui.stackedWidget.count():
    #         self.ui.stackedWidget.setCurrentIndex(self.ui.stackedWidget.currentIndex() + 1)
    #     self.btnNextAndbtnPreviewSetEnabled()
    def btnPrevious_clicked(self):
        self.setVisible(False)
        self.parent().show()
        # if self.ui.stackedWidget.currentIndex() > 0:
        #     self.ui.stackedWidget.setCurrentIndex(self.ui.stackedWidget.currentIndex() - 1)
        # self.btnNextAndbtnPreviewSetEnabled()

    def composer(self, setData, flag=True):
        paperWidth = setData["Width"]
        paperHeight = setData["Height"]
        mapRenderer = define._canvas.mapRenderer()
        #         comp = None
        comp = QgsComposition(mapRenderer)
        comp.setPlotStyle(QgsComposition.Print)

        comp.setPaperSize(paperWidth, paperHeight)
        # rectangleAll = QgsComposerShape(comp)
        # rectangleAll.setItemPosition(3, 3, paperWidth - 3, paperHeight - 3)
        # rectangleAll.setShapeType(1)
        # comp.addItem(rectangleAll)

        self.txt1 = QgsComposerLabel(comp)
        self.txt1.setItemPosition(20, 20)
        self.txt1.setFrameEnabled(False)
        font = QFont("Arial", 10)
        self.txt1.setFont(font)
        self.txt1.setText(setData["TextData"][0])
        self.txt1.adjustSizeToText()
        comp.addItem(self.txt1)

        self.txt2 = QgsComposerLabel(comp)
        self.txt2.setItemPosition(int(paperWidth / 2) + 10, 20)
        self.txt2.setFrameEnabled(False)
        font = QFont("Arial", 10)
        self.txt2.setFont(font)
        self.txt2.setText(setData["TextData"][1])
        self.txt2.adjustSizeToText()
        comp.addItem(self.txt2)

        self.txt3 = QgsComposerLabel(comp)
        self.txt3.setItemPosition(paperWidth - 40, 20)
        self.txt3.setFrameEnabled(False)
        font = QFont("Arial", 10)
        self.txt3.setFont(font)
        self.txt3.setText(setData["TextData"][2])
        self.txt3.adjustSizeToText()
        comp.addItem(self.txt3)

        w = int((paperWidth - 40) / 4)

        self.txt4 = QgsComposerLabel(comp)
        self.txt4.setItemPosition(20, 35)
        self.txt4.setFrameEnabled(False)
        font = QFont("Arial", 10)
        self.txt4.setFont(font)
        self.txt4.setText(setData["TextData"][3])
        self.txt4.adjustSizeToText()
        comp.addItem(self.txt4)

        self.txt5 = QgsComposerLabel(comp)
        self.txt5.setItemPosition(20 + w, 35)
        self.txt5.setFrameEnabled(False)
        font = QFont("Arial", 10)
        self.txt5.setFont(font)
        self.txt5.setText(setData["TextData"][4])
        self.txt5.adjustSizeToText()
        comp.addItem(self.txt5)

        self.txt6 = QgsComposerLabel(comp)
        self.txt6.setItemPosition(20 + w * 2, 35)
        self.txt6.setFrameEnabled(False)
        font = QFont("Arial", 10)
        self.txt6.setFont(font)
        self.txt6.setText(setData["TextData"][5])
        self.txt6.adjustSizeToText()
        comp.addItem(self.txt6)

        self.txt7 = QgsComposerLabel(comp)
        self.txt7.setItemPosition(20 + w * 3, 35)
        self.txt7.setFrameEnabled(False)
        font = QFont("Arial", 10)
        self.txt7.setFont(font)
        self.txt7.setText(setData["TextData"][6])
        self.txt7.adjustSizeToText()
        comp.addItem(self.txt7)

        # if flag:
        x, y = 20, 45
        composerMap = QgsComposerMap(comp, x, y, paperWidth - 40, 150)
        #         composerMap.setPreviewMode(QgsComposerMap.Render)
        #         composerMap.setGridEnabled(False)

        #rect = composerMap.currentMapExtent ()
        renderer = composerMap.mapRenderer()
        newExtent = renderer.extent()

        #Make sure the width/height ratio is the same as in current composer map extent.
        #This is to keep the map item frame and the page layout fixed
        currentMapExtent = composerMap.currentMapExtent()
        currentWidthHeightRatio = currentMapExtent.width(
        ) / currentMapExtent.height()
        newWidthHeightRatio = newExtent.width() / newExtent.height()

        if currentWidthHeightRatio < newWidthHeightRatio:
            #enlarge height of new extent, ensuring the map center stays the same
            newHeight = newExtent.width() / currentWidthHeightRatio
            deltaHeight = newHeight - newExtent.height()
            newExtent.setYMinimum(newExtent.yMinimum() - deltaHeight / 2)
            newExtent.setYMaximum(newExtent.yMaximum() + deltaHeight / 2)

        else:
            #enlarge width of new extent, ensuring the map center stays the same
            newWidth = currentWidthHeightRatio * newExtent.height()
            deltaWidth = newWidth - newExtent.width()
            newExtent.setXMinimum(newExtent.xMinimum() - deltaWidth / 2)
            newExtent.setXMaximum(newExtent.xMaximum() + deltaWidth / 2)

        composerMap.beginCommand("Map extent changed")
        composerMap.setNewExtent(newExtent)
        composerMap.endCommand()
        # composerMap.setNewScale(3500)

        composerMap.setFrameEnabled(True)
        composerMap.setFrameOutlineWidth(1.0)
        composerMap.setPreviewMode(QgsComposerMap.Render)
        composerMap.updateCachedImage()

        composerMap.setGridEnabled(True)
        composerMap.setGridPenColor(QColor(255, 255, 255, 0))
        composerMap.setGridPenWidth(0.0)
        #composerMap.setGridStyle(QgsComposerMap.FrameAnnotationsOnly)
        composerMap.setGridIntervalX(1.0)
        composerMap.setGridIntervalY(1.0)
        #         mySymbol1 = composerMap.gridLineSymbol ()
        #         mySymbol1.setAlpha(0)
        #composerMap.setGridLineSymbol(mySymbol1)
        composerMap.setShowGridAnnotation(True)
        composerMap.setGridAnnotationFormat(1)
        composerMap.setGridAnnotationPrecision(0)
        composerMap.setGridAnnotationDirection(1, 0)
        composerMap.setGridAnnotationDirection(1, 1)

        comp.addItem(composerMap)

        w = int((paperWidth - 40) / 3)

        self.txt8 = QgsComposerLabel(comp)
        self.txt8.setItemPosition(20, 225)
        self.txt8.setFrameEnabled(False)
        font = QFont("Arial", 10)
        self.txt8.setFont(font)
        self.txt8.setText(setData["TextData"][7])
        self.txt8.adjustSizeToText()
        comp.addItem(self.txt8)

        self.txt9 = QgsComposerLabel(comp)
        self.txt9.setItemPosition(20 + w, 225)
        self.txt9.setFrameEnabled(False)
        font = QFont("Arial", 10)
        self.txt9.setFont(font)
        self.txt9.setText(setData["TextData"][8])
        self.txt9.adjustSizeToText()
        comp.addItem(self.txt9)

        self.txt10 = QgsComposerLabel(comp)
        self.txt10.setItemPosition(20 + w * 2, 225)
        self.txt10.setFrameEnabled(False)
        font = QFont("Arial", 10)
        self.txt10.setFont(font)
        self.txt10.setText(setData["TextData"][9])
        self.txt10.adjustSizeToText()
        comp.addItem(self.txt10)

        # profileRect = QgsComposerPicture(comp)
        # profileRect.setItemPosition(20, 200, paperWidth - 40, 50)
        # comp.addItem(profileRect)

        self.txt11 = QgsComposerLabel(comp)
        self.txt11.setItemPosition(20, paperHeight - 30)
        self.txt11.setFrameEnabled(False)
        font = QFont("Arial", 10)
        self.txt11.setFont(font)
        self.txt11.setText(setData["TextData"][10])
        self.txt11.adjustSizeToText()
        comp.addItem(self.txt11)

        self.txt12 = QgsComposerLabel(comp)
        self.txt12.setItemPosition(20 + w, paperHeight - 30)
        self.txt12.setFrameEnabled(False)
        font = QFont("Arial", 10)
        self.txt12.setFont(font)
        self.txt12.setText(setData["TextData"][11])
        self.txt12.adjustSizeToText()
        comp.addItem(self.txt12)

        self.txt13 = QgsComposerLabel(comp)
        self.txt13.setItemPosition(20 + w * 2, paperHeight - 30)
        self.txt13.setFrameEnabled(False)
        font = QFont("Arial", 10)
        self.txt13.setFont(font)
        self.txt13.setText(setData["TextData"][12])
        self.txt13.adjustSizeToText()
        comp.addItem(self.txt13)

        # gpw = QGraphicsProxyWidget()
        self.tblView = QTableView()
        tableHeight = None
        tableWidth = None
        if self.tableChangedValue == None:
            self.tblView.setFixedWidth(paperWidth - 40)
            tableHeight = 50
            tableWidth = paperWidth - 40
            self.tblView.setFixedHeight(tableHeight)
        else:
            self.tblView.setFixedWidth(self.tableChangedValue["Width"])
            self.tblView.setFixedHeight(self.tableChangedValue["Height"])
            tableHeight = self.tableChangedValue["Height"]
            tableWidth = self.tableChangedValue["Width"]
        self.tblView.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self.tblView.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        hHeder = self.tblView.horizontalHeader()
        hHeder.setVisible(False)
        vHeder = self.tblView.verticalHeader()
        vHeder.setVisible(False)

        # if flag:
        self.stdModel = QStandardItemModel()
        self.data.__setitem__("TableWidth", tableWidth)
        self.data.__setitem__("TableHeight", tableHeight)
        self.setTableView(self.tblView, self.stdModel, self.data)

        self.calcALT()
        self.calcTimeRate()

        self.gpw = QGraphicsProxyWidget()
        self.gpw.setWidget(self.tblView)
        # gpw.setWidget(tblView)
        if self.tableChangedValue == None:
            self.gpw.setPos(20, 210)
            font = QFont()
            font.setPixelSize(2)
            self.gpw.setFont(font)
        else:
            self.gpw.setPos(self.tableChangedValue["X"],
                            self.tableChangedValue["Y"])
            font = QFont()
            font.setPixelSize(self.tableChangedValue["FontSize"])
            self.gpw.setFont(font)

        # tblView.setFrameRect(QRect(20, 210, paperWidth - 40, 50))
        comp.addItem(self.gpw)

        self.connect(self.stdModel, SIGNAL("itemChanged(QStandardItem *)"),
                     self.stdModel_itemChanged)
        return comp

    def setTableView(self, tblView, stdModel, data):
        for i in range(7):
            for j in range(12 + data["CatOfAcftCount"][0]):
                item = QStandardItem("")
                item.setEditable(True)
                item.setTextAlignment(Qt.AlignCenter)
                stdModel.setItem(i, j, item)
        item = QStandardItem("O C A ( H )")
        item.setTextAlignment(Qt.AlignCenter)
        stdModel.setItem(0, 0, item)

        item = QStandardItem("C a t  of  A C F T")
        item.setTextAlignment(Qt.AlignCenter)
        stdModel.setItem(1, 0, item)

        item = QStandardItem("S t r a i g h t-I n  A p p r o a c h")
        item.setTextAlignment(Qt.AlignCenter)
        stdModel.setItem(2, 0, item)

        if data["Template"][0] >= 0 and data["Template"][0] <= 4:
            item = QStandardItem("C i r c l i n g")
            item.setTextAlignment(Qt.AlignCenter)
            stdModel.setItem(4, 0, item)

            item = QStandardItem(
                "F i n a l  A p p r o a c h  L O C  D i s t a n c e  F A F-M A P t"
            )
            item.setTextAlignment(Qt.AlignCenter)
            stdModel.setItem(0, data["CatOfAcftCount"][0] + 3, item)
        else:
            item = QStandardItem("F i n a l  A p p r o a c h  F A F-M A P t")
            item.setTextAlignment(Qt.AlignCenter)
            stdModel.setItem(0, data["CatOfAcftCount"][0] + 3, item)
        if data["Template"][0] == 5:
            item = QStandardItem("LPV")
            item.setTextAlignment(Qt.AlignCenter)
            stdModel.setItem(2, 0, item)

            item = QStandardItem("LNAV / VNAV")
            item.setTextAlignment(Qt.AlignCenter)
            stdModel.setItem(3, 0, item)

            item = QStandardItem("LNAV")
            item.setTextAlignment(Qt.AlignCenter)
            stdModel.setItem(4, 0, item)

            item = QStandardItem("C i r c l i n g")
            item.setTextAlignment(Qt.AlignCenter)
            stdModel.setItem(5, 0, item)
        elif data["Template"][0] == 6:
            item = QStandardItem("LNAV / VNAV")
            item.setTextAlignment(Qt.AlignCenter)
            stdModel.setItem(2, 0, item)

            item = QStandardItem("LNAV")
            item.setTextAlignment(Qt.AlignCenter)
            stdModel.setItem(3, 0, item)

            item = QStandardItem("C i r c l i n g")
            item.setTextAlignment(Qt.AlignCenter)
            stdModel.setItem(4, 0, item)
        elif data["Template"][0] == 7:
            item = QStandardItem("LPV")
            item.setTextAlignment(Qt.AlignCenter)
            stdModel.setItem(2, 0, item)

            item = QStandardItem("LNAV")
            item.setTextAlignment(Qt.AlignCenter)
            stdModel.setItem(3, 0, item)

            item = QStandardItem("C i r c l i n g")
            item.setTextAlignment(Qt.AlignCenter)
            stdModel.setItem(4, 0, item)
        elif data["Template"][0] == 8:
            item = QStandardItem("LNAV")
            item.setTextAlignment(Qt.AlignCenter)
            stdModel.setItem(2, 0, item)

            item = QStandardItem("C i r c l i n g")
            item.setTextAlignment(Qt.AlignCenter)
            stdModel.setItem(3, 0, item)
        elif data["Template"][0] == 9:
            item = QStandardItem("RNP 0.3")
            item.setTextAlignment(Qt.AlignCenter)
            stdModel.setItem(2, 0, item)

            item = QStandardItem("C i r c l i n g")
            item.setTextAlignment(Qt.AlignCenter)
            stdModel.setItem(3, 0, item)

        if data["CatOfAcftCount"][0] == 1:
            item = QStandardItem("A")
            item.setTextAlignment(Qt.AlignCenter)
            stdModel.setItem(1, 3, item)
        elif data["CatOfAcftCount"][0] == 2:
            item = QStandardItem("A")
            item.setTextAlignment(Qt.AlignCenter)
            stdModel.setItem(1, 3, item)

            item = QStandardItem("B")
            item.setTextAlignment(Qt.AlignCenter)
            stdModel.setItem(1, 4, item)
        elif data["CatOfAcftCount"][0] == 3:
            item = QStandardItem("A")
            item.setTextAlignment(Qt.AlignCenter)
            stdModel.setItem(1, 3, item)

            item = QStandardItem("B")
            item.setTextAlignment(Qt.AlignCenter)
            stdModel.setItem(1, 4, item)

            item = QStandardItem("C")
            item.setTextAlignment(Qt.AlignCenter)
            stdModel.setItem(1, 5, item)
        elif data["CatOfAcftCount"][0] == 4:
            item = QStandardItem("A")
            item.setTextAlignment(Qt.AlignCenter)
            stdModel.setItem(1, 3, item)

            item = QStandardItem("B")
            item.setTextAlignment(Qt.AlignCenter)
            stdModel.setItem(1, 4, item)

            item = QStandardItem("C")
            item.setTextAlignment(Qt.AlignCenter)
            stdModel.setItem(1, 5, item)

            item = QStandardItem("D")
            item.setTextAlignment(Qt.AlignCenter)
            stdModel.setItem(1, 6, item)
        elif data["CatOfAcftCount"][0] == 5:
            if data["CatOfAcftCount"][1] == 4:
                item = QStandardItem("A")
                item.setTextAlignment(Qt.AlignCenter)
                stdModel.setItem(1, 3, item)

                item = QStandardItem("B")
                item.setTextAlignment(Qt.AlignCenter)
                stdModel.setItem(1, 4, item)

                item = QStandardItem("C")
                item.setTextAlignment(Qt.AlignCenter)
                stdModel.setItem(1, 5, item)

                item = QStandardItem("D")
                item.setTextAlignment(Qt.AlignCenter)
                stdModel.setItem(1, 6, item)

                item = QStandardItem("DL")
                item.setTextAlignment(Qt.AlignCenter)
                stdModel.setItem(1, 7, item)
            else:
                item = QStandardItem("A")
                item.setTextAlignment(Qt.AlignCenter)
                stdModel.setItem(1, 3, item)

                item = QStandardItem("B")
                item.setTextAlignment(Qt.AlignCenter)
                stdModel.setItem(1, 4, item)

                item = QStandardItem("C")
                item.setTextAlignment(Qt.AlignCenter)
                stdModel.setItem(1, 5, item)

                item = QStandardItem("D")
                item.setTextAlignment(Qt.AlignCenter)
                stdModel.setItem(1, 6, item)

                item = QStandardItem("E")
                item.setTextAlignment(Qt.AlignCenter)
                stdModel.setItem(1, 7, item)
        elif data["CatOfAcftCount"][0] == 6:
            item = QStandardItem("A")
            item.setTextAlignment(Qt.AlignCenter)
            stdModel.setItem(1, 3, item)

            item = QStandardItem("B")
            item.setTextAlignment(Qt.AlignCenter)
            stdModel.setItem(1, 4, item)

            item = QStandardItem("C")
            item.setTextAlignment(Qt.AlignCenter)
            stdModel.setItem(1, 5, item)

            item = QStandardItem("D")
            item.setTextAlignment(Qt.AlignCenter)
            stdModel.setItem(1, 6, item)

            item = QStandardItem("DL")
            item.setTextAlignment(Qt.AlignCenter)
            stdModel.setItem(1, 7, item)

            item = QStandardItem("E")
            item.setTextAlignment(Qt.AlignCenter)
            stdModel.setItem(1, 8, item)

        # item = QStandardItem("DME MX NM")
        # item.setTextAlignment(Qt.AlignCenter)
        # stdModel.setItem(1, 6, item)

        item = QStandardItem("DME SSA")
        item.setTextAlignment(Qt.AlignCenter)
        stdModel.setItem(1, data["CatOfAcftCount"][0] + 3, item)

        item = QStandardItem("6")
        item.setTextAlignment(Qt.AlignCenter)
        stdModel.setItem(1, data["CatOfAcftCount"][0] + 5, item)

        item = QStandardItem("5")
        item.setTextAlignment(Qt.AlignCenter)
        stdModel.setItem(1, data["CatOfAcftCount"][0] + 6, item)

        item = QStandardItem("4")
        item.setTextAlignment(Qt.AlignCenter)
        stdModel.setItem(1, data["CatOfAcftCount"][0] + 7, item)

        item = QStandardItem("3")
        item.setTextAlignment(Qt.AlignCenter)
        stdModel.setItem(1, data["CatOfAcftCount"][0] + 8, item)

        item = QStandardItem("2")
        item.setTextAlignment(Qt.AlignCenter)
        stdModel.setItem(1, data["CatOfAcftCount"][0] + 9, item)

        item = QStandardItem("1")
        item.setTextAlignment(Qt.AlignCenter)
        stdModel.setItem(1, data["CatOfAcftCount"][0] + 10, item)

        item = QStandardItem("A L T(HGT)")
        item.setTextAlignment(Qt.AlignCenter)
        stdModel.setItem(2, data["CatOfAcftCount"][0] + 3, item)

        item = QStandardItem("G S")
        item.setTextAlignment(Qt.AlignCenter)
        stdModel.setItem(3, data["CatOfAcftCount"][0] + 3, item)

        item = QStandardItem("kt")
        item.setTextAlignment(Qt.AlignCenter)
        stdModel.setItem(3, data["CatOfAcftCount"][0] + 5, item)

        item = QStandardItem("80")
        item.setTextAlignment(Qt.AlignCenter)
        stdModel.setItem(3, data["CatOfAcftCount"][0] + 6, item)

        item = QStandardItem("100")
        item.setTextAlignment(Qt.AlignCenter)
        stdModel.setItem(3, data["CatOfAcftCount"][0] + 7, item)

        item = QStandardItem("120")
        item.setTextAlignment(Qt.AlignCenter)
        stdModel.setItem(3, data["CatOfAcftCount"][0] + 8, item)

        item = QStandardItem("140")
        item.setTextAlignment(Qt.AlignCenter)
        stdModel.setItem(3, data["CatOfAcftCount"][0] + 9, item)

        item = QStandardItem("160")
        item.setTextAlignment(Qt.AlignCenter)
        stdModel.setItem(3, data["CatOfAcftCount"][0] + 10, item)

        item = QStandardItem("180")
        item.setTextAlignment(Qt.AlignCenter)
        stdModel.setItem(3, data["CatOfAcftCount"][0] + 11, item)

        item = QStandardItem("T i me")
        item.setTextAlignment(Qt.AlignCenter)
        stdModel.setItem(4, data["CatOfAcftCount"][0] + 3, item)

        item = QStandardItem("mi n:s")
        item.setTextAlignment(Qt.AlignCenter)
        stdModel.setItem(4, data["CatOfAcftCount"][0] + 5, item)

        item = QStandardItem("Rate  Of  D e s c e n t")
        item.setTextAlignment(Qt.AlignCenter)
        stdModel.setItem(5, data["CatOfAcftCount"][0] + 3, item)

        item = QStandardItem("ft/mi n")
        item.setTextAlignment(Qt.AlignCenter)
        stdModel.setItem(5, data["CatOfAcftCount"][0] + 5, item)

        tblView.setModel(stdModel)
        for i in range(7):
            tblView.setRowHeight(i, int(data["TableHeight"] / 7))
        for j in range(12 + data["CatOfAcftCount"][0]):
            tblView.setColumnWidth(
                j,
                int(data["TableWidth"] /
                    float(12 + data["CatOfAcftCount"][0])))
        # tblView.setColumnWidth(0, 25)
        # tblView.setColumnWidth(6, 20)
        tblView.setSpan(0, 0, 1, data["CatOfAcftCount"][0] + 3)
        tblView.setSpan(1, 0, 1, 3)
        if data["Template"][0] >= 0 and data["Template"][0] <= 4:
            tblView.setSpan(2, 0, 1, 3)
            tblView.setSpan(2, 3, 1, data["CatOfAcftCount"][0])
            tblView.setSpan(3, 0, 1, data["CatOfAcftCount"][0] + 3)
            tblView.setSpan(4, 0, 1, 3)
            tblView.setSpan(5, 0, 1, 3)
            tblView.setSpan(6, 0, 1, 3)
        else:
            tblView.setSpan(2, 0, 1, 3)
            tblView.setSpan(3, 0, 1, 3)
            tblView.setSpan(4, 0, 1, 3)
            tblView.setSpan(5, 0, 1, 3)
            tblView.setSpan(6, 0, 1, 3)

        # tblView.setSpan(data["StraightCount"] + 2, 0, 1, 3)

        tblView.setSpan(0, data["CatOfAcftCount"][0] + 3, 1, 9)
        # tblView.setSpan(1, data["CatOfAcftCount"][0] + 4, 1, 5)
        # tblView.setSpan(1, data["CatOfAcftCount"][0] + 9, 1, 3)
        # tblView.setSpan(2, data["CatOfAcftCount"][0] + 5, 1, 4)
        # tblView.setSpan(2, data["CatOfAcftCount"][0] + 9, 1, 3)

        tblView.setSpan(1, data["CatOfAcftCount"][0] + 3, 1, 2)
        tblView.setSpan(2, data["CatOfAcftCount"][0] + 3, 1, 2)
        tblView.setSpan(3, data["CatOfAcftCount"][0] + 3, 1, 2)
        tblView.setSpan(4, data["CatOfAcftCount"][0] + 3, 1, 2)
        tblView.setSpan(5, data["CatOfAcftCount"][0] + 3, 1, 2)
        tblView.setSpan(6, data["CatOfAcftCount"][0] + 3, 1, 2)

    def stdModel_itemChanged(self, item):
        if item.row() != 1 and item.row() != 3:
            return
        self.calcTimeRate()
        self.calcALT()

    def calcALT(self):
        thrAlt = Unit.ConvertFeetToMeter(self.data["ThrAltitude"])
        rdhAlt = Unit.ConvertFeetToMeter(self.data["RDHAltitude"])
        gradient = self.data["DescentGradient"]
        dx = self.data["dX"]

        for i in range(7):
            item = self.stdModel.item(1,
                                      self.data["CatOfAcftCount"][0] + 5 + i)
            val = 0.0
            try:
                val = float(item.text())
            except:
                continue
            dist = val * 1852
            valueHgt = Unit.ConvertFeetToMeter(
                (dist - dx) * math.tan(Unit.ConvertDegToRad(gradient)))
            valueAlt = valueHgt + thrAlt + rdhAlt
            if valueAlt > int(valueAlt):
                valueAlt = int(valueAlt) + 1
            if valueHgt > int(valueHgt):
                valueHgt = int(valueHgt) + 1

            itemTemp = QStandardItem(
                str(valueAlt) + "\n(" + str(valueHgt) + ")")
            itemTemp.setTextAlignment(Qt.AlignCenter)
            self.stdModel.setItem(2, self.data["CatOfAcftCount"][0] + 5 + i,
                                  itemTemp)

    def calcTimeRate(self):
        for i in range(6):
            item = self.stdModel.item(3,
                                      self.data["CatOfAcftCount"][0] + 6 + i)
            val = 0.0
            try:
                val = float(item.text())
            except:
                continue
            time = (3600 * self.data["Distance"]) / val
            minute = int(time / 60)
            second = int(time % 60)

            timeStr = str(minute) + " : " + str(second)
            if second == 0:
                timeStr = str(minute) + " : " + "00"
            elif second < 10:
                timeStr = str(minute) + " : 0" + str(second)
            itemTemp = QStandardItem(timeStr)
            itemTemp.setTextAlignment(Qt.AlignCenter)
            self.stdModel.setItem(4, self.data["CatOfAcftCount"][0] + 6 + i,
                                  itemTemp)

            rate = int(
                (val * 6076.1 *
                 (AngleGradientSlope(self.data["DescentGradient"]).Percent /
                  float(100))) / float(60))
            itemTemp = QStandardItem(str(rate))
            itemTemp.setTextAlignment(Qt.AlignCenter)
            self.stdModel.setItem(5, self.data["CatOfAcftCount"][0] + 6 + i,
                                  itemTemp)
class CandidateCrawlerUI(object):
    def setupUi(self, MainWindow):
        self.centralwidget = QtGui.QWidget(MainWindow)
        self.qbox = QBoxLayout(QBoxLayout.TopToBottom, self.centralwidget)
        self.centralwidget.setLayout(self.qbox)
               
        #####Mots-clés###
        self.keywords_label = QtGui.QLabel(self.centralwidget)
        self.keywords_label.setText(_translate("AdminWindow", "Mots-clés de recherche", None))
         
        self.keywords_help = QtGui.QPushButton(self.centralwidget)
        self.keywords_help.setIcon(QIcon('./share/icon/point interrogation.png'))
        self.keywords_help.setIconSize(QSize(10,10))
        
        self.hbox_keywords = QtGui.QHBoxLayout()
        self.hbox_keywords.addWidget(self.keywords_label)
        self.hbox_keywords.addWidget(self.keywords_help)
        self.hbox_keywords.setContentsMargins(0, 0, 120, 0)
        
        self.keywords_entry = QtGui.QLineEdit(self.centralwidget)
        
        self.vbox_keywords = QtGui.QVBoxLayout()
        self.vbox_keywords.addLayout(self.hbox_keywords)
        self.vbox_keywords.addWidget(self.keywords_entry)
        self.vbox_keywords.setContentsMargins(0, 0, 0, 5) 
         
        ###Région### 
        self.region_label = QtGui.QLabel(self.centralwidget)
        self.region_label.setText(_translate("AdminWindow", "Région (5 choix maximum)", None))
                        
        self.region_list = QtGui.QListView(self.centralwidget)
               
        self.vbox_region = QtGui.QVBoxLayout()
        self.vbox_region.addWidget(self.region_label)
        self.vbox_region.addWidget(self.region_list)
        self.vbox_region.setContentsMargins(0, 0, 0, 5)
        
        ###Mobilité###
        self.mobilite_label = QtGui.QLabel(self.centralwidget)
        self.mobilite_label.setText(_translate("AdminWindow", "Mobilité", None))
                        
        self.mobilite_combobox = QtGui.QComboBox(self.centralwidget)
        
        self.vbox_mobilite = QtGui.QVBoxLayout()
        self.vbox_mobilite.addWidget(self.mobilite_label)
        self.vbox_mobilite.addWidget(self.mobilite_combobox)
        self.vbox_mobilite.setContentsMargins(0, 0, 0, 5)
        
        ###Salaire###
        self.salaire_label = QtGui.QLabel(self.centralwidget)
        self.salaire_label.setText(_translate("AdminWindow", "Salaire", None))
                
        self.salaire_combobox = QtGui.QComboBox(self.centralwidget)
        
        self.vbox_salaire = QtGui.QVBoxLayout()
        self.vbox_salaire.addWidget(self.salaire_label)
        self.vbox_salaire.addWidget(self.salaire_combobox)
        self.vbox_salaire.setContentsMargins(0, 0, 0, 5)
        
        ###Disponibilité###
        self.disponibilite_label = QtGui.QLabel(self.centralwidget)
        self.disponibilite_label.setText(_translate("AdminWindow", "Disponibilité", None))
                
        self.disponibilite_list = QtGui.QListView(self.centralwidget)
        
        self.vbox_disponibilite = QtGui.QVBoxLayout()
        self.vbox_disponibilite.addWidget(self.disponibilite_label)
        self.vbox_disponibilite.addWidget(self.disponibilite_list)
        self.vbox_disponibilite.setContentsMargins(0, 0, 0, 5)
        
        ###Fraîcheur###
        self.fraicheur_label = QtGui.QLabel(self.centralwidget)
        self.fraicheur_label.setText(_translate("AdminWindow", "Fraîcheur", None))
                
        self.fraicheur_combobox = QtGui.QComboBox(self.centralwidget)
        
        self.vbox_fraicheur = QtGui.QVBoxLayout()
        self.vbox_fraicheur.addWidget(self.fraicheur_label)
        self.vbox_fraicheur.addWidget(self.fraicheur_combobox)
        self.vbox_fraicheur.setContentsMargins(0, 0, 0, 5)
        
        ###Nombre de CVs###
        self.cv_number_label = QtGui.QLabel(self.centralwidget)
        self.cv_number_label.setText(_translate("AdminWindow", "Nombre de CV", None))
        
        self.cv_number_entry = QtGui.QLineEdit(self.centralwidget)
        self.cv_number_entry.setInputMethodHints(QtCore.Qt.ImhNone)
        self.cv_number_entry.setText("50")
        
        self.vbox_cv_number = QtGui.QVBoxLayout()
        self.vbox_cv_number.addWidget(self.cv_number_label)
        self.vbox_cv_number.addWidget(self.cv_number_entry)
        self.vbox_cv_number.setContentsMargins(0, 0, 0, 5)
            
        ###Progression###         
        self.progression_label = QtGui.QLabel(self.centralwidget)
        self.progression_label.setText(_translate("AdminWindow", "Progression", None))
                     
        self.progression_text = QtGui.QTextBrowser(self.centralwidget)
        
        self.vbox_progression = QtGui.QVBoxLayout()
        self.vbox_progression.addWidget(self.progression_label)
        self.vbox_progression.addWidget(self.progression_text)
        self.vbox_progression.setContentsMargins(0, 0, 0, 5)
        
        ###Bouton de lancement###
        self.run_button = QtGui.QPushButton(self.centralwidget)
        self.run_button.setText(_translate("AdminWindow", "Lancer la recherche", None))
        
        
        ###Ajout a la fenetre principale###
        
        self.qbox.addLayout(self.vbox_keywords)
        self.qbox.addLayout(self.vbox_region)
        self.qbox.addLayout(self.vbox_mobilite)
        self.qbox.addLayout(self.vbox_salaire)
        self.qbox.addLayout(self.vbox_disponibilite)
        self.qbox.addLayout(self.vbox_fraicheur)
        self.qbox.addLayout(self.vbox_cv_number)
        self.qbox.addLayout(self.vbox_progression)
        self.qbox.addWidget(self.run_button)
        
        MainWindow.setCentralWidget(self.centralwidget)

        
    ###Barre de menu###           
        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtGui.QMenuBar(MainWindow)
        self.menuFichier = QtGui.QMenu(self.menubar)
        self.menuEdition = QtGui.QMenu(self.menubar)
        self.menuAide = QtGui.QMenu(self.menubar)
        
        MainWindow.setMenuBar(self.menubar)
        self.about_action = QtGui.QAction(MainWindow)
        self.admin_action = QtGui.QAction(MainWindow)
        self.exit_action = QtGui.QAction(MainWindow)
        self.menuFichier.addAction(self.admin_action)
        self.menuFichier.addAction(self.exit_action)
        self.menuAide.addAction(self.about_action)
        self.menubar.addAction(self.menuFichier.menuAction())
        self.menubar.addAction(self.menuAide.menuAction())
        
     
        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

        # Values for combobox
        staticsxmlfile = "statics.xml"

        region_list = tuple(toolbox.xml_reader(staticsxmlfile, "regions").split(','))
        mobilite_list = tuple(toolbox.xml_reader(staticsxmlfile, "mobilite").split(','))
        salaire_list = tuple(toolbox.xml_reader(staticsxmlfile, "salaire").split(','))
        disponibilite_list = tuple(toolbox.xml_reader(staticsxmlfile, "disponibilite").split(','))
        fraicheur_list = tuple(toolbox.xml_reader(staticsxmlfile, "fraicheur").split(','))
         
        
        self.model = QStandardItemModel(self.region_list)
        for region in region_list:
            item = QStandardItem(region)
            item.setFlags(Qt.ItemIsUserCheckable | Qt.ItemIsEnabled)
            item.setData(QVariant(Qt.Unchecked), Qt.CheckStateRole)
            self.model.appendRow(item)
        self.region_list.setModel(self.model)

        self.model2 = QStandardItemModel(self.disponibilite_list)
        for disponibilite in disponibilite_list:
            item = QStandardItem(disponibilite)
            item.setFlags(Qt.ItemIsUserCheckable | Qt.ItemIsEnabled)
            item.setData(QVariant(Qt.Unchecked), Qt.CheckStateRole)
            self.model2.appendRow(item)
        self.disponibilite_list.setModel(self.model2)
         
        for element in mobilite_list:
            self.mobilite_combobox.addItem(element)
        
        for element in salaire_list:
            self.salaire_combobox.addItem(element)
         
        
        for element in fraicheur_list:
            self.fraicheur_combobox.addItem(element)
            
         

        # Action attached to buttons
        ####################################################################
        self.about_action.triggered.connect(self.about_window) 
        self.admin_action.triggered.connect(self.admin_window)  
        self.exit_action.triggered.connect(self.close)
        self.run_button.clicked.connect(self.run_program)
        self.keywords_help.clicked.connect(self.ouvrirDialogue)
        

        
    def retranslateUi(self, MainWindow):
        MainWindow.setWindowTitle(_translate("MainWindow", "Candidate Crawler APEC", None))
        
        
        self.menuFichier.setTitle(_translate("MainWindow", "Fichier", None))
        self.menuAide.setTitle(_translate("MainWindow", "Aide", None))
        self.about_action.setText(_translate("MainWindow", "A propos", None))
        self.admin_action.setText(_translate("MainWindow", "Administration", None))
        self.exit_action.setText(_translate("MainWindow", "Quitter", None))
        

    # Methods for class CandidateCrawlerUI

    def about_window(self):
        """Method to generate About window"""
        self.about_w = About_window.AboutWindowGUI()
        self.about_w.show()
    
    def admin_window(self):
        """Method to generate About window"""
        self.admin_w = Admin_window.AdminWindowGUI()
        self.admin_w.show()
        
    def reset(self):
        """Method to reset main window"""
        self.progression_text.clear()

    def close(self):
        """Method to close main window"""
        self.close()
    
    def ouvrirDialogue(self):
        QMessageBox.information(self, self.trUtf8("Aide mots-clés"),self.trUtf8("Vous pouvez entrer plusieurs mots-clés, sans accents, en les séparant par des espaces."))

    
    def _entries_retriever(self):
        """Method to get user entries"""
        self.keywords = self.trUtf8(self.keywords_entry.text())
    
        self.region = []
        for row in range(self.model.rowCount()):
            item = self.model.item(row)
            if item.checkState() == QtCore.Qt.Checked:
                self.region = [str(item.text())]+self.region
        
        self.mobilite = self.mobilite_combobox.currentText()
        self.salaire = self.salaire_combobox.currentText()
        
        self.disponibilite = []
        for row in range(self.model2.rowCount()):
            item = self.model2.item(row)
            if item.checkState() == QtCore.Qt.Checked:
                self.disponibilite = [str(item.text())]+self.disponibilite

        self.fraicheur = self.fraicheur_combobox.currentText()
        self.nombreCV = self.trUtf8(self.cv_number_entry.text())
        
    def _entries_checker(self):
        """Method to check user entries"""
        error_code = False
        error_list = []

        if self.keywords[0] == "":
            error_code = True
            error_list.append(_translate("MainWindow", "Veuillez entrer des mots-clés", None))

        if self.nombreCV[0] == "":
            error_code = True
            error_list.append(_translate("MainWindow", "Veuillez entrer un nombre de CVs", None))


        return error_code, error_list


    def run_program(self):
        """Method to run program on tab1: ponctual search"""
        self.progression_text.append("Lancement du programme")
        self.progression_text.append("Programme en cours ...")

        app.processEvents() # Window refresh

        try:
            self._entries_retriever()

            if self._entries_checker()[0]:
                self.progression_text.setTextColor(QtGui.QColor("red"))
                for element in self._entries_checker()[1]:
                    self.progression_text.append(element)
                self.progression_text.setTextColor(QtGui.QColor("black"))
                self.progression_text.append(_translate("MainWindow", "Programme stoppé", None))

                return
            
            runapp = core.CandidateCrawlerCore(toolbox.getconfigvalue("APEC", "login"), toolbox.getconfigvalue("APEC", "password"),self.keywords, self.region
                                               , self.mobilite, self.salaire, self.disponibilite, self.fraicheur, self.nombreCV)
            print(self.keywords)
            print(self.region)
            print(self.mobilite)
            print(self.salaire)
            print(self.disponibilite)
            print(self.fraicheur)
            print(self.nombreCV)

            runapp.crawl()
            self.progression_text.append(self.trUtf8("Fin du programme\n"))
            
        except:
            self.progression_text.append(self.trUtf8("Oups, quelque chose s'est mal passé"))
            self.progression_text.append(self.trUtf8("Veuillez vérifier les champs de l'adiministration"))
            self.progression_text.append(self.trUtf8("Fin du programme\n"))
            raise
예제 #22
0
파일: qt.py 프로젝트: odipus/orange3
class QtWidgetRegistry(QObject, WidgetRegistry):
    """
    A QObject wrapper for `WidgetRegistry`

    A QStandardItemModel instance containing the widgets in
    a tree (of depth 2). The items in a model can be quaries using standard
    roles (DisplayRole, BackgroundRole, DecorationRole ToolTipRole).
    They also have QtWidgetRegistry.CATEGORY_DESC_ROLE,
    QtWidgetRegistry.WIDGET_DESC_ROLE, which store Category/WidgetDescription
    respectfully. Furthermore QtWidgetRegistry.WIDGET_ACTION_ROLE stores an
    default QAction which can be used for widget creation action.

    """

    CATEGORY_DESC_ROLE = Qt.UserRole + 1
    """Category Description Role"""

    WIDGET_DESC_ROLE = Qt.UserRole + 2
    """Widget Description Role"""

    WIDGET_ACTION_ROLE = Qt.UserRole + 3
    """Widget Action Role"""

    BACKGROUND_ROLE = Qt.UserRole + 4
    """Background color for widget/category in the canvas
    (different from Qt.BackgroundRole)
    """

    category_added = Signal(str, CategoryDescription)
    """signal: category_added(name: str, desc: CategoryDescription)
    """

    widget_added = Signal(str, str, WidgetDescription)
    """signal widget_added(category_name: str, widget_name: str,
                           desc: WidgetDescription)
    """

    reset = Signal()
    """signal: reset()
    """
    def __init__(self, other_or_parent=None, parent=None):
        if isinstance(other_or_parent, QObject) and parent is None:
            parent, other_or_parent = other_or_parent, None
        QObject.__init__(self, parent)
        WidgetRegistry.__init__(self, other_or_parent)

        # Should  the QStandardItemModel be subclassed?
        self.__item_model = QStandardItemModel(self)

        for i, desc in enumerate(self.categories()):
            cat_item = self._cat_desc_to_std_item(desc)
            self.__item_model.insertRow(i, cat_item)

            for j, wdesc in enumerate(self.widgets(desc.name)):
                widget_item = self._widget_desc_to_std_item(wdesc, desc)
                cat_item.insertRow(j, widget_item)

    def model(self):
        """
        Return the widget descriptions in a Qt Item Model instance
        (QStandardItemModel).

        .. note:: The model should not be modified outside of the registry.

        """
        return self.__item_model

    def item_for_widget(self, widget):
        """Return the QStandardItem for the widget.
        """
        if isinstance(widget, str):
            widget = self.widget(widget)
        cat = self.category(widget.category)
        cat_ind = self.categories().index(cat)
        cat_item = self.model().item(cat_ind)
        widget_ind = self.widgets(cat).index(widget)
        return cat_item.child(widget_ind)

    def action_for_widget(self, widget):
        """
        Return the QAction instance for the widget (can be a string or
        a WidgetDescription instance).

        """
        item = self.item_for_widget(widget)
        return item.data(self.WIDGET_ACTION_ROLE)

    def create_action_for_item(self, item):
        """
        Create a QAction instance for the widget description item.
        """
        name = item.text()
        tooltip = item.toolTip()
        whatsThis = item.whatsThis()
        icon = item.icon()
        if icon:
            action = QAction(icon,
                             name,
                             self,
                             toolTip=tooltip,
                             whatsThis=whatsThis,
                             statusTip=name)
        else:
            action = QAction(name,
                             self,
                             toolTip=tooltip,
                             whatsThis=whatsThis,
                             statusTip=name)

        widget_desc = item.data(self.WIDGET_DESC_ROLE)
        action.setData(widget_desc)
        action.setProperty("item", item)
        return action

    def _insert_category(self, desc):
        """
        Override to update the item model and emit the signals.
        """
        priority = desc.priority
        priorities = [c.priority for c, _ in self.registry]
        insertion_i = bisect.bisect_right(priorities, priority)

        WidgetRegistry._insert_category(self, desc)

        cat_item = self._cat_desc_to_std_item(desc)
        self.__item_model.insertRow(insertion_i, cat_item)

        self.category_added.emit(desc.name, desc)

    def _insert_widget(self, category, desc):
        """
        Override to update the item model and emit the signals.
        """
        assert (isinstance(category, CategoryDescription))
        categories = self.categories()
        cat_i = categories.index(category)
        _, widgets = self._categories_dict[category.name]
        priorities = [w.priority for w in widgets]
        insertion_i = bisect.bisect_right(priorities, desc.priority)

        WidgetRegistry._insert_widget(self, category, desc)

        cat_item = self.__item_model.item(cat_i)
        widget_item = self._widget_desc_to_std_item(desc, category)

        cat_item.insertRow(insertion_i, widget_item)

        self.widget_added.emit(category.name, desc.name, desc)

    def _cat_desc_to_std_item(self, desc):
        """
        Create a QStandardItem for the category description.
        """
        item = QStandardItem()
        item.setText(desc.name)

        if desc.icon:
            icon = desc.icon
        else:
            icon = "icons/default-category.svg"

        icon = icon_loader.from_description(desc).get(icon)
        item.setIcon(icon)

        if desc.background:
            background = desc.background
        else:
            background = DEFAULT_COLOR

        background = NAMED_COLORS.get(background, background)

        brush = QBrush(QColor(background))
        item.setData(brush, self.BACKGROUND_ROLE)

        tooltip = desc.description if desc.description else desc.name

        item.setToolTip(tooltip)
        item.setFlags(Qt.ItemIsEnabled)
        item.setData(desc, self.CATEGORY_DESC_ROLE)
        return item

    def _widget_desc_to_std_item(self, desc, category):
        """
        Create a QStandardItem for the widget description.
        """
        item = QStandardItem(desc.name)
        item.setText(desc.name)

        if desc.icon:
            icon = desc.icon
        else:
            icon = "icons/default-widget.svg"

        icon = icon_loader.from_description(desc).get(icon)
        item.setIcon(icon)

        # This should be inherited from the category.
        background = None
        if desc.background:
            background = desc.background
        elif category.background:
            background = category.background
        else:
            background = DEFAULT_COLOR

        if background is not None:
            background = NAMED_COLORS.get(background, background)
            brush = QBrush(QColor(background))
            item.setData(brush, self.BACKGROUND_ROLE)

        tooltip = tooltip_helper(desc)
        style = "ul { margin-top: 1px; margin-bottom: 1px; }"
        tooltip = TOOLTIP_TEMPLATE.format(style=style, tooltip=tooltip)
        item.setToolTip(tooltip)
        item.setWhatsThis(whats_this_helper(desc))
        item.setFlags(Qt.ItemIsEnabled | Qt.ItemIsSelectable)
        item.setData(desc, self.WIDGET_DESC_ROLE)

        # Create the action for the widget_item
        action = self.create_action_for_item(item)
        item.setData(action, self.WIDGET_ACTION_ROLE)
        return item
예제 #23
0
class ModelAtrributesView(QListView):
    """
    Custom QListView implementation that displays checkable model attributes.
    """
    def __init__(self, parent=None, dataModel=None):
        QListView.__init__(self, parent)

        self._dataModel = dataModel
        self._selectedDisplayMapping = OrderedDict()
        self._attrModel = QStandardItemModel(self)

    def dataModel(self):
        """
        Returns the data model instance.
        """
        return self._dataModel

    def setDataModel(self, dataModel):
        """
        Sets the data model. Should be a callable class rather than the class
        instance.
        """
        if callable(dataModel):
            self._dataModel = dataModel

        else:
            self._dataModel = dataModel.__class__

    def load(self):
        """
        Load the model's attributes into the list view.
        """
        if self._dataModel == None:
            return

        try:
            self._loadAttrs(self._dataModel.displayMapping())
        except AttributeError:
            #Ignore error if model does not contain the displayMapping static method
            pass

    def _loadAttrs(self, attrMapping):
        """
        Loads display mapping into the list view.
        """
        self._attrModel.clear()
        self._attrModel.setColumnCount(2)

        for attrName, displayName in attrMapping.iteritems():
            #Exclude row ID in the list, other unique identifier attributes in the model can be used
            if attrName != "id":
                displayNameItem = QStandardItem(displayName)
                displayNameItem.setCheckable(True)
                attrNameItem = QStandardItem(attrName)

                self._attrModel.appendRow([displayNameItem, attrNameItem])

        self.setModel(self._attrModel)

    def selectedMappings(self):
        """
        Return a dictionary of field names and their corresponding display values.
        """
        selectedAttrs = {}

        for i in range(self._attrModel.rowCount()):
            displayNameItem = self._attrModel.item(i, 0)

            if displayNameItem.checkState() == Qt.Checked:
                attrNameItem = self._attrModel.item(i, 1)
                selectedAttrs[attrNameItem.text()] = displayNameItem.text()

        return selectedAttrs
예제 #24
0
class ImportUpdateDialog(QDialog, Ui_ImportUpdate):
    """
    Class responsible for handling the update() function.
    """
    def __init__(self, iface):
        QDialog.__init__(self)
        self.setupUi(self)
        self.iface = iface
        self.dbconn = DBConn(iface)
        self.get_attributes()
        self.set_importable_tables()

    def get_attributes(self):
        """Place excludable attributes in model list"""
        # Model Structure used from Tutorial at
        # http://pythoncentral.io/pyside-pyqt-tutorial-qlistview-and-qstandarditemmodel/

        self.model = QStandardItemModel(self.listTblAttrib)
        self.hasGeometry = self.iface.activeLayer().hasGeometryType()
        self.provider = self.iface.activeLayer().dataProvider()
        fields = self.iface.activeLayer().pendingFields()

        for field in fields:
            item = QStandardItem(field.name())
            item.setCheckable(True)
            self.model.appendRow(item)
        self.listTblAttrib.setModel(self.model)

    def get_checked_attributes(self):
        """Creates a list of checked elements to be excluded"""
        i = 0
        exclList = list()
        while self.model.item(i):
            if self.model.item(i).checkState():
                exclList.append(self.model.item(i).text())
            i += 1
        return exclList

    def set_importable_tables(self):
        """Populates combobox with importable tables

           Name Structure <schema.tablename>"""
        self.uri = QgsDataSourceURI(self.provider.dataSourceUri())
        self.execute = SQLExecute(
            self.iface, self.iface.mainWindow(), self.uri)

        # Returns Result to be parsed
        schemaTableList = self.execute.retrieve_all_importable_tables()
        cmbList = list()
        if schemaTableList:
            for entry in schemaTableList:
                cmbEntry = entry[0] + '.' + entry[1]
                cmbList.append(cmbEntry)
        self.cmbImportTable.addItems(cmbList)

    @pyqtSignature("")
    def on_buttonBox_accepted(self):
        """
        Run hist_tabs.update() SQL function with given parameters
        """
        select = self.cmbImportTable.currentText()
        exclList = self.get_checked_attributes()
        # Split the user selection for querying
        splitString = select.split('.')
        importSchema = splitString[0]
        importTable = splitString[1]
        self.execute.update_table_entries(
            importSchema,
            importTable,
            self.uri.schema(),
            self.iface.activeLayer().name(),
            self.hasGeometry, exclList)

    @pyqtSignature("")
    def on_buttonBox_rejected(self):
        """
        Slot documentation goes here.
        """
        self.close()
예제 #25
0
class LogDialog(QDialogWithDpi):
    """LogDialog for the Freeseer project.

    It is the dialog window for the log.
    There is an instance for every FreeseerApp.
    It has a LogHandler which calls LogDialog's
    message() method when a new log message is received.
    The call to message() causes a call to add_entry()
    which adds the information to a new row in the table.
    """
    def __init__(self, parent=None):
        super(LogDialog, self).__init__(parent)

        self.resize(800, 500)

        self.app = QApplication.instance()

        icon = QIcon()
        icon.addPixmap(QPixmap(_fromUtf8(":/freeseer/logo.png")), QIcon.Normal,
                       QIcon.Off)
        self.setWindowIcon(icon)

        layout = QVBoxLayout()
        self.setLayout(layout)

        self.level = 0
        self.handler = LogHandler()

        self.table_model = QStandardItemModel(0, 5)
        header_names = ["Date", "Level", "Module", "Message", "LevelNo"]
        date_column = header_names.index("Date")
        level_column = header_names.index("Level")
        module_column = header_names.index("Module")
        self.level_num_column = header_names.index("LevelNo")
        self.table_model.setHorizontalHeaderLabels(header_names)

        self.table_view = QTableView()
        self.table_view.setModel(self.table_model)
        self.table_view.horizontalHeader().setStretchLastSection(True)
        self.table_view.setColumnWidth(date_column,
                                       self.set_width_with_dpi(125))
        self.table_view.setColumnWidth(level_column,
                                       self.set_width_with_dpi(60))
        self.table_view.setColumnWidth(module_column,
                                       self.set_width_with_dpi(250))
        self.table_view.setColumnHidden(self.level_num_column, True)
        self.table_view.setShowGrid(False)
        self.table_view.horizontalHeader().setClickable(False)
        self.table_view.verticalHeader().hide()
        self.table_view.setStyleSheet("""Qtable_view::item {
            border-bottom: 1px solid lightgrey;
            selection-background-color: white;
            selection-color: black;
            }""")

        top_panel = QHBoxLayout()
        self.log_levels = ["Debug", "Info", "Warning", "Error"]
        self.level_colors = ["#3E4C85", "#269629", "#B0AB21", "#B32020"]

        self.levels_label = QLabel("Filter Level: ")
        self.levels_label.setStyleSheet("QLabel { font-weight: bold }")
        self.current_level_label = QLabel(self.log_levels[0])
        self.current_level_label.setStyleSheet("QLabel {{ color: {} }}".format(
            self.level_colors[0]))
        self.clear_button = QPushButton("Clear Log")
        self.levels_slider = QSlider(Qt.Horizontal)
        self.levels_slider.setStyleSheet("""
        QSlider::handle:horizontal {
            background: qlineargradient(x1:0, y1:0, x2:1, y2:1,
                stop:0 #FFFFFF, stop:1 #E3E3E3);
            border: 1px solid #707070;
            width: 10px;
            margin-top: -4px;
            margin-bottom: -4px;
            border-radius: 4px;
        }

        QSlider::handle:horizontal:hover {
            background: qlineargradient(x1:0, y1:0, x2:1, y2:1,
                stop:0 #DEDEDE, stop:1 #C9C9C9);
            border: 1px solid #4F4F4F;
            border-radius: 4px;
        }

        QSlider::sub-page:horizontal {
            background: qlineargradient(x1: 0, y1: 0,    x2: 0, y2: 1,
                stop: 0 #BFBFBF, stop: 1 #9E9E9E);
            background: qlineargradient(x1: 0, y1: 0.2, x2: 1, y2: 1,
                stop: 0 #9E9E9E, stop: 1 #858585);
            border: 1px solid #777;
            height: 10px;
            border-radius: 4px;
        }

        QSlider::add-page:horizontal {
            background: #fff;
            border: 1px solid #707070;
            height: 10px;
            border-radius: 4px;
        }""")
        self.levels_slider.setRange(0, len(self.log_levels) - 1)
        self.levels_slider.setTickPosition(QSlider.TicksBelow)
        self.levels_slider.setTickInterval(1)

        top_panel.addSpacerItem(self.qspacer_item_with_dpi(10, 0))
        top_panel.addWidget(self.levels_label, 3)
        top_panel.addWidget(self.current_level_label, 2)
        top_panel.addWidget(self.levels_slider, 8)
        top_panel.addSpacerItem(self.qspacer_item_with_dpi(25, 0))
        top_panel.addWidget(self.clear_button, 10)

        layout.addLayout(top_panel)
        layout.addWidget(self.table_view)

        self.connect(self.clear_button, SIGNAL('clicked()'),
                     functools.partial(self.table_model.setRowCount, 0))
        self.connect(self.levels_slider, SIGNAL('valueChanged(int)'),
                     self.slider_set_level)

        self.setWindowTitle("Log")
        self.handler.add_listener(self)

    def __del__(self):
        self.handler.remove_listener(self)

    def retranslate(self):
        self.setWindowTitle(self.app.translate("LogDialog", "Log"))
        self.clear_button.setText(self.app.translate("LogDialog", "Clear Log"))
        self.levels_label.setText("{}: ".format(
            self.app.translate("LogDialog", "Filter Level")))

    def message(self, message):
        """Passes the log fields to add_entry()

        It is called by LogHandler when a log message is received"""
        self.add_entry(message["time"], message["level"],
                       message["full_module_name"], message["message"],
                       str(message["levelno"]))

    def add_entry(self, date, level, module, message, levelno):
        """Adds the given fields to a new row in the log table

        It is called by message() when a log message is received"""
        items = [
            QStandardItem(date),
            QStandardItem(level),
            QStandardItem(module),
            QStandardItem(message),
            QStandardItem(levelno)
        ]
        for item in items:
            item.setEditable(False)
        self.table_model.appendRow(items)

    def slider_set_level(self, level):
        self.current_level_label.setText(self.log_levels[level])
        self.current_level_label.setStyleSheet("QLabel {{ color: {} }}".format(
            self.level_colors[level]))
        self.set_level(level + 1)

    def set_level(self, level):
        """Sets the current level of the LogDialog.

        Level is based on the selection made in the levels_combo_box.
        It hides all messages with a lower level."""
        self.level = level * 10
        for i in range(self.table_model.rowCount()):
            if int(str(self.table_model.item(
                    i, self.level_num_column).text())) < self.level:
                self.table_view.setRowHidden(i, True)
            else:
                self.table_view.setRowHidden(i, False)
예제 #26
0
class MultipleSelectTreeView(QListView):
    """
    Custom QListView implementation that displays checkable items from a
    multiple select column type.
    """
    def __init__(self, column, parent=None):
        """
        Class constructor.
        :param column: Multiple select column object.
        :type column: MultipleSelectColumn
        :param parent: Parent widget for the control.
        :type parent: QWidget
        """
        QListView.__init__(self, parent)

        #Disable editing of lookup values
        self.setEditTriggers(QAbstractItemView.NoEditTriggers)

        self.column = column

        self._item_model = QStandardItemModel(self)

        self._value_list = self.column.value_list

        #Stores lookup objects based on primary keys
        self._lookup_cache = {}

        self._initialize()

        self._association = self.column.association

        self._first_parent_col = self._association.first_reference_column.name
        self._second_parent_col = self._association.second_reference_column.name

        #Association model
        self._assoc_cls = entity_model(self._association)

    def reset_model(self):
        """
        Resets the item model.
        """
        self._item_model.clear()
        self._item_model.setColumnCount(2)

    def clear(self):
        """
        Clears all items in the model.
        """
        self._item_model.clear()

    @property
    def association(self):
        """
        :return: Returns the association object corresponding to the column.
        :rtype: AssociationEntity
        """
        return self._association

    @property
    def value_list(self):
        """
        :return: Returns the ValueList object corresponding to the configured
        column object.
        :rtype: ValueList
        """
        return self._value_list

    @property
    def item_model(self):
        """
        :return: Returns the model corresponding to the checkable items.
        :rtype: QStandardItemModel
        """
        return self._item_model

    def _add_item(self, id, value):
        """
        Adds a row corresponding to id and corresponding value from a lookup
        table.
        :param id: Primary key of a lookup record.
        :type id: int
        :param value: Lookup value
        :type value: str
        """
        value_item = QStandardItem(value)
        value_item.setCheckable(True)
        id_item = QStandardItem(str(id))

        self._item_model.appendRow([value_item, id_item])

    def _initialize(self):
        #Populate list with lookup items
        self.reset_model()

        #Add all lookup values in the value list table
        vl_cls = entity_model(self._value_list)
        if not vl_cls is None:
            vl_obj = vl_cls()
            res = vl_obj.queryObject().all()
            for r in res:
                self._lookup_cache[r.id] = r
                self._add_item(r.id, r.value)

        self.setModel(self._item_model)

    def clear_selection(self):
        """
        Unchecks all items in the view.
        """
        for i in range(self._item_model.rowCount()):
            value_item = self._item_model.item(i, 0)

            if value_item.checkState() == Qt.Checked:
                value_item.setCheckState(Qt.Unchecked)

                if value_item.rowCount() > 0:
                    value_item.removeRow(0)

    def selection(self):
        """
        :return: Returns a list of selected items.
        :rtype: list
        """
        selection = []

        for i in range(self._item_model.rowCount()):
            value_item = self._item_model.item(i, 0)

            if value_item.checkState() == Qt.Checked:
                id_item = self._item_model.item(i, 1)
                id = int(id_item.text())

                #Get item from the lookup cache and append to selection
                if id in self._lookup_cache:
                    lookup_rec = self._lookup_cache[id]
                    selection.append(lookup_rec)

        return selection

    def set_selection(self, models):
        """
        Checks items corresponding to the specified models.
        :param models: List containing model values in the view for selection.
        :type models: list
        """
        for m in models:
            search_value = m.value
            v_items = self._item_model.findItems(search_value)

            #Loop through result and check items
            for vi in v_items:
                if vi.checkState() == Qt.Unchecked:
                    vi.setCheckState(Qt.Checked)
예제 #27
0
class DefaultsDlg(QDialog, Ui_Dialog):
    """
    Class documentation goes here.
    """
    def __init__(self, defaults, parent=None):
        """
        Constructor
        
        @param parent reference to the parent widget (QWidget)
        """
        super().__init__(parent)
        self.setupUi(self)
        self.setAttribute(Qt.WA_DeleteOnClose)

        self.defaults = defaults

        self.fillScalars()
        self.fillPlots()
        self.fillCalculations()

    def updateDefaults(self):
        self.defaults['defaultScalars'] = self.setDefaultScalars()
        self.defaults['defaultPlots'] = self.setDefaultPlots()
        self.defaults['defaultCalculations'] = self.setDefaultCalculations()

    def fillScalars(self):
        scalars = [
            'absorbance (%)', 'reflectance (%)', 'transmittance (%)',
            'absorbance (mA/cm²)', 'reflectance (mA/cm²)',
            'transmittance (mA/cm²)', 'generation', 'Jmax (mA/cm²)',
            'absorption layerwise (%)', 'absorption layerwise (mA/cm²)',
            'collection layerwise (%)', 'collection layerwise (mA/cm²)',
            'calc. time (s)'
        ]

        self.scalarListModel = QStandardItemModel()
        scalarsToShow = self.defaults['defaultScalars']
        for value in scalars:
            item = QStandardItem(value)
            check = Qt.Checked if value in scalarsToShow else Qt.Unchecked
            item.setCheckState(check)
            item.setCheckable(True)
            self.scalarListModel.appendRow(item)

        self.scalarListView.setModel(self.scalarListModel)

    def setDefaultScalars(self):
        setVisible = []
        for row in range(self.scalarListModel.rowCount()):
            item = self.scalarListModel.item(row)
            if item.checkState() == Qt.Checked:
                setVisible.append(item.text())

        return setVisible

    def fillPlots(self):
        plots = [
            'total A,R,T',  # requires calc [0]
            'Ellipsometry',  # requires nothing
            'absorption (layerwise)',  # requires calc [2]
            'collection (layerwise)',  # requires calc [2]
            'QE',  # requires calc [2]
            'reflection (interfacewise)',
            'generation'  # requires calc [3]
        ]

        self.plotListModel = QStandardItemModel()
        plotsToShow = self.defaults['defaultPlots']
        for value in plots:
            item = QStandardItem(value)
            check = Qt.Checked if value in plotsToShow else Qt.Unchecked
            item.setCheckState(check)
            item.setCheckable(True)
            self.plotListModel.appendRow(item)

        self.plotListView.setModel(self.plotListModel)

    def setDefaultPlots(self):
        setVisible = []
        for row in range(self.plotListModel.rowCount()):
            item = self.plotListModel.item(row)
            if item.checkState() == Qt.Checked:
                setVisible.append(item.text())

        return setVisible

    def fillCalculations(self):
        self.calculations = [
            'Stack optics (A,R,T)', 'Ellipsometry', 'Field intensity',
            'Layerwise optics (absorption, collection, QE)', 'Generation'
        ]

        self.calcListModel = QStandardItemModel()
        calculationsToShow = self.defaults['defaultCalculations']
        for value in self.calculations:
            item = QStandardItem(value)
            check = Qt.Checked if value in calculationsToShow else Qt.Unchecked
            item.setCheckState(check)
            item.setCheckable(True)
            #item.setEnabled(False)
            self.calcListModel.appendRow(item)

        self.calculationsListView.setModel(self.calcListModel)

    def setDefaultCalculations(self):
        for row in range(self.calcListModel.rowCount()):
            item = self.calcListModel.item(row)
            if item.checkState() == Qt.Checked:
                highestRow = row

        setCalcOn = self.calculations[:highestRow + 1]

        return setCalcOn
예제 #28
0
class OWConfusionMatrix(widget.OWWidget):
    name = "Confusion Matrix"
    description = "Display confusion matrix constructed from results " \
                  "of evaluation of classifiers."
    icon = "icons/ConfusionMatrix.svg"
    priority = 1001

    inputs = [("Evaluation Results", Orange.evaluation.Results, "set_results")]
    outputs = [("Selected Data", Orange.data.Table)]

    quantities = [
        "Number of instances", "Proportion of predicted",
        "Proportion of actual"
    ]

    selected_learner = settings.Setting([])
    selected_quantity = settings.Setting(0)
    append_predictions = settings.Setting(True)
    append_probabilities = settings.Setting(False)
    autocommit = settings.Setting(True)

    def __init__(self):
        super().__init__()

        self.data = None
        self.results = None
        self.learners = []
        self.headers = []

        box = gui.widgetBox(self.controlArea, "Learners")

        self.learners_box = gui.listBox(box,
                                        self,
                                        "selected_learner",
                                        "learners",
                                        callback=self._learner_changed)
        box = gui.widgetBox(self.controlArea, "Show")

        gui.comboBox(box,
                     self,
                     "selected_quantity",
                     items=self.quantities,
                     callback=self._update)

        box = gui.widgetBox(self.controlArea, "Select")

        gui.button(box,
                   self,
                   "Correct",
                   callback=self.select_correct,
                   autoDefault=False)
        gui.button(box,
                   self,
                   "Misclassified",
                   callback=self.select_wrong,
                   autoDefault=False)
        gui.button(box,
                   self,
                   "None",
                   callback=self.select_none,
                   autoDefault=False)

        self.outputbox = box = gui.widgetBox(self.controlArea, "Output")
        gui.checkBox(box,
                     self,
                     "append_predictions",
                     "Predictions",
                     callback=self._invalidate)
        gui.checkBox(box,
                     self,
                     "append_probabilities",
                     "Probabilities",
                     callback=self._invalidate)

        gui.auto_commit(self.controlArea, self, "autocommit", "Send Data",
                        "Auto send is on")

        grid = QGridLayout()

        self.tablemodel = QStandardItemModel(self)
        view = self.tableview = QTableView(
            editTriggers=QTableView.NoEditTriggers)
        view.setModel(self.tablemodel)
        view.horizontalHeader().hide()
        view.verticalHeader().hide()
        view.horizontalHeader().setMinimumSectionSize(60)
        view.selectionModel().selectionChanged.connect(self._invalidate)
        view.setShowGrid(False)
        view.clicked.connect(self.cell_clicked)
        grid.addWidget(view, 0, 0)
        self.mainArea.layout().addLayout(grid)

    def sizeHint(self):
        return QSize(750, 490)

    def _item(self, i, j):
        return self.tablemodel.item(i, j) or QStandardItem()

    def _set_item(self, i, j, item):
        self.tablemodel.setItem(i, j, item)

    def set_results(self, results):
        """Set the input results."""

        self.clear()
        self.warning([0, 1])

        data = None
        if results is not None:
            if results.data is not None:
                data = results.data

        if data is not None and not data.domain.has_discrete_class:
            data = None
            results = None
            self.warning(
                0, "Confusion Matrix cannot be used for regression results.")

        self.results = results
        self.data = data

        if data is not None:
            class_values = data.domain.class_var.values
        elif results is not None:
            raise NotImplementedError

        if results is not None:
            nmodels, ntests = results.predicted.shape
            self.headers = class_values + \
                           [unicodedata.lookup("N-ARY SUMMATION")]

            # NOTE: The 'learner_names' is set in 'Test Learners' widget.
            if hasattr(results, "learner_names"):
                self.learners = results.learner_names
            else:
                self.learners = [
                    "Learner #%i" % (i + 1) for i in range(nmodels)
                ]

            item = self._item(0, 2)
            item.setData("Predicted", Qt.DisplayRole)
            item.setTextAlignment(Qt.AlignCenter)
            item.setFlags(Qt.NoItemFlags)

            self._set_item(0, 2, item)
            item = self._item(2, 0)
            item.setData("Actual", Qt.DisplayRole)
            item.setTextAlignment(Qt.AlignHCenter | Qt.AlignBottom)
            item.setFlags(Qt.NoItemFlags)
            self.tableview.setItemDelegateForColumn(0,
                                                    gui.VerticalItemDelegate())
            self._set_item(2, 0, item)
            self.tableview.setSpan(0, 2, 1, len(class_values))
            self.tableview.setSpan(2, 0, len(class_values), 1)

            for i in (0, 1):
                for j in (0, 1):
                    item = self._item(i, j)
                    item.setFlags(Qt.NoItemFlags)
                    self._set_item(i, j, item)

            for p, label in enumerate(self.headers):
                for i, j in ((1, p + 2), (p + 2, 1)):
                    item = self._item(i, j)
                    item.setData(label, Qt.DisplayRole)
                    item.setData(QBrush(QColor(208, 208, 208)),
                                 Qt.BackgroundColorRole)
                    item.setTextAlignment(Qt.AlignRight | Qt.AlignVCenter)
                    item.setFlags(Qt.ItemIsEnabled)
                    self._set_item(i, j, item)

            hor_header = self.tableview.horizontalHeader()
            if len(' '.join(self.headers)) < 120:
                hor_header.setResizeMode(QHeaderView.ResizeToContents)
            else:
                hor_header.setDefaultSectionSize(60)
            self.tablemodel.setRowCount(len(class_values) + 3)
            self.tablemodel.setColumnCount(len(class_values) + 3)
            self.selected_learner = [0]
            self._update()

    def clear(self):
        self.results = None
        self.data = None
        self.tablemodel.clear()
        self.headers = []
        # Clear learners last. This action will invoke `_learner_changed`
        # method
        self.learners = []

    def select_correct(self):
        selection = QItemSelection()
        n = self.tablemodel.rowCount()
        for i in range(2, n):
            index = self.tablemodel.index(i, i)
            selection.select(index, index)

        self.tableview.selectionModel().select(
            selection, QItemSelectionModel.ClearAndSelect)

    def select_wrong(self):
        selection = QItemSelection()
        n = self.tablemodel.rowCount()

        for i in range(2, n):
            for j in range(i + 1, n):
                index = self.tablemodel.index(i, j)
                selection.select(index, index)
                index = self.tablemodel.index(j, i)
                selection.select(index, index)

        self.tableview.selectionModel().select(
            selection, QItemSelectionModel.ClearAndSelect)

    def select_none(self):
        self.tableview.selectionModel().clear()

    def cell_clicked(self, model_index):
        i, j = model_index.row(), model_index.column()
        if not i or not j:
            return
        n = self.tablemodel.rowCount()
        index = self.tablemodel.index
        selection = None
        if i == j == 1 or i == j == n - 1:
            selection = QItemSelection(index(2, 2), index(n - 1, n - 1))
        elif i in (1, n - 1):
            selection = QItemSelection(index(2, j), index(n - 1, j))
        elif j in (1, n - 1):
            selection = QItemSelection(index(i, 2), index(i, n - 1))

        if selection is not None:
            self.tableview.selectionModel().select(
                selection, QItemSelectionModel.ClearAndSelect)

    def commit(self):
        if self.results is not None and self.data is not None \
                and self.selected_learner:
            indices = self.tableview.selectedIndexes()
            indices = {(ind.row() - 2, ind.column() - 2) for ind in indices}
            actual = self.results.actual
            selected_learner = self.selected_learner[0]
            learner_name = self.learners[selected_learner]
            predicted = self.results.predicted[selected_learner]
            selected = [
                i for i, t in enumerate(zip(actual, predicted)) if t in indices
            ]
            row_indices = self.results.row_indices[selected]

            extra = []
            class_var = self.data.domain.class_var
            metas = self.data.domain.metas

            if self.append_predictions:
                predicted = numpy.array(predicted[selected], dtype=object)
                extra.append(predicted.reshape(-1, 1))
                var = Orange.data.DiscreteVariable(
                    "{}({})".format(class_var.name, learner_name),
                    class_var.values)
                metas = metas + (var, )

            if self.append_probabilities and \
                    self.results.probabilities is not None:
                probs = self.results.probabilities[selected_learner, selected]
                extra.append(numpy.array(probs, dtype=object))
                pvars = [
                    Orange.data.ContinuousVariable("p({})".format(value))
                    for value in class_var.values
                ]
                metas = metas + tuple(pvars)

            X = self.data.X[row_indices]
            Y = self.data.Y[row_indices]
            M = self.data.metas[row_indices]
            row_ids = self.data.ids[row_indices]

            M = numpy.hstack((M, ) + tuple(extra))
            domain = Orange.data.Domain(self.data.domain.attributes,
                                        self.data.domain.class_vars, metas)
            data = Orange.data.Table.from_numpy(domain, X, Y, M)
            data.ids = row_ids
            data.name = learner_name

        else:
            data = None

        self.send("Selected Data", data)

    def _invalidate(self):
        self.commit()

    def _learner_changed(self):
        # The selected learner has changed
        indices = self.tableview.selectedIndexes()
        self._update()
        selection = QItemSelection()
        for sel in indices:
            selection.select(sel, sel)
        self.tableview.selectionModel().select(
            selection, QItemSelectionModel.ClearAndSelect)
        self.commit()

    def _update(self):
        # Update the displayed confusion matrix
        if self.results is not None and self.selected_learner:
            index = self.selected_learner[0]
            cmatrix = confusion_matrix(self.results, index)
            colsum = cmatrix.sum(axis=0)
            rowsum = cmatrix.sum(axis=1)
            total = rowsum.sum()

            if self.selected_quantity == 0:
                value = lambda i, j: int(cmatrix[i, j])
            elif self.selected_quantity == 1:
                value = lambda i, j: \
                    ("{:2.1f} %".format(100 * cmatrix[i, j] / colsum[i])
                     if colsum[i] else "N/A")
            elif self.selected_quantity == 2:
                value = lambda i, j: \
                    ("{:2.1f} %".format(100 * cmatrix[i, j] / rowsum[i])
                     if colsum[i] else "N/A")
            else:
                assert False

            for i, row in enumerate(cmatrix):
                for j, _ in enumerate(row):
                    item = self._item(i + 2, j + 2)
                    item.setData(value(i, j), Qt.DisplayRole)
                    item.setToolTip("actual: {}\npredicted: {}".format(
                        self.headers[i], self.headers[j]))
                    item.setTextAlignment(Qt.AlignRight | Qt.AlignVCenter)
                    item.setFlags(Qt.ItemIsEnabled | Qt.ItemIsSelectable)
                    self._set_item(i + 2, j + 2, item)

            model = self.tablemodel
            font = model.invisibleRootItem().font()
            bold_font = QFont(font)
            bold_font.setBold(True)

            def sum_item(value):
                item = QStandardItem()
                item.setData(value, Qt.DisplayRole)
                item.setTextAlignment(Qt.AlignRight | Qt.AlignVCenter)
                item.setFlags(Qt.ItemIsEnabled)
                item.setFont(bold_font)
                return item

            N = len(colsum)
            for i in range(N):
                model.setItem(N + 2, i + 2, sum_item(int(colsum[i])))
                model.setItem(i + 2, N + 2, sum_item(int(rowsum[i])))

            model.setItem(N + 2, N + 2, sum_item(int(total)))
예제 #29
0
class DirDocumentTypeSelector(QDialog):
    """
    Dialog for selecting supporting documents from a given directory. Default
    filter searches for PDF files only.
    """
    def __init__(self, dir, doc_types, parent=None, filters=None):
        super(DirDocumentTypeSelector, self).__init__(parent)
        self.setWindowTitle(
            self.tr('Documents in Folder')
        )
        self._filters = filters
        # Use PDF as default filter
        if not self._filters:
            self._filters = ['*.pdf']

        self._init_ui()
        self._dir = QDir(dir)
        self._dir.setNameFilters(self._filters)
        self._doc_types = doc_types

        self._attr_model = QStandardItemModel(self)
        self._sel_doc_types = OrderedDict()

        # Notification bar
        self._notif_bar = NotificationBar(self.vl_notif)

        self.resize(320, 350)

        # Load documents
        self.load_document_types()

    @property
    def selected_document_types(self):
        """
        :return: Returns a dictionary of the document types and the
        corresponding file paths as selected by the user.
        :rtype: dict
        """
        return self._sel_doc_types

    def _init_ui(self):
        # Draw UI widgets
        layout = QVBoxLayout()

        # Add layout for notification bar
        self.vl_notif = QVBoxLayout()
        layout.addLayout(self.vl_notif)
        self.lbl_info = QLabel()
        self.lbl_info.setObjectName('lbl_info')
        self.lbl_info.setText(self.tr(
            'The selected document types have been found in the directory, '
            'check/uncheck to specify which ones to upload.'
        ))
        self.lbl_info.setWordWrap(True)
        layout.addWidget(self.lbl_info)
        self.lst_docs = QListView()
        layout.addWidget(self.lst_docs)
        self.lbl_warning = QLabel()
        self.lbl_warning.setTextFormat(Qt.RichText)
        self.lbl_warning.setText(self.tr(
            '<html><head/><body><p><span style=" font-style:italic;">'
            '* Previously uploaded documents will be replaced.</span></p>'
            '</body></html>'
        ))
        self.lbl_warning.setWordWrap(True)
        layout.addWidget(self.lbl_warning)
        self.btn_box = QDialogButtonBox(
            QDialogButtonBox.Ok | QDialogButtonBox.Cancel
        )
        layout.addWidget(self.btn_box)
        self.setLayout(layout)

        # Connect signals
        self.btn_box.accepted.connect(
            self.set_selected_document_types
        )
        self.btn_box.rejected.connect(
            self.reject
        )

    def set_selected_document_types(self):
        """
        Sets the collections of accepted document types and their
        corresponding file paths and accepts the dialog.
        """
        self._sel_doc_types = OrderedDict()
        for i in range(self._attr_model.rowCount()):
            doc_type_item = self._attr_model.item(i, 0)

            if doc_type_item.checkState() == Qt.Checked:
                path_item = self._attr_model.item(i, 1)
                self._sel_doc_types[doc_type_item.text()] = path_item.text()

        if len(self._sel_doc_types) == 0:
            self._notif_bar.clear()
            msg = self.tr('No matching documents found or selected.')
            self._notif_bar.insertWarningNotification(msg)

            return

        self.accept()

    def load_document_types(self):
        """
        Load all document types to the list view and enable/check the items
        for those types that have been found.
        """
        self._attr_model.clear()
        self._attr_model.setColumnCount(2)

        file_infos = self._dir.entryInfoList(
            QDir.Readable | QDir.Files,
            QDir.Name
        )

        # Index file info based on name
        idx_file_infos = {fi.completeBaseName().lower(): fi for fi in file_infos}

        for d in self._doc_types:
            doc_type_item = QStandardItem(d)
            doc_type_item.setCheckable(True)
            path_item = QStandardItem()

            item_enabled = False
            check_state = Qt.Unchecked
            dl = d.lower()
            if dl in idx_file_infos:
                item_enabled = True
                check_state = Qt.Checked
                path = idx_file_infos[dl].filePath()
                path_item.setText(path)
                doc_type_item.setToolTip(path)

            doc_type_item.setEnabled(item_enabled)
            doc_type_item.setCheckState(check_state)

            self._attr_model.appendRow([doc_type_item, path_item])

        self.lst_docs.setModel(self._attr_model)
예제 #30
0
파일: manager.py 프로젝트: s-chand/qmap
class QMapManager(QDialog):
    def __init__(self, config, parent=None):
        QDialog.__init__(self, parent)
        curdir = os.path.abspath(os.path.dirname(__file__))
        PyQt4.uic.loadUi(os.path.join(curdir, 'manager.ui'), self)
        self.model = QStandardItemModel()
        self.projectsmodel = QStandardItemModel()
        self.projectlist.setModel(self.projectsmodel)
        self.clientlist.setModel(self.model)
        self.clientlist.selectionModel().selectionChanged.connect(self.update)
        self.installbutton.pressed.connect(self.installToClient)
        self.mapper = QDataWidgetMapper()
        self.mapper.setModel(self.model)
        self.mapper.addMapping(self.installpath, 1)
        self.config = config
        self.populateProjects()
        self.populateClients()

    def installToClient(self):
        index = self.clientlist.selectionModel().currentIndex()
        item = self.model.itemFromIndex(index)
        print "Deploying to " + item.text()
        build.deployTargetByName(item.text())

    def update(self, selected, deselected):
        index = selected.indexes()[0]
        self.mapper.setCurrentModelIndex(index)
        item = self.model.itemFromIndex(index)
        settings = item.data()

        for row in xrange(0, self.projectsmodel.rowCount()):
            index = self.projectsmodel.index(row, 0)
            item = self.projectsmodel.itemFromIndex(index)
            item.setCheckState(Qt.Unchecked)

        projects = settings['projects']

        for project in projects:
            if project == "All":
                i = 0
                while self.projectsmodel.item(i):
                    item = self.projectsmodel.item(i)
                    item.setCheckState(Qt.Checked)
                    i += 1
                break

            projectitem = self.projectsmodel.findItems(project)[0]
            projectitem.setCheckState(Qt.Checked)

    def populateClients(self):
        row = 0
        for client, settings in self.config['clients'].iteritems():
            name = QStandardItem(client)
            name.setData(settings)
            path = QStandardItem(settings['path'])
            self.model.insertRow(row, [name, path])
            row += 1

    def populateProjects(self):
        row = 0
        for project in getProjects():
            projectitem = QStandardItem(project.name)
            projectitem.setCheckable(True)
            self.projectsmodel.insertRow(row, projectitem)
            row += 1
class PluginRepositoriesGUI(QWidget):
    PATH_COLUMN = 1
    ACTIVE_COLUMN = 0
    AUTO_UPDATE_COLUMN = 2
    STATUS_COLUMN = 3
    
    addRepository = pyqtSignal()
    checkForUpdates = pyqtSignal()
    
    def __init__(self, logger, parent):
        super(PluginRepositoriesGUI, self).__init__(parent)
       
        self.logger = logger
        self._gitHandler = GitHandler(logger)
        
        layout = QVBoxLayout(self)
        
        self._reposTable = QTreeView(self) 
        self._reposTable.setIndentation(0)
        self._reposTable.header().setStretchLastSection(False)
                
        self._reposModel = QStandardItemModel(self._reposTable)
        self._initModel()
        self._reposTable.setModel(self._reposModel)
        
        self._reposTable.setSelectionMode(QTreeView.ExtendedSelection)
        self._reposTable.selectionModel().selectionChanged.connect(self._selectionChanged)
        
        layout.addWidget(self._reposTable)

        buttonLayout = QHBoxLayout()    
        addButton = QPushButton("Add...")
        addButton.clicked.connect(self.addRepository)
        self._removeButton = QPushButton("Remove")
        self._removeButton.setEnabled(False)
        self._removeButton.clicked.connect(self._removeSelected)
        refreshButton = QPushButton("Check Status")
        refreshButton.clicked.connect(self.checkForUpdates)
        buttonLayout.addWidget(addButton)
        buttonLayout.addWidget(self._removeButton)
        buttonLayout.addWidget(refreshButton)
        
        layout.addLayout(buttonLayout)
        
        self._statusWidget = QWidget(self) 
        self._statusWidget.setVisible(False)
        statusLayout = QHBoxLayout(self._statusWidget)
        statusLayout.setContentsMargins(0, 0, 0, 0)
        self._statusLabel = QLabel(self)
        statusLayout.addWidget(self._statusLabel)
        layout.addWidget(self._statusWidget)
        
    def clear(self):
        self._initModel()
        
    def _updateStatusItem(self, item, path, outdated=None, upToDate=None):
        # first check fresh results, then the ones from repositories
        if upToDate and path in upToDate:
            item.setText(upToDate[path])
            if upToDate[path] == GitHandler.UP_TO_DATE_REASON:
                item.setData(QColor(0, 255, 0), Qt.DecorationRole)
            else:
                item.setData(QColor(255, 0, 0), Qt.DecorationRole)
        elif outdated and path in outdated:
            item.setText("Repository can be updated")
            item.setData(QColor(255, 215, 0), Qt.DecorationRole)
        elif get_settings().get_plugin_repositories().isUpToDate(path):
            item.setText("No updates (for details, check status)")
            item.setData(QColor(0, 255, 0), Qt.DecorationRole)
        elif get_settings().get_plugin_repositories().isOutdated(path):
            item.setText("Repository can be updated")
            item.setData(QColor(255, 215, 0), Qt.DecorationRole)
        else:
            item.setData(None, Qt.DecorationRole)
        
    def updateStatusItems(self, outdated=None, upToDate=None):
        for row in xrange(self._reposModel.rowCount()):
            path = convert_string(self._reposModel.item(row, self.PATH_COLUMN).data(Qt.DisplayRole).toString())
            self._updateStatusItem(self._reposModel.item(row, self.STATUS_COLUMN), path, outdated, upToDate)
        
    def _initModel(self):
        from PyQt4.QtCore import QStringList
        self._reposModel.clear()
        stringList = QStringList([u"Active", u"Path", u"Auto Update", u"Status"])
        self._reposModel.setColumnCount(stringList.count())
        self._reposModel.setHorizontalHeaderLabels(stringList)
        
    def appendRepository(self, path, active, autoUpdate, canAutoUpdate = None):
        activeItem = QStandardItem()
        activeItem.setEditable(False)
        activeItem.setCheckState(Qt.Checked if active else Qt.Unchecked)
        activeItem.setCheckable(True)
        
        pathItem = QStandardItem()
        pathItem.setData(path, Qt.DisplayRole)
        pathItem.setEditable(False)
        
        autoUpdateItem = QStandardItem()
        autoUpdateItem.setEditable(False)
        if canAutoUpdate == None:
            canAutoUpdate = self._gitHandler.hasGit(path)
        if canAutoUpdate:
            autoUpdateItem.setCheckState(Qt.Checked if autoUpdate else Qt.Unchecked)
            autoUpdateItem.setCheckable(True)
                
        statusItem = QStandardItem()
        self._updateStatusItem(statusItem, path)
                
        self._reposModel.appendRow([activeItem, pathItem, autoUpdateItem, statusItem])
        
    def resizeColumns(self):
        self._reposTable.resizeColumnToContents(self.ACTIVE_COLUMN)
        self._reposTable.resizeColumnToContents(self.AUTO_UPDATE_COLUMN)
        self._reposTable.header().setResizeMode(self.PATH_COLUMN, QHeaderView.Stretch)
        self._reposTable.header().setResizeMode(self.STATUS_COLUMN, QHeaderView.ResizeToContents)
    
    def getTable(self):
        return self._reposTable
    
    @loggingSlot(QItemSelection, QItemSelection)
    def _selectionChanged(self, _sel, _desel):
        selection = self._reposTable.selectionModel().selectedRows()
        self._removeButton.setEnabled(len(selection) > 0)
        
    @loggingSlot()
    def _removeSelected(self):
        selection = self._reposTable.selectionModel().selectedRows()
        for index in selection:
            self._reposTable.model().removeRow(index.row())
        
    def setStatus(self, msg, _progress=False):
        if msg:
            self._statusLabel.setText(msg)
            self._statusWidget.setVisible(True)
        else:
            self._statusWidget.setVisible(False)
예제 #32
0
class DetailsTreeView(DetailsDBHandler, DetailsDockWidget):
    def __init__(self, iface, spatial_unit_dock):

        """
        The method initializes the dockwidget.
        :param iface: QGIS user interface class
        :type class qgis.utils.iface
        :param plugin: The STDM plugin
        :type class
        :return: None
        """
        from stdm.ui.entity_browser import _EntityDocumentViewerHandler
        DetailsDockWidget.__init__(self, iface, spatial_unit_dock)

        DetailsDBHandler.__init__(self)

        self.spatial_unit_dock = spatial_unit_dock

        self.view = QTreeView()
        self.view.setSelectionBehavior(
            QAbstractItemView.SelectRows
        )
        #self.feature_ids = []
        self.layer_table = None
        self.entity = None
        self.feature_models = {}
        self.party_models = {}
        self.STR_models = {}
        self.feature_STR_model = {}
        self.removed_feature = None
        self.selected_root = None
        self.model = QStandardItemModel()
        self.view.setModel(self.model)
        self.view.setUniformRowHeights(True)
        self.view.setRootIsDecorated(True)
        self.view.setAlternatingRowColors(True)
        self.view.setWordWrap(True)
        self.view.setHeaderHidden(True)
        self.view.setEditTriggers(
            QAbstractItemView.NoEditTriggers
        )
        self.current_profile = current_profile()
        self.social_tenure = self.current_profile.social_tenure
        self.spatial_unit = self.social_tenure.spatial_unit
        self.party = self.social_tenure.party
        self.view.setMinimumWidth(250)
        self.doc_viewer_title = QApplication.translate(
            'EntityBrowser',
            'Document Viewer'
        )
        self.doc_viewer = _EntityDocumentViewerHandler(
            self.doc_viewer_title, self.iface.mainWindow()
        )

    def set_layer_entity(self):
        self.layer_table = self.get_layer_source(
            self.iface.activeLayer()
        )
        if self.layer_table in spatial_tables():
            self.entity = self.current_profile.entity_by_name(
                self.layer_table
            )

        else:
            self.treeview_error('The layer is not a spatial entity layer. ')

    def activate_feature_details(self, button_clicked=True):
        """
        Action for showing feature details.
        :return:
        """
        # Get the active layer.
        active_layer = self.iface.activeLayer()
        # TODO fix feature_details_btn is deleted error.
        if active_layer is not None and \
                self.spatial_unit_dock.feature_details_btn.isChecked():
            # if feature detail dock is not defined or hidden, create empty dock.
            if self is None or self.isHidden():
                # if the selected layer is not a feature layer, show not
                # feature layer. (implicitly included in the if statement).
                if not self.feature_layer(active_layer):
                    self.spatial_unit_dock.feature_details_btn.setChecked(False)
                    return
                # If the selected layer is feature layer, get data and
                # display treeview in a dock widget
                else:
                    select_feature = QApplication.translate(
                        "STDMQGISLoader",
                        "Please select a feature to view their details."
                    )
                    self.init_dock()
                    self.add_tree_view()
                    self.model.clear()
                    self.treeview_error(select_feature)

                    # enable the select tool
                    self.activate_select_tool()
                    # set entity from active layer in the child class
                    self.set_layer_entity()
                    # set entity for the super class DetailModel
                    self.set_entity(self.entity)
                    # Registery column widget
                    self.set_formatter()
                    #set formatter for social tenure relationship.
                    self.set_formatter(self.social_tenure)
                    self.set_formatter(self.party)
                    # pull data, show treeview
                    active_layer.selectionChanged.connect(
                        self.show_tree
                    )
                    self.steam_signals(self.entity)

            # if feature_detail dock is open, toggle close
            else:
                self.close_dock(
                    self.spatial_unit_dock.feature_details_btn
                )
                self.feature_details = None
        # if no active layer, show error message and uncheck the feature tool
        else:
            if button_clicked:
                self.active_layer_check()
            self.spatial_unit_dock.feature_details_btn.setChecked(False)

    def add_tree_view(self):
        """
        Adds tree view to the dock widget and sets style.
        :return: None
        """
        self.tree_scrollArea.setWidget(self.view)

    def clear_feature_models(self):
        self.feature_models.clear()

    def reset_tree_view(self, no_feature=False):
        #clear feature_ids list, model and highlight
        self.model.clear()

        self.clear_sel_highlight() # remove sel_highlight
        self.disable_buttons(no_feature)
        if self.removed_feature is None:
            self.STR_models.clear()
            self.feature_models.clear()
        else:
            self.removed_feature = None
        features = self.selected_features()
        # if the selected feature is over 1,
        # activate multi_select_highlight
        if not features is None:
            self.view.clicked.connect(
                self.multi_select_highlight
            )
        # if there is at least one selected feature
        if len(features) > 0:
            self.add_tree_view()
            #self.feature_ids = features

    def disable_buttons(self, bool):
        self.edit_btn.setDisabled(bool)
        self.delete_btn.setDisabled(bool)

    def show_tree(self):
        selected_features = self.selected_features()
        if len(selected_features) < 1:
            self.reset_tree_view(True)
            return
        if not self.entity is None:
            self.reset_tree_view()
            if len(selected_features) < 1:
                self.disable_buttons(True)
                return

            layer_icon = QIcon(':/plugins/stdm/images/icons/layer.gif')
            roots = self.add_parent_tree(
                layer_icon, format_name(self.entity.short_name)
            )
            if roots is None:
                return

            for id, root in roots.iteritems():
                db_model = entity_id_to_model(self.entity, id)

                self.add_roots(db_model, root, id)

    def add_parent_tree(self, icon, title):
        roots = OrderedDict()
        for feature_id in self.selected_features():
            root = QStandardItem(icon, title)
            root.setData(feature_id)
            self.set_bold(root)
            self.model.appendRow(root)
            roots[feature_id] = root
        return roots

    def add_roots(self, model, parent, feature_id):
        self.feature_models[feature_id] = model
        if model is None:
            return
        self.column_widget_registry(model, self.entity)

        for i, (col, row) in enumerate(self.formatted_record.iteritems()):
            child = QStandardItem('{}: {}'.format(col, row))
            child.setSelectable(False)
            parent.appendRow([child])

            # Add Social Tenure Relationship steam as a last child
            if i == len(self.formatted_record)-1:
                self.add_STR_child(parent, feature_id)
        self.expand_node(parent)

    def add_STR_steam(self, parent, STR_id):
        str_icon = QIcon(
            ':/plugins/stdm/images/icons/social_tenure.png'
        )
        title = 'Social Tenure Relationship'
        str_root = QStandardItem(str_icon, title)
        str_root.setData(STR_id)
        self.set_bold(str_root)
        parent.appendRow([str_root])
        return str_root
    def add_no_STR_steam(self, parent):
        if self.entity.name == self.spatial_unit.name:
            no_str_icon = QIcon(
                ':/plugins/stdm/images/icons/remove.png'
            )
            title = 'No STR Defined'
            no_str_root = QStandardItem(no_str_icon, title)
            self.set_bold(no_str_root)
            parent.appendRow([no_str_root])

    def add_STR_child(self, parent, feature_id):
        if len(self.feature_STR_link(feature_id)) < 1:
            self.add_no_STR_steam(parent)
            return
        for record in self.feature_STR_link(feature_id):
            self.STR_models[record.id] = record
            str_root = self.add_STR_steam(parent, record.id)
            # add STR children
            self.column_widget_registry(record, self.social_tenure)
            for i, (col, row) in enumerate(
                    self.formatted_record.iteritems()
            ):
                STR_child = QStandardItem(
                    '{}: {}'.format(col, row)
                )
                STR_child.setSelectable(False)
                str_root.appendRow([STR_child])
                if i == len(self.formatted_record)-1:
                    self.add_party_child(
                        str_root, record.party_id
                    )
        self.feature_STR_model[feature_id] = self.STR_models.keys()

    def add_party_steam(self, parent, party_id):
        party_icon = QIcon(
            ':/plugins/stdm/images/icons/table.png'
        )
        title = format_name(self.party.short_name)
        party_root = QStandardItem(party_icon, title)
        party_root.setData(party_id)
        self.set_bold(party_root)

        parent.appendRow([party_root])
        party_root.setEditable(False)
        return party_root

    def add_party_child(self, parent, party_id):

        db_model = entity_id_to_model(self.party, party_id)
        self.party_models[party_id] = db_model
        party_root = self.add_party_steam(parent, party_id)
        # add STR children
        self.column_widget_registry(db_model, self.party)
        for col, row in self.formatted_record.iteritems():
            party_child = QStandardItem('{}: {}'.format(col, row))
            party_child.setSelectable(False)
            party_root.appendRow([party_child])

    def set_bold(self, standard_item):
        """
        Make a text of Qstandaritem to bold.
        :param standard_item: Qstandaritem
        :type: Qstandaritem
        :return: None
        """
        font = standard_item.font()
        font.setBold(True)
        standard_item.setFont(font)

    def treeview_error(self, message, icon=None):
        """
        Displays error message in feature details treeview.
        :param title: the title of the treeview.
        :type: String
        :param message: The message to be displayed.
        :type: String
        :param icon: The icon of the item.
        :type: Resource string
        :return: None
        """
        not_feature_ft_msg = QApplication.translate(
            'FeatureDetails', message
        )
        if icon== None:
            root = QStandardItem(not_feature_ft_msg)
        else:
            root = QStandardItem(icon, not_feature_ft_msg)

        self.view.setRootIsDecorated(False)
        self.model.appendRow(root)
        self.view.setRootIsDecorated(True)

    def expand_node(self, parent):
        """
        Make the last tree node expand.
        :param parent: The parent to expand
        :type QStandardItem
        :return:None
        """
        index = self.model.indexFromItem(parent)
        self.view.expand(index)


    def multi_select_highlight(self, index):
        """
        Highlights a feature with rubberBald class when selecting
        features are more than one.
        :param index: Selected QTreeView item index
        :type Integer
        :return: None
        """
        map = self.iface.mapCanvas()
        try:

            # Get the selected item text using the index
            selected_item = self.model.itemFromIndex(index)
            # Use mutli-select only when more than 1 items are selected.
            if self.layer.selectedFeatures() < 2:
                return
            self.selected_root = selected_item
            # Split the text to get the key and value.
            selected_item_text = selected_item.text()

            selected_value = selected_item.data()
            # If the first word is feature, expand & highlight.
            if selected_item_text == format_name(self.spatial_unit.short_name):
                self.view.expand(index)  # expand the item
                # Clear any existing highlight
                self.clear_sel_highlight()
                # Insert highlight
                # Create expression to target the selected feature
                expression = QgsExpression(
                    "\"id\"='" + str(selected_value) + "'"
                )
                # Get feature iteration based on the expression
                ft_iteration = self.layer.getFeatures(
                    QgsFeatureRequest(expression)
                )

                # Retrieve geometry and attributes
                for feature in ft_iteration:
                    # Fetch geometry
                    geom = feature.geometry()
                    self.sel_highlight = QgsHighlight(map, geom, self.layer)

                    self.sel_highlight.setFillColor(selection_color())
                    self.sel_highlight.setWidth(4)
                    self.sel_highlight.setColor(QColor(212,95,0, 255))
                    self.sel_highlight.show()
                    break
        except AttributeError:
            # pass attribute error on child items such as party
            pass
        except IndexError:
            pass

    def steam_signals(self, entity):
        self.edit_btn.clicked.connect(
            lambda : self.edit_selected_steam(
                entity
            )
        )
        self.delete_btn.clicked.connect(
            self.delete_selected_item
        )
        self.view_document_btn.clicked.connect(
            lambda : self.view_steam_document(
                entity
            )
        )

    def steam_data(self, mode):
        item = None
        # if self.view.currentIndex().text() == format_name(self.party):
        #     return None, None
        # One item is selected and number of feature is also 1
        if len(self.layer.selectedFeatures()) == 1 and \
                        len(self.view.selectedIndexes()) == 1:
            index = self.view.selectedIndexes()[0]
            item = self.model.itemFromIndex(index)
            result = item.data()

        # One item is selected on the map but not on the treeview
        elif len(self.layer.selectedFeatures()) == 1 and \
                        len(self.view.selectedIndexes()) == 0:
            item = self.model.item(0, 0)
            result = item.data()

        # multiple features are selected but one treeview item is selected
        elif len(self.layer.selectedFeatures()) > 1 and \
                        len(self.view.selectedIndexes()) == 1:
            item = self.selected_root
            result = self.selected_root.data()
        # multiple features are selected but no treeview item is selected
        elif len(self.layer.selectedFeatures()) > 1 and \
             len(self.view.selectedIndexes()) == 0:
            result = 'Please, select an item to {}.'.format(mode)
        else:
            result = 'Please, select at least one feature to {}.'.format(mode)
        if result is None:

            if item is None:
                item = self.model.item(0, 0)
                result = item.data()
            else:
                result = item.parent().data()
        return result, item

    def edit_selected_steam(self, entity):
        id, item = self.steam_data('edit')

        feature_edit = True
        if id is None:
            return
        if isinstance(id, str):
            data_error = QApplication.translate('DetailsTreeView', id)
            QMessageBox.warning(
                self.iface.mainWindow(), "Edit Error", data_error
            )
            return

        if item.text() == 'Social Tenure Relationship':
            model = self.STR_models[id]

            feature_edit = False
            ##TODO add STR wizard edit mode here.
        elif item.text() == format_name(self.party.short_name):
            feature_edit = False

            model = self.party_models[id]
            editor = EntityEditorDialog(
                self.party, model, self.iface.mainWindow()
            )
            editor.exec_()
        else:
            model = self.feature_models[id]

            editor = EntityEditorDialog(
                entity, model, self.iface.mainWindow()
            )
            editor.exec_()
        #root = self.find_root(entity, id)
        self.view.expand(item.index())
        if feature_edit:
            self.update_edited_steam(entity, id)
        else:
            self.update_edited_steam(self.social_tenure, id)

    def delete_selected_item(self):
        str_edit = False
        id, item = self.steam_data('delete')

        if isinstance(id, str):
            data_error = QApplication.translate(
                'DetailsTreeView', id
            )
            QMessageBox.warning(
                self.iface.mainWindow(),
                'Delete Error',
                data_error
            )
            return
        if item.text() == 'Social Tenure Relationship':
            str_edit = True
            db_model = self.STR_models[id]

        elif item.text() == format_name(self.spatial_unit.short_name) and \
            id not in self.feature_STR_model.keys():
            db_model = self.feature_models[id]

        # if spatial unit is linked to STR, don't allow delete
        elif item.text() == format_name(self.spatial_unit.short_name) and \
                        id in self.feature_STR_model.keys():


            delete_warning = QApplication.translate(
                'DetailsTreeView',
                'You have to first delete the social tenure \n'
                'relationship to delete the {} record.'.format(
                    item.text()
                )

            )
            QMessageBox.warning(
                self.iface.mainWindow(),
                'Delete Error',
                delete_warning
            )
            return
        # If it is party node, STR exists and don't allow delete.
        elif item.text() == format_name(self.party.short_name):
            delete_warning = QApplication.translate(
                'DetailsTreeView',
                'You have to first delete the social tenure \n'
                'relationship to delete the {} record.'.format(
                    item.text()
                )
            )
            QMessageBox.warning(
                self.iface.mainWindow(),
                'Delete Error',
                delete_warning
            )
            return
        else:
            return
        delete_warning = QApplication.translate(
            'DetailsTreeView',
            'Are you sure you want to delete '
            'the selected record(s)?\n'
            'This action cannot be undone.'
        )

        delete_question = QMessageBox.warning(
            self.iface.mainWindow(),
            "Delete Warning",
            delete_warning,
            QMessageBox.Yes | QMessageBox.No
        )
        if delete_question == QMessageBox.Yes:
            db_model.delete()

            if str_edit:
                del self.STR_models[id]
            else:
                self.removed_feature = id
                del self.feature_models[id]

            self.updated_removed_steam(str_edit, item)
        else:
            return

    def update_edited_steam(self, entity, feature_id):

        # remove rows before adding the updated ones.
        self.layer.setSelectedFeatures(
            self.feature_models.keys()
        )
        root = self.find_root(entity, feature_id)
        if root is None:
            return
        self.view.selectionModel().select(
            root.index(), self.view.selectionModel().Select
        )
        self.expand_node(root)
        self.multi_select_highlight(root.index())

    def find_root(self, entity, feature_id):
        all_roots = self.model.findItems(
            format_name(entity.short_name)
        )
        root = None
        for item in all_roots:
            if item.data() == feature_id:
                root = item
                break
        return root

    def updated_removed_steam(self, STR_edit, item):
        if not STR_edit:
            if len(self.feature_models) > 1:
                self.refresh_layers()
            feature_ids = self.feature_models.keys()
            self.layer.setSelectedFeatures(
                feature_ids
            )
        else:
            item.removeRows(0, 2)
            item.setText('No STR Definded')
            no_str_icon = QIcon(
                ':/plugins/stdm/images/icons/remove.png'
            )
            item.setIcon(no_str_icon)

    def view_steam_document(self, entity):
        # Slot raised to show the document viewer for the selected entity

        id, item = self.steam_data('edit')

        if id is None:
            return
        if isinstance(id, str):
            data_error = QApplication.translate('DetailsTreeView', id)
            QMessageBox.warning(
                self.iface.mainWindow(), "Edit Error", data_error
            )
            return
        if item.text() == 'Social Tenure Relationship':
            db_model = self.STR_models[id]
        else:
            db_model = self.feature_models[id]

        if not db_model is None:
            docs = db_model.documents
            # Notify there are no documents for the selected doc
            if len(docs) == 0:
                msg = QApplication.translate(
                    'EntityBrowser',
                    'There are no supporting documents '
                    'for the selected record.'
                )

                QMessageBox.warning(
                    self,
                    self.doc_viewer_title,
                    msg
                )
            else:
                self.doc_viewer.load(docs)
예제 #33
0
class DlgSqlLayerWindow(QWidget, Ui_Dialog):
    nameChanged = pyqtSignal(str)

    def __init__(self, iface, layer, parent=None):
        QWidget.__init__(self, parent)
        self.iface = iface
        self.layer = layer

        uri = QgsDataSourceUri(layer.source())
        dbplugin = None
        db = None
        if layer.dataProvider().name() == 'postgres':
            dbplugin = createDbPlugin('postgis', 'postgres')
        elif layer.dataProvider().name() == 'spatialite':
            dbplugin = createDbPlugin('spatialite', 'spatialite')
        elif layer.dataProvider().name() == 'oracle':
            dbplugin = createDbPlugin('oracle', 'oracle')
        elif layer.dataProvider().name() == 'virtual':
            dbplugin = createDbPlugin('vlayers', 'virtual')
        if dbplugin:
            dbplugin.connectToUri(uri)
            db = dbplugin.db

        self.dbplugin = dbplugin
        self.db = db
        self.filter = ""
        self.allowMultiColumnPk = isinstance(db, PGDatabase) # at the moment only PostgreSQL allows a primary key to span multiple columns, spatialite doesn't
        self.aliasSubQuery = isinstance(db, PGDatabase) # only PostgreSQL requires subqueries to be aliases
        self.setupUi(self)
        self.setWindowTitle(
            u"%s - %s [%s]" % (self.windowTitle(), db.connection().connectionName(), db.connection().typeNameString()))

        self.defaultLayerName = 'QueryLayer'

        if self.allowMultiColumnPk:
            self.uniqueColumnCheck.setText(self.trUtf8("Column(s) with unique values"))
        else:
            self.uniqueColumnCheck.setText(self.trUtf8("Column with unique values"))

        self.editSql.setFocus()
        self.editSql.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded)
        self.editSql.setMarginVisible(True)
        self.initCompleter()

        # allow copying results
        copyAction = QAction("copy", self)
        self.viewResult.addAction(copyAction)
        copyAction.setShortcuts(QKeySequence.Copy)

        copyAction.triggered.connect(self.copySelectedResults)

        self.btnExecute.clicked.connect(self.executeSql)
        self.btnSetFilter.clicked.connect(self.setFilter)
        self.btnClear.clicked.connect(self.clearSql)

        self.presetStore.clicked.connect(self.storePreset)
        self.presetDelete.clicked.connect(self.deletePreset)
        self.presetCombo.activated[str].connect(self.loadPreset)
        self.presetCombo.activated[str].connect(self.presetName.setText)

        self.updatePresetsCombobox()

        self.geomCombo.setEditable(True)
        self.geomCombo.lineEdit().setReadOnly(True)

        self.uniqueCombo.setEditable(True)
        self.uniqueCombo.lineEdit().setReadOnly(True)
        self.uniqueModel = QStandardItemModel(self.uniqueCombo)
        self.uniqueCombo.setModel(self.uniqueModel)
        if self.allowMultiColumnPk:
            self.uniqueCombo.setItemDelegate(QStyledItemDelegate())
            self.uniqueModel.itemChanged.connect(self.uniqueChanged)                # react to the (un)checking of an item
            self.uniqueCombo.lineEdit().textChanged.connect(self.uniqueTextChanged) # there are other events that change the displayed text and some of them can not be caught directly

        self.layerTypeWidget.hide()  # show if load as raster is supported
        #self.loadLayerBtn.clicked.connect(self.loadSqlLayer)
        self.updateLayerBtn.clicked.connect(self.updateSqlLayer)
        self.getColumnsBtn.clicked.connect(self.fillColumnCombos)

        self.queryBuilderFirst = True
        self.queryBuilderBtn.setIcon(QIcon(":/db_manager/icons/sql.gif"))
        self.queryBuilderBtn.clicked.connect(self.displayQueryBuilder)

        self.presetName.textChanged.connect(self.nameChanged)

        # Update from layer
        # Fisrtly the SQL from QgsDataSourceUri table
        sql = uri.table()
        if uri.keyColumn() == '_uid_':
            match = re.search('^\(SELECT .+ AS _uid_,\* FROM \((.*)\) AS _subq_.+_\s*\)$', sql, re.S)
            if match:
                sql = match.group(1)
        else:
            match = re.search('^\((SELECT .+ FROM .+)\)$', sql, re.S)
            if match:
                sql = match.group(1)
        self.editSql.setText(sql)
        self.executeSql()

        # Then the columns
        self.geomCombo.setCurrentIndex(self.geomCombo.findText(uri.geometryColumn(), Qt.MatchExactly))
        if uri.keyColumn() != '_uid_':
            self.uniqueColumnCheck.setCheckState(Qt.Checked)
            if self.allowMultiColumnPk:
                itemsData = uri.keyColumn().split(',')
                for item in self.uniqueModel.findItems("*", Qt.MatchWildcard):
                    if item.data() in itemsData:
                        item.setCheckState(Qt.Checked)
            else:
                keyColumn = uri.keyColumn()
                for item in self.uniqueModel.findItems("*", Qt.MatchWildcard):
                    if item.data() == keyColumn:
                        self.uniqueCombo.setCurrentIndex(self.uniqueModel.indexFromItem(item).row())

        # Finally layer name, filter and selectAtId
        self.layerNameEdit.setText(layer.name())
        self.filter = uri.sql()
        if uri.selectAtIdDisabled():
            self.avoidSelectById.setCheckState(Qt.Checked)

    def updatePresetsCombobox(self):
        self.presetCombo.clear()

        names = []
        entries = QgsProject.instance().subkeyList('DBManager', 'savedQueries')
        for entry in entries:
            name = QgsProject.instance().readEntry('DBManager', 'savedQueries/' + entry + '/name')[0]
            names.append(name)

        for name in sorted(names):
            self.presetCombo.addItem(name)
        self.presetCombo.setCurrentIndex(-1)

    def storePreset(self):
        query = self._getSqlQuery()
        if query == "":
            return
        name = self.presetName.text()
        QgsProject.instance().writeEntry('DBManager', 'savedQueries/q' + unicode(name.__hash__()) + '/name', name)
        QgsProject.instance().writeEntry('DBManager', 'savedQueries/q' + unicode(name.__hash__()) + '/query', query)
        index = self.presetCombo.findText(name)
        if index == -1:
            self.presetCombo.addItem(name)
            self.presetCombo.setCurrentIndex(self.presetCombo.count() - 1)
        else:
            self.presetCombo.setCurrentIndex(index)

    def deletePreset(self):
        name = self.presetCombo.currentText()
        QgsProject.instance().removeEntry('DBManager', 'savedQueries/q' + unicode(name.__hash__()))
        self.presetCombo.removeItem(self.presetCombo.findText(name))
        self.presetCombo.setCurrentIndex(-1)

    def loadPreset(self, name):
        query = QgsProject.instance().readEntry('DBManager', 'savedQueries/q' + unicode(name.__hash__()) + '/query')[0]
        name = QgsProject.instance().readEntry('DBManager', 'savedQueries/q' + unicode(name.__hash__()) + '/name')[0]
        self.editSql.setText(query)

    def clearSql(self):
        self.editSql.clear()
        self.editSql.setFocus()
        self.filter = ""

    def executeSql(self):

        sql = self._getSqlQuery()
        if sql == "":
            return

        QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))

        # delete the old model
        old_model = self.viewResult.model()
        self.viewResult.setModel(None)
        if old_model:
            old_model.deleteLater()

        cols = []
        quotedCols = []

        try:
            # set the new model
            model = self.db.sqlResultModel(sql, self)
            self.viewResult.setModel(model)
            self.lblResult.setText(self.tr("%d rows, %.1f seconds") % (model.affectedRows(), model.secs()))
            cols = self.viewResult.model().columnNames()
            for col in cols:
                quotedCols.append(self.db.connector.quoteId(col))

        except BaseError as e:
            QApplication.restoreOverrideCursor()
            DlgDbError.showError(e, self)
            self.uniqueModel.clear()
            self.geomCombo.clear()
            return

        self.setColumnCombos(cols, quotedCols)

        self.update()
        QApplication.restoreOverrideCursor()

    def _getSqlLayer(self, _filter):
        hasUniqueField = self.uniqueColumnCheck.checkState() == Qt.Checked
        if hasUniqueField:
            if self.allowMultiColumnPk:
                checkedCols = []
                for item in self.uniqueModel.findItems("*", Qt.MatchWildcard):
                    if item.checkState() == Qt.Checked:
                        checkedCols.append(item.data())
                uniqueFieldName = ",".join(checkedCols)
            elif self.uniqueCombo.currentIndex() >= 0:
                uniqueFieldName = self.uniqueModel.item(self.uniqueCombo.currentIndex()).data()
            else:
                uniqueFieldName = None
        else:
            uniqueFieldName = None
        hasGeomCol = self.hasGeometryCol.checkState() == Qt.Checked
        if hasGeomCol:
            geomFieldName = self.geomCombo.currentText()
        else:
            geomFieldName = None

        query = self._getSqlQuery()
        if query == "":
            return None

        # remove a trailing ';' from query if present
        if query.strip().endswith(';'):
            query = query.strip()[:-1]

        from qgis.core import QgsMapLayer, QgsMapLayerRegistry

        layerType = QgsMapLayer.VectorLayer if self.vectorRadio.isChecked() else QgsMapLayer.RasterLayer

        # get a new layer name
        names = []
        for layer in QgsMapLayerRegistry.instance().mapLayers().values():
            names.append(layer.name())

        layerName = self.layerNameEdit.text()
        if layerName == "":
            layerName = self.defaultLayerName
        newLayerName = layerName
        index = 1
        while newLayerName in names:
            index += 1
            newLayerName = u"%s_%d" % (layerName, index)

        # create the layer
        layer = self.db.toSqlLayer(query, geomFieldName, uniqueFieldName, newLayerName, layerType,
                                   self.avoidSelectById.isChecked(), _filter)
        if layer.isValid():
            return layer
        else:
            return None

    def loadSqlLayer(self):
        QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))
        try:
            layer = self._getSqlLayer(self.filter)
            if layer == None:
                return

            from qgis.core import QgsMapLayerRegistry
            QgsMapLayerRegistry.instance().addMapLayers([layer], True)
        finally:
            QApplication.restoreOverrideCursor()

    def updateSqlLayer(self):
        QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))
        try:
            layer = self._getSqlLayer(self.filter)
            if layer == None:
                return

            #self.layer.dataProvider().setDataSourceUri(layer.dataProvider().dataSourceUri())
            #self.layer.dataProvider().reloadData()
            XMLDocument = QDomDocument("style")
            XMLMapLayers = XMLDocument.createElement("maplayers")
            XMLMapLayer = XMLDocument.createElement("maplayer")
            self.layer.writeLayerXML(XMLMapLayer, XMLDocument)
            XMLMapLayer.firstChildElement("datasource").firstChild().setNodeValue(layer.source())
            XMLMapLayers.appendChild(XMLMapLayer)
            XMLDocument.appendChild(XMLMapLayers)
            self.layer.readLayerXML(XMLMapLayer)
            self.layer.reload()
            self.iface.actionDraw().trigger()
            self.iface.mapCanvas().refresh()
            self.iface.legendInterface().refreshLayerSymbology(layer)
        finally:
            QApplication.restoreOverrideCursor()

    def fillColumnCombos(self):
        query = self._getSqlQuery()
        if query == "":
            return

        QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))

        # remove a trailing ';' from query if present
        if query.strip().endswith(';'):
            query = query.strip()[:-1]

        # get all the columns
        cols = []
        quotedCols = []
        connector = self.db.connector
        if self.aliasSubQuery:
            # get a new alias
            aliasIndex = 0
            while True:
                alias = "_subQuery__%d" % aliasIndex
                escaped = re.compile('\\b("?)' + re.escape(alias) + '\\1\\b')
                if not escaped.search(query):
                    break
                aliasIndex += 1

            sql = u"SELECT * FROM (%s\n) AS %s LIMIT 0" % (unicode(query), connector.quoteId(alias))
        else:
            sql = u"SELECT * FROM (%s\n) WHERE 1=0" % unicode(query)

        c = None
        try:
            c = connector._execute(None, sql)
            cols = connector._get_cursor_columns(c)
            for col in cols:
                quotedCols.append(connector.quoteId(col))

        except BaseError as e:
            QApplication.restoreOverrideCursor()
            DlgDbError.showError(e, self)
            self.uniqueModel.clear()
            self.geomCombo.clear()
            return

        finally:
            if c:
                c.close()
                del c

        self.setColumnCombos(cols, quotedCols)

        QApplication.restoreOverrideCursor()

    def setColumnCombos(self, cols, quotedCols):
        # get sensible default columns. do this before sorting in case there's hints in the column order (eg, id is more likely to be first)
        try:
            defaultGeomCol = next(col for col in cols if col in ['geom', 'geometry', 'the_geom', 'way'])
        except:
            defaultGeomCol = None
        try:
            defaultUniqueCol = [col for col in cols if 'id' in col][0]
        except:
            defaultUniqueCol = None

        colNames = sorted(zip(cols, quotedCols))
        newItems = []
        uniqueIsFilled = False
        for (col, quotedCol) in colNames:
            item = QStandardItem(col)
            item.setData(quotedCol)
            item.setEnabled(True)
            item.setCheckable(self.allowMultiColumnPk)
            item.setSelectable(not self.allowMultiColumnPk)
            if self.allowMultiColumnPk:
                matchingItems = self.uniqueModel.findItems(col)
                if matchingItems:
                    item.setCheckState(matchingItems[0].checkState())
                    uniqueIsFilled = uniqueIsFilled or matchingItems[0].checkState() == Qt.Checked
                else:
                    item.setCheckState(Qt.Unchecked)
            newItems.append(item)
        if self.allowMultiColumnPk:
            self.uniqueModel.clear()
            self.uniqueModel.appendColumn(newItems)
            self.uniqueChanged()
        else:
            previousUniqueColumn = self.uniqueCombo.currentText()
            self.uniqueModel.clear()
            self.uniqueModel.appendColumn(newItems)
            if self.uniqueModel.findItems(previousUniqueColumn):
                self.uniqueCombo.setEditText(previousUniqueColumn)
                uniqueIsFilled = True

        oldGeometryColumn = self.geomCombo.currentText()
        self.geomCombo.clear()
        self.geomCombo.addItems(cols)
        self.geomCombo.setCurrentIndex(self.geomCombo.findText(oldGeometryColumn, Qt.MatchExactly))

        # set sensible default columns if the columns are not already set
        try:
            if self.geomCombo.currentIndex() == -1:
                self.geomCombo.setCurrentIndex(cols.index(defaultGeomCol))
        except:
            pass
        items = self.uniqueModel.findItems(defaultUniqueCol)
        if items and not uniqueIsFilled:
            if self.allowMultiColumnPk:
                items[0].setCheckState(Qt.Checked)
            else:
                self.uniqueCombo.setEditText(defaultUniqueCol)
        try:
            pass
        except:
            pass

    def copySelectedResults(self):
        if len(self.viewResult.selectedIndexes()) <= 0:
            return
        model = self.viewResult.model()

        # convert to string using tab as separator
        text = model.headerToString("\t")
        for idx in self.viewResult.selectionModel().selectedRows():
            text += "\n" + model.rowToString(idx.row(), "\t")

        QApplication.clipboard().setText(text, QClipboard.Selection)
        QApplication.clipboard().setText(text, QClipboard.Clipboard)

    def initCompleter(self):
        dictionary = None
        if self.db:
            dictionary = self.db.connector.getSqlDictionary()
        if not dictionary:
            # use the generic sql dictionary
            from .sql_dictionary import getSqlDictionary

            dictionary = getSqlDictionary()

        wordlist = []
        for name, value in dictionary.iteritems():
            wordlist += value  # concat lists
        wordlist = list(set(wordlist))  # remove duplicates

        api = QsciAPIs(self.editSql.lexer())
        for word in wordlist:
            api.add(word)

        api.prepare()
        self.editSql.lexer().setAPIs(api)

    def displayQueryBuilder(self):
        dlg = QueryBuilderDlg(self.iface, self.db, self, reset=self.queryBuilderFirst)
        self.queryBuilderFirst = False
        r = dlg.exec_()
        if r == QDialog.Accepted:
            self.editSql.setText(dlg.query)

    def _getSqlQuery(self):
        sql = self.editSql.selectedText()
        if len(sql) == 0:
            sql = self.editSql.text()
        return sql

    def uniqueChanged(self):
        # when an item is (un)checked, simply trigger an update of the combobox text
        self.uniqueTextChanged(None)

    def uniqueTextChanged(self, text):
        # Whenever there is new text displayed in the combobox, check if it is the correct one and if not, display the correct one.
        checkedItems = []
        for item in self.uniqueModel.findItems("*", Qt.MatchWildcard):
            if item.checkState() == Qt.Checked:
                checkedItems.append(item.text())
        label = ", ".join(checkedItems)
        if text != label:
            self.uniqueCombo.setEditText(label)

    def setFilter(self):
        from qgis.gui import QgsQueryBuilder
        layer = self._getSqlLayer("")
        if not layer:
            return

        dlg = QgsQueryBuilder(layer)
        dlg.setSql(self.filter)
        if dlg.exec_():
            self.filter = dlg.sql()
        layer.deleteLater()
class FormItem(QStandardItem):
    def __init__(self, name, fields, setup):
        super(FormItem, self).__init__(name)
        fields = [("Name", str, name)] + fields
        self.name = lambda: str(self.text())
        self.names, _, _ = zip(*fields)
        self.dtypes = {}
        self.widgets = {}
        self.method_names = []
        self.val_items = {}
        self.expr_items = {}
        self.group_items = {}
        self.setup = setup
        self.params_model = QStandardItemModel()
        self.params_model.itemChanged.connect(self.update_name)
        self.params_model.setHorizontalHeaderLabels(["Name", "Formula", "Evaluated"])
        self.params_widget = QTableView()
        self.params_widget.setModel(self.params_model)
        self.params_widget.setItemDelegate(FormDelegate(self.params_model, self.widgets))
        self.params_widget.verticalHeader().hide()

        for name, item_type, default in fields:
            self.add_field(name, item_type, default)
        self.params_widget.resizeRowsToContents()
        self.context_menu = ActionsMenu([])

        self.params_model.itemChanged.connect(self.notify_group_item_children)

    def notify_group_item_children(self, item):
        method_name = method_style(self.params_model.item(item.row(), 0).text())
        if method_name in self.group_items:
            current_item = self.dtypes[method_name](item.text())
            previous_item = self.dtypes[method_name](self.group_items[method_name])
            self.group_items[method_name] = current_item

            current_item.register_dependency(self)
            previous_item.unregister_dependency(self)


    def add_field(self, word_name, item_type, value):
        word_name = word_style(word_name)
        method_name = method_style(word_name)
        if item_type is int:
            self.dtypes[method_name] = int
            self.widgets[word_name] = lambda: IntVarLineEdit(self.setup)
        elif item_type is float:
            self.dtypes[method_name] = float
            self.widgets[word_name] = lambda: VarLineEdit(self.setup)
        elif isinstance(item_type, bool):
            self.dtypes[method_name] = bool
            self.widgets[word_name] = QCheckBox
        elif isinstance(item_type, (list, tuple)):
            self.dtypes[method_name] = str
            self.widgets[word_name] = \
                lambda grp=item_type, **kwargs: MyComboBox(grp, **kwargs)
        elif isinstance(item_type, GroupItem):
            group = item_type
            value = group.items_list()[0].text()
            self.dtypes[method_name] = lambda i_name, grp=group: grp.item_from_name(i_name)
            self.widgets[word_name] = \
                lambda grp=group, **kwargs: ItemsComboBox(grp, **kwargs)
            self.group_items[method_name] = value
            group.item_from_name(value).register_dependency(self)
        self.expr_items[method_name] = QStandardItem(str(value))
        self.val_items[method_name] = ConstantItem("")
        self.params_model.appendRow([ConstantItem(word_name), self.expr_items[method_name], self.val_items[method_name]])
        self.method_names.append(method_name)

    def set_name(self, name):
        self.setText(name)
        self.params_model.item(0, 1).setText(name)

    def update_name(self):
        self.setText(self.params_model.item(0, 1).text())

    def eval_item(self, item):
        if item in self.method_names:
            dtype = self.dtypes[item]
            text = self.val_items[item].text()
            if text == "":
                text = self.expr_items[item].text()
            return dtype(text)
        else:
            raise AttributeError(item)

    def __getattr__(self, item):
        return self.eval_item(item)
예제 #35
0
class PosiviewProperties(QgsOptionsDialogBase, Ui_PosiviewPropertiesBase):
    '''
    GUI class classdocs for the Configuration dialog
    '''
    applyChanges = pyqtSignal(dict)

    def __init__(self, project, parent=None):
        '''
        Setup dialog widgets with the project properties
        '''
        super(PosiviewProperties, self).__init__("PosiViewProperties", parent)
        self.setupUi(self)
        self.groupBox_6.hide()
        self.initOptionsBase(False)
        self.restoreOptionsBaseUi()
        self.comboBoxParser.addItems(PARSERS)
        self.comboBoxProviderType.addItems(DEVICE_TYPES)
        self.project = project
        self.projectProperties = project.properties()
        self.mToolButtonLoad.setDefaultAction(self.actionLoadConfiguration)
        self.mToolButtonSave.setDefaultAction(self.actionSaveConfiguration)

        self.mobileModel = QStringListModel()
        self.mobileListModel = QStringListModel()
        self.mMobileListView.setModel(self.mobileListModel)
        self.mobileProviderModel = QStandardItemModel()
        self.mobileProviderModel.setHorizontalHeaderLabels(('Provider', 'Filter'))
        self.mMobileProviderTableView.setModel(self.mobileProviderModel)

        self.providerListModel = QStringListModel()
        self.mDataProviderListView.setModel(self.providerListModel)
        self.comboBoxProviders.setModel(self.providerListModel)
        self.setupModelData(self.projectProperties)
        self.setupGeneralData(self.projectProperties)

    def setupModelData(self, properties):
        self.mobileListModel.setStringList(sorted(properties['Mobiles'].keys()))
        self.providerListModel.setStringList(sorted(properties['Provider'].keys()))

    def setupGeneralData(self, properties):
        self.lineEditCruise.setText(properties['Mission']['cruise'])
        self.lineEditDive.setText(properties['Mission']['dive'])
        self.lineEditStation.setText(properties['Mission']['station'])
        self.lineEditRecorderPath.setText(properties['RecorderPath'])
        self.checkBoxAutoRecording.setChecked(properties['AutoRecord'])
        self.spinBoxNotifyDuration.setValue(properties['NotifyDuration'])
        self.checkBoxUtcClock.setChecked((properties['ShowUtcClock']))

    def updateGeneralData(self):
        self.projectProperties['Mission']['cruise'] = self.lineEditCruise.text()
        self.projectProperties['Mission']['dive'] = self.lineEditDive.text()
        self.projectProperties['Mission']['station'] = self.lineEditStation.text()
        self.projectProperties['RecorderPath'] = self.lineEditRecorderPath.text()
        self.projectProperties['AutoRecord'] = self.checkBoxAutoRecording.isChecked()
        self.projectProperties['NotifyDuration'] = self.spinBoxNotifyDuration.value()
        self.projectProperties['ShowUtcClock'] = self.checkBoxUtcClock.isChecked()

    def getColor(self, value):
        try:
            return QColor.fromRgba(int(value))
        except ValueError:
            return QColor(value)

    @pyqtSlot(QAbstractButton, name='on_buttonBox_clicked')
    def onButtonBoxClicked(self, button):
        role = self.buttonBox.buttonRole(button)
        if role == QDialogButtonBox.ApplyRole or role == QDialogButtonBox.AcceptRole:
            self.updateGeneralData()
            self.applyChanges.emit(self.projectProperties)

    @pyqtSlot(name='on_actionSaveConfiguration_triggered')
    def onActionSaveConfigurationTriggered(self):
        ''' Save the current configuration
        '''
        fn = QFileDialog.getSaveFileName(None, 'Save PosiView configuration', '', 'Configuration (*.ini *.conf)')
        self.project.store(fn)

    @pyqtSlot(name='on_actionLoadConfiguration_triggered')
    def onActionLoadConfigurationTriggered(self):
        ''' Load configuration from file
        '''
        fn = QFileDialog.getOpenFileName(None, 'Save PosiView configuration', '', 'Configuration (*.ini *.conf)')
        self.projectProperties = self.project.read(fn)
        self.setupModelData(self.projectProperties)
        self.setupGeneralData(self.projectProperties)

    @pyqtSlot(QModelIndex, name='on_mMobileListView_clicked')
    def editMobile(self, index):
        ''' Populate the widgets with the selected mobiles properties
        '''
        if index.isValid():
            self.populateMobileWidgets(index)

    @pyqtSlot(str, name='on_comboBoxMobileType_currentIndexChanged')
    def mobileTypeChanged(self, mType):
        if mType == 'SHAPE':
#             self.lineEditMobileShape.setText(str(mobile['shape']))
            self.lineEditMobileShape.setEnabled(True)
        else:
            self.lineEditMobileShape.setEnabled(False)

    @pyqtSlot(QModelIndex, name='on_mMobileListView_activated')
    def activated(self, index):
        pass

    @pyqtSlot(name='on_toolButtonAddMobile_clicked')
    def addMobile(self):
        self.mobileListModel.insertRow(self.mobileListModel.rowCount())
        index = self.mobileListModel.index(self.mobileListModel.rowCount() - 1)
        self.lineEditMobileName.setText('NewMobile')
        self.mobileListModel.setData(index, 'NewMobile', Qt.DisplayRole)
        self.mMobileListView.setCurrentIndex(index)
        self.applyMobile()

    @pyqtSlot(name='on_pushButtonApplyMobile_clicked')
    def applyMobile(self):
        index = self.mMobileListView.currentIndex()
        if index.isValid() and not self.lineEditMobileName.text() == '':
            mobile = dict()
            mobile['Name'] = self.lineEditMobileName.text()
            mobile['type'] = self.comboBoxMobileType.currentText()
            try:
                t = eval(self.lineEditMobileShape.text())
                if t.__class__ is tuple or t.__class__ is dict:
                    mobile['shape'] = t
            except SyntaxError:
                mobile['shape'] = ((0.0, -0.5), (0.3, 0.5), (0.0, 0.2), (-0.5, 0.5))
            mobile['length'] = self.doubleSpinBoxMobileLength.value()
            mobile['width'] = self.doubleSpinBoxMobileWidth.value()
            mobile['zValue'] = self.spinBoxZValue.value()
            mobile['color'] = self.mColorButtonMobileColor.color().rgba()
            mobile['fillColor'] = self.mColorButtonMobileFillColor.color().rgba()
            mobile['timeout'] = self.spinBoxMobileTimeout.value() * 1000
            mobile['nofixNotify'] = self.spinBoxMobileNotification.value()
            mobile['trackLength'] = self.spinBoxTrackLength.value()
            mobile['trackColor'] = self.mColorButtonMobileTrackColor.color().rgba()
            provs = dict()
            for r in range(self.mobileProviderModel.rowCount()):
                try:
                    fil = int(self.mobileProviderModel.item(r, 1).data(Qt.DisplayRole))
                except:
                    fil = self.mobileProviderModel.item(r, 1).data(Qt.DisplayRole)
                    if not fil:
                        fil = None
                provs[self.mobileProviderModel.item(r, 0).data(Qt.DisplayRole)] = fil
            mobile['provider'] = provs
            currName = self.mobileListModel.data(index, Qt.DisplayRole)
            if not currName == mobile['Name']:
                del self.projectProperties['Mobiles'][currName]
                self.mobileListModel.setData(index, mobile['Name'], Qt.DisplayRole)
            self.projectProperties['Mobiles'][mobile['Name']] = mobile

    def populateMobileWidgets(self, index):
        mobile = self.projectProperties['Mobiles'][self.mobileListModel.data(index, Qt.DisplayRole)]
        self.lineEditMobileName.setText(mobile.get('Name'))
        self.comboBoxMobileType.setCurrentIndex(self.comboBoxMobileType.findText(mobile.setdefault('type', 'BOX').upper()))
        if mobile['type'] == 'SHAPE':
            self.lineEditMobileShape.setText(str(mobile['shape']))
            self.lineEditMobileShape.setEnabled(True)
        else:
            self.lineEditMobileShape.setEnabled(False)
            self.lineEditMobileShape.clear()
        self.doubleSpinBoxMobileLength.setValue(mobile.get('length', 20.0))
        self.doubleSpinBoxMobileWidth.setValue(mobile.get('width', 5.0))
        self.spinBoxZValue.setValue(mobile.get('zValue', 100))
        self.mColorButtonMobileColor.setColor(self.getColor(mobile.get('color', 'black')))
        self.mColorButtonMobileFillColor.setColor(self.getColor(mobile.get('fillColor', 'green')))
        self.spinBoxMobileTimeout.setValue(mobile.get('timeout', 3000) / 1000)
        self.spinBoxMobileNotification.setValue(mobile.get('nofixNotify', 0))
        self.spinBoxTrackLength.setValue(mobile.get('trackLength', 100))
        self.mColorButtonMobileTrackColor.setColor(self.getColor(mobile.get('trackColor', 'green')))

        r = 0
        self.mobileProviderModel.removeRows(0, self.mobileProviderModel.rowCount())
        if 'provider' in mobile:
            for k, v in mobile['provider'].items():
                prov = QStandardItem(k)
                val = QStandardItem(str(v))
                self.mobileProviderModel.setItem(r, 0, prov)
                self.mobileProviderModel.setItem(r, 1, val)
                r += 1

    @pyqtSlot(name='on_toolButtonRemoveMobile_clicked')
    def removeMobile(self):
        idx = self.mMobileListView.currentIndex()
        if idx.isValid():
            self.projectProperties['Mobiles'].pop(self.mobileListModel.data(idx, Qt.DisplayRole))
            self.mobileListModel.removeRows(idx.row(), 1)
            idx = self.mMobileListView.currentIndex()
            if idx.isValid():
                self.populateMobileWidgets(idx)

    @pyqtSlot(name='on_toolButtonRefreshMobileProvider_clicked')
    def refreshMobileProvider(self):
        prov = self.comboBoxProviders.currentText()
        if prov == '':
            return
        fil = None
        if self.lineEditProviderFilter.text() != '':
            fil = self.lineEditProviderFilter.text()
        items = self.mobileProviderModel.findItems(prov, Qt.MatchExactly, 0)
        if items:
            for item in items:
                self.mobileProviderModel.setItem(item.row(), 1, QStandardItem(fil))
        else:
            self.mobileProviderModel.appendRow([QStandardItem(prov), QStandardItem(fil)])

    @pyqtSlot(name='on_toolButtonRemoveMobileProvider_clicked')
    def removeMobileProvider(self):
        idx = self.mMobileProviderTableView.currentIndex()
        if idx.isValid():
            self.mobileProviderModel.removeRow(idx.row())

    @pyqtSlot(name='on_pushButtonApplyDataProvider_clicked')
    def applyDataProvider(self):
        index = self.mDataProviderListView.currentIndex()
        if index.isValid() and not self.lineEditProviderName.text() == '':
            provider = dict()
            provider['Name'] = self.lineEditProviderName.text()
            provider['DataDeviceType'] = self.comboBoxProviderType.currentText()
            if provider['DataDeviceType'] in NETWORK_TYPES:
                provider['Host'] = self.lineEditProviderHostName.text()
                provider['Port'] = self.spinBoxProviderPort.value()
            provider['Parser'] = self.comboBoxParser.currentText()
            currName = self.providerListModel.data(index, Qt.DisplayRole)
            if not currName == provider['Name']:
                del self.projectProperties['Provider'][currName]
                self.providerListModel.setData(index, provider['Name'], Qt.DisplayRole)
            self.projectProperties['Provider'][provider['Name']] = provider

    @pyqtSlot(QModelIndex, name='on_mDataProviderListView_clicked')
    def editDataProvider(self, index):
        '''
        '''
        if index.isValid():
            self.populateDataProviderWidgets(index)

    def populateDataProviderWidgets(self, index):
        provider = self.projectProperties['Provider'][self.providerListModel.data(index, Qt.DisplayRole)]
        self.lineEditProviderName.setText(provider.get('Name'))
        self.comboBoxProviderType.setCurrentIndex(self.comboBoxProviderType.findText(provider.setdefault('DataDeviceType', 'UDP').upper()))
        if provider['DataDeviceType'] in NETWORK_TYPES:
            self.stackedWidgetDataDevice.setCurrentIndex(0)
            self.lineEditProviderHostName.setText(provider.setdefault('Host', '0.0.0.0'))
            self.spinBoxProviderPort.setValue(int(provider.setdefault('Port', 2000)))

        self.comboBoxParser.setCurrentIndex(self.comboBoxParser.findText(provider.setdefault('Parser', 'NONE').upper()))

    @pyqtSlot(name='on_toolButtonAddDataProvider_clicked')
    def addDataProvider(self):
        self.providerListModel.insertRow(self.providerListModel.rowCount())
        index = self.providerListModel.index(self.providerListModel.rowCount() - 1)
        self.lineEditProviderName.setText('NewDataProvider')
        self.providerListModel.setData(index, 'NewDataProvider', Qt.DisplayRole)
        self.mDataProviderListView.setCurrentIndex(index)
        self.applyDataProvider()

    @pyqtSlot(name='on_toolButtonRemoveDataProvider_clicked')
    def removeDataProvider(self):
        idx = self.mDataProviderListView.currentIndex()
        if idx.isValid():
            self.projectProperties['Provider'].pop(self.providerListModel.data(idx, Qt.DisplayRole))
            self.providerListModel.removeRows(idx.row(), 1)
            idx = self.mDataProviderListView.currentIndex()
            if idx.isValid():
                self.populateDataProviderWidgets(idx)

    @pyqtSlot(name='on_toolButtonSelectLogPath_clicked')
    def selectRecorderPath(self):
        path = QFileDialog.getExistingDirectory(self, self.tr('Select Recorder Path'), self.lineEditRecorderPath.text(),
                                                QFileDialog.ShowDirsOnly | QFileDialog.DontResolveSymlinks)
        if path != '':
            self.lineEditRecorderPath.setText(path)

    @pyqtSlot(QPoint, name='on_lineEditMobileShape_customContextMenuRequested')
    def mobileShapeContextMenu(self, pos):
        menu = QMenu(self.lineEditMobileShape)
        vesselAction = menu.addAction(self.tr('Vessel'))
        rovAction = menu.addAction(self.tr('ROV'))
        auvAction = menu.addAction(self.tr('AUV'))
        arrowAction = menu.addAction(self.tr('Arrow'))
        selectedAction = menu.exec_(self.lineEditMobileShape.mapToGlobal(pos))
        if selectedAction == vesselAction:
            self.lineEditMobileShape.setText(u'((0, -0.5), (0.5, -0.3), (0.5, 0.5), (-0.5, 0.5), (-0.5, -0.3))')
        elif selectedAction == rovAction:
            self.lineEditMobileShape.setText(u'((0.3, -0.5), (0.5, -0.3), (0.5, 0.5), (-0.5, 0.5), (-0.5, -0.3), (-0.3, -0.5))')
        elif selectedAction == auvAction:
            self.lineEditMobileShape.setText(u'((0, -0.5), (0.5, -0.3), (0.5, 0.5), (-0.5, 0.5), (-0.5, -0.3))')
        elif selectedAction == arrowAction:
            self.lineEditMobileShape.setText(u'((0, -0.5), (0.5, 0.5), (0, 0), (-0.5, 0.5))')

    @pyqtSlot(name='on_buttonBox_helpRequested')
    def showHelp(self):
        """Display application help to the user."""
        help_file = os.path.join(os.path.split(os.path.dirname(__file__))[0], 'help', 'index.html')
        QDesktopServices.openUrl(QUrl.fromLocalFile(help_file))
예제 #36
0
파일: browser.py 프로젝트: jmechnich/qmpc
class Browser(QWidget):
    entrytype = type("EntryType", (object,), dict((v,k) for k,v in enumerate(
        ["directory", "playlist", "mediafile", "url"]
    )))
    col = type("BrowserColumns", (object,), dict((v,k) for k,v in enumerate(
        ["name", "last_modified", "entrytype", "uri"]
    )))
    
    @staticmethod
    def columns():
        return len(dict((k,v) for k,v in Browser.col.__dict__.items()
                        if not k.startswith("__")))


    def __init__(self,app):
        super(Browser,self).__init__()
        self.mpd = app.mpd
        self.ih  = app.imagehelper
        self.model = QStandardItemModel(0,self.columns(),self)
        self.initGUI()
        self.initActions()

    def initGUI(self):
        self.setWindowTitle(QApplication.applicationName())
        layout = QVBoxLayout()

        headerlayout = QHBoxLayout()
        homeBtn = QToolButton()
        homeBtn.setIcon(self.ih.homeButton)
        homeBtn.setFixedSize(64,64)
        homeBtn.clicked.connect(self.home)
        headerlayout.addWidget(homeBtn)
        label = QLabel("<b>Location</b>")
        label.setMargin(10)
        label.setFixedSize(label.sizeHint())
        headerlayout.addWidget(label)
        self.currentLocation = ClickableLabel("")
        self.currentLocation.setAlignment(Qt.AlignLeft | Qt.AlignVCenter)
        self.currentLocation.setWordWrap(True)
        self.currentLocation.setFixedSize(400,64)
        self.currentLocation.clicked.connect(self.back)
        headerlayout.addWidget(self.currentLocation)
        headerlayout.addStretch()
        layout.addLayout(headerlayout)

        self.view = QListView()
        self.view.setSelectionMode( QAbstractItemView.SingleSelection)
        self.view.setEditTriggers(QAbstractItemView.NoEditTriggers)
        self.view.setContextMenuPolicy(Qt.CustomContextMenu)
        self.view.customContextMenuRequested.connect(self.contextMenu)
        self.view.setModel(self.model)
        self.view.setModelColumn(0)
        #self.view.doubleClicked.connect(self.doubleClicked)
        self.view.activated.connect(self.activated)
        layout.addWidget(self.view)
        self.setLayout(layout)

    def initActions(self):
        self.actionAdd         = QAction("Add", self)
        self.actionAddPlay     = QAction("Add and Play", self)
        self.actionInsert      = QAction("Insert", self)
        self.actionReplace     = QAction("Replace", self)
        self.actionReplacePlay = QAction("Replace and Play", self)
        self.actionUpdate      = QAction("Update", self)
        self.actionUpdateAll   = QAction("Update all", self)
        # playlist actions
        self.actionPlsRename   = QAction("Rename", self)
        self.actionPlsDelete   = QAction("Delete", self)
            
        
    def contextMenu(self,pos):
        if self.model.rowCount() == 0: return
        mi = self.view.selectionModel().currentIndex()
        if not mi.isValid(): return
        uri = self.model.item(mi.row(),self.col.uri).text()
        entrytype = int(self.model.item(mi.row(),self.col.entrytype).text())

        addfunc = None
        if entrytype != self.entrytype.playlist:
            addfunc = self.mpd.add
        else:
            addfunc = self.mpd.load
        
        popup = QMenu()
        popup.addAction(self.actionAdd)
        popup.addAction(self.actionAddPlay)
        if entrytype == self.entrytype.mediafile or \
           entrytype == self.entrytype.url:
            popup.addAction(self.actionInsert)
        popup.addAction(self.actionReplace)
        popup.addAction(self.actionReplacePlay)
        if entrytype == self.entrytype.playlist:
            popup.addAction(self.actionPlsRename)
            popup.addAction(self.actionPlsDelete)
        else:
            popup.addAction(self.actionUpdate)
        popup.addAction(self.actionUpdateAll)
        action = popup.exec_(self.mapToGlobal(pos))
        
        status = self.mpd.status()
        if action == self.actionAdd:
            addfunc(uri)
        elif action == self.actionAddPlay:
            addfunc(uri)
            self.mpd.play(int(status['playlistlength']))
        elif action == self.actionInsert:
            song = int(status.get('song',-1))+1
            self.mpd.addid(uri,song)
        elif action == self.actionReplace:
            self.mpd.clear()
            addfunc(uri)
        elif action == self.actionReplacePlay:
            self.mpd.clear()
            addfunc(uri)
            self.mpd.play()
        elif action == self.actionUpdate:
            ans = QMessageBox.question(
                self, "Update", "Trigger update for '%s'?" % uri,
                QMessageBox.Yes | QMessageBox.No, QMessageBox.No)
            if ans == QMessageBox.Yes:
                self.mpd.update(uri)
        elif action == self.actionUpdateAll:
            self.mpd.update()
        elif action == self.actionPlsRename:
            ans, ok = QInputDialog.getText(
                self, "Rename playlist", "Rename playlist '%s':" % uri)
            plsname = unicode(ans)
            if ok and plsname != uri:
                for pls in self.mpd.listplaylists():
                    if pls['playlist'] == plsname:
                        overwrite = QMessageBox.question(
                            self, "Rename playlist",
                            "Playlist exists, overwrite?",
                            QMessageBox.Yes | QMessageBox.No, QMessageBox.No)
                        if overwrite == QMessageBox.Yes:
                            self.mpd.rm(plsname)
                            self.mpd.rename(uri,plsname)
                        break
                else:
                    self.mpd.rename(uri, plsname)
                    self.home()
        elif action == self.actionPlsDelete:
            ans = QMessageBox.question(
                self, "Delete '%s'" % uri, "Are you sure?" % uri,
                QMessageBox.Yes | QMessageBox.No, QMessageBox.No)
            if ans == QMessageBox.Yes:
                self.mpd.rm(uri)
                self.home()
         
    def showDirectory(self,uri):
        try:
            info = self.mpd.lsinfo(uri)
        except MPDError, e:
            print e
            return
        rows = []
        for entry in [ d for d in info if not d.has_key('playlist')]:
            row = self.createRow(entry)
            if not row: continue
            rows += [row]
        for entry in sorted([ d for d in info if d.has_key('playlist')],
                            key=operator.itemgetter('playlist')):
            row = self.createRow(entry)
            if not row: continue
            rows += [row]
        self.currentLocation.setText(uri)
        self.updateModel(rows)
예제 #37
0
class QgsAttributeTableDialog(QDialog):
    '''
    classdocs
    '''
    def __init__(self, parent, vectorlayer):
        QDialog.__init__(self, parent)
        #         self.w = QDialog(self)
        self.baseLayer = vectorlayer
        self.canChangeAttributes = self.validate(
            QgsVectorDataProvider.ChangeAttributeValues)
        self.canDeleteFeatures = self.validate(
            QgsVectorDataProvider.DeleteFeatures)
        self.canAddAttributes = self.validate(
            QgsVectorDataProvider.AddAttributes)
        self.canDeleteAttributes = self.validate(
            QgsVectorDataProvider.DeleteAttributes)
        self.canAddFeatures = self.validate(QgsVectorDataProvider.AddFeatures)

        gridLayout = QGridLayout(self)
        self.setLayout(gridLayout)

        self.setWindowTitle("Attribute Table")
        self.setFixedSize(QSize(800, 600))

        editorToolbar = QToolBar()
        editorToolbar.setFixedSize(QSize(768, 48))
        self.actionToggleEditing = QAction(QIcon("Resource\\edit.png"),
                                           "ToggleEditing", self)
        self.actionToggleEditing.triggered.connect(self.toggleEditing)
        if (self.canChangeAttributes or self.canDeleteFeatures
                or self.canAddAttributes or self.canDeleteAttributes
                or self.canAddFeatures) and (not self.baseLayer.isReadOnly()):
            self.actionToggleEditing.setEnabled(True)
        else:
            self.actionToggleEditing.setEnabled(False)
        self.actionToggleEditing.setCheckable(True)
        editorToolbar.addAction(self.actionToggleEditing)

        self.actionSave = QAction(QIcon("Resource\\filesave.png"),
                                  "Save Edits", self)
        self.actionSave.triggered.connect(self.saveEditing)
        self.actionSave.setCheckable(False)
        self.actionSave.setEnabled(False)
        editorToolbar.addAction(self.actionSave)

        self.actiondeleteRows = QAction(
            QIcon("Resource\\mActionDeleteSelected.png"),
            "Delete selected features", self)
        self.actiondeleteRows.triggered.connect(self.deleteRows)
        self.actiondeleteRows.setCheckable(False)
        self.actiondeleteRows.setEnabled(False)
        editorToolbar.addAction(self.actiondeleteRows)

        self.actionUnselectAll = QAction(
            QIcon("Resource\\mActionDeselectAll.png"), "Unselect All", self)
        self.actionUnselectAll.triggered.connect(self.unselectAll)
        self.actionUnselectAll.setCheckable(False)
        self.actionUnselectAll.setEnabled(True)
        editorToolbar.addAction(self.actionUnselectAll)

        self.actionSelectedToZoom = QAction(
            QIcon("Resource\\mActionZoomToSelected.png"),
            "Zoom map to the selected rows", self)
        self.actionSelectedToZoom.triggered.connect(self.selectedToZoom)
        self.actionSelectedToZoom.setCheckable(False)
        self.actionSelectedToZoom.setEnabled(True)
        editorToolbar.addAction(self.actionSelectedToZoom)

        gridLayout.addWidget(editorToolbar, 0, 0, 1, 1)

        self.model = QStandardItemModel()

        #         self.model.itemChanged.connect(self.attributeChanged)
        self.attributeTable = QTableView(self)
        self.attributeTable.setModel(self.model)
        self.attributeTable.setColumnWidth(0, 200)
        self.attributeTable.setColumnWidth(1, 160)
        self.attributeTable.clicked.connect(self.tableSelectionChanged)
        self.attributeTable.setSortingEnabled(True)

        self.changeItemList = []
        self.selectRows = []
        self.isSave = True
        self.initTable()
        gridLayout.addWidget(self.attributeTable, 1, 0, 1, 1)
#         self.attributeTable.selectionChanged.connect(self.selectFeature)

    def tableSelectionChanged(self):
        idxList = self.attributeTable.selectedIndexes()
        if idxList != None and len(idxList) > 0:
            self.baseLayer.removeSelection()
            fidList = []
            for idx in idxList:
                fid = int(self.model.item(idx.row()).text())
                fidList.append(fid)
            self.baseLayer.setSelectedFeatures(fidList)

    def toggleEditing(self):
        if self.baseLayer != None:

            if not self.actionToggleEditing.isChecked():

                if self.isSave:
                    self.baseLayer.commitChanges()
                    self.actionSave.setEnabled(False)
                    self.actiondeleteRows.setEnabled(False)
                    self.model.itemChanged.disconnect(self.attributeChanged)
                    self.toggleEditingTable(False)
                else:
                    button = QMessageBox.warning(
                        self, "Stop Editing",
                        "Do you want to save the changes to layer?",
                        QMessageBox.Save | QMessageBox.Discard
                        | QMessageBox.Cancel)
                    if (button == QMessageBox.Cancel):
                        self.actionToggleEditing.setChecked(True)

                    elif button == QMessageBox.Save:
                        self.saveEditing()
                        self.baseLayer.commitChanges()
                        self.actionSave.setEnabled(False)
                        self.actiondeleteRows.setEnabled(False)
                        self.model.itemChanged.disconnect(
                            self.attributeChanged)
                        self.toggleEditingTable(False)
                    else:
                        self.initTable()
                        self.baseLayer.commitChanges()
                        self.actionSave.setEnabled(False)
                        self.actiondeleteRows.setEnabled(False)
                        self.model.itemChanged.disconnect(
                            self.attributeChanged)
                        self.toggleEditingTable(False)
#                 self.isEditable = False
            else:
                self.actionSave.setEnabled(True)
                self.actiondeleteRows.setEnabled(True)
                self.baseLayer.startEditing()
                self.toggleEditingTable(True)
                self.model.itemChanged.connect(self.attributeChanged)
#                 self.isEditable = True

    def toggleEditingTable(self, isEditable):
        columnCount = self.model.columnCount()
        rowCount = self.model.rowCount()
        col = 0
        while col < columnCount:
            row = 0
            while row < rowCount:
                self.model.item(row, col).setEditable(isEditable)
                row += 1
            col += 1

    def attributeChanged(self, standardItem):
        self.isSave = False
        #         if not self.isDelete:
        self.changeItemList.append(standardItem)
#         featureId = standardItem.row()
#         self.baseLayer.changeAttributeValue(featureId,
#                                        standardItem.column(), standardItem.text())

    def saveEditing(self):
        self.isSave = True
        if len(self.changeItemList) > 0:
            for standardItem in self.changeItemList:
                featureId = standardItem.row()
                self.baseLayer.changeAttributeValue(featureId,
                                                    standardItem.column(),
                                                    standardItem.text())
            self.changeItemList = []
        if len(self.selectRows) > 0:
            for id in self.selectRows:
                self.baseLayer.deleteFeature(id)
            self.selectRows = []

    def initTable(self):
        self.model.clear()
        #         header = QHeaderView(Qt.Horizontal)
        #         headerModel = QStandardItemModel()

        layer = self.baseLayer
        fields = layer.pendingFields()
        headersList = ["fid"]
        for field in fields:
            headersList.append(field.name())
        self.model.setHorizontalHeaderLabels(headersList)

        #         headerModel.setHorizontalHeaderLabels(headersList)
        #         header.setModel(headerModel)
        #         self.attributeTable.setHorizontalHeader(header)

        if len(layer.selectedFeatures()) > 0:
            features = layer.selectedFeatures()
        else:
            features = layer.getFeatures()
        for feature in features:
            record = [QStandardItem(str(feature.id()))]

            for field in feature.fields():
                name = field.name()
                attribute = feature.attribute(name).toString()

                stdItemValue = QStandardItem(attribute)
                stdItemValue.setEditable(False)
                record.append(stdItemValue)
            self.model.appendRow(record)

    def deleteRows(self):
        if len(self.attributeTable.selectedIndexes()) > 0:
            self.isSave = False
            selectedIndexs = self.attributeTable.selectedIndexes()
            k = -1
            self.selectRows = []
            for index in selectedIndexs:
                if k != index.row():
                    k = index.row()
                    self.selectRows.append(k)
            for row in self.selectRows:
                self.model.takeRow(row)

    def unselectAll(self):
        if len(self.attributeTable.selectedIndexes()) > 0:
            self.attributeTable.clearSelection()

    def selectedToZoom(self):
        if len(self.attributeTable.selectedIndexes()) > 0:
            self.baseLayer.removeSelection()

            selectedIndexs = self.attributeTable.selectedIndexes()
            k = -1
            self.selectRows = []
            for index in selectedIndexs:
                if k != index.row():
                    k = index.row()
                    self.selectRows.append(k)
            self.baseLayer.setSelectedFeatures(self.selectRows)
#             for row in self.selectRows:
#                 self.model.takeRow(row)
        define._canvas.zoomToSelected(self.baseLayer)

    def validate(self, condition):
        if self.baseLayer.dataProvider().capabilities() & condition:
            return True
        else:
            return False
예제 #38
0
class OrderSelectorModel(QObject):
    """"""

    #----------------------------------------------------------------------
    def __init__(self,
                 full_string_list,
                 init_selected_string_list=None,
                 permanently_selected_string_list=None):
        """Constructor"""

        QObject.__init__(self)

        self.output = []

        if not self.hasNoDuplicateStrings(full_string_list):
            raise ValueError('Duplicate strings detected in full string list.')
        else:
            self.full_string_list = full_string_list[:]

        if init_selected_string_list is not None:
            if not self.allStringsInList1FoundInList2(
                    init_selected_string_list, self.full_string_list):
                raise ValueError(
                    'Some of the strings in initially selected string list are not in full string list.'
                )
        else:
            init_selected_string_list = []

        if permanently_selected_string_list is not None:
            if not self.allStringsInList1FoundInList2(
                    permanently_selected_string_list,
                    init_selected_string_list):
                raise ValueError(
                    'Some of the strings in permanently selected string list are not in initially selected string list.'
                )
        else:
            permanently_selected_string_list = []

        self.permanently_selected_string_list = permanently_selected_string_list[:]

        self.model_Selected = QStandardItemModel()
        self.model_NotSelected = QStandardItemModel()

        Selected_item_list = [None for s in init_selected_string_list]
        NotSelected_item_list = []
        for s in self.full_string_list:
            item = QStandardItem(s)
            try:
                Selected_item_list[init_selected_string_list.index(s)] = item
            except:
                NotSelected_item_list.append(item)

        for item in NotSelected_item_list:
            self.model_NotSelected.appendRow(item)
        for item in Selected_item_list:
            self.model_Selected.appendRow(item)

    #----------------------------------------------------------------------
    def getSelectedList(self):
        """"""

        selectedList = []
        for i in range(self.model_Selected.rowCount()):
            selectedList.append(self.model_Selected.item(i, 0).text())

        return selectedList

    #----------------------------------------------------------------------
    def hasNoDuplicateStrings(self, full_string_list):
        """"""

        str_list = full_string_list
        str_set = set(full_string_list)

        if len(str_list) == len(str_set):
            return True
        else:
            return False

    #----------------------------------------------------------------------
    def allStringsInList1FoundInList2(self, str_list_1, str_list_2):
        """"""

        stringsNotFound = [s for s in str_list_1 if s not in str_list_2]

        if stringsNotFound != []:
            return False
        else:
            return True
예제 #39
0
class SubPowerWidget(QWidget):
    """
	@brief Zeigt alle Unterkräfte in einer Baumstruktur an.
	"""
    def __init__(self, template, character, parent=None):
        super(SubPowerWidget, self).__init__(parent)

        self.__storage = template
        self.__character = character

        self.__model = QStandardItemModel()
        # Das ungenutzte Model dient dazu, alle Unterkräfte aufzunehmen, die ich nicht darstellen möchte. Ist einfacher, als diese im View zu verstecken.
        self.__modelUnused = QStandardItemModel()

        self._layout = QVBoxLayout()
        self.setLayout(self._layout)

        self.__view = QTreeView()
        self.__view.setHeaderHidden(True)
        self.__view.setModel(self.__model)

        self._layout.addWidget(self.__view)

        self._typ = "Subpower"
        categories = self.__storage.categories(self._typ)

        self.__items = {}

        self.__rootItem = QStandardItem()
        self.__rootItem = self.__model.invisibleRootItem()

        self.__rootItemUnused = QStandardItem()
        self.__rootItemUnused = self.__modelUnused.invisibleRootItem()

        for item in categories:
            categoryItem = QStandardItem(item)
            self.__rootItem.appendRow(categoryItem)

            ## Ich benötige diese Items auch im ungenutzten Model.
            categoryItemUnused = QStandardItem(item)
            self.__rootItemUnused.appendRow(categoryItemUnused)

            traitList = list(self.__character.traits[self._typ][item].items())
            traitList.sort()
            for trait in traitList:
                traitItem = QStandardItem(trait[1].name)
                traitItem.setCheckable(True)
                ## Unhashable Type
                self.__items[trait[1]] = traitItem
                categoryItem.appendRow(traitItem)

                ## Funktioniert mit PySide nicht:
                #trait[1].availableChanged.connect(traitItem.setEnabled)
                ## Funktioniert auch mit PySide:
                trait[1].availableChanged.connect(
                    lambda enable, item=traitItem: item.setEnabled(enable))
                trait[1].valueChanged.connect(lambda val, trait=trait[
                    1], item=traitItem: self.__setItemValue(trait, item))

        self.__model.itemChanged.connect(self.__getItemValue)
        self.__character.speciesChanged.connect(self.hideOrShowToolPage)
        self.__character.breedChanged.connect(self.hideOrShowToolPage)
        self.__character.factionChanged.connect(self.hideOrShowToolPage)

    def __setItemValue(self, trait, item):
        """
		Setzt den Wert der Angezeigten Items.
		"""

        if trait.value == 0:
            item.setCheckState(Qt.Unchecked)
        elif trait.value == 1:
            item.setCheckState(Qt.PartiallyChecked)
        else:
            item.setCheckState(Qt.Checked)

    def __getItemValue(self, item):
        """
		Setzt den Wert der Eigenschaft im Speicher.
		"""

        for trait in self.__items.items():
            if id(trait[1]) == id(item):
                trait[0].value = item.checkState()
                break

    def hideOrShowToolPage(self, res):
        """
		Alle Eigenschaften, die nicht zur Verfügung stehen, werden verborgen, indem sie in ein anderes Model verschoben werden.

		\bug Möglicher Fehler in PySide: Der Aufruf von QStandardItem.model() führt beim Beenden des Programms zu einem Segmentation Fault.
		"""

        # Versteckt alle Unterkräfte, die zu gewähltem Charakter nicht passen.
        for item in self.__items.items():
            if ((item[0].species
                 and item[0].species != self.__character.species) or
                (item[0].only and self.__character.breed not in item[0].only
                 and self.__character.faction not in item[0].only)):
                #self.__view.setRowHidden(item[1].index().row(), item[1].parent().index(), True)
                #Debug.debug(item[1].model())
                ## Hier wird beispielsweise besagter Aufruf getätigt, der zu einem segfault führt.
                if item[1].model() == self.__model:
                    parent = item[1].parent()
                    itemUnused = parent.takeRow(item[1].index().row())
                    parentUnused = self.__modelUnused.findItems(
                        parent.text())[0]
                    parentUnused.appendRow(itemUnused)
            else:
                #self.__view.setRowHidden(item[1].index().row(), item[1].parent().index(), False)
                if item[1].model() == self.__modelUnused:
                    parent = item[1].parent()
                    itemUsed = parent.takeRow(item[1].index().row())
                    parentUsed = self.__model.findItems(parent.text())[0]
                    parentUsed.appendRow(itemUsed)

        ## Versteckt alle Elternzeilen, wenn sie keine Kinder enthalten.
        for i in range(self.__model.rowCount()):
            categoryItem = self.__model.item(i)
            if categoryItem.hasChildren():
                self.__view.setRowHidden(categoryItem.index().row(),
                                         self.__rootItem.index(), False)
            else:
                self.__view.setRowHidden(categoryItem.index().row(),
                                         self.__rootItem.index(), True)
예제 #40
0
class DialListCheckBox(object):
    """
    Dialog with list check box
    example : 1,2,4,6,8
    """
    def __init__(self, values, checked_values=[]):
        self.dial = QDialog()
        self.result = ""

        # Layout Principal
        m_vbl = QVBoxLayout(self.dial)

        # List item checkable
        view = QListView()
        m_vbl.addWidget(view)

        self.m_sim = QStandardItemModel()
        view.setModel(self.m_sim)

        self._load_item(values, checked_values)

        # List buttons
        bt_all = QPushButton(self.tr("All"))
        bt_all.clicked.connect(lambda: self._check_all())

        bt_nothing = QPushButton(self.tr("Nothing"))
        bt_nothing.clicked.connect(lambda: self._check_nothing())

        bt_print = QPushButton(self.tr("Ok"))
        bt_print.clicked.connect(lambda: self._check_ok())

        # Sub layout for buttons
        m_vbh = QHBoxLayout()
        m_vbl.addLayout(m_vbh)

        m_vbh.addWidget(bt_all)
        m_vbh.addWidget(bt_nothing)
        m_vbh.addWidget(bt_print)

    def _load_item(self, values, checked_values):
        """Load item list"""
        for v in values:
            item = QStandardItem(str(v))
            if v in checked_values:
                item.setCheckState(Qt.Checked)
            else:
                item.setCheckState(Qt.Unchecked)
            item.setCheckable(True)
            self.m_sim.appendRow(item)

    def _check_all(self):
        """Check all item"""
        for index in range(self.m_sim.rowCount(
        )):  ## Iteration sur le model (contient la list des items)
            item = self.m_sim.item(index)
            if item.isCheckable() and item.checkState(
            ) == Qt.Unchecked:  # Si Unchecked
                item.setCheckState(Qt.Checked)

    def _check_nothing(self):
        """Uncheck all item"""
        for index in range(self.m_sim.rowCount(
        )):  ## Iteration sur le model (contient la list des items)
            item = self.m_sim.item(index)
            if item.isCheckable() and item.checkState(
            ) == Qt.Checked:  # Si Checked
                item.setCheckState(Qt.Unchecked)

    def _check_ok(self):
        """Get value of checked items and exit"""
        l_value = []
        for index in range(self.m_sim.rowCount(
        )):  ## Iteration sur le model (contient la list des items)
            item = self.m_sim.item(index)
            if item.isCheckable() and item.checkState(
            ) == Qt.Checked:  # Si Checked
                l_value.append(str(item.text()))

        if l_value:
            s_value = ";".join(l_value)
        else:
            s_value = ""

        self.result = s_value
        self.dial.close()

    def run(self):

        self.dial.setWindowTitle(self.tr("Select values"))

        self.dial.exec_()
        return self.result

    def tr(self, string, context=''):
        if context == '' or context == None:
            context = self.__class__.__name__
        return QCoreApplication.translate(context, string)
예제 #41
0
class MainWindow(QMainWindow):
        def __init__(self):
                QMainWindow.__init__(self)
                
                self.ui = Ui_MainWindow()
                self.ui.setupUi(self)

                self.setCentralWidget(self.ui.mangaTableView)
                self.newMangaDialog = NewMangaDialog()
                self.mangaDownloadDialog = MangaDownloadDialog()

                self.mangaTableModel = QStandardItemModel(0, 3, self)
                self.mangaTableModel.setHorizontalHeaderItem(0, QStandardItem(QString("Manga")))
                self.mangaTableModel.setHorizontalHeaderItem(1, QStandardItem(QString("Latest Chapter")))
                self.mangaTableModel.setHorizontalHeaderItem(2, QStandardItem(QString("Status")))
                self.ui.mangaTableView.setModel(self.mangaTableModel)

                newMangaAction = QAction(QIcon("./icon/add.ico"),'New Manga', self)
                newMangaAction.setShortcut('Ctrl+N')
                newMangaAction.triggered.connect(self.newMangaDialog.show)

                removeMangaAction = QAction(QIcon("./icon/delete.ico"),'Remove Manga', self)
                removeMangaAction.setShortcut('Delete')

                preferencesAction = QAction(QIcon("./icon/preferences.ico"),'Preferences', self)                

                aboutAction = QAction(QIcon("./icon/about.ico"),'About', self)

                self.ui.toolBar.addAction(newMangaAction)
                self.ui.toolBar.addAction(removeMangaAction)
                self.ui.toolBar.addSeparator()
                self.ui.toolBar.addAction(preferencesAction)
                self.ui.toolBar.addSeparator()
                self.ui.toolBar.addAction(aboutAction)

                self.progressBar = QProgressBar(self.ui.statusbar)
                self.ui.statusbar.addPermanentWidget(self.progressBar)
                self.progressBar.hide()

        def closeEvent(self, QCloseEvent):
                mangaList = []
                for i in range(self.mangaTableModel.rowCount()):
                        mangaList.append({
                                                "name" : str(self.mangaTableModel.item(i, 0).text()),
                                                "latestChapter" : str(self.mangaTableModel.item(i, 1).text()),
                                                "status" : "Updated",
                                                "link" : "/trial.html"
                                        })
                self.emit(SIGNAL("applicationClosed"),mangaList)

        def initializeProgressBar(self, size):
                self.progressBar.setRange(0, size)
                self.progressBar.setValue(0)
                self.progressBar.show()

        def updateProgressBar(self, value):
                self.progressBar.setValue(value)

        def updateStatusBar(self, msg):
                self.ui.statusbar.showMessage(msg)

        def updateMangaTable(self, chapter):
                isFound = False
                for i in range(self.mangaTableModel.rowCount()):
                        mangaItem = self.mangaTableModel.item(i)
                        if mangaItem.text() == chapter["name"]:
                                self.mangaTableModel.item(i, 1).setText(chapter["latestChapter"])
                                self.mangaTableModel.item(i, 2).setText(chapter["status"])
                                isFound = True
                                break

                if not isFound:
                        self.addRowToMangaTable(chapter)

        def addMangaListToMangaTable(self, mangaList):
                for i in range(len(mangaList)):
                        self.addRowToMangaTable(mangaList[i])

        def addRowToMangaTable(self, manga):
                i = self.mangaTableModel.rowCount()

                mangaItem = QStandardItem(QString(manga["name"]))
                latestChapterItem = QStandardItem(QString(manga["latestChapter"]))
                statusItem = QStandardItem(QString(manga["status"]))

                brush = QBrush(QColor(255, 255, 255)) if i%2==0 else QBrush(QColor(200, 200, 200))

                mangaItem.setBackground(brush)
                latestChapterItem.setBackground(brush)
                statusItem.setBackground(brush)

                self.mangaTableModel.setItem(i, 0, mangaItem)
                self.mangaTableModel.setItem(i, 1, latestChapterItem)
                self.mangaTableModel.setItem(i, 2, statusItem)
class CheckedListBox(QWidget):
    def __init__(self, parent):
        QWidget.__init__(self, parent)
        while not isinstance(parent, QDialog):
            parent = parent.parent()
        self.setObjectName("CheckedListBox" +
                           str(len(parent.findChildren(CheckedListBox))))

        self.setObjectName("checkBoxWidget")
        self.hLayout = QHBoxLayout(self)
        self.hLayout.setObjectName("hLayout")

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

        # self.frame = Frame()
        self.listView = QListView(self)
        self.hLayout.addWidget(self.listView)

        self.stdModel = QStandardItemModel()
        self.listView.setModel(self.stdModel)

        self.hasObject = False
        self.objList = []

        self.checkBoxList = []

        self.listView.pressed.connect(self.listView_clicked)

    def listView_clicked(self, index):
        self.emit(SIGNAL("ItemCheck"), self.stdModel.itemFromIndex(index))

    def mouseMoveEvent(self, mouseEvent):
        pt = mouseEvent.pos()
        pass

    def Clear(self):
        self.stdModel.clear()
        self.hasObject = False
        self.objList = []

    def Add(self, caption, isCheckedFlag=False):
        captionStr = ""
        if isinstance(caption, str) or isinstance(caption, QString):
            captionStr = caption
        else:
            captionStr = caption.ToString()
            self.hasObject = True
            self.objList.append([self.stdModel.rowCount(), caption])
        item = QStandardItem(captionStr)
        item.setCheckable(True)
        if isCheckedFlag:
            item.setCheckState(Qt.Checked)
        else:
            item.setCheckState(Qt.Unchecked)
        self.stdModel.setItem(self.stdModel.rowCount(), item)

        # checkBox = QCheckBox(self)
        # checkBox.setText(captionStr)
        # checkBox.setChecked(isCheckedFlag)
        # checkBox.clicked.connect(self.checkBox_clicked)
        # self.hLayout.addWidget(checkBox)

    def GetItemChecked(self, index):
        if self.stdModel.rowCount() > 0:
            item = self.stdModel.item(index)
            if item.checkState() == Qt.Unchecked:
                return False
            return True
        return False

    def get_CheckedItems(self):
        if not self.stdModel.rowCount() > 0:
            return []
        resultCheckedItems = []
        for i in range(self.stdModel.rowCount()):
            item = self.stdModel.item(i)
            if item.checkState() == Qt.Checked:
                flag = False
                if self.hasObject:
                    for obj in self.objList:
                        if obj[0] == i:
                            resultCheckedItems.append(obj)
                            flag = True
                            break
                if not flag:
                    resultCheckedItems.append(item)
        return resultCheckedItems

    CheckedItems = property(get_CheckedItems, None, None, None)

    def get_Items(self):
        if not self.stdModel.rowCount() > 0:
            return None
        resultItems = []
        for i in range(self.stdModel.rowCount()):
            item = self.stdModel.item(i)
            flag = False
            if self.hasObject:
                for obj in self.objList:
                    if obj[0] == i:
                        resultItems.append(obj)
                        flag = True
                        break
            if not flag:
                resultItems.append(item.text())
        return resultItems

    Items = property(get_Items, None, None, None)

    def get_Enabled(self):
        return self.isEnabled()

    def set_Enabled(self, bool):
        self.setEnabled(bool)

    Enabled = property(get_Enabled, set_Enabled, None, None)

    def get_Visible(self):
        return self.isVisible()

    def set_Visible(self, bool):
        self.setVisible(bool)

    Visible = property(get_Visible, set_Visible, None, None)
예제 #43
0
class Regression_PLOT_PyQt(QDialog):
    """
    This calss return a PyQt GUI with a regression plot
    """
    def __init__(self, Minerals=None, string=None, flag=None):
        super(Regression_PLOT_PyQt, self).__init__()
        if string is not None:
            self.stringK, self.stringG, self.stringRho, self.user_input = string
        else:
            self.stringK = None
            self.stringG = None
            self.stringRho = None
            self.user_input = False
        self.resize(1400, 600)
        self.Minerals = Minerals

        self.dirty = False
        #self.user_input = user_input

        self.Minerals.original_flag()
        self.Minerals.read_data()
        self.table = QTableView()
        self.model = QStandardItemModel(25, 7, self)
        self.model.setHorizontalHeaderLabels([
            'flag', 'Water Content', 'Iron Content', 'K (Gpa)', 'G (Gpa)',
            'Rho (g/cm³)', 'Reference'
        ])
        for i in range(len(self.Minerals.Flag)):
            a = self.Minerals.Return_original_data(i)
            for j in range(0, 7):
                item = QStandardItem(str(a[j]))
                self.model.setItem(i, j, item)
                if j != 0:
                    item.setFlags(Qt.ItemIsEnabled)
                    item.setBackground(QColor(211, 211, 211))

        if flag is not None:
            self.Minerals.change_flag(flag)
            for i in range(len(self.Minerals.Flag)):
                item = QStandardItem(str(self.Minerals.Flag[i]))
                self.model.setItem(i, 0, item)

        self.table.setModel(self.model)

        self.button = QPushButton('Update and use in thermoelastic model')
        self.button.clicked.connect(self.Update)
        self.button.setAutoDefault(False)
        self.button1 = QPushButton('Add data file ')
        self.button1.clicked.connect(self.Export)
        self.button1.setAutoDefault(False)
        self.layout = QGridLayout()

        self.label = QLabel()
        self.label.setText('''
        Please input equation, Water: water content (wt%) and Fe: iron content (mol%)
        for example -2.41*Water-30*Fe+81,K'=4.1,  
        ''')

        self.Kinput_formula = QLineEdit()
        self.Ginput_formula = QLineEdit()
        self.Rhoinput_formula = QLineEdit()
        if self.stringK is not None:
            self.Kinput_formula.setText(self.stringK)
            self.Ginput_formula.setText(self.stringG)
            self.Rhoinput_formula.setText(self.stringRho)
            self.Userinput()
        else:
            self.Kinput_formula.setText(
                self.Minerals.Show_fit_function(self.Minerals.function_K()[0],
                                                self.Minerals.function_K()[1],
                                                "K'",
                                                error=False))
            self.Ginput_formula.setText(
                self.Minerals.Show_fit_function(self.Minerals.function_G()[0],
                                                self.Minerals.function_G()[1],
                                                "G'",
                                                error=False))
            self.Rhoinput_formula.setText(
                self.Minerals.Show_fit_function(
                    self.Minerals.function_Rho()[0],
                    self.Minerals.function_Rho()[1],
                    '',
                    error=False))
        self.Kinput_formula.returnPressed.connect(self.Kformula)
        self.Ginput_formula.returnPressed.connect(self.Gformula)
        self.Rhoinput_formula.returnPressed.connect(self.Rhoformula)
        #self.connect(self.Kinput_formula,SIGNAL("returnPressed()"),self.Kformula)
        #self.connect(self.Ginput_formula,SIGNAL("returnPressed()"),self.Gformula)
        #self.connect(self.Rhoinput_formula,SIGNAL("returnPressed()"),self.Rhoformula)

        self.user_change_confrim = QPushButton('Change to user input')
        self.user_change_confrim.clicked.connect(self.Userinput)
        self.user_change_confrim.setAutoDefault(False)

        self.extension = QWidget()
        self.extensionLayout = QGridLayout()
        self.extensionLayout.setContentsMargins(0, 0, 0, 0)

        labelK = QLabel()
        labelK.setText('K<sub>0</sub>=')
        labelG = QLabel()
        labelG.setText('G<sub>0</sub>=')
        labelRho = QLabel()
        labelRho.setText('Rho<sub>0</sub>=')

        self.extensionLayout.addWidget(labelK, 0, 0, 1, 3)
        self.extensionLayout.addWidget(labelG, 1, 0, 1, 3)
        self.extensionLayout.addWidget(labelRho, 2, 0, 1, 3)
        self.extensionLayout.addWidget(self.Kinput_formula, 0, 1, 1, 3)
        self.extensionLayout.addWidget(self.Ginput_formula, 1, 1, 1, 3)
        self.extensionLayout.addWidget(self.Rhoinput_formula, 2, 1, 1, 3)
        self.extensionLayout.addWidget(self.user_change_confrim, 3, 0, 9, 4)

        self.extension.setLayout(self.extensionLayout)

        self.check_change = QCheckBox("user input")
        self.check_change.setChecked(False)
        self.check_change.toggled.connect(self.extension.setVisible)

        #self.PLOT(switch=True)
        self.PLOT()
        self.layout.addWidget(self.table, 0, 1, 1, 17)
        self.layout.addWidget(self.button, 2, 0, 1, 9)
        self.layout.addWidget(self.button1, 2, 9, 1, 9)
        self.layout.addWidget(self.check_change, 3, 0, 1, 1)
        self.layout.addWidget(self.label, 3, 3, 1, 5)
        self.layout.addWidget(self.extension, 4, 0, 1, 9)
        self.setLayout(self.layout)

        self.extension.hide()

    def Kformula(self):
        self.stringK = str(self.Kinput_formula.text())
        self.K0 = np.array(
            re.findall(r"[+-]? *(?:\d+(?:\.\d*)?|\.\d+)(?:[eE][+-]?\d+)?",
                       self.stringK))
        return self.K0, self.stringK

    def Gformula(self):
        self.stringG = str(self.Ginput_formula.text())
        self.G0 = np.array(
            re.findall(r"[+-]? *(?:\d+(?:\.\d*)?|\.\d+)(?:[eE][+-]?\d+)?",
                       self.stringG))
        return self.G0, self.stringG

    def Rhoformula(self):
        self.stringRho = str(self.Rhoinput_formula.text())
        self.Rho0 = np.array(
            re.findall(r"[+-]? *(?:\d+(?:\.\d*)?|\.\d+)(?:[eE][+-]?\d+)?",
                       self.stringRho))
        return self.Rho0, self.stringRho

    def Userinput(self):
        self.Minerals.User_Change(self.Kformula(), self.Gformula(),
                                  self.Rhoformula())
        self.user_input = True
        self.PLOT()

    def PLOT(self, switch=True):
        if self.dirty == False:
            #self.Minerals.Clean_content()
            params = []
            for i in range(20):
                index = self.model.index(i, 0)
                try:
                    aa = (float(self.model.itemData(index)[0]))
                    #print (aa)
                    params.append(aa)
                except:
                    break
            #print (params)
            self.Minerals.Change_data_from_table(params)
            #print ('wf')
        else:
            self.model.setHorizontalHeaderLabels([
                'flag', 'Water Content', 'Iron Content', 'K (Gpa)', 'G (Gpa)',
                'Rho (g/cm3)', 'Reference'
            ])
            for i in range(len(self.Minerals.Flag)):
                #a=self.Minerals.Return_original_data(i)
                item = QStandardItem(str(self.Minerals.Flag[i]))
                self.model.setItem(i, 0, item)


#==============================================================================
#                 for j in range(1,7):
#                     item = QStandardItem(str(a[j]))
#                     self.model.setItem(i, j,item)
#                     if j != 0:
#                         item.setFlags(Qt.ItemIsEnabled)
#                         item.setBackground(QColor(211,211,211))
#==============================================================================

#print (self.Minerals.Change)

        if self.user_input == False:
            self.a, self.b, self.c = self.Minerals.PLOT(return_fig=False)
            #print (self.Minerals.number_of_data)
            self.Kinput_formula.setText(
                self.Minerals.Show_fit_function(self.Minerals.function_K()[0],
                                                self.Minerals.function_K()[1],
                                                "K'",
                                                error=False))
            self.Ginput_formula.setText(
                self.Minerals.Show_fit_function(self.Minerals.function_G()[0],
                                                self.Minerals.function_G()[1],
                                                "G'",
                                                error=False))
            self.Rhoinput_formula.setText(
                self.Minerals.Show_fit_function(
                    self.Minerals.function_Rho()[0],
                    self.Minerals.function_Rho()[1],
                    '',
                    error=False))

        else:
            self.a, self.b, self.c = self.Minerals.PLOT_input_formula(
                return_fig=False)

        self.canvas1 = FigureCanvas3D(self.a)
        self.canvas2 = FigureCanvas3D(self.b)
        self.canvas3 = FigureCanvas3D(self.c)
        self.canvas1.mpl_connect('pick_event', self.onpick)
        self.canvas2.mpl_connect('pick_event', self.onpick)
        self.canvas3.mpl_connect('pick_event', self.onpick)

        self.toolbar1 = NavigationToolbar(self.canvas1, self)
        self.toolbar2 = NavigationToolbar(self.canvas2, self)
        self.toolbar3 = NavigationToolbar(self.canvas3, self)

        self.layout1_widget = QWidget()
        self.layout1 = QGridLayout(self.layout1_widget)
        self.layout1_widget.setFixedSize(600, 600)
        self.layout1.addWidget(self.canvas1, 0, 1, 5, 5)
        self.layout1.addWidget(self.toolbar1, 5, 1, 1, 5)
        self.layout1.addWidget(self.canvas2, 6, 1, 5, 5)
        self.layout1.addWidget(self.toolbar2, 11, 1, 1, 5)
        self.layout1.addWidget(self.canvas3, 12, 1, 5, 5)
        self.layout1.addWidget(self.toolbar3, 17, 1, 1, 5)
        self.layout.addWidget(self.layout1_widget, 0, 0, 1, 1)

    def onpick(self, event):
        try:
            for i in range(6):
                self.model.item(self.ind,
                                i + 1).setBackground(QColor(211, 211, 211))
        except:
            pass

        count = -1
        for j in range(len((self.Minerals.Flag))):
            if self.Minerals.Flag[j] == 1:
                count += 1
                if count == event.ind[0]:
                    self.ind = j
                    break
        #print (self.ind)
        #self.ind = event.ind
        for i in range(6):
            self.model.item(self.ind,
                            i + 1).setBackground(QColor(111, 111, 111))

    def Update(self):
        self.user_input = False
        self.dirty = False
        self.check_change.setChecked(False)
        self.PLOT()

    def Export(self):
        self.dirty = True
        dialog = TextEditor(name=self.Minerals.name)
        if dialog.exec_():
            pass
        self.Minerals.read_data()
        self.PLOT()

    def ReturnString(self):
        aa = self.Minerals.Flag
        bb = str(int(aa[0]))
        for i in range(1, len(aa)):
            bb += str(int(aa[i]))
        return [self.stringK, self.stringG, self.stringRho,
                self.user_input], bb
예제 #44
0
class OWConfusionMatrix(widget.OWWidget):
    """Confusion matrix widget"""

    name = "Confusion Matrix"
    description = "Display a confusion matrix constructed from " \
                  "the results of classifier evaluations."
    icon = "icons/ConfusionMatrix.svg"
    priority = 1001

    inputs = [("Evaluation Results", Orange.evaluation.Results, "set_results")]
    outputs = [("Selected Data", Orange.data.Table)]

    quantities = ["Number of instances",
                  "Proportion of predicted",
                  "Proportion of actual"]

    settingsHandler = settings.ClassValuesContextHandler()

    selected_learner = settings.Setting([0], schema_only=True)
    selection = settings.ContextSetting(set())
    selected_quantity = settings.Setting(0)
    append_predictions = settings.Setting(True)
    append_probabilities = settings.Setting(False)
    autocommit = settings.Setting(True)

    UserAdviceMessages = [
        widget.Message(
            "Clicking on cells or in headers outputs the corresponding "
            "data instances",
            "click_cell")]

    def __init__(self):
        super().__init__()

        self.data = None
        self.results = None
        self.learners = []
        self.headers = []

        box = gui.vBox(self.controlArea, "Learners")

        self.learners_box = gui.listBox(
            box, self, "selected_learner", "learners",
            callback=self._learner_changed
        )
        box = gui.vBox(self.controlArea, "Show")

        gui.comboBox(box, self, "selected_quantity", items=self.quantities,
                     callback=self._update)

        box = gui.vBox(self.controlArea, "Select")

        gui.button(box, self, "Select Correct",
                   callback=self.select_correct, autoDefault=False)
        gui.button(box, self, "Select Misclassified",
                   callback=self.select_wrong, autoDefault=False)
        gui.button(box, self, "Clear Selection",
                   callback=self.select_none, autoDefault=False)

        self.outputbox = box = gui.vBox(self.controlArea, "Output")
        gui.checkBox(box, self, "append_predictions",
                     "Predictions", callback=self._invalidate)
        gui.checkBox(box, self, "append_probabilities",
                     "Probabilities",
                     callback=self._invalidate)

        gui.auto_commit(self.controlArea, self, "autocommit",
                        "Send Selected", "Send Automatically")

        grid = QGridLayout()

        self.tablemodel = QStandardItemModel(self)
        view = self.tableview = QTableView(
            editTriggers=QTableView.NoEditTriggers)
        view.setModel(self.tablemodel)
        view.horizontalHeader().hide()
        view.verticalHeader().hide()
        view.horizontalHeader().setMinimumSectionSize(60)
        view.selectionModel().selectionChanged.connect(self._invalidate)
        view.setShowGrid(False)
        view.setItemDelegate(BorderedItemDelegate(Qt.white))
        view.clicked.connect(self.cell_clicked)
        grid.addWidget(view, 0, 0)
        self.mainArea.layout().addLayout(grid)

    def sizeHint(self):
        """Initial size"""
        return QSize(750, 490)

    def _item(self, i, j):
        return self.tablemodel.item(i, j) or QStandardItem()

    def _set_item(self, i, j, item):
        self.tablemodel.setItem(i, j, item)

    def _init_table(self, nclasses):
        item = self._item(0, 2)
        item.setData("Predicted", Qt.DisplayRole)
        item.setTextAlignment(Qt.AlignCenter)
        item.setFlags(Qt.NoItemFlags)

        self._set_item(0, 2, item)
        item = self._item(2, 0)
        item.setData("Actual", Qt.DisplayRole)
        item.setTextAlignment(Qt.AlignHCenter | Qt.AlignBottom)
        item.setFlags(Qt.NoItemFlags)
        self.tableview.setItemDelegateForColumn(0, gui.VerticalItemDelegate())
        self._set_item(2, 0, item)
        self.tableview.setSpan(0, 2, 1, nclasses)
        self.tableview.setSpan(2, 0, nclasses, 1)

        font = self.tablemodel.invisibleRootItem().font()
        bold_font = QFont(font)
        bold_font.setBold(True)

        for i in (0, 1):
            for j in (0, 1):
                item = self._item(i, j)
                item.setFlags(Qt.NoItemFlags)
                self._set_item(i, j, item)

        for p, label in enumerate(self.headers):
            for i, j in ((1, p + 2), (p + 2, 1)):
                item = self._item(i, j)
                item.setData(label, Qt.DisplayRole)
                item.setFont(bold_font)
                item.setTextAlignment(Qt.AlignRight | Qt.AlignVCenter)
                item.setFlags(Qt.ItemIsEnabled)
                if p < len(self.headers) - 1:
                    item.setData("br"[j == 1], BorderRole)
                    item.setData(QColor(192, 192, 192), BorderColorRole)
                self._set_item(i, j, item)

        hor_header = self.tableview.horizontalHeader()
        if len(' '.join(self.headers)) < 120:
            hor_header.setResizeMode(QHeaderView.ResizeToContents)
        else:
            hor_header.setDefaultSectionSize(60)
        self.tablemodel.setRowCount(nclasses + 3)
        self.tablemodel.setColumnCount(nclasses + 3)

    def set_results(self, results):
        """Set the input results."""

        prev_sel_learner = self.selected_learner.copy()
        self.clear()
        self.warning()
        self.closeContext()

        data = None
        if results is not None and results.data is not None:
            data = results.data

        if data is not None and not data.domain.has_discrete_class:
            self.warning("Confusion Matrix cannot show regression results.")

        self.results = results
        self.data = data

        if data is not None:
            class_values = data.domain.class_var.values
        elif results is not None:
            raise NotImplementedError

        if results is None:
            self.report_button.setDisabled(True)
        else:
            self.report_button.setDisabled(False)

            nmodels = results.predicted.shape[0]
            self.headers = class_values + \
                           [unicodedata.lookup("N-ARY SUMMATION")]

            # NOTE: The 'learner_names' is set in 'Test Learners' widget.
            if hasattr(results, "learner_names"):
                self.learners = results.learner_names
            else:
                self.learners = ["Learner #{}".format(i + 1)
                                 for i in range(nmodels)]

            self._init_table(len(class_values))
            self.openContext(data.domain.class_var)
            if not prev_sel_learner or prev_sel_learner[0] >= len(self.learners):
                self.selected_learner[:] = [0]
            else:
                self.selected_learner[:] = prev_sel_learner
            self._update()
            self._set_selection()
            self.unconditional_commit()

    def clear(self):
        """Reset the widget, clear controls"""
        self.results = None
        self.data = None
        self.tablemodel.clear()
        self.headers = []
        # Clear learners last. This action will invoke `_learner_changed`
        self.learners = []

    def select_correct(self):
        """Select the diagonal elements of the matrix"""
        selection = QItemSelection()
        n = self.tablemodel.rowCount()
        for i in range(2, n):
            index = self.tablemodel.index(i, i)
            selection.select(index, index)
        self.tableview.selectionModel().select(
            selection, QItemSelectionModel.ClearAndSelect)

    def select_wrong(self):
        """Select the off-diagonal elements of the matrix"""
        selection = QItemSelection()
        n = self.tablemodel.rowCount()
        for i in range(2, n):
            for j in range(i + 1, n):
                index = self.tablemodel.index(i, j)
                selection.select(index, index)
                index = self.tablemodel.index(j, i)
                selection.select(index, index)
        self.tableview.selectionModel().select(
            selection, QItemSelectionModel.ClearAndSelect)

    def select_none(self):
        """Reset selection"""
        self.tableview.selectionModel().clear()

    def cell_clicked(self, model_index):
        """Handle cell click event"""
        i, j = model_index.row(), model_index.column()
        if not i or not j:
            return
        n = self.tablemodel.rowCount()
        index = self.tablemodel.index
        selection = None
        if i == j == 1 or i == j == n - 1:
            selection = QItemSelection(index(2, 2), index(n - 1, n - 1))
        elif i in (1, n - 1):
            selection = QItemSelection(index(2, j), index(n - 1, j))
        elif j in (1, n - 1):
            selection = QItemSelection(index(i, 2), index(i, n - 1))

        if selection is not None:
            self.tableview.selectionModel().select(
                selection, QItemSelectionModel.ClearAndSelect)

    def commit(self):
        """Output data instances corresponding to selected cells"""
        if self.results is not None and self.data is not None \
                and self.selected_learner:
            indices = self.tableview.selectedIndexes()
            indices = {(ind.row() - 2, ind.column() - 2) for ind in indices}
            actual = self.results.actual
            learner_name = self.learners[self.selected_learner[0]]
            predicted = self.results.predicted[self.selected_learner[0]]
            selected = [i for i, t in enumerate(zip(actual, predicted))
                        if t in indices]
            row_indices = self.results.row_indices[selected]

            extra = []
            class_var = self.data.domain.class_var
            metas = self.data.domain.metas

            if self.append_predictions:
                predicted = numpy.array(predicted[selected], dtype=object)
                extra.append(predicted.reshape(-1, 1))
                var = Orange.data.DiscreteVariable(
                    "{}({})".format(class_var.name, learner_name),
                    class_var.values
                )
                metas = metas + (var,)

            if self.append_probabilities and \
                    self.results.probabilities is not None:
                probs = self.results.probabilities[self.selected_learner[0],
                                                   selected]
                extra.append(numpy.array(probs, dtype=object))
                pvars = [Orange.data.ContinuousVariable("p({})".format(value))
                         for value in class_var.values]
                metas = metas + tuple(pvars)

            X = self.data.X[row_indices]
            Y = self.data.Y[row_indices]
            M = self.data.metas[row_indices]
            row_ids = self.data.ids[row_indices]

            M = numpy.hstack((M,) + tuple(extra))
            domain = Orange.data.Domain(
                self.data.domain.attributes,
                self.data.domain.class_vars,
                metas
            )
            data = Orange.data.Table.from_numpy(domain, X, Y, M)
            data.ids = row_ids
            data.name = learner_name

        else:
            data = None

        self.send("Selected Data", data)

    def _invalidate(self):
        indices = self.tableview.selectedIndexes()
        self.selection = {(ind.row() - 2, ind.column() - 2) for ind in indices}
        self.commit()

    def _set_selection(self):
        selection = QItemSelection()
        index = self.tableview.model().index
        for row, col in self.selection:
            sel = index(row + 2, col + 2)
            selection.select(sel, sel)
        self.tableview.selectionModel().select(
            selection, QItemSelectionModel.ClearAndSelect)

    def _learner_changed(self):
        self._update()
        self._set_selection()
        self.commit()

    def _update(self):
        def _isinvalid(x):
            return isnan(x) or isinf(x)

        # Update the displayed confusion matrix
        if self.results is not None and self.selected_learner:
            cmatrix = confusion_matrix(self.results, self.selected_learner[0])
            colsum = cmatrix.sum(axis=0)
            rowsum = cmatrix.sum(axis=1)
            n = len(cmatrix)
            diag = numpy.diag_indices(n)

            colors = cmatrix.astype(numpy.double)
            colors[diag] = 0
            if self.selected_quantity == 0:
                normalized = cmatrix.astype(numpy.int)
                formatstr = "{}"
                div = numpy.array([colors.max()])
            else:
                if self.selected_quantity == 1:
                    normalized = 100 * cmatrix / colsum
                    div = colors.max(axis=0)
                else:
                    normalized = 100 * cmatrix / rowsum[:, numpy.newaxis]
                    div = colors.max(axis=1)[:, numpy.newaxis]
                formatstr = "{:2.1f} %"
            div[div == 0] = 1
            colors /= div
            colors[diag] = normalized[diag] / normalized[diag].max()

            for i in range(n):
                for j in range(n):
                    val = normalized[i, j]
                    col_val = colors[i, j]
                    item = self._item(i + 2, j + 2)
                    item.setData(
                        "NA" if _isinvalid(val) else formatstr.format(val),
                        Qt.DisplayRole)
                    bkcolor = QColor.fromHsl(
                        [0, 240][i == j], 160,
                        255 if _isinvalid(col_val) else int(255 - 30 * col_val))
                    item.setData(QBrush(bkcolor), Qt.BackgroundRole)
                    item.setData("trbl", BorderRole)
                    item.setToolTip("actual: {}\npredicted: {}".format(
                        self.headers[i], self.headers[j]))
                    item.setTextAlignment(Qt.AlignRight | Qt.AlignVCenter)
                    item.setFlags(Qt.ItemIsEnabled | Qt.ItemIsSelectable)
                    self._set_item(i + 2, j + 2, item)

            bold_font = self.tablemodel.invisibleRootItem().font()
            bold_font.setBold(True)

            def _sum_item(value, border=""):
                item = QStandardItem()
                item.setData(value, Qt.DisplayRole)
                item.setTextAlignment(Qt.AlignRight | Qt.AlignVCenter)
                item.setFlags(Qt.ItemIsEnabled)
                item.setFont(bold_font)
                item.setData(border, BorderRole)
                item.setData(QColor(192, 192, 192), BorderColorRole)
                return item

            for i in range(n):
                self._set_item(n + 2, i + 2, _sum_item(int(colsum[i]), "t"))
                self._set_item(i + 2, n + 2, _sum_item(int(rowsum[i]), "l"))
            self._set_item(n + 2, n + 2, _sum_item(int(rowsum.sum())))

    def send_report(self):
        """Send report"""
        if self.results is not None and self.selected_learner:
            self.report_table(
                "Confusion matrix for {} (showing {})".
                format(self.learners[self.selected_learner[0]],
                       self.quantities[self.selected_quantity].lower()),
                self.tableview)
예제 #45
0
class DlgSqlLayerWindow(QWidget, Ui_Dialog):
    nameChanged = pyqtSignal(str)

    def __init__(self, iface, layer, parent=None):
        QWidget.__init__(self, parent)
        self.iface = iface
        self.layer = layer

        uri = QgsDataSourceURI(layer.source())
        dbplugin = None
        db = None
        if layer.dataProvider().name() == 'postgres':
            dbplugin = createDbPlugin('postgis', 'postgres')
        elif layer.dataProvider().name() == 'spatialite':
            dbplugin = createDbPlugin('spatialite', 'spatialite')
        elif layer.dataProvider().name() == 'oracle':
            dbplugin = createDbPlugin('oracle', 'oracle')
        elif layer.dataProvider().name() == 'virtual':
            dbplugin = createDbPlugin('vlayers', 'virtual')
        elif layer.dataProvider().name() == 'ogr':
            dbplugin = createDbPlugin('gpkg', 'gpkg')
        if dbplugin:
            dbplugin.connectToUri(uri)
            db = dbplugin.db

        self.dbplugin = dbplugin
        self.db = db
        self.filter = ""
        self.allowMultiColumnPk = isinstance(db, PGDatabase) # at the moment only PostgreSQL allows a primary key to span multiple columns, spatialite doesn't
        self.aliasSubQuery = isinstance(db, PGDatabase) # only PostgreSQL requires subqueries to be aliases
        self.setupUi(self)
        self.setWindowTitle(
            u"%s - %s [%s]" % (self.windowTitle(), db.connection().connectionName(), db.connection().typeNameString()))

        self.defaultLayerName = 'QueryLayer'

        if self.allowMultiColumnPk:
            self.uniqueColumnCheck.setText(self.trUtf8("Column(s) with unique values"))
        else:
            self.uniqueColumnCheck.setText(self.trUtf8("Column with unique values"))

        self.editSql.setFocus()
        self.editSql.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded)
        self.editSql.setMarginVisible(True)
        self.initCompleter()

        # allow copying results
        copyAction = QAction("copy", self)
        self.viewResult.addAction(copyAction)
        copyAction.setShortcuts(QKeySequence.Copy)

        copyAction.triggered.connect(self.copySelectedResults)

        self.btnExecute.clicked.connect(self.executeSql)
        self.btnSetFilter.clicked.connect(self.setFilter)
        self.btnClear.clicked.connect(self.clearSql)

        self.presetStore.clicked.connect(self.storePreset)
        self.presetDelete.clicked.connect(self.deletePreset)
        self.presetCombo.activated[str].connect(self.loadPreset)
        self.presetCombo.activated[str].connect(self.presetName.setText)

        self.updatePresetsCombobox()

        self.geomCombo.setEditable(True)
        self.geomCombo.lineEdit().setReadOnly(True)

        self.uniqueCombo.setEditable(True)
        self.uniqueCombo.lineEdit().setReadOnly(True)
        self.uniqueModel = QStandardItemModel(self.uniqueCombo)
        self.uniqueCombo.setModel(self.uniqueModel)
        if self.allowMultiColumnPk:
            self.uniqueCombo.setItemDelegate(QStyledItemDelegate())
            self.uniqueModel.itemChanged.connect(self.uniqueChanged)                # react to the (un)checking of an item
            self.uniqueCombo.lineEdit().textChanged.connect(self.uniqueTextChanged) # there are other events that change the displayed text and some of them can not be caught directly

        self.layerTypeWidget.hide()  # show if load as raster is supported
        #self.loadLayerBtn.clicked.connect(self.loadSqlLayer)
        self.updateLayerBtn.clicked.connect(self.updateSqlLayer)
        self.getColumnsBtn.clicked.connect(self.fillColumnCombos)

        self.queryBuilderFirst = True
        self.queryBuilderBtn.setIcon(QIcon(":/db_manager/icons/sql.gif"))
        self.queryBuilderBtn.clicked.connect(self.displayQueryBuilder)

        self.presetName.textChanged.connect(self.nameChanged)

        # Update from layer
        # Fisrtly the SQL from QgsDataSourceURI table
        sql = uri.table()
        if uri.keyColumn() == '_uid_':
            match = re.search('^\(SELECT .+ AS _uid_,\* FROM \((.*)\) AS _subq_.+_\s*\)$', sql, re.S)
            if match:
                sql = match.group(1)
        else:
            match = re.search('^\((SELECT .+ FROM .+)\)$', sql, re.S)
            if match:
                sql = match.group(1)
        self.editSql.setText(sql)
        self.executeSql()

        # Then the columns
        self.geomCombo.setCurrentIndex(self.geomCombo.findText(uri.geometryColumn(), Qt.MatchExactly))
        if uri.keyColumn() != '_uid_':
            self.uniqueColumnCheck.setCheckState(Qt.Checked)
            if self.allowMultiColumnPk:
                itemsData = uri.keyColumn().split(',')
                for item in self.uniqueModel.findItems("*", Qt.MatchWildcard):
                    if item.data() in itemsData:
                        item.setCheckState(Qt.Checked)
            else:
                keyColumn = uri.keyColumn()
                if self.uniqueModel.findItems(keyColumn):
                    self.uniqueCombo.setEditText(keyColumn)

        # Finally layer name, filter and selectAtId
        self.layerNameEdit.setText(layer.name())
        self.filter = uri.sql()
        if uri.selectAtIdDisabled():
            self.avoidSelectById.setCheckState(Qt.Checked)

    def updatePresetsCombobox(self):
        self.presetCombo.clear()

        names = []
        entries = QgsProject.instance().subkeyList('DBManager', 'savedQueries')
        for entry in entries:
            name = QgsProject.instance().readEntry('DBManager', 'savedQueries/' + entry + '/name')[0]
            names.append(name)

        for name in sorted(names):
            self.presetCombo.addItem(name)
        self.presetCombo.setCurrentIndex(-1)

    def storePreset(self):
        query = self._getSqlQuery()
        if query == "":
            return
        name = self.presetName.text()
        QgsProject.instance().writeEntry('DBManager', 'savedQueries/q' + unicode(name.__hash__()) + '/name', name)
        QgsProject.instance().writeEntry('DBManager', 'savedQueries/q' + unicode(name.__hash__()) + '/query', query)
        index = self.presetCombo.findText(name)
        if index == -1:
            self.presetCombo.addItem(name)
            self.presetCombo.setCurrentIndex(self.presetCombo.count() - 1)
        else:
            self.presetCombo.setCurrentIndex(index)

    def deletePreset(self):
        name = self.presetCombo.currentText()
        QgsProject.instance().removeEntry('DBManager', 'savedQueries/q' + unicode(name.__hash__()))
        self.presetCombo.removeItem(self.presetCombo.findText(name))
        self.presetCombo.setCurrentIndex(-1)

    def loadPreset(self, name):
        query = QgsProject.instance().readEntry('DBManager', 'savedQueries/q' + unicode(name.__hash__()) + '/query')[0]
        name = QgsProject.instance().readEntry('DBManager', 'savedQueries/q' + unicode(name.__hash__()) + '/name')[0]
        self.editSql.setText(query)

    def clearSql(self):
        self.editSql.clear()
        self.editSql.setFocus()
        self.filter = ""

    def executeSql(self):

        sql = self._getSqlQuery()
        if sql == "":
            return

        QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))

        # delete the old model
        old_model = self.viewResult.model()
        self.viewResult.setModel(None)
        if old_model:
            old_model.deleteLater()

        cols = []
        quotedCols = []

        try:
            # set the new model
            model = self.db.sqlResultModel(sql, self)
            self.viewResult.setModel(model)
            self.lblResult.setText(self.tr("%d rows, %.1f seconds") % (model.affectedRows(), model.secs()))
            cols = self.viewResult.model().columnNames()
            for col in cols:
                quotedCols.append(self.db.connector.quoteId(col))

        except BaseError as e:
            QApplication.restoreOverrideCursor()
            DlgDbError.showError(e, self)
            self.uniqueModel.clear()
            self.geomCombo.clear()
            return

        self.setColumnCombos(cols, quotedCols)

        self.update()
        QApplication.restoreOverrideCursor()

    def _getSqlLayer(self, _filter):
        hasUniqueField = self.uniqueColumnCheck.checkState() == Qt.Checked
        if hasUniqueField:
            if self.allowMultiColumnPk:
                checkedCols = []
                for item in self.uniqueModel.findItems("*", Qt.MatchWildcard):
                    if item.checkState() == Qt.Checked:
                        checkedCols.append(item.data())
                uniqueFieldName = ",".join(checkedCols)
            elif self.uniqueCombo.currentIndex() >= 0:
                uniqueFieldName = self.uniqueModel.item(self.uniqueCombo.currentIndex()).data()
            else:
                uniqueFieldName = None
        else:
            uniqueFieldName = None
        hasGeomCol = self.hasGeometryCol.checkState() == Qt.Checked
        if hasGeomCol:
            geomFieldName = self.geomCombo.currentText()
        else:
            geomFieldName = None

        query = self._getSqlQuery()
        if query == "":
            return None

        # remove a trailing ';' from query if present
        if query.strip().endswith(';'):
            query = query.strip()[:-1]

        from qgis.core import QgsMapLayer, QgsMapLayerRegistry

        layerType = QgsMapLayer.VectorLayer if self.vectorRadio.isChecked() else QgsMapLayer.RasterLayer

        # get a new layer name
        names = []
        for layer in QgsMapLayerRegistry.instance().mapLayers().values():
            names.append(layer.name())

        layerName = self.layerNameEdit.text()
        if layerName == "":
            layerName = self.defaultLayerName
        newLayerName = layerName
        index = 1
        while newLayerName in names:
            index += 1
            newLayerName = u"%s_%d" % (layerName, index)

        # create the layer
        layer = self.db.toSqlLayer(query, geomFieldName, uniqueFieldName, newLayerName, layerType,
                                   self.avoidSelectById.isChecked(), _filter)
        if layer.isValid():
            return layer
        else:
            return None

    def loadSqlLayer(self):
        QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))
        try:
            layer = self._getSqlLayer(self.filter)
            if layer == None:
                return

            from qgis.core import QgsMapLayerRegistry
            QgsMapLayerRegistry.instance().addMapLayers([layer], True)
        finally:
            QApplication.restoreOverrideCursor()

    def updateSqlLayer(self):
        QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))
        try:
            layer = self._getSqlLayer(self.filter)
            if layer == None:
                return

            #self.layer.dataProvider().setDataSourceUri(layer.dataProvider().dataSourceUri())
            #self.layer.dataProvider().reloadData()
            XMLDocument = QDomDocument("style")
            XMLMapLayers = XMLDocument.createElement("maplayers")
            XMLMapLayer = XMLDocument.createElement("maplayer")
            self.layer.writeLayerXML(XMLMapLayer, XMLDocument)
            XMLMapLayer.firstChildElement("datasource").firstChild().setNodeValue(layer.source())
            XMLMapLayers.appendChild(XMLMapLayer)
            XMLDocument.appendChild(XMLMapLayers)
            self.layer.readLayerXML(XMLMapLayer)
            self.layer.reload()
            self.iface.actionDraw().trigger()
            self.iface.mapCanvas().refresh()
            self.iface.legendInterface().refreshLayerSymbology(layer)
        finally:
            QApplication.restoreOverrideCursor()

    def fillColumnCombos(self):
        query = self._getSqlQuery()
        if query == "":
            return

        QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))

        # remove a trailing ';' from query if present
        if query.strip().endswith(';'):
            query = query.strip()[:-1]

        # get all the columns
        cols = []
        quotedCols = []
        connector = self.db.connector
        if self.aliasSubQuery:
            # get a new alias
            aliasIndex = 0
            while True:
                alias = "_subQuery__%d" % aliasIndex
                escaped = re.compile('\\b("?)' + re.escape(alias) + '\\1\\b')
                if not escaped.search(query):
                    break
                aliasIndex += 1

            sql = u"SELECT * FROM (%s\n) AS %s LIMIT 0" % (unicode(query), connector.quoteId(alias))
        else:
            sql = u"SELECT * FROM (%s\n) WHERE 1=0" % unicode(query)

        c = None
        try:
            c = connector._execute(None, sql)
            cols = connector._get_cursor_columns(c)
            for col in cols:
                quotedCols.append(connector.quoteId(col))

        except BaseError as e:
            QApplication.restoreOverrideCursor()
            DlgDbError.showError(e, self)
            self.uniqueModel.clear()
            self.geomCombo.clear()
            return

        finally:
            if c:
                c.close()
                del c

        self.setColumnCombos(cols, quotedCols)

        QApplication.restoreOverrideCursor()

    def setColumnCombos(self, cols, quotedCols):
        # get sensible default columns. do this before sorting in case there's hints in the column order (eg, id is more likely to be first)
        try:
            defaultGeomCol = next(col for col in cols if col in ['geom', 'geometry', 'the_geom', 'way'])
        except:
            defaultGeomCol = None
        try:
            defaultUniqueCol = [col for col in cols if 'id' in col][0]
        except:
            defaultUniqueCol = None

        colNames = sorted(zip(cols, quotedCols))
        newItems = []
        uniqueIsFilled = False
        for (col, quotedCol) in colNames:
            item = QStandardItem(col)
            item.setData(quotedCol)
            item.setEnabled(True)
            item.setCheckable(self.allowMultiColumnPk)
            item.setSelectable(not self.allowMultiColumnPk)
            if self.allowMultiColumnPk:
                matchingItems = self.uniqueModel.findItems(col)
                if matchingItems:
                    item.setCheckState(matchingItems[0].checkState())
                    uniqueIsFilled = uniqueIsFilled or matchingItems[0].checkState() == Qt.Checked
                else:
                    item.setCheckState(Qt.Unchecked)
            newItems.append(item)
        if self.allowMultiColumnPk:
            self.uniqueModel.clear()
            self.uniqueModel.appendColumn(newItems)
            self.uniqueChanged()
        else:
            previousUniqueColumn = self.uniqueCombo.currentText()
            self.uniqueModel.clear()
            self.uniqueModel.appendColumn(newItems)
            if self.uniqueModel.findItems(previousUniqueColumn):
                self.uniqueCombo.setEditText(previousUniqueColumn)
                uniqueIsFilled = True

        oldGeometryColumn = self.geomCombo.currentText()
        self.geomCombo.clear()
        self.geomCombo.addItems(cols)
        self.geomCombo.setCurrentIndex(self.geomCombo.findText(oldGeometryColumn, Qt.MatchExactly))

        # set sensible default columns if the columns are not already set
        try:
            if self.geomCombo.currentIndex() == -1:
                self.geomCombo.setCurrentIndex(cols.index(defaultGeomCol))
        except:
            pass
        items = self.uniqueModel.findItems(defaultUniqueCol)
        if items and not uniqueIsFilled:
            if self.allowMultiColumnPk:
                items[0].setCheckState(Qt.Checked)
            else:
                self.uniqueCombo.setEditText(defaultUniqueCol)
        try:
            pass
        except:
            pass

    def copySelectedResults(self):
        if len(self.viewResult.selectedIndexes()) <= 0:
            return
        model = self.viewResult.model()

        # convert to string using tab as separator
        text = model.headerToString("\t")
        for idx in self.viewResult.selectionModel().selectedRows():
            text += "\n" + model.rowToString(idx.row(), "\t")

        QApplication.clipboard().setText(text, QClipboard.Selection)
        QApplication.clipboard().setText(text, QClipboard.Clipboard)

    def initCompleter(self):
        dictionary = None
        if self.db:
            dictionary = self.db.connector.getSqlDictionary()
        if not dictionary:
            # use the generic sql dictionary
            from .sql_dictionary import getSqlDictionary

            dictionary = getSqlDictionary()

        wordlist = []
        for name, value in dictionary.iteritems():
            wordlist += value  # concat lists
        wordlist = list(set(wordlist))  # remove duplicates

        api = QsciAPIs(self.editSql.lexer())
        for word in wordlist:
            api.add(word)

        api.prepare()
        self.editSql.lexer().setAPIs(api)

    def displayQueryBuilder(self):
        dlg = QueryBuilderDlg(self.iface, self.db, self, reset=self.queryBuilderFirst)
        self.queryBuilderFirst = False
        r = dlg.exec_()
        if r == QDialog.Accepted:
            self.editSql.setText(dlg.query)

    def _getSqlQuery(self):
        sql = self.editSql.selectedText()
        if len(sql) == 0:
            sql = self.editSql.text()
        return sql

    def uniqueChanged(self):
        # when an item is (un)checked, simply trigger an update of the combobox text
        self.uniqueTextChanged(None)

    def uniqueTextChanged(self, text):
        # Whenever there is new text displayed in the combobox, check if it is the correct one and if not, display the correct one.
        checkedItems = []
        for item in self.uniqueModel.findItems("*", Qt.MatchWildcard):
            if item.checkState() == Qt.Checked:
                checkedItems.append(item.text())
        label = ", ".join(checkedItems)
        if text != label:
            self.uniqueCombo.setEditText(label)

    def setFilter(self):
        from qgis.gui import QgsQueryBuilder
        layer = self._getSqlLayer("")
        if not layer:
            return

        dlg = QgsQueryBuilder(layer)
        dlg.setSql(self.filter)
        if dlg.exec_():
            self.filter = dlg.sql()
        layer.deleteLater()
class ConnectionsDialog(QtGui.QDialog, Ui_DlgConnections):

    on_connect = pyqtSignal(str, str)
    on_add = pyqtSignal(str, list)
    on_connection_change = pyqtSignal()
    on_zoom_change = pyqtSignal()

    _connections_array = "connections"
    _table_headers = OrderedDict([("ID", "id"), ("Min. Zoom", "minzoom"),
                                  ("Max. Zoom", "maxzoom"),
                                  ("Description", "description")])

    _OMT = "OpenMapTiles.com"

    _predefined_connections = {
        _OMT: "https://free.tilehosting.com/data/v3.json?key={token}"
    }
    _tokens = {_OMT: "6irhAXGgsi8TrIDL0211"}

    def __init__(self, default_browse_directory):
        QtGui.QDialog.__init__(self)
        self.setupUi(self)
        self.options = OptionsGroup(self.grpOptions, self._on_zoom_change)
        self.settings = QSettings("VtrSettings")
        self.connections = {}
        self.selected_connection = None
        self.selected_layer_id = None
        self.cbxConnections.currentIndexChanged['QString'].connect(
            self._handle_connection_change)
        self.btnCreateConnection.clicked.connect(self._create_connection)
        self.btnConnect.clicked.connect(self._handle_connect)
        self.btnEdit.clicked.connect(self._edit_connection)
        self.btnDelete.clicked.connect(self._delete_connection)
        self.btnAdd.clicked.connect(self._load_tiles_for_connection)
        self.btnSave.clicked.connect(self._export_connections)
        self.btnLoad.clicked.connect(self._import_connections)
        self.btnHelp.clicked.connect(lambda: webbrowser.open(_HELP_URL))
        self.btnBrowse.clicked.connect(self._select_file_path)
        self.btnBrowseTrexCache.clicked.connect(self._select_trex_cache_folder)
        self.open_path = None
        self.browse_path = default_browse_directory
        self.model = QStandardItemModel()
        self.model.setHorizontalHeaderLabels(self._table_headers.keys())
        self.tblLayers.setModel(self.model)
        self._load_connections()
        self._add_loaded_connections()
        self.edit_connection_dialog = EditConnectionDialog()
        _update_size(self)

    def _select_file_path(self):
        open_file_name = QFileDialog.getOpenFileName(
            None, "Select Mapbox Tiles", self.browse_path,
            "Mapbox Tiles (*.mbtiles)")
        if open_file_name and os.path.isfile(open_file_name):
            self.txtPath.setText(open_file_name)
            self._handle_path_or_folder_selection(open_file_name)

    def _select_trex_cache_folder(self):
        open_file_name = QFileDialog.getExistingDirectory(
            None, "Select t-rex Cache directory", self.browse_path)
        if open_file_name and os.path.isdir(open_file_name):
            self.txtTrexCachePath.setText(open_file_name)
            self._handle_path_or_folder_selection(open_file_name)

    def _handle_path_or_folder_selection(self, path):
        self.browse_path = path
        self.open_path = path
        name = os.path.basename(path)
        self.on_connect.emit(name, path)

    def _on_zoom_change(self):
        self.on_zoom_change.emit()

    def set_nr_of_tiles(self, nr_tiles):
        self.options.set_nr_of_tiles(nr_tiles)

    def _load_tiles_for_connection(self):
        indexes = self.tblLayers.selectionModel().selectedRows()
        selected_layers = map(lambda i: self.model.item(i.row()).text(),
                              indexes)
        name, url = self._get_current_connection()
        self.on_add.emit(url, selected_layers)

    def _export_connections(self):
        file_name = QFileDialog.getSaveFileName(
            None, "Export Vector Tile Reader Connections", "", "csv (*.csv)")
        if file_name:
            with open(file_name, 'w') as csvfile:
                fieldnames = ['name', 'url']
                writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
                writer.writeheader()
                for name in self.connections:
                    writer.writerow({
                        'name': name,
                        'url': self.connections[name]
                    })

    def _import_connections(self):
        file_name = QFileDialog.getOpenFileName(
            None, "Export Vector Tile Reader Connections", "", "csv (*.csv)")
        if file_name:
            with open(file_name, 'r') as csvfile:
                reader = csv.DictReader(csvfile)
                for row in reader:
                    self._set_connection_url(row['name'], row['url'])
            self._add_loaded_connections()

    def _load_connections(self):
        settings = self.settings
        connections = settings.beginReadArray(self._connections_array)
        for i in range(connections):
            settings.setArrayIndex(i)
            name = settings.value("name")
            url = settings.value("url")
            self._set_connection_url(name, url)
        settings.endArray()

    def _add_loaded_connections(self):
        for index, name in enumerate(self._predefined_connections.keys()):
            url = self._predefined_connections[name]
            self._set_connection_url(name, url)

        for name in sorted(self.connections):
            is_already_added = self.cbxConnections.findText(name) != -1
            if not is_already_added:
                self.cbxConnections.addItem(name)
        if len(self.connections) > 0:
            self.cbxConnections.setCurrentIndex(0)

    def _delete_connection(self):
        index = self.cbxConnections.currentIndex()
        connection = self.cbxConnections.currentText()
        msg = "Are you sure you want to remove the connection '{}' and all associated settings?".format(
            connection)
        reply = QMessageBox.question(self.activateWindow(), 'Confirm Delete',
                                     msg, QMessageBox.Yes, QMessageBox.No)
        if reply == QtGui.QMessageBox.Yes:
            self.cbxConnections.removeItem(index)
            self.connections.pop(connection)
            self._save_connections()

    def _save_connections(self):
        settings = self.settings
        settings.beginWriteArray(self._connections_array)
        for index, key in enumerate(self.connections):
            settings.setArrayIndex(index)
            settings.setValue("name", key)
            settings.setValue("url", self.connections[key])
        settings.endArray()

    def _set_connection_url(self, name, url):
        self.connections[name] = url

    def _handle_connect(self):
        conn = self._get_current_connection()
        name = conn[0]
        url = conn[1]
        self.on_connect.emit(name, url)
        self.txtPath.setText("")

    def _get_current_connection(self):
        if self.tabServer.isEnabled():
            name = self.cbxConnections.currentText()
            url = self.connections[name]
        elif self.tabFile.isEnabled():
            url = self.txtPath.text()
            name = os.path.basename(url)
        else:
            url = self.txtTrexCachePath.text()
            name = os.path.basename(url)
        if name in self._predefined_connections:
            url = url.replace("{token}", self._tokens[name])
        return name, url

    def show(self):
        self.exec_()

    def keep_dialog_open(self):
        return self.chkKeepOpen.isChecked()

    def set_layers(self, layers):
        self.model.removeRows(0, self.model.rowCount())
        for row_index, layer in enumerate(layers):
            for header_index, header in enumerate(self._table_headers.keys()):
                header_value = self._table_headers[header]
                if header_value in layer:
                    value = str(layer[header_value])
                else:
                    value = "-"
                self.model.setItem(row_index, header_index,
                                   QStandardItem(value))
        add_enabled = layers is not None and len(layers) > 0
        self.btnAdd.setEnabled(add_enabled)

    def _edit_connection(self):
        conn = self._get_current_connection()
        self._create_or_update_connection(name=conn[0], url=conn[1])

    def _create_connection(self):
        self._create_or_update_connection("", "")

    def _create_or_update_connection(self, name=None, url=None):
        self.edit_connection_dialog.set_name_and_path(name, url)
        result = self.edit_connection_dialog.exec_()
        if result == QtGui.QDialog.Accepted:
            newname, newurl = self.edit_connection_dialog.get_connection()
            self._set_connection_url(newname, newurl)
            if newname != name:
                self.cbxConnections.addItem(newname)
                self.cbxConnections.setCurrentIndex(len(self.connections) - 1)
            self._save_connections()

    def _handle_connection_change(self, name):
        self.set_layers([])
        enable_connect = False
        enable_edit = False
        if name in self.connections:
            enable_connect = True
            enable_edit = name not in self._predefined_connections
        self.btnConnect.setEnabled(enable_connect)
        self.btnEdit.setEnabled(enable_edit)
        self.btnDelete.setEnabled(enable_edit)
        self.on_connection_change.emit()
예제 #47
0
class OrderSelectorModel(QObject):
    """"""

    #----------------------------------------------------------------------
    def __init__(self, full_string_list, init_selected_string_list=None,
                 permanently_selected_string_list=None):
        """Constructor"""

        QObject.__init__(self)

        self.output = []

        if not self.hasNoDuplicateStrings(full_string_list):
            raise ValueError('Duplicate strings detected in full string list.')
        else:
            self.full_string_list = full_string_list[:]

        if init_selected_string_list is not None:
            if not self.allStringsInList1FoundInList2(
                init_selected_string_list, self.full_string_list):
                raise ValueError('Some of the strings in initially selected string list are not in full string list.')
        else:
            init_selected_string_list = []

        if permanently_selected_string_list is not None:
            if not self.allStringsInList1FoundInList2(
                permanently_selected_string_list, init_selected_string_list):
                raise ValueError('Some of the strings in permanently selected string list are not in initially selected string list.')
        else:
            permanently_selected_string_list = []

        self.permanently_selected_string_list = permanently_selected_string_list[:]

        self.model_Selected = QStandardItemModel()
        self.model_NotSelected = QStandardItemModel()

        Selected_item_list = [None for s in init_selected_string_list]
        NotSelected_item_list = []
        for s in self.full_string_list:
            item = QStandardItem(s)
            try:
                Selected_item_list[init_selected_string_list.index(s)] = item
            except:
                NotSelected_item_list.append(item)

        for item in NotSelected_item_list: self.model_NotSelected.appendRow(item)
        for item in Selected_item_list: self.model_Selected.appendRow(item)

    #----------------------------------------------------------------------
    def getSelectedList(self):
        """"""

        selectedList = []
        for i in range(self.model_Selected.rowCount()):
            selectedList.append(self.model_Selected.item(i,0).text())

        return selectedList


    #----------------------------------------------------------------------
    def hasNoDuplicateStrings(self, full_string_list):
        """"""

        str_list = full_string_list
        str_set = set(full_string_list)

        if len(str_list) == len(str_set):
            return True
        else:
            return False

    #----------------------------------------------------------------------
    def allStringsInList1FoundInList2(self, str_list_1, str_list_2):
        """"""

        stringsNotFound = [ s for s in str_list_1
                            if s not in str_list_2 ]

        if stringsNotFound != []:
            return False
        else:
            return True
예제 #48
0
class GroupPhotoWindow(QMainWindow, Ui_main_win):
    def __init__(self):
        QMainWindow.__init__(self)
        self.setupUi(self)

        self.image_model = QStandardItemModel()
        self.image_list.setModel(self.image_model)

        QObject.connect(self.add_btn, QtCore.SIGNAL('clicked()'),
                        self.on_add_image)
        QObject.connect(self.delete_btn, QtCore.SIGNAL('clicked()'),
                        self.on_remove_image)
        QObject.connect(
            self.image_list.selectionModel(),
            QtCore.SIGNAL(
                'currentChanged (const QModelIndex &, const QModelIndex &)'),
            self.on_row_changed)
        QObject.connect(self.harris_btn, QtCore.SIGNAL('clicked()'),
                        self.on_harris_detect)
        QObject.connect(self.stitch_btn, QtCore.SIGNAL('clicked()'),
                        self.on_stitch)

    def on_add_image(self):
        image_path = QFileDialog.getOpenFileName(
            self, 'Select image', filter='Images (*.png *.jpg *.bmp)')
        ignored, name = os.path.split(unicode(image_path))
        self.image_model.appendRow(
            [QStandardItem(name),
             QStandardItem(image_path)])

    def on_remove_image(self):
        row = self.image_list.selectionModel().currentIndex().row()
        if row == -1:
            return
        self.image_model.removeRows(row, 1)

    def on_row_changed(self, current, previous):
        row = current.row()
        if row == -1:
            file_path = PLACE_HOLDER
        else:
            file_path = self.image_model.item(row, 1).text()
        self.set_pixmap(QPixmap(file_path))

    def on_harris_detect(self):
        row = self.image_list.selectionModel().currentIndex().row()
        if row == -1:
            return
        file_path = self.image_model.item(row, 1).text()

        image_pfm = convert_to_pfm(imread(unicode(file_path)))
        image = image_to_gray(image_pfm)
        kernel = self.ksize_slider.value()
        cornerness = harris_corner(image, ksize=kernel)
        is_corner = cornerness > 0.000001
        suppress = non_max_suppression(cornerness, ksize=kernel)
        result = np.array(is_corner * suppress)
        zero = np.zeros_like(result)
        gray_img = np.dstack((zero, zero, draw_cross(result)))

        self.set_pixmap(
            QPixmap.fromImage(
                image_from_ndarray(np.array(gray_img + image_pfm))))

    def on_stitch(self):
        i = 0
        images = []
        while self.image_model.item(i):
            file_path = self.image_model.item(i, 1).text()
            image = image_to_gray(convert_to_pfm(imread(unicode(file_path))))
            images.append(image)
            i += 1
        stitch(self.ksize_slider.value(), images)

    def set_pixmap(self, pixmap):
        self.image_label.setPixmap(
            pixmap.scaled(self.image_label.size(), QtCore.Qt.KeepAspectRatio))
예제 #49
0
class InputDialog(GenericDialog):

    TBL_HEADER_LABEL=["Input Mesh", "Output group name"]

    def __init__(self, parent=None, name="InputDialog", modal=0):
        """
        This initializes a dialog windows to define the input data of
        the plugin function. The input data consist in a list of
        meshes characterizes each by a name, a pointer to the smesh
        servant object, a type and a group name (see data model in the
        inputdata.py).
        """
        GenericDialog.__init__(self, parent, name, modal)
        # Set up the user interface from Designer.
        self.__ui = Ui_InputFrame()
        # BE CAREFULL HERE, the ui form is NOT drawn in the global
        # dialog (already containing some generic widgets) but in the
        # center panel created in the GenericDialog as a void
        # container for the form. The InputFrame form is supposed
        # here to create only the widgets to be placed in the center
        # panel. Then, the setupUi function of this form draws itself
        # in the specified panel, i.e. the panel returned by
        # self.getPanel().
        self.__ui.setupUi(self.getPanel())

        self.setWindowTitle("Specification of input files")

        # The icon are supposed to be located in the plugin folder,
        # i.e. in the same folder than this python module file
        iconfolder=os.path.dirname(os.path.abspath(__file__))
        icon = QIcon()
        icon.addFile(os.path.join(iconfolder,"select.png"))
        self.__ui.btnSmeshObject.setIcon(icon)
        icon = QIcon()
        icon.addFile(os.path.join(iconfolder,"addinput.png"))
        self.__ui.btnAddInput.setIcon(icon)
        icon = QIcon()
        icon.addFile(os.path.join(iconfolder,"deleteinput.png"))
        self.__ui.btnDeleteInput.setIcon(icon)

        # We specify here the items in the combo box (even if already
        # defined in the designer) so that we can be sure of the item
        # indexation.
        self.MESHTYPE_ICONS = {}
        meshTypeIndex = InputData.MESHTYPES.CONCRETE
        self.__ui.cmbMeshType.setItemText(meshTypeIndex, "Béton")
        icon = QIcon()
        icon.addFile(os.path.join(iconfolder,"concrete.png"))
        self.__ui.cmbMeshType.setItemIcon(meshTypeIndex, icon)
        self.MESHTYPE_ICONS[meshTypeIndex] = icon

        meshTypeIndex = InputData.MESHTYPES.STEELBAR
        self.__ui.cmbMeshType.setItemText(meshTypeIndex, "Acier")
        icon = QIcon()
        icon.addFile(os.path.join(iconfolder,"steelbar.png"))
        self.__ui.cmbMeshType.setItemIcon(meshTypeIndex, icon)
        self.MESHTYPE_ICONS[meshTypeIndex] = icon
        
        # The click on btnSmeshObject (signal clicked() emitted by the
        # button btnSmeshObject) is connected to the slot
        # onSelectSmeshObject, etc ...
        self.connect(self.__ui.btnSmeshObject, SIGNAL('clicked()'), self.onSelectSmeshObject )
        self.connect(self.__ui.btnAddInput,    SIGNAL('clicked()'), self.onAddInput )
        self.connect(self.__ui.btnDeleteInput, SIGNAL('clicked()'), self.onDeleteInput )

        # Set up the model of the Qt table list
        self.__inputModel = QStandardItemModel(0,2)
        self.__inputModel.setHorizontalHeaderLabels(InputDialog.TBL_HEADER_LABEL)
        self.__ui.tblListInput.setModel(self.__inputModel)
        self.__ui.tblListInput.verticalHeader().hide()
        self.__ui.tblListInput.horizontalHeader().setStretchLastSection(True)
        # Note that the type is not display explicitly in the Qt table
        # because it is specified using an icon on the text of the
        # name item. 

        # Note that PADDER does not support group name longer than 8
        # characters. We apply then this limit in the gui field.
        self.__ui.txtGroupName.setMaxLength(GROUPNAME_MAXLENGTH)

        self.clear()

        self.smeshStudyTool = SMeshStudyTools()

    def clear(self):
        """
        This function clears the data gui area and associated values.
        """
        self.__ui.txtSmeshObject.setText("")
        self.__ui.txtGroupName.setText("")
        self.__inputModel.clear()
        self.__inputModel.setHorizontalHeaderLabels(InputDialog.TBL_HEADER_LABEL)
        if not DEBUG_MODE:
            self.__ui.txtSmeshObject.setEnabled(False)
            self.__ui.btnAddInput.setEnabled(False)
        self.__selectedMesh = None
        self.__dictInputData = {}
        self.__nbConcreteMesh = 0
        self.__nbSteelbarMesh = 0

    def accept(self):
        """
        This function is the slot connected to the button OK
        """
        # The dialog is raised in a non modal mode to get
        # interactivity with the parents windows. Then we have to emit
        # a signal to warn the parent observer that the dialog has
        # been validated so that it can process the event
        GenericDialog.accept(self)
        if self.wasOk():
            self.emit(SIGNAL('inputValidated()'))

    def onSelectSmeshObject(self):
        '''
        This function is the slot connected on the mesh selection
        button. It memorizes the selected mesh and put its name in the
        text field of the dialog box.
        '''
        mySObject, myEntry = guihelper.getSObjectSelected()
        if CORBA.is_nil(mySObject):
            self.__ui.txtSmeshObject.setText("You must choose a mesh")
            self.__ui.txtGroupName.setText("")
            self.__ui.txtSmeshObject.setEnabled(False)
            self.__ui.btnAddInput.setEnabled(False)
            self.__selectedMesh = None
            return

        self.smeshStudyTool.updateStudy(studyedit.getActiveStudyId())
        self.__selectedMesh = self.smeshStudyTool.getMeshObjectFromSObject(mySObject)
        if CORBA.is_nil(self.__selectedMesh):
            self.__ui.txtSmeshObject.setText("The selected object is not a mesh")
            self.__ui.txtGroupName.setText("")
            self.__ui.txtSmeshObject.setEnabled(False)
            self.__ui.btnAddInput.setEnabled(False)
            self.__selectedMesh = None
            return
        myName = mySObject.GetName()
        self.__ui.txtSmeshObject.setText(myName)
        self.__ui.txtSmeshObject.setEnabled(True)
        self.__ui.btnAddInput.setEnabled(True)

        # We can suggest a default group name from the mesh name
        self.__ui.txtGroupName.setText(myName)

    def onAddInput(self):
        """
        This function is the slot connected to the Add button. It
        creates a new entry in the list of input data, or updates this
        entry if it already exists.
        """
        meshName   = str(self.__ui.txtSmeshObject.text().trimmed())
        meshObject = self.__selectedMesh
        meshType   = self.__ui.cmbMeshType.currentIndex()
        groupName  = str(self.__ui.txtGroupName.text().trimmed())

        self.__addInputInGui(meshName, meshObject, meshType, groupName)
        self.__addInputInMap(meshName, meshObject, meshType, groupName)

    def __addInputInGui(self, meshName, meshObject, meshType, groupName):
        """
        This function adds an entry with the specified data int the
        GUI table (for data visualization purpose).
        """
        # The mesh name is used as the key index in the model. We have
        # to check first if this item already exists in the list.
        tblItems = self.__inputModel.findItems(meshName)
        row = self.__inputModel.rowCount()
        if not tblItems:
            tblItems = []
            tblItems.append(QStandardItem()) # input mesh name
            tblItems.append(QStandardItem()) # output group name
        else:
            row = tblItems[0].index().row()
            tblItems.append(self.__inputModel.item(row,1))

        tblItems[0].setText(meshName)
        tblItems[0].setIcon(self.MESHTYPE_ICONS[meshType])
        tblItems[1].setText(groupName)
        self.__inputModel.setItem(row,0,tblItems[0])
        self.__inputModel.setItem(row,1,tblItems[1])
        self.__ui.tblListInput.setCurrentIndex(tblItems[0].index())

    def __addInputInMap(self, meshName, meshObject, meshType, groupName):
        """
        This function adds an entry with the specified data in the
        internal map (for data management purpose).
        """
        # if the entry already exists, we remove it to replace by a
        # new one
        if self.__dictInputData.has_key(meshName):
            self.__delInputFromMap(meshName)
        
        inputData = InputData()
        inputData.meshName   = meshName
        inputData.meshObject = meshObject
        inputData.meshType   = meshType
        inputData.groupName  = groupName
        # The key of the map is the mesh name
        self.__dictInputData[meshName] = inputData
        if inputData.meshType == InputData.MESHTYPES.CONCRETE:
            self.__nbConcreteMesh += 1
        else:
            self.__nbSteelbarMesh += 1

        print inputData
        print "meshType = ",inputData.meshType
        print "nb concrete mesh ",self.__nbConcreteMesh
        print "nb steelbar mesh ",self.__nbSteelbarMesh
            

    def onDeleteInput(self):
        """
        This function is the slot connected to the Delete button. It
        remove from the data list the entry selected in the Qt table.
        """
        selectedIdx = self.__ui.tblListInput.selectedIndexes()
        if selectedIdx:
            row  = selectedIdx[0].row()
            tblItem  = self.__inputModel.item(row,0)
            meshName = str(tblItem.text())
            self.__inputModel.takeRow(row)
            # Don't forget to remove this entry from the mesh object
            # internal dictionnary
            self.__delInputFromMap(meshName)

    def __delInputFromMap(self, meshName):
        """
        This function removes the specified entry from the internal
        map (for data management purpose) 
        """
        inputData = self.__dictInputData.pop(meshName)
        if inputData.meshType == InputData.MESHTYPES.CONCRETE:
            self.__nbConcreteMesh -= 1
        else:
            self.__nbSteelbarMesh -= 1

        print inputData
        print "nb concrete mesh ",self.__nbConcreteMesh
        print "nb steelbar mesh ",self.__nbSteelbarMesh


    def setData(self, listInputData=[]):
        """
        This function fills the dialog widgets with values provided by
        the specified data list.
        """
        self.clear()
        for inputData in listInputData:

            meshName   = inputData.meshName
            meshObject = inputData.meshObject
            meshType   = inputData.meshType
            groupName  = inputData.groupName
            
            self.__addInputInGui(meshName, meshObject, meshType, groupName)
            self.__addInputInMap(meshName, meshObject, meshType, groupName)

            if not DEBUG_MODE:
                self.onSelectSmeshObject()

    def getData(self):
        """
        This function returns a list of InputData that corresponds to
        the data in the dialog widgets of the current dialog.
        """
        # Note that the values() function returns a copy of the list
        # of values.
        return self.__dictInputData.values()
        
    def checkData(self):
        """
        This function checks if the data are valid, from the dialog
        window point of view.
        """
        if self.__nbConcreteMesh == 0 and self.__nbSteelbarMesh == 0:
            self.checkDataMessage = "You must define at least one mesh (CONCRETE or STEELBAR)"
            return False        
        if self.__nbConcreteMesh > 1:
            self.checkDataMessage  = "You define multiple CONCRETE meshes."
            self.checkDataMessage += "You should verify first that your version of PADDER support this configuration."
            # just warn the user, but don't block
            QMessageBox.information(self, "Info", self.checkDataMessage)
            return True

        return True
예제 #50
0
class AbstractSTREnityListView(QListView):
    """
    A widget for listing and selecting one or more STR entities.
    .. versionadded:: 1.7
    """
    def __init__(self, parent=None, **kwargs):
        super(AbstractSTREnityListView, self).__init__(parent)

        self._model = QStandardItemModel(self)
        self._model.setColumnCount(1)
        self.setModel(self._model)
        self.setEditTriggers(QAbstractItemView.NoEditTriggers)
        self._model.itemChanged.connect(self._on_item_changed)

        self._profile = kwargs.get('profile', None)
        self._social_tenure = kwargs.get('social_tenure', None)

        # Load appropriate entities to the view
        if not self._profile is None:
            self._load_profile_entities()

        # Load entities in the STR definition
        if not self._social_tenure is None:
            self._select_str_entities()

    def _on_item_changed(self, item):
        # Emit signals when an item has been (de)selected. To be
        # implemented by subclasses.
        pass

    @property
    def profile(self):
        """
        :return: Returns the current profile object in the configuration.
        :rtype: Profile
        """
        return self._profile

    @profile.setter
    def profile(self, profile):
        """
        Sets the current profile object in the configuration.
        :param profile: Profile object.
        :type profile: Profile
        """
        self._profile = profile
        self._load_profile_entities()

    @property
    def social_tenure(self):
        """
        :return: Returns the profile's social tenure entity.
        :rtype: SocialTenure
        """
        return self._social_tenure

    @social_tenure.setter
    def social_tenure(self, social_tenure):
        """
        Set the social_tenure entity.
        :param social_tenure: A profile's social tenure entity.
        :type social_tenure: SocialTenure
        """
        self._social_tenure = social_tenure
        self._select_str_entities()

    def _select_str_entities(self):
        """
        Select the entities defined in the STR. E.g. parties for party 
        entity and spatial units for spatial unit entity. Default 
        implementation does nothing, to be implemented by subclasses.
        """
        pass

    def _load_profile_entities(self):
        # Reset view
        self.clear()

        # Populate entity items in the view
        for e in self._profile.user_entities():
            self._add_entity(e)

    def _add_entity(self, entity):
        # Add entity item to view
        item = QStandardItem(
            QIcon(':/plugins/stdm/images/icons/table.png'),
            entity.short_name
        )
        item.setCheckable(True)
        item.setCheckState(Qt.Unchecked)

        self._model.appendRow(item)

    def select_entities(self, entities):
        """
        Checks STR entities in the view and emit the entity_selected
        signal for each item selected.
        :param entities: Collection of STR entities.
        :type entities: list
        """
        # Clear selection
        self.clear_selection()

        for e in entities:
            name = e.short_name
            self.select_entity(name)

    def selected_entities(self):
        """
        :return: Returns a list of selected entity short names.
        :rtype: list
        """
        selected_items = []

        for i in range(self._model.rowCount()):
            item = self._model.item(i)
            if item.checkState() == Qt.Checked:
                selected_items.append(item.text())

        return selected_items

    def clear(self):
        """
        Remove all party items in the view.
        """
        self._model.clear()
        self._model.setColumnCount(1)

    def clear_selection(self):
        """
        Uncheck all items in the view.
        """
        for i in range(self._model.rowCount()):
            item = self._model.item(i)
            if item.checkState() == Qt.Checked:
                item.setCheckState(Qt.Unchecked)

    def select_entity(self, name):
        """
        Selects a party entity with the given short name.
        :param name: Entity short name
        :type name: str
        """
        items = self._model.findItems(name)
        if len(items) > 0:
            item = items[0]
            if item.checkState() == Qt.Unchecked:
                item.setCheckState(Qt.Checked)

    def deselect_entity(self, name):
        """
        Deselects an entity with the given short name.
        :param name: Entity short name
        :type name: str
        """
        items = self._model.findItems(name)
        if len(items) > 0:
            item = items[0]
            if item.checkState() == Qt.Checked:
                item.setCheckState(Qt.Unchecked)
예제 #51
0
class Formation(QMainWindow, Ui_Formation):
    """
    Class documentation goes here.
    """
    #signal
    fermeture_reouverture = pyqtSignal()
    maj = pyqtSignal()

    def __init__(self, engine, gui_parent, parent=None):
        """
        Constructor
        
        @param parent reference to the parent widget (QWidget)
        """
        super().__init__(parent)
        self.setupUi(self)

        self.setWindowTitle("Enregistrement d'une formation")

        self.engine = engine
        self.dateEdit.setDate(pendulum.now('Europe/Paris'))
        self.cmr_bdd = Bdd_Cmr(self.engine)

        gen_cmr = self.cmr_bdd.recup_cmr_en_activite()

        self.remplir_tableau_cmr(next(gen_cmr))

        #        self.threadpool = QThreadPool()

        self.gui_parent = gui_parent

        ####Threads
        self.thread_finish = False
        #        self.affectation_lancement_threads()

        init_domaine = Insertion_Domaine(self.engine)
        areas = init_domaine.recuperation_domaine()
        #        print(areas)

        self.model = QStandardItemModel((len(areas) + 1), 1)  # 5 rows, 1 col

        firstItem = QStandardItem("---- Select domaine(s) ----")
        firstItem.setBackground(QBrush(QColor(200, 200, 200)))
        firstItem.setSelectable(False)
        self.model.setItem(0, 0, firstItem)

        for i, area in enumerate(areas):
            item = QStandardItem(area)
            item.setFlags(Qt.ItemIsUserCheckable | Qt.ItemIsEnabled)
            item.setData(Qt.Unchecked, Qt.CheckStateRole)
            self.model.setItem(i + 1, 0, item)

        self.comboBox_domaine.setModel(self.model)

        self.gui_parent.formation_a_modifier.connect(
            self.reaffectation_formation)


#
#    def affectation_lancement_threads(self):
#        """"met en place les threads et les lance"""

#        bdd_thread = Gestion_BDD_Thread(self.cmr_bdd )
#        bdd_thread.signals.signalData_dispo.connect(self.remplir_tableau_cmr)
#        self.threadpool.start(bdd_thread)
###        bdd_thread.run()
#
#        self.thread_combobox = Gestion_Combobox_domaine_Thread(self.engine)
#        self.thread_combobox.signals.signalmodel_dispo.connect(self.affectation_model_combobox_domaine)
##        self.thread_combobox.finished.connect(self.danslemille)
#        self.threadpool.start(self.thread_combobox)
#
#        print(self.thread_combobox)
##        self.thread_combobox.run()
#
#    @pyqtSlot(QStandardItemModel)
#    def affectation_model_combobox_domaine(self, model):
#        """permet de recevoir le model créé et affecte au combobox dans le thread specifique"""
#        print("jy suis")
#        mutex = QMutex()
#        mutex.lock()
#        self.model = model
#        self.comboBox_domaine.setModel(self.model)
#
#        self.thread_finish = True
#        mutex.unlock()
#        print(self.thread_finish)

    @pyqtSlot(list)
    def remplir_tableau_cmr(self, gen_list_cmr):

        self.tableWidget.setRowCount(0)
        for cmr in reversed(gen_list_cmr):
            #            print(cmr)
            self.tableWidget.insertRow(0)

            item_nom = QTableWidgetItem(cmr.NOM)
            item_prenom = QTableWidgetItem(cmr.PRENOM)

            self.tableWidget.setItem(0, 0, item_nom)
            self.tableWidget.setItem(0, 1, item_prenom)

            self.tableWidget.setCellWidget(0, 2, QComboBox())
            self.tableWidget.cellWidget(0, 2).addItems(
                ["*", "Acquise", "À améliorer", "Non acquise"])

            self.tableWidget.setCellWidget(0, 3, QComboBox())
            self.tableWidget.cellWidget(0, 3).addItems(
                [str(x) for x in range(21)])

            self.tableWidget.setCellWidget(0, 4, QTextEdit())
            self.tableWidget.setCellWidget(0, 5, QCheckBox())

    @pyqtSlot()
    def on_pushButton_enregistrer_clicked(self):
        """
        Slot documentation goes here.
        """

        nom_formation = self.lineEdit_nom_formation.text()
        if nom_formation:
            date = self.dateEdit.date().toString("dd-MM-yyyy")
            type_formation = self.comboBox_type_formation.currentText()
            #            domaine = self.comboBox_domaine.currentText()
            domaine = []
            for ligne in range(self.model.rowCount()):
                if self.model.item(ligne, 0).checkState() == Qt.Checked:
                    domaine.append(self.model.item(ligne, 0).text())

            plan = self.textEdit_plan_formation.toPlainText()

            nbr_ligne = self.tableWidget.rowCount()
            sauvegarde_dico = []
            for ligne in range(nbr_ligne):
                if self.tableWidget.cellWidget(ligne, 5).isChecked():
                    nom = self.tableWidget.item(ligne, 0).text()
                    prenom = self.tableWidget.item(ligne, 1).text()
                    gen_id = self.cmr_bdd.recup_id_cmr(nom, prenom)
                    try:
                        resultat = self.tableWidget.cellWidget(
                            ligne, 2).currentText()
                    except:
                        resultat = None
                    try:
                        note = self.tableWidget.cellWidget(ligne,
                                                           3).currentText()
                    except:
                        note = None
                    try:
                        remarque = self.tableWidget.item(ligne, 4).text()
                    except:
                        remarque = None

                    dico = {
                        "nom": nom,
                        "prenom": prenom,
                        "id": gen_id,
                        "resultat": resultat,
                        "note": note,
                        "remarque": remarque
                    }
                    #                    print(dico)
                    sauvegarde_dico.append(json.dumps(dico))

            sauvegarde = {
                "nom_formation": nom_formation,
                "date": date,
                "type_formation": type_formation,
                "domaine": domaine,
                "plan": plan,
                "participants": sauvegarde_dico
            }

            #            print(sauvegarde)

            if self.windowTitle() == "Enregistrement d'une formation":
                self.cmr_bdd.insertion_formation(sauvegarde)
                self.close()
                self.fermeture_reouverture.emit()
            else:  #on est dans une modification
                self.cmr_bdd.modif_formation(self.id_formation_a_modif,
                                             sauvegarde)
                self.close()
                self.maj.emit()

    @pyqtSlot(object)
    def reaffectation_formation(self, formation):
        """fct qui reaffecte les donnees recues par le signal"""

        self.setWindowTitle("Modification d'une formation")
        #        print(formation)

        self.id_formation_a_modif = formation.ID
        #        print(formation.ID)

        self.lineEdit_nom_formation.setText(formation.NOM_FORMATION)
        self.dateEdit.setDate(formation.DATE_FORMATION)

        index = self.comboBox_type_formation.findText(formation.TYPE_FORMATION,
                                                      Qt.MatchExactly)
        if index:
            self.comboBox_type_formation.setCurrentIndex(index)

        #gestion des domaines :
        for domaine in formation.DOMAINE:
            for ligne in range(self.model.rowCount()):
                #                print(f"ligne {ligne}")
                if self.model.item(ligne, 0).text() == domaine:
                    self.model.item(ligne, 0).setData(Qt.Checked,
                                                      Qt.CheckStateRole)

        self.textEdit_plan_formation.setText(formation.PLAN)

        for participant in formation.LIST_PARTICIPANTS:
            nom = json.loads(participant)["nom"]
            prenom = json.loads(participant)["prenom"]
            #            id = json.loads(participant)["id"]
            resultat = json.loads(participant)["resultat"]
            note = json.loads(participant)["note"]
            remarque = json.loads(participant)["remarque"]

            for ligne in range(self.tableWidget.rowCount()):

                if self.tableWidget.item(
                        ligne, 0).text() == nom and self.tableWidget.item(
                            ligne, 1).text() == prenom:

                    index = self.tableWidget.cellWidget(ligne, 2).findText(
                        resultat, Qt.MatchExactly)
                    if index != -1:
                        self.tableWidget.cellWidget(ligne,
                                                    2).setCurrentIndex(index)

                    index = self.tableWidget.cellWidget(ligne, 3).findText(
                        note, Qt.MatchExactly)
                    if index != -1:
                        self.tableWidget.cellWidget(ligne,
                                                    3).setCurrentIndex(index)

                    self.tableWidget.cellWidget(ligne, 4).setText(remarque)

                    self.tableWidget.cellWidget(ligne, 5).setChecked(True)
예제 #52
0
파일: qt.py 프로젝트: AutumnLight/orange
class QtWidgetRegistry(QObject, WidgetRegistry):
    """
    A QObject wrapper for `WidgetRegistry`

    A QStandardItemModel instance containing the widgets in
    a tree (of depth 2). The items in a model can be quaries using standard
    roles (DisplayRole, BackgroundRole, DecorationRole ToolTipRole).
    They also have QtWidgetRegistry.CATEGORY_DESC_ROLE,
    QtWidgetRegistry.WIDGET_DESC_ROLE, which store Category/WidgetDescription
    respectfully. Furthermore QtWidgetRegistry.WIDGET_ACTION_ROLE stores an
    default QAction which can be used for widget creation action.

    """

    CATEGORY_DESC_ROLE = Qt.UserRole + 1
    """Category Description Role"""

    WIDGET_DESC_ROLE = Qt.UserRole + 2
    """Widget Description Role"""

    WIDGET_ACTION_ROLE = Qt.UserRole + 3
    """Widget Action Role"""

    BACKGROUND_ROLE = Qt.UserRole + 4
    """Background color for widget/category in the canvas
    (different from Qt.BackgroundRole)
    """

    category_added = Signal(str, CategoryDescription)
    """signal: category_added(name: str, desc: CategoryDescription)
    """

    widget_added = Signal(str, str, WidgetDescription)
    """signal widget_added(category_name: str, widget_name: str,
                           desc: WidgetDescription)
    """

    reset = Signal()
    """signal: reset()
    """

    def __init__(self, other_or_parent=None, parent=None):
        if isinstance(other_or_parent, QObject) and parent is None:
            parent, other_or_parent = other_or_parent, None
        QObject.__init__(self, parent)
        WidgetRegistry.__init__(self, other_or_parent)

        # Should  the QStandardItemModel be subclassed?
        self.__item_model = QStandardItemModel(self)

        for i, desc in enumerate(self.categories()):
            cat_item = self._cat_desc_to_std_item(desc)
            self.__item_model.insertRow(i, cat_item)

            for j, wdesc in enumerate(self.widgets(desc.name)):
                widget_item = self._widget_desc_to_std_item(wdesc, desc)
                cat_item.insertRow(j, widget_item)

    def model(self):
        """
        Return the widget descriptions in a Qt Item Model instance
        (QStandardItemModel).

        .. note:: The model should not be modified outside of the registry.

        """
        return self.__item_model

    def item_for_widget(self, widget):
        """Return the QStandardItem for the widget.
        """
        if isinstance(widget, basestring):
            widget = self.widget(widget)
        cat = self.category(widget.category)
        cat_ind = self.categories().index(cat)
        cat_item = self.model().item(cat_ind)
        widget_ind = self.widgets(cat).index(widget)
        return cat_item.child(widget_ind)

    def action_for_widget(self, widget):
        """
        Return the QAction instance for the widget (can be a string or
        a WidgetDescription instance).

        """
        item = self.item_for_widget(widget)
        return item.data(self.WIDGET_ACTION_ROLE).toPyObject()

    def create_action_for_item(self, item):
        """
        Create a QAction instance for the widget description item.
        """
        name = item.text()
        tooltip = item.toolTip()
        whatsThis = item.whatsThis()
        icon = item.icon()
        if icon:
            action = QAction(icon, name, self, toolTip=tooltip,
                             whatsThis=whatsThis,
                             statusTip=name)
        else:
            action = QAction(name, self, toolTip=tooltip,
                             whatsThis=whatsThis,
                             statusTip=name)

        widget_desc = item.data(self.WIDGET_DESC_ROLE)
        action.setData(widget_desc)
        action.setProperty("item", QVariant(item))
        return action

    def _insert_category(self, desc):
        """
        Override to update the item model and emit the signals.
        """
        priority = desc.priority
        priorities = [c.priority for c, _ in self.registry]
        insertion_i = bisect.bisect_right(priorities, priority)

        WidgetRegistry._insert_category(self, desc)

        cat_item = self._cat_desc_to_std_item(desc)
        self.__item_model.insertRow(insertion_i, cat_item)

        self.category_added.emit(desc.name, desc)

    def _insert_widget(self, category, desc):
        """
        Override to update the item model and emit the signals.
        """
        assert(isinstance(category, CategoryDescription))
        categories = self.categories()
        cat_i = categories.index(category)
        _, widgets = self._categories_dict[category.name]
        priorities = [w.priority for w in widgets]
        insertion_i = bisect.bisect_right(priorities, desc.priority)

        WidgetRegistry._insert_widget(self, category, desc)

        cat_item = self.__item_model.item(cat_i)
        widget_item = self._widget_desc_to_std_item(desc, category)

        cat_item.insertRow(insertion_i, widget_item)

        self.widget_added.emit(category.name, desc.name, desc)

    def _cat_desc_to_std_item(self, desc):
        """
        Create a QStandardItem for the category description.
        """
        item = QStandardItem()
        item.setText(desc.name)

        if desc.icon:
            icon = desc.icon
        else:
            icon = "icons/default-category.svg"

        icon = icon_loader.from_description(desc).get(icon)
        item.setIcon(icon)

        if desc.background:
            background = desc.background
        else:
            background = DEFAULT_COLOR

        background = NAMED_COLORS.get(background, background)

        brush = QBrush(QColor(background))
        item.setData(brush, self.BACKGROUND_ROLE)

        tooltip = desc.description if desc.description else desc.name

        item.setToolTip(tooltip)
        item.setFlags(Qt.ItemIsEnabled)
        item.setData(QVariant(desc), self.CATEGORY_DESC_ROLE)
        return item

    def _widget_desc_to_std_item(self, desc, category):
        """
        Create a QStandardItem for the widget description.
        """
        item = QStandardItem(desc.name)
        item.setText(desc.name)

        if desc.icon:
            icon = desc.icon
        else:
            icon = "icons/default-widget.svg"

        icon = icon_loader.from_description(desc).get(icon)
        item.setIcon(icon)

        # This should be inherited from the category.
        background = None
        if desc.background:
            background = desc.background
        elif category.background:
            background = category.background
        else:
            background = DEFAULT_COLOR

        if background is not None:
            background = NAMED_COLORS.get(background, background)
            brush = QBrush(QColor(background))
            item.setData(brush, self.BACKGROUND_ROLE)

        tooltip = tooltip_helper(desc)
        style = "ul { margin-top: 1px; margin-bottom: 1px; }"
        tooltip = TOOLTIP_TEMPLATE.format(style=style, tooltip=tooltip)
        item.setToolTip(tooltip)
        item.setWhatsThis(whats_this_helper(desc))
        item.setFlags(Qt.ItemIsEnabled | Qt.ItemIsSelectable)
        item.setData(QVariant(desc), self.WIDGET_DESC_ROLE)

        # Create the action for the widget_item
        action = self.create_action_for_item(item)
        item.setData(QVariant(action), self.WIDGET_ACTION_ROLE)
        return item
예제 #53
0
class DlgSqlWindow(QWidget, Ui_Dialog):
    nameChanged = pyqtSignal(str)

    def __init__(self, iface, db, parent=None):
        QWidget.__init__(self, parent)
        self.iface = iface
        self.db = db
        self.allowMultiColumnPk = isinstance(
            db, PGDatabase
        )  # at the moment only PostGIS allows a primary key to span multiple columns, spatialite doesn't
        self.setupUi(self)
        self.setWindowTitle(
            u"%s - %s [%s]" %
            (self.windowTitle(), db.connection().connectionName(),
             db.connection().typeNameString()))

        self.defaultLayerName = 'QueryLayer'

        if self.allowMultiColumnPk:
            self.uniqueColumnCheck.setText(
                self.trUtf8("Column(s) with unique values"))
        else:
            self.uniqueColumnCheck.setText(
                self.trUtf8("Column with unique values"))

        self.editSql.setFocus()
        self.editSql.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded)
        self.initCompleter()

        # allow to copy results
        copyAction = QAction("copy", self)
        self.viewResult.addAction(copyAction)
        copyAction.setShortcuts(QKeySequence.Copy)

        copyAction.triggered.connect(self.copySelectedResults)

        self.btnExecute.clicked.connect(self.executeSql)
        self.btnClear.clicked.connect(self.clearSql)

        self.presetStore.clicked.connect(self.storePreset)
        self.presetDelete.clicked.connect(self.deletePreset)
        self.presetCombo.activated[str].connect(self.loadPreset)
        self.presetCombo.activated[str].connect(self.presetName.setText)

        self.updatePresetsCombobox()

        self.geomCombo.setEditable(True)
        self.geomCombo.lineEdit().setReadOnly(True)

        self.uniqueCombo.setEditable(True)
        self.uniqueCombo.lineEdit().setReadOnly(True)
        self.uniqueModel = QStandardItemModel(self.uniqueCombo)
        self.uniqueCombo.setModel(self.uniqueModel)
        if self.allowMultiColumnPk:
            self.uniqueCombo.setItemDelegate(QStyledItemDelegate())
            self.uniqueModel.itemChanged.connect(
                self.uniqueChanged)  # react to the (un)checking of an item
            self.uniqueCombo.lineEdit().textChanged.connect(
                self.uniqueTextChanged
            )  # there are other events that change the displayed text and some of them can not be caught directly

        # hide the load query as layer if feature is not supported
        self._loadAsLayerAvailable = self.db.connector.hasCustomQuerySupport()
        self.loadAsLayerGroup.setVisible(self._loadAsLayerAvailable)
        if self._loadAsLayerAvailable:
            self.layerTypeWidget.hide()  # show if load as raster is supported
            self.loadLayerBtn.clicked.connect(self.loadSqlLayer)
            self.getColumnsBtn.clicked.connect(self.fillColumnCombos)
            self.loadAsLayerGroup.toggled.connect(self.loadAsLayerToggled)
            self.loadAsLayerToggled(False)

        self._createViewAvailable = self.db.connector.hasCreateSpatialViewSupport(
        )
        self.btnCreateView.setVisible(self._createViewAvailable)
        if self._createViewAvailable:
            self.btnCreateView.clicked.connect(self.createView)

        self.queryBuilderFirst = True
        self.queryBuilderBtn.setIcon(QIcon(":/db_manager/icons/sql.gif"))
        self.queryBuilderBtn.clicked.connect(self.displayQueryBuilder)

        self.presetName.textChanged.connect(self.nameChanged)

    def updatePresetsCombobox(self):
        self.presetCombo.clear()

        names = []
        entries = QgsProject.instance().subkeyList('DBManager', 'savedQueries')
        for entry in entries:
            name = QgsProject.instance().readEntry(
                'DBManager', 'savedQueries/' + entry + '/name')[0]
            names.append(name)

        for name in sorted(names):
            self.presetCombo.addItem(name)
        self.presetCombo.setCurrentIndex(-1)

    def storePreset(self):
        query = self._getSqlQuery()
        if query == "":
            return
        name = self.presetName.text()
        QgsProject.instance().writeEntry(
            'DBManager', 'savedQueries/q' + unicode(name.__hash__()) + '/name',
            name)
        QgsProject.instance().writeEntry(
            'DBManager',
            'savedQueries/q' + unicode(name.__hash__()) + '/query', query)
        index = self.presetCombo.findText(name)
        if index == -1:
            self.presetCombo.addItem(name)
            self.presetCombo.setCurrentIndex(self.presetCombo.count() - 1)
        else:
            self.presetCombo.setCurrentIndex(index)

    def deletePreset(self):
        name = self.presetCombo.currentText()
        QgsProject.instance().removeEntry(
            'DBManager', 'savedQueries/q' + unicode(name.__hash__()))
        self.presetCombo.removeItem(self.presetCombo.findText(name))
        self.presetCombo.setCurrentIndex(-1)

    def loadPreset(self, name):
        query = QgsProject.instance().readEntry(
            'DBManager',
            'savedQueries/q' + unicode(name.__hash__()) + '/query')[0]
        name = QgsProject.instance().readEntry(
            'DBManager',
            'savedQueries/q' + unicode(name.__hash__()) + '/name')[0]
        self.editSql.setText(query)

    def loadAsLayerToggled(self, checked):
        self.loadAsLayerGroup.setChecked(checked)
        self.loadAsLayerWidget.setVisible(checked)
        if checked:
            self.fillColumnCombos()

    def clearSql(self):
        self.editSql.clear()
        self.editSql.setFocus()

    def executeSql(self):

        sql = self._getSqlQuery()
        if sql == "":
            return

        QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))

        # delete the old model
        old_model = self.viewResult.model()
        self.viewResult.setModel(None)
        if old_model:
            old_model.deleteLater()

        cols = []
        quotedCols = []

        try:
            # set the new model
            model = self.db.sqlResultModel(sql, self)
            self.viewResult.setModel(model)
            self.lblResult.setText(
                self.tr("%d rows, %.1f seconds") %
                (model.affectedRows(), model.secs()))
            cols = self.viewResult.model().columnNames()
            for col in cols:
                quotedCols.append(self.db.connector.quoteId(col))

        except BaseError as e:
            QApplication.restoreOverrideCursor()
            DlgDbError.showError(e, self)
            self.uniqueModel.clear()
            self.geomCombo.clear()
            return

        self.setColumnCombos(cols, quotedCols)

        self.update()
        QApplication.restoreOverrideCursor()

    def loadSqlLayer(self):
        hasUniqueField = self.uniqueColumnCheck.checkState() == Qt.Checked
        if hasUniqueField:
            if self.allowMultiColumnPk:
                checkedCols = []
                for item in self.uniqueModel.findItems("*", Qt.MatchWildcard):
                    if item.checkState() == Qt.Checked:
                        checkedCols.append(item.data())
                uniqueFieldName = ",".join(checkedCols)
            elif self.uniqueCombo.currentIndex() >= 0:
                uniqueFieldName = self.uniqueModel.item(
                    self.uniqueCombo.currentIndex()).data()
            else:
                uniqueFieldName = None
        else:
            uniqueFieldName = None
        hasGeomCol = self.hasGeometryCol.checkState() == Qt.Checked
        if hasGeomCol:
            geomFieldName = self.geomCombo.currentText()
        else:
            geomFieldName = None

        query = self._getSqlQuery()
        if query == "":
            return

        # remove a trailing ';' from query if present
        if query.strip().endswith(';'):
            query = query.strip()[:-1]

        QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))

        from qgis.core import QgsMapLayer, QgsMapLayerRegistry

        layerType = QgsMapLayer.VectorLayer if self.vectorRadio.isChecked(
        ) else QgsMapLayer.RasterLayer

        # get a new layer name
        names = []
        for layer in QgsMapLayerRegistry.instance().mapLayers().values():
            names.append(layer.name())

        layerName = self.layerNameEdit.text()
        if layerName == "":
            layerName = self.defaultLayerName
        newLayerName = layerName
        index = 1
        while newLayerName in names:
            index += 1
            newLayerName = u"%s_%d" % (layerName, index)

        # create the layer
        layer = self.db.toSqlLayer(query, geomFieldName, uniqueFieldName,
                                   newLayerName, layerType,
                                   self.avoidSelectById.isChecked())
        if layer.isValid():
            QgsMapLayerRegistry.instance().addMapLayers([layer], True)

        QApplication.restoreOverrideCursor()

    def fillColumnCombos(self):
        query = self._getSqlQuery()
        if query == "":
            return

        QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))

        # get a new alias
        aliasIndex = 0
        while True:
            alias = "_%s__%d" % ("subQuery", aliasIndex)
            escaped = re.compile('\\b("?)' + re.escape(alias) + '\\1\\b')
            if not escaped.search(query):
                break
            aliasIndex += 1

        # remove a trailing ';' from query if present
        if query.strip().endswith(';'):
            query = query.strip()[:-1]

        # get all the columns
        cols = []
        quotedCols = []
        connector = self.db.connector
        sql = u"SELECT * FROM (%s\n) AS %s LIMIT 0" % (
            unicode(query), connector.quoteId(alias))

        c = None
        try:
            c = connector._execute(None, sql)
            cols = connector._get_cursor_columns(c)
            for col in cols:
                quotedCols.append(connector.quoteId(col))

        except BaseError as e:
            QApplication.restoreOverrideCursor()
            DlgDbError.showError(e, self)
            self.uniqueModel.clear()
            self.geomCombo.clear()
            return

        finally:
            if c:
                c.close()
                del c

        self.setColumnCombos(cols, quotedCols)

        QApplication.restoreOverrideCursor()

    def setColumnCombos(self, cols, quotedCols):
        # get sensible default columns. do this before sorting in case there's hints in the column order (eg, id is more likely to be first)
        try:
            defaultGeomCol = next(
                col for col in cols
                if col in ['geom', 'geometry', 'the_geom', 'way'])
        except:
            defaultGeomCol = None
        try:
            defaultUniqueCol = [col for col in cols if 'id' in col][0]
        except:
            defaultUniqueCol = None

        colNames = sorted(zip(cols, quotedCols))
        newItems = []
        uniqueIsFilled = False
        for (col, quotedCol) in colNames:
            item = QStandardItem(col)
            item.setData(quotedCol)
            item.setEnabled(True)
            item.setCheckable(self.allowMultiColumnPk)
            item.setSelectable(not self.allowMultiColumnPk)
            if self.allowMultiColumnPk:
                matchingItems = self.uniqueModel.findItems(col)
                if matchingItems:
                    item.setCheckState(matchingItems[0].checkState())
                    uniqueIsFilled = uniqueIsFilled or matchingItems[
                        0].checkState() == Qt.Checked
                else:
                    item.setCheckState(Qt.Unchecked)
            newItems.append(item)
        if self.allowMultiColumnPk:
            self.uniqueModel.clear()
            self.uniqueModel.appendColumn(newItems)
            self.uniqueChanged()
        else:
            previousUniqueColumn = self.uniqueCombo.currentText()
            self.uniqueModel.clear()
            self.uniqueModel.appendColumn(newItems)
            if self.uniqueModel.findItems(previousUniqueColumn):
                self.uniqueCombo.setEditText(previousUniqueColumn)
                uniqueIsFilled = True

        oldGeometryColumn = self.geomCombo.currentText()
        self.geomCombo.clear()
        self.geomCombo.addItems(cols)
        self.geomCombo.setCurrentIndex(
            self.geomCombo.findText(oldGeometryColumn, Qt.MatchExactly))

        # set sensible default columns if the columns are not already set
        try:
            if self.geomCombo.currentIndex() == -1:
                self.geomCombo.setCurrentIndex(cols.index(defaultGeomCol))
        except:
            pass
        items = self.uniqueModel.findItems(defaultUniqueCol)
        if items and not uniqueIsFilled:
            if self.allowMultiColumnPk:
                items[0].setCheckState(Qt.Checked)
            else:
                self.uniqueCombo.setEditText(defaultUniqueCol)
        try:
            pass
        except:
            pass

    def copySelectedResults(self):
        if len(self.viewResult.selectedIndexes()) <= 0:
            return
        model = self.viewResult.model()

        # convert to string using tab as separator
        text = model.headerToString("\t")
        for idx in self.viewResult.selectionModel().selectedRows():
            text += "\n" + model.rowToString(idx.row(), "\t")

        QApplication.clipboard().setText(text, QClipboard.Selection)
        QApplication.clipboard().setText(text, QClipboard.Clipboard)

    def initCompleter(self):
        dictionary = None
        if self.db:
            dictionary = self.db.connector.getSqlDictionary()
        if not dictionary:
            # use the generic sql dictionary
            from .sql_dictionary import getSqlDictionary

            dictionary = getSqlDictionary()

        wordlist = []
        for name, value in dictionary.iteritems():
            wordlist += value  # concat lists
        wordlist = list(set(wordlist))  # remove duplicates

        api = QsciAPIs(self.editSql.lexer())
        for word in wordlist:
            api.add(word)

        api.prepare()
        self.editSql.lexer().setAPIs(api)

    def displayQueryBuilder(self):
        dlg = QueryBuilderDlg(self.iface,
                              self.db,
                              self,
                              reset=self.queryBuilderFirst)
        self.queryBuilderFirst = False
        r = dlg.exec_()
        if r == QDialog.Accepted:
            self.editSql.setText(dlg.query)

    def createView(self):
        name, ok = QInputDialog.getText(None, "View name", "View name")
        if ok:
            try:
                self.db.connector.createSpatialView(name, self._getSqlQuery())
            except BaseError as e:
                DlgDbError.showError(e, self)

    def _getSqlQuery(self):
        sql = self.editSql.selectedText()
        if len(sql) == 0:
            sql = self.editSql.text()
        return sql

    def uniqueChanged(self):
        # when an item is (un)checked, simply trigger an update of the combobox text
        self.uniqueTextChanged(None)

    def uniqueTextChanged(self, text):
        # Whenever there is new text displayed in the combobox, check if it is the correct one and if not, display the correct one.
        checkedItems = []
        for item in self.uniqueModel.findItems("*", Qt.MatchWildcard):
            if item.checkState() == Qt.Checked:
                checkedItems.append(item.text())
        label = ", ".join(checkedItems)
        if text != label:
            self.uniqueCombo.setEditText(label)
예제 #54
0
파일: gui.py 프로젝트: imclab/GroupPhoto
class GroupPhotoWindow(QMainWindow, Ui_main_win):

    def __init__(self):
        QMainWindow.__init__(self)
        self.setupUi(self)

        self.image_model = QStandardItemModel()
        self.image_list.setModel(self.image_model)

        QObject.connect(self.add_btn, QtCore.SIGNAL('clicked()'), self.on_add_image)
        QObject.connect(self.delete_btn, QtCore.SIGNAL('clicked()'), self.on_remove_image)
        QObject.connect(self.image_list.selectionModel(), QtCore.SIGNAL(
            'currentChanged (const QModelIndex &, const QModelIndex &)'), self.on_row_changed)
        QObject.connect(self.harris_btn, QtCore.SIGNAL('clicked()'), self.on_harris_detect)
        QObject.connect(self.stitch_btn, QtCore.SIGNAL('clicked()'), self.on_stitch)

    def on_add_image(self):
        image_path = QFileDialog.getOpenFileName(self, 'Select image', filter='Images (*.png *.jpg *.bmp)')
        ignored, name = os.path.split(unicode(image_path))
        self.image_model.appendRow([QStandardItem(name), QStandardItem(image_path)])

    def on_remove_image(self):
        row = self.image_list.selectionModel().currentIndex().row()
        if row == -1:
            return
        self.image_model.removeRows(row, 1)

    def on_row_changed(self, current, previous):
        row = current.row()
        if row == -1:
            file_path = PLACE_HOLDER
        else:
            file_path = self.image_model.item(row, 1).text()
        self.set_pixmap(QPixmap(file_path))

    def on_harris_detect(self):
        row = self.image_list.selectionModel().currentIndex().row()
        if row == -1:
            return
        file_path = self.image_model.item(row, 1).text()

        image_pfm = convert_to_pfm(imread(unicode(file_path)))
        image = image_to_gray(image_pfm)
        kernel = self.ksize_slider.value()
        cornerness = harris_corner(image, ksize=kernel)
        is_corner = cornerness > 0.000001
        suppress = non_max_suppression(cornerness, ksize=kernel)
        result = np.array(is_corner * suppress)
        zero = np.zeros_like(result)
        gray_img = np.dstack((zero, zero, draw_cross(result)))

        self.set_pixmap(QPixmap.fromImage(image_from_ndarray(np.array(gray_img + image_pfm))))

    def on_stitch(self):
        i = 0
        images = []
        while self.image_model.item(i):
            file_path = self.image_model.item(i, 1).text()
            image = image_to_gray(convert_to_pfm(imread(unicode(file_path))))
            images.append(image)
            i += 1
        stitch(self.ksize_slider.value(), images)

    def set_pixmap(self, pixmap):
        self.image_label.setPixmap(pixmap.scaled(self.image_label.size(), QtCore.Qt.KeepAspectRatio))
예제 #55
0
class ClusterWidget(QSplitter):
    def __init__(self, peaks, parent=None):
        QSplitter.__init__(self, Qt.Vertical, parent)
        self.peaks = peaks
        self.choosenOne = [pe for pe in self.peaks if pe is not None][0]
        #self.peakModel = QStandardItemModel()
        self.identificationModel = QStandardItemModel()
        self.setupUi()
        self.setModel()
        self.connect(self.calcCorr, SIGNAL('pressed()'), self.setRankValue)
        #self.setRankValue()

    def setupUi(self):
        self.widget = MSView(
            MSQtCanvas(self.peaks,
                       "peaks@%s" % str(self.peaks[0]),
                       labels={
                           'bottom': 'RT(s)',
                           'left': 'INTENSITY'
                       },
                       flags='peak'))
        self.tableView = QTableView()
        self.tableView.horizontalHeader().setStretchLastSection(True)
        self.tableView.setSortingEnabled(True)

        self.corr = QLabel("Nan")
        self.calcCorr = QPushButton("r_coef:")
        #v = QVBoxLayout(self)
        self.addWidget(self.widget)

        self.wid = QWidget()
        vb = QVBoxLayout()
        vb.addWidget(self.calcCorr)
        vb.addWidget(self.corr)
        hb = QHBoxLayout(self.wid)
        #if self.choosenOne.formulas:
        hb.addWidget(self.tableView)
        #else:
        #    hb.addWidget(QLabel("Identification not performed yet..."))
        hb.addLayout(vb)
        self.addWidget(self.wid)

    def setModel(self):
        from gui.MetBaseGui import MSStandardItem
        #we assume that the different peaks have the same identifiers
        #TODO: may have to merge several stuffs later
        if self.choosenOne.formulas:
            self.identificationModel.setHorizontalHeaderLabels(
                ["score", "formula", "diff mass", "names"])
            for i, f in enumerate(self.choosenOne.formulas.iterkeys()):

                self.identificationModel.setItem(
                    i, 0,
                    MSStandardItem(str(self.choosenOne.formulas[f]["score"])))
                self.identificationModel.setItem(i, 1, QStandardItem(str(f)))
                self.identificationModel.setItem(
                    i, 2,
                    MSStandardItem(str(
                        self.choosenOne.formulas[f]["diffmass"])))
                self.identificationModel.setItem(
                    i, 3, QStandardItem(self.choosenOne.formulas[f]["names"]))
                if self.choosenOne.formulas[f]["names"] != 'Not Found':
                    for j in xrange(4):
                        self.identificationModel.item(i, j).setBackground(
                            QBrush(Qt.green))
                else:
                    for j in xrange(4):
                        self.identificationModel.item(i, j).setBackground(
                            QBrush(Qt.red))
            self.tableView.setModel(self.identificationModel)

    def setRankValue(self):
        #m = qApp.instance().model
        #m.pearsonIntraCalculation()
        #peaks =[]
        #for spl in m:
        #    peaks+=[p.r_coef for p in spl.mappedPeaks if p.r_coef]
        #if not self.choosenOne.r_coef:
        self.choosenOne.pCalcBasedOnPeakShape()
        #from _bisect import bisect_left
        #x = bisect_left(sorted(peaks), self.choosenOne.r_coef)
        s = '<br><b>%f</b></br>' % np.round(self.choosenOne.r_coef, 4)
        #s+='<br><b>Rank: </b>%d</br>'%abs(len(peaks)-x)
        self.corr.setText(s)
예제 #56
0
class DlgSqlWindow(QWidget, Ui_Dialog):
    nameChanged = pyqtSignal(str)

    def __init__(self, iface, db, parent=None):
        QWidget.__init__(self, parent)
        self.iface = iface
        self.db = db
        self.allowMultiColumnPk = isinstance(db, PGDatabase) # at the moment only PostGIS allows a primary key to span multiple columns, spatialite doesn't
        self.setupUi(self)
        self.setWindowTitle(
            u"%s - %s [%s]" % (self.windowTitle(), db.connection().connectionName(), db.connection().typeNameString()))

        self.defaultLayerName = 'QueryLayer'

        if self.allowMultiColumnPk:
            self.uniqueColumnCheck.setText(self.trUtf8("Column(s) with unique values"))
        else:
            self.uniqueColumnCheck.setText(self.trUtf8("Column with unique values"))

        self.editSql.setFocus()
        self.editSql.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded)
        self.initCompleter()

        # allow to copy results
        copyAction = QAction("copy", self)
        self.viewResult.addAction(copyAction)
        copyAction.setShortcuts(QKeySequence.Copy)

        copyAction.triggered.connect(self.copySelectedResults)

        self.btnExecute.clicked.connect(self.executeSql)
        self.btnClear.clicked.connect(self.clearSql)

        self.presetStore.clicked.connect(self.storePreset)
        self.presetDelete.clicked.connect(self.deletePreset)
        self.presetCombo.activated[str].connect(self.loadPreset)
        self.presetCombo.activated[str].connect(self.presetName.setText)

        self.updatePresetsCombobox()

        self.geomCombo.setEditable(True)
        self.geomCombo.lineEdit().setReadOnly(True)

        self.uniqueCombo.setEditable(True)
        self.uniqueCombo.lineEdit().setReadOnly(True)
        self.uniqueModel = QStandardItemModel(self.uniqueCombo)
        self.uniqueCombo.setModel(self.uniqueModel)
        if self.allowMultiColumnPk:
            self.uniqueCombo.setItemDelegate(QStyledItemDelegate())
            self.uniqueModel.itemChanged.connect(self.uniqueChanged)                # react to the (un)checking of an item
            self.uniqueCombo.lineEdit().textChanged.connect(self.uniqueTextChanged) # there are other events that change the displayed text and some of them can not be caught directly

        # hide the load query as layer if feature is not supported
        self._loadAsLayerAvailable = self.db.connector.hasCustomQuerySupport()
        self.loadAsLayerGroup.setVisible(self._loadAsLayerAvailable)
        if self._loadAsLayerAvailable:
            self.layerTypeWidget.hide()  # show if load as raster is supported
            self.loadLayerBtn.clicked.connect(self.loadSqlLayer)
            self.getColumnsBtn.clicked.connect(self.fillColumnCombos)
            self.loadAsLayerGroup.toggled.connect(self.loadAsLayerToggled)
            self.loadAsLayerToggled(False)

        self._createViewAvailable = self.db.connector.hasCreateSpatialViewSupport()
        self.btnCreateView.setVisible(self._createViewAvailable)
        if self._createViewAvailable:
            self.btnCreateView.clicked.connect(self.createView)

        self.queryBuilderFirst = True
        self.queryBuilderBtn.setIcon(QIcon(":/db_manager/icons/sql.gif"))
        self.queryBuilderBtn.clicked.connect(self.displayQueryBuilder)

        self.presetName.textChanged.connect(self.nameChanged)

    def updatePresetsCombobox(self):
        self.presetCombo.clear()

        names = []
        entries = QgsProject.instance().subkeyList('DBManager', 'savedQueries')
        for entry in entries:
            name = QgsProject.instance().readEntry('DBManager', 'savedQueries/' + entry + '/name')[0]
            names.append(name)

        for name in sorted(names):
            self.presetCombo.addItem(name)
        self.presetCombo.setCurrentIndex(-1)

    def storePreset(self):
        query = self._getSqlQuery()
        if query == "":
            return
        name = self.presetName.text()
        QgsProject.instance().writeEntry('DBManager', 'savedQueries/q' + unicode(name.__hash__()) + '/name', name)
        QgsProject.instance().writeEntry('DBManager', 'savedQueries/q' + unicode(name.__hash__()) + '/query', query)
        index = self.presetCombo.findText(name)
        if index == -1:
            self.presetCombo.addItem(name)
            self.presetCombo.setCurrentIndex(self.presetCombo.count() - 1)
        else:
            self.presetCombo.setCurrentIndex(index)

    def deletePreset(self):
        name = self.presetCombo.currentText()
        QgsProject.instance().removeEntry('DBManager', 'savedQueries/q' + unicode(name.__hash__()))
        self.presetCombo.removeItem(self.presetCombo.findText(name))
        self.presetCombo.setCurrentIndex(-1)

    def loadPreset(self, name):
        query = QgsProject.instance().readEntry('DBManager', 'savedQueries/q' + unicode(name.__hash__()) + '/query')[0]
        name = QgsProject.instance().readEntry('DBManager', 'savedQueries/q' + unicode(name.__hash__()) + '/name')[0]
        self.editSql.setText(query)

    def loadAsLayerToggled(self, checked):
        self.loadAsLayerGroup.setChecked(checked)
        self.loadAsLayerWidget.setVisible(checked)
        if checked:
            self.fillColumnCombos()

    def clearSql(self):
        self.editSql.clear()
        self.editSql.setFocus()

    def executeSql(self):

        sql = self._getSqlQuery()
        if sql == "":
            return

        QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))

        # delete the old model
        old_model = self.viewResult.model()
        self.viewResult.setModel(None)
        if old_model:
            old_model.deleteLater()

        cols = []
        quotedCols = []

        try:
            # set the new model
            model = self.db.sqlResultModel(sql, self)
            self.viewResult.setModel(model)
            self.lblResult.setText(self.tr("%d rows, %.1f seconds") % (model.affectedRows(), model.secs()))
            cols = self.viewResult.model().columnNames()
            for col in cols:
                quotedCols.append(self.db.connector.quoteId(col))

        except BaseError as e:
            QApplication.restoreOverrideCursor()
            DlgDbError.showError(e, self)
            self.uniqueModel.clear()
            self.geomCombo.clear()
            return

        self.setColumnCombos(cols, quotedCols)

        self.update()
        QApplication.restoreOverrideCursor()

    def loadSqlLayer(self):
        hasUniqueField = self.uniqueColumnCheck.checkState() == Qt.Checked
        if hasUniqueField:
            if self.allowMultiColumnPk:
                checkedCols = []
                for item in self.uniqueModel.findItems("*", Qt.MatchWildcard):
                    if item.checkState() == Qt.Checked:
                        checkedCols.append(item.data())
                uniqueFieldName = ",".join(checkedCols)
            elif self.uniqueCombo.currentIndex() >= 0:
                uniqueFieldName = self.uniqueModel.item(self.uniqueCombo.currentIndex()).data()
            else:
                uniqueFieldName = None
        else:
            uniqueFieldName = None
        hasGeomCol = self.hasGeometryCol.checkState() == Qt.Checked
        if hasGeomCol:
            geomFieldName = self.geomCombo.currentText()
        else:
            geomFieldName = None

        query = self._getSqlQuery()
        if query == "":
            return

        # remove a trailing ';' from query if present
        if query.strip().endswith(';'):
            query = query.strip()[:-1]

        QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))

        from qgis.core import QgsMapLayer, QgsMapLayerRegistry

        layerType = QgsMapLayer.VectorLayer if self.vectorRadio.isChecked() else QgsMapLayer.RasterLayer

        # get a new layer name
        names = []
        for layer in QgsMapLayerRegistry.instance().mapLayers().values():
            names.append(layer.name())

        layerName = self.layerNameEdit.text()
        if layerName == "":
            layerName = self.defaultLayerName
        newLayerName = layerName
        index = 1
        while newLayerName in names:
            index += 1
            newLayerName = u"%s_%d" % (layerName, index)

        # create the layer
        layer = self.db.toSqlLayer(query, geomFieldName, uniqueFieldName, newLayerName, layerType,
                                   self.avoidSelectById.isChecked())
        if layer.isValid():
            QgsMapLayerRegistry.instance().addMapLayers([layer], True)

        QApplication.restoreOverrideCursor()

    def fillColumnCombos(self):
        query = self._getSqlQuery()
        if query == "":
            return

        QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))

        # get a new alias
        aliasIndex = 0
        while True:
            alias = "_%s__%d" % ("subQuery", aliasIndex)
            escaped = re.compile('\\b("?)' + re.escape(alias) + '\\1\\b')
            if not escaped.search(query):
                break
            aliasIndex += 1

        # remove a trailing ';' from query if present
        if query.strip().endswith(';'):
            query = query.strip()[:-1]

        # get all the columns
        cols = []
        quotedCols = []
        connector = self.db.connector
        sql = u"SELECT * FROM (%s\n) AS %s LIMIT 0" % (unicode(query), connector.quoteId(alias))

        c = None
        try:
            c = connector._execute(None, sql)
            cols = connector._get_cursor_columns(c)
            for col in cols:
                quotedCols.append(connector.quoteId(col))

        except BaseError as e:
            QApplication.restoreOverrideCursor()
            DlgDbError.showError(e, self)
            self.uniqueModel.clear()
            self.geomCombo.clear()
            return

        finally:
            if c:
                c.close()
                del c

        self.setColumnCombos(cols, quotedCols)

        QApplication.restoreOverrideCursor()

    def setColumnCombos(self, cols, quotedCols):
        # get sensible default columns. do this before sorting in case there's hints in the column order (eg, id is more likely to be first)
        try:
            defaultGeomCol = next(col for col in cols if col in ['geom', 'geometry', 'the_geom', 'way'])
        except:
            defaultGeomCol = None
        try:
            defaultUniqueCol = [col for col in cols if 'id' in col][0]
        except:
            defaultUniqueCol = None

        colNames = sorted(zip(cols, quotedCols))
        newItems = []
        uniqueIsFilled = False
        for (col, quotedCol) in colNames:
            item = QStandardItem(col)
            item.setData(quotedCol)
            item.setEnabled(True)
            item.setCheckable(self.allowMultiColumnPk)
            item.setSelectable(not self.allowMultiColumnPk)
            if self.allowMultiColumnPk:
                matchingItems = self.uniqueModel.findItems(col)
                if matchingItems:
                    item.setCheckState(matchingItems[0].checkState())
                    uniqueIsFilled = uniqueIsFilled or matchingItems[0].checkState() == Qt.Checked
                else:
                    item.setCheckState(Qt.Unchecked)
            newItems.append(item)
        if self.allowMultiColumnPk:
            self.uniqueModel.clear()
            self.uniqueModel.appendColumn(newItems)
            self.uniqueChanged()
        else:
            previousUniqueColumn = self.uniqueCombo.currentText()
            self.uniqueModel.clear()
            self.uniqueModel.appendColumn(newItems)
            if self.uniqueModel.findItems(previousUniqueColumn):
                self.uniqueCombo.setEditText(previousUniqueColumn)
                uniqueIsFilled = True

        oldGeometryColumn = self.geomCombo.currentText()
        self.geomCombo.clear()
        self.geomCombo.addItems(cols)
        self.geomCombo.setCurrentIndex(self.geomCombo.findText(oldGeometryColumn, Qt.MatchExactly))

        # set sensible default columns if the columns are not already set
        try:
            if self.geomCombo.currentIndex() == -1:
                self.geomCombo.setCurrentIndex(cols.index(defaultGeomCol))
        except:
            pass
        items = self.uniqueModel.findItems(defaultUniqueCol)
        if items and not uniqueIsFilled:
            if self.allowMultiColumnPk:
                items[0].setCheckState(Qt.Checked)
            else:
                self.uniqueCombo.setEditText(defaultUniqueCol)
        try:
            pass
        except:
            pass

    def copySelectedResults(self):
        if len(self.viewResult.selectedIndexes()) <= 0:
            return
        model = self.viewResult.model()

        # convert to string using tab as separator
        text = model.headerToString("\t")
        for idx in self.viewResult.selectionModel().selectedRows():
            text += "\n" + model.rowToString(idx.row(), "\t")

        QApplication.clipboard().setText(text, QClipboard.Selection)
        QApplication.clipboard().setText(text, QClipboard.Clipboard)

    def initCompleter(self):
        dictionary = None
        if self.db:
            dictionary = self.db.connector.getSqlDictionary()
        if not dictionary:
            # use the generic sql dictionary
            from .sql_dictionary import getSqlDictionary

            dictionary = getSqlDictionary()

        wordlist = []
        for name, value in dictionary.iteritems():
            wordlist += value  # concat lists
        wordlist = list(set(wordlist))  # remove duplicates

        api = QsciAPIs(self.editSql.lexer())
        for word in wordlist:
            api.add(word)

        api.prepare()
        self.editSql.lexer().setAPIs(api)

    def displayQueryBuilder(self):
        dlg = QueryBuilderDlg(self.iface, self.db, self, reset=self.queryBuilderFirst)
        self.queryBuilderFirst = False
        r = dlg.exec_()
        if r == QDialog.Accepted:
            self.editSql.setText(dlg.query)

    def createView(self):
        name, ok = QInputDialog.getText(None, "View name", "View name")
        if ok:
            try:
                self.db.connector.createSpatialView(name, self._getSqlQuery())
            except BaseError as e:
                DlgDbError.showError(e, self)

    def _getSqlQuery(self):
        sql = self.editSql.selectedText()
        if len(sql) == 0:
            sql = self.editSql.text()
        return sql

    def uniqueChanged(self):
        # when an item is (un)checked, simply trigger an update of the combobox text
        self.uniqueTextChanged(None)

    def uniqueTextChanged(self, text):
        # Whenever there is new text displayed in the combobox, check if it is the correct one and if not, display the correct one.
        checkedItems = []
        for item in self.uniqueModel.findItems("*", Qt.MatchWildcard):
            if item.checkState() == Qt.Checked:
                checkedItems.append(item.text())
        label = ", ".join(checkedItems)
        if text != label:
            self.uniqueCombo.setEditText(label)
예제 #57
0
class ClusterWidget(QSplitter):
    def __init__(self, peaks, parent=None):
        QSplitter.__init__(self, Qt.Vertical, parent)
        self.peaks = peaks
        self.choosenOne = [pe for pe in self.peaks if pe is not None][0]
        #self.peakModel = QStandardItemModel()
        self.identificationModel = QStandardItemModel()
        self.setupUi()
        self.setModel()
        self.connect(self.calcCorr, SIGNAL('pressed()'), self.setRankValue)
        #self.setRankValue()
    
    def setupUi(self):
        self.widget = MSView(MSQtCanvas(self.peaks, "peaks@%s"%str(self.peaks[0]), 
                                 labels={'bottom':'RT(s)', 'left':'INTENSITY'},
                                 flags='peak'))
        self.tableView = QTableView()
        self.tableView.horizontalHeader().setStretchLastSection(True)
        self.tableView.setSortingEnabled(True)

        self.corr = QLabel("Nan")
        self.calcCorr = QPushButton("r_coef:")
        #v = QVBoxLayout(self)
        self.addWidget(self.widget)
        
        self.wid = QWidget()        
        vb = QVBoxLayout()
        vb.addWidget(self.calcCorr)
        vb.addWidget(self.corr)
        hb = QHBoxLayout(self.wid)
        #if self.choosenOne.formulas:
        hb.addWidget(self.tableView)
        #else:
        #    hb.addWidget(QLabel("Identification not performed yet..."))
        hb.addLayout(vb)
        self.addWidget(self.wid)
    
    def setModel(self):
        from gui.MetBaseGui import MSStandardItem
        #we assume that the different peaks have the same identifiers
        #TODO: may have to merge several stuffs later
        if self.choosenOne.formulas:
            self.identificationModel.setHorizontalHeaderLabels(["score", "formula", "diff mass", "names"])
            for i, f in enumerate(self.choosenOne.formulas.iterkeys()):
                
                self.identificationModel.setItem(i, 0, MSStandardItem(str(self.choosenOne.formulas[f]["score"])))
                self.identificationModel.setItem(i, 1, QStandardItem(str(f)))
                self.identificationModel.setItem(i, 2, MSStandardItem(str(self.choosenOne.formulas[f]["diffmass"])))
                self.identificationModel.setItem(i, 3, QStandardItem(self.choosenOne.formulas[f]["names"]))
                if self.choosenOne.formulas[f]["names"] != 'Not Found':
                    for j in xrange(4):
                        self.identificationModel.item(i, j).setBackground(QBrush(Qt.green))
                else:
                    for j in xrange(4):
                        self.identificationModel.item(i, j).setBackground(QBrush(Qt.red))
            self.tableView.setModel(self.identificationModel)
    
    def setRankValue(self):
        #m = qApp.instance().model
        #m.pearsonIntraCalculation()
        #peaks =[]
        #for spl in m:
        #    peaks+=[p.r_coef for p in spl.mappedPeaks if p.r_coef]
        #if not self.choosenOne.r_coef:        
        self.choosenOne.pCalcBasedOnPeakShape()
        #from _bisect import bisect_left
        #x = bisect_left(sorted(peaks), self.choosenOne.r_coef)
        s = '<br><b>%f</b></br>'%np.round(self.choosenOne.r_coef, 4)
        #s+='<br><b>Rank: </b>%d</br>'%abs(len(peaks)-x)
        self.corr.setText(s)