コード例 #1
0
ファイル: lyr_items.py プロジェクト: nyalldawson/slyr
    def extract_symbols(self):  # pylint: disable=too-many-locals
        """
        Extract symbols from a lyr file
        """

        style = QgsStyle()
        style.createMemoryDatabase()

        context = Context()
        # context.style_folder, _ = os.path.split(output_file)

        with open(self.path(), 'rb') as f:
            try:
                stream = Stream(f, False, force_layer=True, offset=-1)
                root_object = stream.read_object()

            except RequiresLicenseException as e:
                message = '<p>{}. Please see <a href="https://north-road.com/slyr/">here</a> for details.</p>'.format(
                    e)
                BrowserUtils.show_warning('Licensed version required',
                                          'Convert LYR',
                                          message,
                                          level=Qgis.Critical)

                return True

            layers = LayerConverter.unique_layer_name_map(root_object)

            for name, layer in layers.items():
                if not isinstance(layer, FeatureLayer):
                    continue

                symbols = VectorRendererConverter.extract_symbols_from_renderer(
                    layer,
                    context,
                    default_name=name,
                    base_name=name if len(layers) > 1 else '')

                for k, v in symbols.items():
                    if isinstance(v, QgsSymbol):
                        style.addSymbol(k, v, True)
                    elif isinstance(v, QgsColorRamp):
                        style.addColorRamp(k, v, True)
                    elif isinstance(v, QgsTextFormat):
                        if Qgis.QGIS_VERSION_INT >= 30900:
                            style.addTextFormat(k, v, True)

        dlg = QgsStyleManagerDialog(style, readOnly=True)
        dlg.setFavoritesGroupVisible(False)
        dlg.setSmartGroupsVisible(False)
        fi = QFileInfo(self.path())
        dlg.setBaseStyleName(fi.baseName())
        dlg.setWindowTitle(fi.baseName())
        dlg.exec_()
        return True
