File indexing completed on 2024-04-28 04:36:31

0001 /*
0002     SPDX-FileCopyrightText: 2008 Cédric Pasteur <cedric.pasteur@free.fr>
0003 
0004     SPDX-License-Identifier: LGPL-2.0-or-later
0005 */
0006 
0007 #ifndef KDEVPLATFORM_ISOURCEFORMATTER_H
0008 #define KDEVPLATFORM_ISOURCEFORMATTER_H
0009 
0010 #include <QMetaType>
0011 #include <QWidget>
0012 
0013 #include "interfacesexport.h"
0014 
0015 #include <memory>
0016 
0017 class QDebug;
0018 class QUrl;
0019 class QMimeType;
0020 class QStringList;
0021 
0022 namespace KDevelop
0023 {
0024 
0025 class KDEVPLATFORMINTERFACES_EXPORT SourceFormatterStyle
0026 {
0027 public:
0028     struct MimeHighlightPair {
0029         QString mimeType;
0030         QString highlightMode;
0031     };
0032     using MimeList = QVector<MimeHighlightPair>;
0033 
0034     SourceFormatterStyle();
0035     explicit SourceFormatterStyle( const QString& name );
0036 
0037     const QString& name() const
0038     {
0039         return m_name;
0040     }
0041 
0042     void setContent( const QString& content );
0043     void setCaption( const QString& caption );
0044     QString content() const;
0045     const QString& caption() const
0046     {
0047         return m_caption;
0048     }
0049 
0050     QString description() const;
0051     void setDescription( const QString& desc );
0052     bool usePreview() const;
0053     void setUsePreview(bool use);
0054 
0055     void setMimeTypes( const MimeList& types );
0056     void setMimeTypes( const QStringList& types );
0057 
0058     /// Provides the possibility to the item to return a better-suited
0059     /// code sample. If empty, the default is used.
0060     QString overrideSample() const;
0061     void setOverrideSample( const QString& sample );
0062 
0063     MimeList mimeTypes() const;
0064     /// mime types as a QVariantList, type and mode separated by | in strings
0065     QVariant mimeTypesVariant() const;
0066     bool supportsLanguage(const QString& language) const;
0067 
0068     /// get the language / highlight mode for a given @p mime
0069     QString modeForMimetype(const QMimeType& mime) const;
0070 
0071     /// Copy everything but name, caption and description from @p other to *this.
0072     /// Call this function to set up a new user-defined style based on an existing style.
0073     void copyDataFrom(const SourceFormatterStyle& other);
0074 
0075 private:
0076     bool m_usePreview = false;
0077     /// logically const: is modified only in compiler-generated special member functions
0078     QString m_name;
0079     QString m_caption;
0080     QString m_content;
0081     QString m_description;
0082     QString m_overrideSample;
0083     MimeList m_mimeTypes;
0084 };
0085 
0086 inline bool operator==(const SourceFormatterStyle::MimeHighlightPair& a,
0087                        const SourceFormatterStyle::MimeHighlightPair& b)
0088 {
0089     return a.mimeType == b.mimeType && a.highlightMode == b.highlightMode;
0090 }
0091 
0092 KDEVPLATFORMINTERFACES_EXPORT QDebug operator<<(QDebug dbg, const SourceFormatterStyle& style);
0093 
0094 /**
0095  * @brief An object describing a style associated with a plugin
0096  *        which can deal with this style.
0097  */
0098 struct SourceFormatterStyleItem {
0099     QString engine;
0100     SourceFormatterStyle style;
0101 };
0102 
0103 using SourceFormatterItemList = QVector<SourceFormatterStyleItem>;
0104 
0105 /**
0106 * @short A widget to edit a style
0107 * A plugin should inherit this widget to create a widget to
0108 * edit a style.
0109 * @author Cédric Pasteur
0110 */
0111 class KDEVPLATFORMINTERFACES_EXPORT SettingsWidget : public QWidget
0112 {
0113         Q_OBJECT
0114 
0115     public:
0116         explicit SettingsWidget(QWidget *parent = nullptr);
0117         ~SettingsWidget() override;
0118 
0119         /** This function is called after the creation of the dialog.
0120          *
0121          * @param style a custom, not predefined, style to be edited
0122          *
0123          * @note This function must emit previewTextChanged().
0124          */
0125         virtual void load(const SourceFormatterStyle& style) = 0;
0126 
0127         /** \return A string representing the state of the config.
0128         */
0129         virtual QString save() const = 0;
0130 
0131     Q_SIGNALS:
0132         /**
0133          * This signal is emitted whenever a setting changes and the preview needs to be updated.
0134          *
0135          * @param text non-empty code sample to be formatted and displayed as style preview
0136          *
0137          * @note The preview text may depend on the current page shown in the widget.
0138          *       So @p text may be different each time this signal is emitted.
0139          */
0140         void previewTextChanged(const QString &text);
0141 };
0142 
0143 using SettingsWidgetPtr = std::unique_ptr<SettingsWidget>;
0144 
0145 /**
0146  * @short An interface for a source beautifier
0147  * An example of a plugin using an external executable to do
0148  * the formatting can be found in kdevelop/plugins/formatters/indent_plugin.cpp.
0149  * @author Cédric Pasteur
0150  */
0151 class KDEVPLATFORMINTERFACES_EXPORT ISourceFormatter
0152 {
0153     public:
0154         virtual ~ISourceFormatter();
0155 
0156         /** \return The name of the plugin. This should contain only
0157         * ASCII chars and no spaces. This will be used internally to identify
0158         * the plugin.
0159         */
0160         virtual QString name() const = 0;
0161         /** \return A caption describing the plugin.
0162         */
0163         virtual QString caption() const = 0;
0164         /** \return A more complete description of the plugin.
0165         * The string should be written in Rich text. It can eg contain
0166         * a link to the project homepage.
0167         */
0168         virtual QString description() const = 0;
0169 
0170         /**
0171          * @return important information to display in style configuration UI
0172          *
0173          * @note The default implementation returns an empty string, which conveniently
0174          *       saves UI space if there is no important information to display.
0175          */
0176         virtual QString usageHint() const;
0177 
0178         /**
0179          * Format with the given style, this is mostly for the kcm to format the preview text
0180          * Its a bit of a hassle that this needs to be public API, but I can't find a better way
0181          * to do this.
0182          */
0183         virtual QString formatSourceWithStyle( const SourceFormatterStyle& style,
0184                                                const QString& text,
0185                                                const QUrl& url,
0186                                                const QMimeType &mime,
0187                                                const QString& leftContext = QString(),
0188                                                const QString& rightContext = QString() ) const = 0;
0189 
0190         /** \return A map of predefined styles (a key and a caption for each type)
0191         */
0192         virtual QVector<SourceFormatterStyle> predefinedStyles() const = 0;
0193 
0194         /** \return A predefined style with the specified name or SourceFormatterStyle{name}
0195         * if this formatter has no such predefined style.
0196         */
0197         SourceFormatterStyle predefinedStyle(const QString& name) const;
0198 
0199         /**
0200          * @return whether editStyleWidget() returns a valid pointer
0201          */
0202         virtual bool hasEditStyleWidget() const = 0;
0203 
0204         /** \return The widget to edit a style.
0205         */
0206         virtual SettingsWidgetPtr editStyleWidget(const QMimeType &mime) const = 0;
0207 
0208         /** \return The text used in the config dialog to preview the current style.
0209         */
0210         virtual QString previewText(const SourceFormatterStyle& style, const QMimeType &mime) const = 0;
0211 
0212         struct Indentation {
0213             Indentation() {
0214             }
0215             // If this indentation is really valid
0216             bool isValid() const {
0217                 return indentationTabWidth != 0 || indentWidth != 0;
0218             }
0219 
0220             // The length of one tab used for indentation.
0221             // Zero if unknown, -1 if tabs should not be used for indentation
0222             int indentationTabWidth = 0;
0223 
0224             // The number of columns that equal one indentation level.
0225             // If this is zero, the default should be used.
0226             int indentWidth = 0;
0227         };
0228 
0229         /** \return The indentation of @p style applicable for @p url and its MIME type @p mime
0230         */
0231         virtual Indentation indentation(const SourceFormatterStyle& style, const QUrl& url,
0232                                         const QMimeType& mime) const = 0;
0233 
0234         /** \return A string representing the map. Values are written in the form
0235         * key=value and separated with ','.
0236         */
0237         static QString optionMapToString(const QMap<QString, QVariant> &map);
0238         /** \return A map corresponding to the string, that was created with
0239         * \ref optionMapToString.
0240         */
0241         static QMap<QString, QVariant> stringToOptionMap(const QString &option);
0242 
0243         /** \return The shared list of MIME types supported by each built-in style.
0244         */
0245         static SourceFormatterStyle::MimeList mimeTypesSupportedByBuiltInStyles();
0246 
0247         /** \return A message to display when an executable needed by a
0248         * plugin is missing. This should be returned as description
0249         * if a needed executable is not found.
0250         */
0251         static QString missingExecutableMessage(const QString &name);
0252 };
0253 
0254 }
0255 
0256 Q_DECLARE_INTERFACE(KDevelop::ISourceFormatter, "org.kdevelop.ISourceFormatter")
0257 Q_DECLARE_METATYPE(KDevelop::SourceFormatterStyle*)
0258 Q_DECLARE_TYPEINFO(KDevelop::SourceFormatterStyle::MimeHighlightPair, Q_MOVABLE_TYPE);
0259 Q_DECLARE_TYPEINFO(KDevelop::SourceFormatterStyle, Q_MOVABLE_TYPE);
0260 Q_DECLARE_TYPEINFO(KDevelop::SourceFormatterStyleItem, Q_MOVABLE_TYPE);
0261 
0262 #endif // KDEVPLATFORM_ISOURCEFORMATTER_H