def printProfile(self):
        printer = QPrinter(QPrinter.HighResolution)
        printer.setOutputFormat(QPrinter.PdfFormat)
        printer.setPaperSize(QPrinter.A4)
        printer.setOrientation(QPrinter.Landscape)

        printpreviewdlg = QPrintPreviewDialog()
        printpreviewdlg.paintRequested.connect(self.printRequested)

        printpreviewdlg.exec_()
Exemple #2
0
 def outPDF(self, iface, wdg, mdl, library):
     for i in range(0, mdl.rowCount()):
         if mdl.item(i, 0).data(Qt.CheckStateRole):
             name = str(mdl.item(i, 2).data(Qt.EditRole))
             break
     fileName, _ = QFileDialog.getSaveFileName(
         iface.mainWindow(), "Save As", "Profile of " + name + ".pdf",
         "Portable Document Format (*.pdf)")
     if fileName:
         if library == "Qwt5" and has_qwt:
             printer = QPrinter()
             printer.setCreator('QGIS Profile Plugin')
             printer.setOutputFileName(fileName)
             printer.setOutputFormat(QPrinter.PdfFormat)
             printer.setOrientation(QPrinter.Landscape)
             wdg.plotWdg.print_(printer)
         elif library == "Matplotlib" and has_mpl:
             wdg.plotWdg.figure.savefig(str(fileName))
Exemple #3
0
 def outPrint(
         self, iface, wdg, mdl,
         library):  # Postscript file rendering doesn't work properly yet.
     for i in range(0, mdl.rowCount()):
         if mdl.item(i, 0).data(Qt.CheckStateRole):
             name = str(mdl.item(i, 2).data(Qt.EditRole))
             #return
     fileName, __, __ = QFileDialog.getSaveFileName(
         iface.mainWindow(), "Save As", "Profile of " + name + ".ps",
         "PostScript Format (*.ps)")
     if fileName:
         if library == "Qwt5" and has_qwt:
             printer = QPrinter()
             printer.setCreator("QGIS Profile Plugin")
             printer.setDocName("QGIS Profile")
             printer.setOutputFileName(fileName)
             printer.setColorMode(QPrinter.Color)
             printer.setOrientation(QPrinter.Portrait)
             dialog = QPrintDialog(printer)
             if dialog.exec_():
                 wdg.plotWdg.print_(printer)
         elif library == "Matplotlib" and has_mpl:
             wdg.plotWdg.figure.savefig(str(fileName))