コード例 #2
0
    def test_model(self):
        model = QgsCombinedStyleModel()
        self.assertFalse(model.styles())
        self.assertEqual(model.rowCount(), 0)

        style1 = QgsStyle()
        style1.createMemoryDatabase()
        style1.setName('first style')
        style1.setFileName('/home/my style1.db')

        model.addStyle(style1)
        self.assertEqual(model.styles(), [style1])
        self.assertEqual(model.headerData(0, Qt.Horizontal), 'Name')
        self.assertEqual(model.headerData(1, Qt.Horizontal), 'Tags')

        self.assertEqual(model.columnCount(), 2)
        self.assertEqual(model.rowCount(), 1)
        self.assertEqual(model.data(model.index(0, 0)), 'first style')
        self.assertTrue(model.data(model.index(0, 0), QgsStyleModel.IsTitleRole))
        self.assertEqual(model.data(model.index(0, 0), QgsStyleModel.StyleName), 'first style')
        self.assertEqual(model.data(model.index(0, 0), QgsStyleModel.StyleFileName), '/home/my style1.db')

        style1.addTextFormat('format 1', QgsTextFormat(), True)
        self.assertEqual(model.rowCount(), 2)
        self.assertEqual(model.data(model.index(0, 0)), 'first style')
        self.assertTrue(model.data(model.index(0, 0), QgsStyleModel.IsTitleRole))
        self.assertEqual(model.data(model.index(1, 0)), 'format 1')
        self.assertFalse(model.data(model.index(1, 0), QgsStyleModel.IsTitleRole))
        self.assertEqual(model.data(model.index(1, 0), QgsStyleModel.StyleName), 'first style')
        self.assertEqual(model.data(model.index(1, 0), QgsStyleModel.StyleFileName), '/home/my style1.db')

        style2 = QgsStyle()
        style2.createMemoryDatabase()
        style2.setName('second style')
        style2.setFileName('/home/my style2.db')
        style2.addTextFormat('format 2', QgsTextFormat(), True)
        style2.addTextFormat('format 3', QgsTextFormat(), True)

        model.addStyle(style2)
        self.assertEqual(model.styles(), [style1, style2])

        self.assertEqual(model.rowCount(), 5)
        self.assertEqual(model.data(model.index(0, 0)), 'first style')
        self.assertTrue(model.data(model.index(0, 0), QgsStyleModel.IsTitleRole))
        self.assertEqual(model.data(model.index(0, 0), QgsStyleModel.StyleName), 'first style')
        self.assertEqual(model.data(model.index(0, 0), QgsStyleModel.StyleFileName), '/home/my style1.db')
        self.assertEqual(model.data(model.index(1, 0)), 'format 1')
        self.assertFalse(model.data(model.index(1, 0), QgsStyleModel.IsTitleRole))
        self.assertEqual(model.data(model.index(1, 0), QgsStyleModel.StyleName), 'first style')
        self.assertEqual(model.data(model.index(1, 0), QgsStyleModel.StyleFileName), '/home/my style1.db')
        self.assertEqual(model.data(model.index(2, 0)), 'second style')
        self.assertTrue(model.data(model.index(2, 0), QgsStyleModel.IsTitleRole))
        self.assertEqual(model.data(model.index(2, 0), QgsStyleModel.StyleName), 'second style')
        self.assertEqual(model.data(model.index(2, 0), QgsStyleModel.StyleFileName), '/home/my style2.db')
        self.assertEqual(model.data(model.index(3, 0)), 'format 2')
        self.assertFalse(model.data(model.index(3, 0), QgsStyleModel.IsTitleRole))
        self.assertEqual(model.data(model.index(3, 0), QgsStyleModel.StyleName), 'second style')
        self.assertEqual(model.data(model.index(3, 0), QgsStyleModel.StyleFileName), '/home/my style2.db')
        self.assertEqual(model.data(model.index(4, 0)), 'format 3')
        self.assertFalse(model.data(model.index(4, 0), QgsStyleModel.IsTitleRole))
        self.assertEqual(model.data(model.index(4, 0), QgsStyleModel.StyleName), 'second style')
        self.assertEqual(model.data(model.index(4, 0), QgsStyleModel.StyleFileName), '/home/my style2.db')

        style1.deleteLater()
        style1 = None
        QCoreApplication.sendPostedEvents(None, QEvent.DeferredDelete)

        self.assertEqual(model.rowCount(), 3)
        self.assertEqual(model.data(model.index(0, 0)), 'second style')
        self.assertTrue(model.data(model.index(0, 0), QgsStyleModel.IsTitleRole))
        self.assertEqual(model.data(model.index(1, 0)), 'format 2')
        self.assertFalse(model.data(model.index(1, 0), QgsStyleModel.IsTitleRole))
        self.assertEqual(model.data(model.index(2, 0)), 'format 3')
        self.assertFalse(model.data(model.index(2, 0), QgsStyleModel.IsTitleRole))

        model.removeStyle(style2)
        self.assertEqual(model.rowCount(), 0)

        model.removeStyle(style2)
