一、HTML编辑器核心类和接口简介

1、HTML编辑器简介

QtCreator最基本的功能是一个文本编辑器。QtCreator还提供了编辑UI文件、QRC文件、PRO/PRI文件以及EXE/DLL/SO文件的功能。

HTML编辑器插件将使QtCreator能够从本地文件系统中加载HTML文件,并且能够查看和编辑。

为了支持新的编辑器类型,需要:

A、实现一个插件类(实现Core::IPlugin接口),暴露出一个“编辑器工厂”。

B、实现“编辑器工厂”,即Core::IEditorFactory接口。Core::IEditorFactory接口提供了帮助创建特定格式编辑器对象的函数。

C、实现编辑器,即Core::IEditor接口。Core::IEditor接口提供了用于辅助编辑一种文件格式(例如 HTML、PDF 等)的函数。编辑器必须提供访问它所要显示或者编辑的文件的函数。

D、实现接口Core::IDocument。Core::IDocument接口用于辅助从磁盘进行数据加载或保存。

2、Core::IDocument接口

Core::IDocument接口将文件操作从用户界面抽象出来,提供用于加载和保存文件以及获取文件名的虚函数。IDocument可以将文件看做具有mime-tyle、“modified”和“read-only”等标记位的对象。IDocument接口在src/plugins/coreplugin/idocument.h中声明:

#ifndef IDOCUMENT_H
#define IDOCUMENT_H#include "core_global.h"
#include <QObject>namespace Core {class MimeType;
class InfoBar;class CORE_EXPORT IDocument : public QObject
{Q_OBJECT
public:// This enum must match the indexes of the reloadBehavior widget// in generalsettings.uienum ReloadSetting {AlwaysAsk = 0,ReloadUnmodified = 1,IgnoreAll = 2};enum Utf8BomSetting {AlwaysAdd = 0,OnlyKeep = 1,AlwaysDelete = 2};enum ChangeTrigger {TriggerInternal,TriggerExternal};enum ChangeType {TypeContents,TypePermissions,TypeRemoved};enum ReloadBehavior {BehaviorAsk,BehaviorSilent};enum ReloadFlag {FlagReload,FlagIgnore};IDocument(QObject *parent = 0);virtual ~IDocument();virtual bool save(QString *errorString, const QString &fileName = QString(), bool autoSave = false) = 0;virtual QString fileName() const = 0;virtual bool isFileReadOnly() const;virtual QString defaultPath() const = 0;virtual QString suggestedFileName() const = 0;virtual QString mimeType() const = 0;virtual bool shouldAutoSave() const;virtual bool isModified() const = 0;virtual bool isSaveAsAllowed() const = 0;virtual ReloadBehavior reloadBehavior(ChangeTrigger state, ChangeType type) const;virtual bool reload(QString *errorString, ReloadFlag flag, ChangeType type) = 0;virtual void rename(const QString &newName) = 0;virtual void checkPermissions();bool autoSave(QString *errorString, const QString &fileName);void setRestoredFrom(const QString &name);void removeAutoSaveFile();bool hasWriteWarning() const { return m_hasWriteWarning; }void setWriteWarning(bool has) { m_hasWriteWarning = has; }InfoBar *infoBar();
signals:void changed();void aboutToReload();void reloadFinished(bool success);void fileNameChanged(const QString &oldName, const QString &newName);
private:QString m_autoSaveName;InfoBar *m_infoBar;bool m_hasWriteWarning;bool m_restored;
};} // namespace Core#endif // IDOCUMENT_H

IDocument与QFile的区别如下:

IDocument关心的是以文件名为参数,将一个文件的内容加载进一个编辑器editor的行为,而QFile仅仅是将文件内容加载到一个QByteArray对象;IDocument需要在用户在编辑器中修改了文件内容的时候发出modified()信号,此时的文件修改并没有写入磁盘;而QFile只有在文件内容写入磁盘时才会发出bytesWritten()信号;IDocument需要处理一个在磁盘被修改的文件如何重新加载到编辑器中,而QFile不需要处理这种问题。

3、Core::IEditor接口