class WeightDataDialog(QDialog, FORM_CLASS):
    """
    Modal dialog allowing to select weights in a d3.js visualization
    """

    #   QVariantMap is to map a JSON to dict see:
    #   http://pyqt.sourceforge.net/Docs/PyQt4/incompatibilities.html#pyqt4-v4-7-4
    #   this is for javascript to emit when it changes the json
    json_updated = pyqtSignal(['QVariantMap'], name='json_updated')
    # Python classes should connect to json_cleaned
    json_cleaned = pyqtSignal(['QVariantMap'], name='json_cleaned')

    def __init__(self, iface, project_definition):
        self.iface = iface
        QDialog.__init__(self)

        # Set up the user interface from Designer.
        self.setupUi(self)
        self.ok_button = self.buttonBox.button(QDialogButtonBox.Ok)

        self.added_attrs_ids = set()
        self.discarded_feats = set()
        self.any_changes_made = False

        # keep track of changes made to the tree while on-the-fly calculations
        # are off (the tree has changed, but indices haven't been recalculated)
        self.modified_project_definition = None

        self.active_layer_numeric_fields = []
        self.active_layer_numeric_fields_aliases = []
        self.update_active_layer_numeric_fields()
        # keep track of the fact that the user has explicitly selected a field
        # to base the style on. Note that also the selection of the empty item
        # means that the user explicitly wants the system to use the default
        # behavior.
        self.style_by_field_selected = False

        self.project_definition = deepcopy(project_definition)
        try:
            proj_title = self.project_definition['title']
        except KeyError:
            proj_title = 'Untitled'
        dialog_title = ('Set weights and operators for project: "%s"' %
                        proj_title)
        self.setWindowTitle(dialog_title)

        self.web_view = self.web_view
        self.web_view.page().mainFrame().setScrollBarPolicy(
            Qt.Vertical, Qt.ScrollBarAlwaysOff)
        self.web_view.page().mainFrame().setScrollBarPolicy(
            Qt.Horizontal, Qt.ScrollBarAlwaysOff)
        self.web_view.load(QUrl('qrc:/plugins/irmt/weight_data.html'))

        self.printer = QPrinter(QPrinter.HighResolution)
        self.printer.setPageSize(QPrinter.A4)
        self.printer.setOutputFormat(QPrinter.PdfFormat)
        self.printer.setPrintRange(QPrinter.AllPages)
        self.printer.setOrientation(QPrinter.Portrait)
        self.printer.setDocName(proj_title)
        self.printer.setCreator(
            'GEM Integrated Risk Modelling Toolkit QGIS Plugin')

        self.frame = self.web_view.page().mainFrame()

        self.frame.javaScriptWindowObjectCleared.connect(self.setup_js)
        self.web_view.loadFinished.connect(self.show_tree)
        self.json_updated.connect(self.handle_json_updated)
        self.populate_style_by_field_cbx()

        if not DEBUG:
            self.web_view.setContextMenuPolicy(Qt.NoContextMenu)

        self.web_view.settings().setAttribute(QWebSettings.JavascriptEnabled,
                                              True)

    def closeEvent(self, event):
        confirmation_on_close(self, event)

    def reject(self):
        confirmation_on_close(self)

    def update_project_definition(self, project_definition):
        self.project_definition = deepcopy(project_definition)
        self.populate_style_by_field_cbx()

    def update_active_layer_numeric_fields(self):
        self.active_layer_numeric_fields = [
            field.name() for field in self.iface.activeLayer().fields()
            if field.typeName() in NUMERIC_FIELD_TYPES
        ]
        self.active_layer_numeric_fields_aliases = [
            self.iface.activeLayer().attributeAlias(field_idx) for field_idx,
            field in enumerate(self.iface.activeLayer().fields())
            if field.typeName() in NUMERIC_FIELD_TYPES
        ]

    def populate_style_by_field_cbx(self):
        self.update_active_layer_numeric_fields()
        fields_in_proj_def = get_field_names(self.project_definition)
        fields_for_styling = [
            field for field in self.active_layer_numeric_fields
            if field in fields_in_proj_def
        ]
        # block signals to avoid performing the onchange actions while adding
        # items programmatically
        self.style_by_field_cbx.blockSignals(True)
        self.style_by_field_cbx.clear()
        self.style_by_field_cbx.addItem('')
        self.style_by_field_cbx.addItems(fields_for_styling)
        if 'style_by_field' in self.project_definition:
            idx = self.style_by_field_cbx.findText(
                self.project_definition['style_by_field'])
            self.style_by_field_cbx.setCurrentIndex(idx)
        # reactivate the signals, so the user's changes will trigger something
        self.style_by_field_cbx.blockSignals(False)

    def setup_js(self):
        # pass a reference (called qt_page) of self to the JS world
        # to expose a member of self to js you need to declare it as property
        # see for example self.json_str()

        if DEBUG:
            log_msg("######################### for weight_data_debug.html")
            self.print_self_for_debug()
            log_msg("######################### end for weight_data_debug.html")

        self.frame.addToJavaScriptWindowObject('qt_page', self)

    def show_tree(self):
        # start the tree
        self.frame.evaluateJavaScript('init_tree()')

    def handle_json_updated(self, data):
        self.any_changes_made = True
        if DEBUG:
            import pprint
            ppdata = pprint.pformat(data, indent=4)
            log_msg('in handle_json_updated, data=\n%s' % ppdata)

        if self.on_the_fly_ckb.isChecked():
            self.project_definition = self.clean_json([data])
            self._manage_style_by_field()
            self.json_cleaned.emit(self.project_definition)

            # nothing has changed since the last recalculation
            self.modified_project_definition = None
        else:
            # keep track of the current status of the project definition
            # as it is in the d3 tree, so it can be used when OK is pressed
            self.modified_project_definition = self.clean_json([data])

    def _manage_style_by_field(self):
        if self.style_by_field_selected:
            if self.style_by_field_cbx.currentText():
                self.project_definition['style_by_field'] = \
                    self.style_by_field_cbx.currentText()
            elif 'style_by_field' in self.project_definition:
                # if the empty item is selected, clean the project definition
                del self.project_definition['style_by_field']

    def clean_json(self, data):
        # this method takes a list of dictionaries and removes some unneeded
        # keys. It recurses into the children elements

        if data == []:
            return data

        ignore_keys = ['depth', 'x', 'y', 'id', 'x0', 'y0', 'parent']
        for element in data:
            for key in ignore_keys:
                element.pop(key, None)
            if 'children' in element:
                self.clean_json(element['children'])
        # return the main element
        return data[0]

    @pyqtSlot()
    def on_print_btn_clicked(self):
        dest_full_path_name = ask_for_destination_full_path_name(
            self, filter='Pdf files (*.pdf)')
        if not dest_full_path_name:
            return
        self.printer.setOutputFileName(dest_full_path_name)
        try:
            self.web_view.print_(self.printer)
        except Exception as exc:
            msg = 'It was impossible to create the pdf'
            log_msg(msg,
                    level='C',
                    message_bar=self.iface.messageBar(),
                    exception=exc)
        else:
            msg = ('Project definition printed as pdf and saved to: %s' %
                   dest_full_path_name)
            log_msg(msg, level='S', message_bar=self.iface.messageBar())

    @pyqtSlot(str)
    def on_style_by_field_cbx_currentIndexChanged(self):
        self.style_by_field_selected = True
        self._manage_style_by_field()
        self.json_updated.emit(self.project_definition)

    @pyqtProperty(str)
    def json_str(self):
        # This method gets exposed to JS thanks to @pyqtProperty(str)
        return json.dumps(self.project_definition,
                          sort_keys=False,
                          indent=2,
                          separators=(',', ': '))

    @pyqtProperty(str)
    def DEFAULT_OPERATOR(self):
        return DEFAULT_OPERATOR

    @pyqtProperty(bool)
    def DEV_MODE(self):
        developer_mode = QSettings().value('/irmt/developer_mode',
                                           True,
                                           type=bool)

        return developer_mode

    @pyqtProperty(str)
    def OPERATORS(self):
        return ';'.join(list(OPERATORS_DICT.values()))

    @pyqtProperty(str)
    def ACTIVE_LAYER_NUMERIC_FIELDS(self):
        return ';'.join(self.active_layer_numeric_fields)

    @pyqtProperty(str)
    def ACTIVE_LAYER_NUMERIC_FIELDS_ALIASES(self):
        return ';'.join(self.active_layer_numeric_fields_aliases)

    @pyqtProperty(str)
    def NODE_TYPES(self):
        return ';'.join(["%s:%s" % (k, v) for k, v in NODE_TYPES.items()])

    def print_self_for_debug(self):
        msg = """
        var qt_page = {
            ACTIVE_LAYER_NUMERIC_FIELDS: "%s",
            ACTIVE_LAYER_NUMERIC_FIELDS_ALIASES: "%s",
            DEFAULT_OPERATOR: "%s",
            NODE_TYPES: "%s",
            OPERATORS: "%s",
            json_str: '%s',
            json_updated: function (updated_json_str) {
                console.log("json_updated signal emitted with this JSON:");
                console.log(updated_json_str)
            },
            DEV_MODE: %s
        };""" % (self.ACTIVE_LAYER_NUMERIC_FIELDS,
                 self.ACTIVE_LAYER_NUMERIC_FIELDS_ALIASES,
                 self.DEFAULT_OPERATOR, self.NODE_TYPES, self.OPERATORS,
                 self.json_str.replace('\n', ''), str(self.DEV_MODE).lower())
        log_msg(msg)