コード例 #3
0
ファイル: lyr_to_style_xml.py プロジェクト: nyalldawson/slyr
    def processAlgorithm(
            self,  # pylint: disable=too-many-locals,too-many-statements,too-many-branches
            parameters,
            context,
            feedback):

        input_file = self.parameterAsString(parameters, self.INPUT, context)
        output_file = self.parameterAsFileOutput(parameters, self.OUTPUT,
                                                 context)

        style = QgsStyle()
        style.createMemoryDatabase()

        warnings = set()

        def unsupported_object_callback(msg, level=Context.WARNING):
            if msg in warnings:
                return

            warnings.add(msg)
            if level == Context.WARNING:
                feedback.reportError('Warning: {}'.format(msg), False)
            elif level == Context.CRITICAL:
                feedback.reportError(msg, False)

        context = Context()
        context.unsupported_object_callback = unsupported_object_callback
        if Qgis.QGIS_VERSION_INT < 30600:
            context.invalid_layer_resolver = GuiUtils.get_valid_mime_uri
        # context.style_folder, _ = os.path.split(output_file)

        with open(input_file, 'rb') as f:
            stream = Stream(f, False, force_layer=True, offset=0)
            try:
                obj = stream.read_object()
            except RequiresLicenseException as e:
                raise QgsProcessingException(
                    '{} - please see https://north-road.com/slyr/ for details'.
                    format(e)) from e
            except UnknownClsidException as e:
                feedback.reportError(str(e), fatalError=True)
                return {}
            except UnreadableSymbolException as e:
                feedback.reportError('Unreadable object: {}'.format(e),
                                     fatalError=True)
                return {}
            except NotImplementedException as e:
                feedback.reportError(str(e), fatalError=True)
                return {}
            except UnicodeDecodeError as e:
                feedback.reportError('Unreadable object: {}'.format(e),
                                     fatalError=True)
                return {}

        if not LayerConverter.is_layer(obj) and not isinstance(
                obj, GroupLayer):
            feedback.reportError('Objects of type {} are not supported'.format(
                obj.__class__.__name__),
                                 fatalError=False)
            return {}

        symbol_names = set()

        def make_name_unique(original_name):
            """
            Ensures that the symbol name is unique (in a case-insensitive way)
            """
            counter = 0
            candidate = original_name
            while candidate.lower() in symbol_names:
                # make name unique
                if counter == 0:
                    candidate += '_1'
                else:
                    candidate = candidate[:candidate.rfind('_') +
                                          1] + str(counter)
                counter += 1
            symbol_names.add(candidate.lower())
            return candidate

        layers = LayerConverter.unique_layer_name_map(obj)
        for name, layer in layers.items():
            feedback.pushInfo('Extracting symbols from {}'.format(name))
            symbols = VectorRendererConverter.extract_symbols_from_renderer(
                layer,
                context,
                default_name=name,
                base_name=name if len(layers) > 1 else '')

            for k, v in symbols.items():
                unique_name = make_name_unique(k)
                if k != unique_name:
                    feedback.pushInfo(
                        'Corrected to unique name of {}'.format(unique_name))

                if isinstance(v, QgsSymbol):
                    style.addSymbol(unique_name, v, True)
                elif isinstance(v, QgsColorRamp):
                    style.addColorRamp(unique_name, v, True)
                elif isinstance(v, QgsTextFormat):
                    if Qgis.QGIS_VERSION_INT >= 30900:
                        style.addTextFormat(unique_name, v, True)

        style.exportXml(output_file)
        return {self.OUTPUT: output_file}