Core::IEditor接口的实现提供了编辑不同类型文件的编辑器。IEditor接口位于src/plugins/coreplugin/editormanager/ieditor.h中。

#ifndef IEDITOR_H
#define IEDITOR_H#include <coreplugin/core_global.h>
#include <coreplugin/icontext.h>#include <QMetaType>namespace Core {class IDocument;class CORE_EXPORT IEditor : public IContext
{Q_OBJECT
public:IEditor(QObject *parent = 0) : IContext(parent) {}virtual ~IEditor() {}virtual bool createNew(const QString &contents = QString()) = 0;virtual bool open(QString *errorString, const QString &fileName, const QString &realFileName) = 0;virtual IDocument *document() = 0;virtual Core::Id id() const = 0;virtual QString displayName() const = 0;virtual void setDisplayName(const QString &title) = 0;virtual bool duplicateSupported() const { return false; }virtual IEditor *duplicate(QWidget * /*parent*/) { return 0; }virtual QByteArray saveState() const { return QByteArray(); }virtual bool restoreState(const QByteArray &/*state*/) { return true; }virtual int currentLine() const { return 0; }virtual int currentColumn() const { return 0; }virtual void gotoLine(int line, int column = 0) { Q_UNUSED(line) Q_UNUSED(column) }virtual bool isTemporary() const = 0;virtual QWidget *toolBar() = 0;virtual bool isDesignModePreferred() const { return false; }
signals:void changed();
};} // namespace CoreQ_DECLARE_METATYPE(Core::IEditor*)#endif // IEDITOR_H

Core::IEditor主要提供以下功能:

A、一个编辑器组件(由Core::IEditor::widget()函数返回)。QtCreator使用这个组件显示编辑文件的内容;

B、Core::IDocument接口实现的document对象的获取(由Core::IEditor::document()函数返回),QtCreator使用document对象触发文件从磁盘加载以及保存到磁盘的操作;

C、一个自定义的工具条 toolbar,QtCreator会在该编辑器可用时自动加载该工具条;

D、在文件中光标的当前位置(Core::IEditor::currentLine()和Core::IEditor::currentColumn()函数)

E、需要显示在“打开文件”列表的名字。

4、Core::IEditorFactory

Core::IEditorFactory提供了用于创建可支持MIME类型的Core::IEditor实例的函数。Core::IEditorFactory接口在src/plugins/coreplugin/editormanager/ieditorfactory.h中声明。

#ifndef IEDITORFACTORY_H
#define IEDITORFACTORY_H#include <coreplugin/idocumentfactory.h>namespace Core {class IEditor;class CORE_EXPORT IEditorFactory : public Core::IDocumentFactory
{Q_OBJECT
public:IEditorFactory(QObject *parent = 0) : IDocumentFactory(parent) {}virtual IEditor *createEditor(QWidget *parent) = 0;virtual IDocument *open(const QString &);
};} // namespace Core#endif // IEDITORFACTORY_H

IEditorFactory::createEditor()则用于创建一个具体的编辑器实例并将其返回。

5、Core::MimeDatabase

Core::MimeDatabase类用于保存QtCreator所支持的所有的 mime-type;同时也可以辅助判断给定文件的mime-type。

#include <coreplugin/mimedatabase.h>Core::ICore* core = Core::ICore::instance();
Core::MimeDatabase* mdb = core->mimeDatabase();
Core::MimeType type1 = mdb->findByFile( QFileInfo("./sample.html") );
qDebug("File Type for sample.html = %s", qPrintable(type1.type()));
Core::MimeType type2 = mdb->findByFile( QFileInfo("./Main.cpp") );
qDebug("File Type for Main.cpp = %s", qPrintable(type2.type()));
Core::MimeType type3 = mdb->findByFile( QFileInfo("./TextEdit.pro") );
qDebug("File Type for TextEdit.pro = %s", qPrintable(type3.type()));

结果如下:

File Type for sample.html = text/plain
File Type for Main.cpp = text/x-c++src
File Type for TextEdit.pro = text/plain

Core::MimeDatabase使用文件名后缀、glob模式(正则表达式)、魔数匹配器计算所给文件的MIME类型。

Core::IEditorFactory接口提供一个指定MIME类型的由Core::IEditor实现的编辑器。以下的过程有助于我们理解QtCreator如何根据给定的文件名选择合适的Core::IEditorFactory。

A、用户点击File->Open,选择要打开的文件

B、QtCreator使用Core::MimeDatabase获取选中文件的MIME类型

C、QtCreator遍历运行所有实现的Core::IEditorFactory,选择支持相应MIME类型的编辑器工厂。

D、QtCreator请求选中的编辑器工厂创建一个编辑器。

E、BaseTextEditor::editorWidget()函数返回组件,在主窗口显示

F、Core::IEditor::open()函数打开选择的文件

6、增加一个MIME类型

如果想要支持一个新的编辑器类型,需要将新编辑器支持的MIME类型注册到Core::MimeDatabase。注册新的MIME类型到Core::MimeDatabase有多种方法。最简单的方法是从一个XML文件注册新的MIME 类型。

假定注册一个MIME类型为text/html,并将其关联*.html文件名,可以创建一个text-html-mimetype.xml文件,内容如下:

<?xml version="1.0" encoding="UTF-8"?>
<mime-info  xmlns='http://www.freedesktop.org/standards/shared-mime-info'><mime-type type="text/html"><sub-class-of type="text/plain"/><comment>HTML File</comment><glob pattern="*.html"/></mime-type>
</mime-info>

注册由XML描述的MIME类型可以使用Core::MimeDatabase::addMimeTypes()函数。

Core::ICore* core = Core::ICore::instance();
Core::MimeDatabase* mdb = core->mimeDatabase();
QString errMsg;
bool success = mdb->addMimeTypes("text-html-mimetype.xml", errMsg);

注册成功后,QtCreator会映射文件名为*.html的文件到text/plain类型。

二、HTMLEditor编辑器的实现

1、HTML编辑器设计

HTML编辑器作为QtCreator的插件存在,支持HTML文件的查看和编辑。用户可以使用标准的File -> Open菜单打开HTML文件,使用File -> Save菜单保存HTML文件的变化。界面如下:

HTML编辑器在底部有Preview和Source两个按钮,点击Source按钮时,HTML编辑器在QPlainTextEdit组件中显示HTML文件代码。在Source选项页时,用户可以修改HTML文件内容,并且在切换到Preview选项页时能够预览HTML的效果。

HTML编辑器的类设计如下:

HTMLEditorWidget:继承自QTabWidget,提供有两个选项卡的tab组件,用于预览HTML效果和显示HTML代码。

HTMLDocument:实现了Core::IDocument接口,用于在HTMLEditorWidget组件显示的文件。

HTMLEditor:实现了Core::IEditor接口,用于管理HTMLEditorWidget组件

HTMLEditorFactory:实现了Core::IEditorFactory接口,用于创建一个text/html类型的IEditor实例。

HTMLEditorPlugin:实现了Core::IPlugin接口,用于在QtCreator中回调HTMLEditorWidget、HTMLDocument、HTMLEditor、HTMLEditorFactory。