コード例 #4
0
    def processAlgorithm(
            self,  # pylint:disable=too-many-locals,too-many-statements,too-many-branches
            parameters,
            context,
            feedback):
        input_file = self.parameterAsString(parameters, self.INPUT, context)
        output_file = self.parameterAsFileOutput(parameters, self.OUTPUT,
                                                 context)

        fields = QgsFields()
        fields.append(QgsField('name', QVariant.String, '', 60))
        fields.append(QgsField('warning', QVariant.String, '', 250))

        sink, dest = self.parameterAsSink(parameters, self.REPORT, context,
                                          fields)

        style = QgsStyle()
        style.createMemoryDatabase()

        results = {}

        symbol_names = set()

        def make_name_unique(original_name):
            """
            Ensures that the symbol name is unique (in a case-insensitive way)
            """
            counter = 0
            candidate = original_name
            while candidate.lower() in symbol_names:
                # make name unique
                if counter == 0:
                    candidate += '_1'
                else:
                    candidate = candidate[:candidate.rfind('_') +
                                          1] + str(counter)
                counter += 1
            symbol_names.add(candidate.lower())
            return candidate

        symbols_to_extract = [
            Extractor.FILL_SYMBOLS, Extractor.LINE_SYMBOLS,
            Extractor.MARKER_SYMBOLS, Extractor.COLOR_RAMPS,
            Extractor.LINE_PATCHES, Extractor.AREA_PATCHES
        ]
        if Qgis.QGIS_VERSION_INT >= 30900:
            symbols_to_extract.extend(
                (Extractor.TEXT_SYMBOLS, Extractor.LABELS,
                 Extractor.MAPLEX_LABELS))

        type_percent = 100.0 / len(symbols_to_extract)

        results[self.LABEL_SETTINGS_COUNT] = 0
        results[self.UNREADABLE_LABEL_SETTINGS] = 0

        for type_index, symbol_type in enumerate(symbols_to_extract):
            feedback.pushInfo('Importing {} from {}'.format(
                symbol_type, input_file))

            try:
                raw_symbols = Extractor.extract_styles(input_file, symbol_type)
            except MissingBinaryException:
                raise QgsProcessingException(  # pylint: disable=raise-missing-from
                    'The MDB tools "mdb-export" utility is required to convert .style databases. Please setup a path to the MDB tools utility in the SLYR options panel.'
                )

            feedback.pushInfo('Found {} symbols of type "{}"\n\n'.format(
                len(raw_symbols), symbol_type))

            if feedback.isCanceled():
                break

            unreadable = 0
            for index, raw_symbol in enumerate(raw_symbols):
                feedback.setProgress(index / len(raw_symbols) * type_percent +
                                     type_percent * type_index)
                if feedback.isCanceled():
                    break
                name = raw_symbol[Extractor.NAME]
                tags = raw_symbol[Extractor.TAGS].split(';')
                feedback.pushInfo('{}/{}: {}'.format(index + 1,
                                                     len(raw_symbols), name))

                unique_name = make_name_unique(name)
                if name != unique_name:
                    feedback.pushInfo(
                        'Corrected to unique name of {}'.format(unique_name))

                handle = BytesIO(raw_symbol[Extractor.BLOB])
                stream = Stream(handle)

                f = QgsFeature()
                try:
                    symbol = stream.read_object()
                except UnreadableSymbolException as e:
                    feedback.reportError(
                        'Error reading symbol {}: {}'.format(name, e), False)
                    unreadable += 1
                    if sink:
                        f.setAttributes(
                            [name, 'Error reading symbol: {}'.format(e)])
                        sink.addFeature(f)
                    continue
                except NotImplementedException as e:
                    feedback.reportError(
                        'Parsing {} is not supported: {}'.format(name, e),
                        False)
                    unreadable += 1
                    if sink:
                        f.setAttributes(
                            [name, 'Parsing not supported: {}'.format(e)])
                        sink.addFeature(f)
                    continue
                except UnsupportedVersionException as e:
                    feedback.reportError(
                        'Cannot read {} version: {}'.format(name, e), False)
                    unreadable += 1
                    if sink:
                        f.setAttributes(
                            [name, 'Version not supported: {}'.format(e)])
                        sink.addFeature(f)
                    continue
                except UnknownClsidException as e:
                    feedback.reportError(str(e), False)
                    unreadable += 1
                    if sink:
                        f.setAttributes([name, 'Unknown object: {}'.format(e)])
                        sink.addFeature(f)
                    continue
                except UnreadablePictureException as e:
                    feedback.reportError(str(e), False)
                    unreadable += 1
                    if sink:
                        f.setAttributes(
                            [name, 'Unreadable picture: {}'.format(e)])
                        sink.addFeature(f)
                    continue

                def unsupported_object_callback(msg, level=Context.WARNING):
                    if level == Context.WARNING:
                        feedback.reportError('Warning: {}'.format(msg), False)
                    elif level == Context.CRITICAL:
                        feedback.reportError(msg, False)

                    if sink:
                        feat = QgsFeature()
                        feat.setAttributes([name, msg])  # pylint: disable=cell-var-from-loop
                        sink.addFeature(feat)

                context = Context()
                context.symbol_name = unique_name
                context.style_folder, _ = os.path.split(output_file)
                context.unsupported_object_callback = unsupported_object_callback

                if symbol_type in (Extractor.AREA_PATCHES,
                                   Extractor.LINE_PATCHES):
                    feedback.reportError(
                        '{}: Legend patch conversion requires the licensed version of SLYR'
                        .format(name), False)
                    unreadable += 1
                    if sink:
                        f.setAttributes(
                            [name, 'Unreadable legend patch: {}'.format(name)])
                        sink.addFeature(f)
                    continue

                try:
                    qgis_symbol = SymbolConverter.Symbol_to_QgsSymbol(
                        symbol, context)

                except NotImplementedException as e:
                    feedback.reportError(str(e), False)
                    unreadable += 1
                    if sink:
                        f.setAttributes([name, str(e)])
                        sink.addFeature(f)
                    continue
                except UnreadablePictureException as e:
                    feedback.reportError(str(e), False)
                    unreadable += 1
                    if sink:
                        f.setAttributes(
                            [name, 'Unreadable picture: {}'.format(e)])
                        sink.addFeature(f)
                    continue

                if isinstance(qgis_symbol, QgsSymbol):
                    style.addSymbol(unique_name, qgis_symbol, True)
                elif isinstance(qgis_symbol, QgsColorRamp):
                    style.addColorRamp(unique_name, qgis_symbol, True)
                elif isinstance(qgis_symbol, QgsTextFormat):
                    if Qgis.QGIS_VERSION_INT >= 30900:
                        style.addTextFormat(unique_name, qgis_symbol, True)
                elif isinstance(qgis_symbol, QgsPalLayerSettings):
                    if Qgis.QGIS_VERSION_INT >= 30900:
                        style.addLabelSettings(unique_name, qgis_symbol, True)
                elif Qgis.QGIS_VERSION_INT >= 31300:
                    if isinstance(qgis_symbol, QgsLegendPatchShape):
                        style.addLegendPatchShape(unique_name, qgis_symbol,
                                                  True)

                if tags:
                    if isinstance(qgis_symbol, QgsSymbol):
                        assert style.tagSymbol(QgsStyle.SymbolEntity,
                                               unique_name, tags)
                    elif isinstance(qgis_symbol, QgsColorRamp):
                        assert style.tagSymbol(QgsStyle.ColorrampEntity,
                                               unique_name, tags)
                    elif isinstance(qgis_symbol, QgsTextFormat) and hasattr(
                            QgsStyle, 'TextFormatEntity'):
                        assert style.tagSymbol(QgsStyle.TextFormatEntity,
                                               unique_name, tags)
                    elif isinstance(qgis_symbol,
                                    QgsPalLayerSettings) and hasattr(
                                        QgsStyle, 'LabelSettingsEntity'):
                        assert style.tagSymbol(QgsStyle.LabelSettingsEntity,
                                               unique_name, tags)
                    elif Qgis.QGIS_VERSION_INT >= 31300:
                        if isinstance(qgis_symbol, QgsLegendPatchShape):
                            assert style.tagSymbol(
                                QgsStyle.LegendPatchShapeEntity, unique_name,
                                tags)

            if symbol_type == Extractor.FILL_SYMBOLS:
                results[self.FILL_SYMBOL_COUNT] = len(raw_symbols)
                results[self.UNREADABLE_FILL_SYMBOLS] = unreadable
            elif symbol_type == Extractor.LINE_SYMBOLS:
                results[self.LINE_SYMBOL_COUNT] = len(raw_symbols)
                results[self.UNREADABLE_LINE_SYMBOLS] = unreadable
            elif symbol_type == Extractor.MARKER_SYMBOLS:
                results[self.MARKER_SYMBOL_COUNT] = len(raw_symbols)
                results[self.UNREADABLE_MARKER_SYMBOLS] = unreadable
            elif symbol_type == Extractor.COLOR_RAMPS:
                results[self.COLOR_RAMP_COUNT] = len(raw_symbols)
                results[self.UNREADABLE_COLOR_RAMPS] = unreadable
            elif symbol_type == Extractor.TEXT_SYMBOLS:
                results[self.TEXT_FORMAT_COUNT] = len(raw_symbols)
                results[self.UNREADABLE_TEXT_FORMATS] = unreadable
            elif symbol_type in (Extractor.MAPLEX_LABELS, Extractor.LABELS):
                results[self.LABEL_SETTINGS_COUNT] += len(raw_symbols)
                results[self.UNREADABLE_LABEL_SETTINGS] += unreadable
            elif symbol_type == Extractor.LINE_PATCHES:
                results[self.LINE_PATCH_COUNT] = len(raw_symbols)
                results[self.UNREADABLE_LINE_PATCHES] = unreadable
            elif symbol_type == Extractor.AREA_PATCHES:
                results[self.AREA_PATCH_COUNT] = len(raw_symbols)
                results[self.UNREADABLE_AREA_PATCHES] = unreadable

        style.exportXml(output_file)
        results[self.OUTPUT] = output_file
        results[self.REPORT] = dest
        return results
コード例 #5
0
ファイル: style_items.py プロジェクト: nyalldawson/slyr
    def open_style(input_file):  # pylint: disable=too-many-locals,too-many-branches,too-many-statements
        """
        Opens a .style file
        """
        if input_file.lower().endswith(
                '.style') and not Extractor.is_mdb_tools_binary_available():
            message_bar = iface.messageBar()
            widget = message_bar.createMessage('SLYR',
                                               "MDB Tools utility not found")
            settings_button = QPushButton("Configure…",
                                          pressed=partial(
                                              BrowserUtils.open_settings,
                                              widget))
            widget.layout().addWidget(settings_button)
            message_bar.pushWidget(widget, Qgis.Critical)
            return True

        style = QgsStyle()
        style.createMemoryDatabase()

        symbol_names = set()

        def make_name_unique(original_name):
            """
            Ensures that the symbol name is unique (in a case-insensitive way)
            """
            counter = 0
            candidate = original_name
            while candidate.lower() in symbol_names:
                # make name unique
                if counter == 0:
                    candidate += '_1'
                else:
                    candidate = candidate[:candidate.rfind('_') +
                                          1] + str(counter)
                counter += 1
            symbol_names.add(candidate.lower())
            return candidate

        feedback = QgsFeedback()

        progress_dialog = QProgressDialog("Loading style database…", "Abort",
                                          0, 100, None)
        progress_dialog.setWindowTitle("Loading Style")

        def progress_changed(progress: float):
            """
            Handles feedback to progress dialog bridge
            """
            progress_dialog.setValue(int(progress))
            iterations = 0
            while QCoreApplication.hasPendingEvents() and iterations < 100:
                QCoreApplication.processEvents()
                iterations += 1

        feedback.progressChanged.connect(progress_changed)

        def cancel():
            """
            Slot to cancel the import
            """
            feedback.cancel()

        progress_dialog.canceled.connect(cancel)
        unreadable = []
        warnings = set()
        errors = set()

        types_to_extract = [
            Extractor.FILL_SYMBOLS, Extractor.LINE_SYMBOLS,
            Extractor.MARKER_SYMBOLS, Extractor.COLOR_RAMPS,
            Extractor.TEXT_SYMBOLS, Extractor.LABELS, Extractor.MAPLEX_LABELS,
            Extractor.AREA_PATCHES, Extractor.LINE_PATCHES
        ]

        type_percent = 100 / len(types_to_extract)

        for type_index, symbol_type in enumerate(types_to_extract):

            try:
                raw_symbols = Extractor.extract_styles(input_file, symbol_type)
            except MissingBinaryException:
                BrowserUtils.show_warning(
                    'MDB Tools utility not found',
                    'Convert style',
                    'The MDB tools "mdb-export" utility is required to convert .style databases. Please setup a path to the MDB tools utility in the SLYR options panel.',
                    level=Qgis.Critical)
                progress_dialog.deleteLater()
                return True

            if feedback.isCanceled():
                break

            for index, raw_symbol in enumerate(raw_symbols):
                feedback.setProgress(
                    int(index / len(raw_symbols) * type_percent +
                        type_percent * type_index))
                if feedback.isCanceled():
                    break
                name = raw_symbol[Extractor.NAME]
                tags = raw_symbol[Extractor.TAGS].split(';')

                unique_name = make_name_unique(name)

                handle = BytesIO(raw_symbol[Extractor.BLOB])
                stream = Stream(handle)
                stream.allow_shortcuts = False

                try:
                    symbol = stream.read_object()
                except UnreadableSymbolException as e:
                    e = 'Unreadable object: {}'.format(e)
                    unreadable.append('<b>{}</b>: {}'.format(
                        html.escape(name), html.escape(str(e))))
                    continue
                except NotImplementedException as e:
                    unreadable.append('<b>{}</b>: {}'.format(
                        html.escape(name), html.escape(str(e))))
                    continue
                except UnsupportedVersionException as e:
                    e = 'Unsupported version: {}'.format(e)
                    unreadable.append('<b>{}</b>: {}'.format(
                        html.escape(name), html.escape(str(e))))
                    continue
                except UnknownClsidException as e:
                    unreadable.append('<b>{}</b>: {}'.format(
                        html.escape(name), html.escape(str(e))))
                    continue
                except UnreadablePictureException as e:
                    unreadable.append('<b>{}</b>: {}'.format(
                        html.escape(name), html.escape(str(e))))
                    continue

                context = Context()
                context.symbol_name = unique_name

                def unsupported_object_callback(msg, level=Context.WARNING):
                    if level == Context.WARNING:
                        warnings.add('<b>{}</b>: {}'.format(
                            html.escape(unique_name),  # pylint: disable=cell-var-from-loop
                            html.escape(msg)))
                    elif level == Context.CRITICAL:
                        errors.add('<b>{}</b>: {}'.format(
                            html.escape(unique_name),  # pylint: disable=cell-var-from-loop
                            html.escape(msg)))

                context.unsupported_object_callback = unsupported_object_callback
                # context.style_folder, _ = os.path.split(output_file)

                if symbol_type in (Extractor.AREA_PATCHES,
                                   Extractor.LINE_PATCHES):
                    unreadable.append(
                        '<b>{}</b>: Legend patch conversion requires the licensed version of SLYR'
                        .format(html.escape(name)))
                    continue

                try:
                    qgis_symbol = SymbolConverter.Symbol_to_QgsSymbol(
                        symbol, context)
                except NotImplementedException as e:
                    unreadable.append('<b>{}</b>: {}'.format(
                        html.escape(name), html.escape(str(e))))
                    continue
                except UnreadablePictureException as e:
                    unreadable.append('<b>{}</b>: {}'.format(
                        html.escape(name), html.escape(str(e))))
                    continue

                if isinstance(qgis_symbol, QgsSymbol):
                    # self.check_for_missing_fonts(qgis_symbol, feedback)
                    style.addSymbol(unique_name, qgis_symbol, True)
                elif isinstance(qgis_symbol, QgsColorRamp):
                    style.addColorRamp(unique_name, qgis_symbol, True)
                elif isinstance(qgis_symbol, QgsTextFormat):
                    if Qgis.QGIS_VERSION_INT >= 30900:
                        style.addTextFormat(unique_name, qgis_symbol, True)
                elif isinstance(qgis_symbol, QgsPalLayerSettings):
                    if Qgis.QGIS_VERSION_INT >= 30900:
                        style.addLabelSettings(unique_name, qgis_symbol, True)
                elif Qgis.QGIS_VERSION_INT >= 31300:
                    if isinstance(qgis_symbol, QgsLegendPatchShape):
                        style.addLegendPatchShape(unique_name, qgis_symbol,
                                                  True)

                if tags:
                    if isinstance(qgis_symbol, QgsSymbol):
                        assert style.tagSymbol(QgsStyle.SymbolEntity,
                                               unique_name, tags)
                    elif isinstance(qgis_symbol, QgsColorRamp):
                        assert style.tagSymbol(QgsStyle.ColorrampEntity,
                                               unique_name, tags)
                    elif isinstance(qgis_symbol, QgsTextFormat) and hasattr(
                            QgsStyle, 'TextFormatEntity'):
                        assert style.tagSymbol(QgsStyle.TextFormatEntity,
                                               unique_name, tags)
                    elif isinstance(qgis_symbol,
                                    QgsPalLayerSettings) and hasattr(
                                        QgsStyle, 'LabelSettingsEntity'):
                        assert style.tagSymbol(QgsStyle.LabelSettingsEntity,
                                               unique_name, tags)
                    elif Qgis.QGIS_VERSION_INT >= 31300:
                        if isinstance(qgis_symbol, QgsLegendPatchShape):
                            assert style.tagSymbol(
                                QgsStyle.LegendPatchShapeEntity, unique_name,
                                tags)
        progress_dialog.deleteLater()
        if feedback.isCanceled():
            return True

        if errors or unreadable or warnings:
            message = ''
            if unreadable:
                message = '<p>The following symbols could not be converted:</p>'
                message += '<ul>'
                for w in unreadable:
                    message += '<li>{}</li>'.format(w.replace('\n', '<br>'))
                message += '</ul>'

            if errors:
                message += '<p>The following errors were generated while converting symbols:</p>'
                message += '<ul>'
                for w in errors:
                    message += '<li>{}</li>'.format(w.replace('\n', '<br>'))
                message += '</ul>'

            if warnings:
                message += '<p>The following warnings were generated while converting symbols:</p>'
                message += '<ul>'
                for w in warnings:
                    message += '<li>{}</li>'.format(w.replace('\n', '<br>'))
                message += '</ul>'

            BrowserUtils.show_warning(
                'style could not be completely converted',
                'Convert style',
                message,
                level=Qgis.Critical if
                (unreadable or errors) else Qgis.Warning)

        if Qgis.QGIS_VERSION_INT >= 30800:
            dlg = QgsStyleManagerDialog(style, readOnly=True)
            dlg.setFavoritesGroupVisible(False)
            dlg.setSmartGroupsVisible(False)
            fi = QFileInfo(input_file)
            dlg.setBaseStyleName(fi.baseName())
        else:
            dlg = QgsStyleManagerDialog(style)
        dlg.setWindowTitle(fi.baseName())
        dlg.exec_()
        return True