QtCreator插件开发(四)——QtCreator编辑器相关推荐

  1. QtCreator插件开发(一)——QtCreator插件实例

    本文将使用QtCreator-2.8.1版本进行插件开发,由于QtCreator-2.8.1的插件机制进行了部分更改,因此将根据QtCreator-2.8.1插件机制为基础撰写本文. 一.QtCrea ...

  2. CorelDRAWX4的VBA插件开发(四) 用一个例子了解CORELDRAW-X4的四个基本对象

    CorelDRAWX4的VBA插件开发(四) 用一个例子了解CORELDRAW-X4的四个基本对象 1.打开第一章的界面如下图: 2.把之前的代码稍作修改 Sub 第一个插件()Dim zongShu ...

  3. SRPG游戏开发(三十四)第八章 游戏中的数据 - 四 数据编辑器(Data Editor)

    返回总目录 第八章 游戏中的数据(Data in Game) 在之前的章节中,我们进行地图对象的生成,移动等操作. 这一章本来可以进行战斗的编写,不过数据缺失是一个问题. 所以这一章我们先来建立一些数 ...

  4. 我的第四款编辑器:微信公众号上使用 Markdown 来显示代码

    这已经是我第四次写编辑器了~~~ 第一次是在三年前(2014年4月份),当时我听说有一个工具叫 Node-Webkit,于是我就结合CodeMirror撸了一个编辑器,界面如下: GitHub 地址: ...

  5. eclipse插件开发(四) 流程图绘制插件(雏形)

    1.新建一个Plug-in Project, 名为FlowPlugin, Templates选择Multi-page editor, 后缀指定为flow 2.分为2个页签: 源码和设计, 源码使用XM ...

  6. CorelDRAWX4的C++插件开发(四十)纯C++插件开发(4)继承插件结构体IVGAppPlugin和自动化接口IDispatch

    因为在注册插件的时候,是要传一个名为IDispatch*这样子的一个参数,所以我们可以看到插件在注册的时候默认就是要求这是一个实现了自动化的接口(IDispatch,如下图所示,是后面将要展示的代码, ...

  7. CorelDRAWX4的C++插件开发(四十三)VBA的错误返回机制

    我们在写程序的时候往往不知道内部出了什么问题,所以问题返回机制还是比较重要的,程序可以不正确,但是程序一出问题直接就闪退崩溃也是一大麻烦,所以这里我们先探讨一下VBA的错误返回机制 我们先上代码 Co ...

  8. CorelDRAWX4的C++插件开发(四十一)纯C++插件开发(5)实现六个纯虚函数

    这一节我们实现六个剩余的纯虚函数,先上代码 HRESULT __stdcall CongLingKaiShi::QueryInterface(REFIID riid, void** ppvObject ...

  9. CorelDRAWX4的VBA插件开发(四十六)VBA插入启动事件让CDR启动时检测并自动添加工具栏和按钮

    先上结果图,这个工具栏和按钮都是主程序自动生成的 在程序的运行当中,如果我们希望程序能够自己创建工具栏和按钮,可以在CDR启动事件中设置一个检测功能 Private Sub GlobalMacroSt ...

最新文章

  1. 例6.12(Java)
  2. 国家发改委:春运期间推动“健康码”全国一码通行
  3. ruby on rails Mac 安装
  4. 一个下课的时间带你手写promise!
  5. 训练千亿参数模型的法宝,昇腾CANN异构计算架构来了~
  6. java中如何访问类中的字段_java – 在子类中使用super关键字访问超类私有字段
  7. 【原创】字典攻击教务处(BurpSuite使用)
  8. 【数据分析方法论】关于思维、营销、咨询、绩效管理的一些经典分析框架
  9. 电脑/手机怎么查看连接的wifi的密码
  10. 看黄天鹅如何下一颗高端鸡蛋?
  11. 构建股票交易平台专业术语
  12. 【技巧】搭建企业公司网站的实施步骤有哪些
  13. Chapter3:根轨迹法(下)
  14. Spring中的IOC介绍
  15. 图文解读Fcoin发布的FT公链
  16. YX360与新华教育集团达成人才招聘合作意向
  17. ExoPlayer播放器剖析(五)ExoPlayer对AudioTrack的操作
  18. asterisk1.8中设置presence或blf
  19. JS笔记(字符串篇)——字符串当中找出元素出现的位置和次数统计字符串中出现最多元素的字符与次数
  20. 快手呆3年,股票3000万!

热门文章

  1. 【金融量化】深度学习在金融中的研究热点以及应用
  2. 爬取百度贴吧图片-python-requests
  3. AndroidStudio 弹出的Safe Delete 安全删除功能是什么
  4. 洛谷 P5664 Emiya 家今天的饭【dp】
  5. dya-11(周一)新的知识点
  6. 深刻理解空间(线性空间,度量空间,赋范空间,线性赋范空间,内积空间,巴拿赫空间以及希尔伯特空间)
  7. 图像成像原理与相机标定
  8. MATLAB将灰度图转换为彩色图像源码实战
  9. 本科毕业论文检测 有没有自己可以检测的系统,怎么进去检测?
  10. CAPEX OPEX