Qt Creator 插件开发(11):添加新的编辑器(续三)

Core::IFile

我们使用HtmlFile类实现Core::IFile接口。除了要实现IFile接口中的纯虚函数,我们还添加了一个名为modified的标志位,用于标记文件内容是否被修改:

#ifndef HTMLFILE_H
#define HTMLFILE_H

#include <coreplugin/ifile.h>

#include "HtmlEditor.h"

class HtmlEditorWidget;
class HtmlEditor;

struct HtmlFileData;

class HtmlFile : public Core::IFile
{
    Q_OBJECT

public:
    HtmlFile(HtmlEditor* editor, HtmlEditorWidget* editorWidget);
    ~HtmlFile();
    void setModified(bool val=true);
    bool open(const QString &fileName);
    void setFilename(const QString& filename);
    QString fileExtension() const;

    bool save(const QString &fileName = QString());
    QString fileName() const;

    QString defaultPath() const;
    QString suggestedFileName() const;
    QString mimeType() const;

    bool isModified() const;
    bool isReadOnly() const;
    bool isSaveAsAllowed() const;

    ReloadBehavior reloadBehavior(ChangeTrigger state, ChangeType type) const;
    void reload(ReloadFlag flag, ChangeType type);
    void rename(const QString &newName);

protected slots:
    void modified() { setModified(true); }

private:
    HtmlFileData* d;
};

struct HtmlFileData
{
    HtmlFileData()
        : mimeType(HtmlEditorConstants::C_HTMLEDITOR_MIMETYPE),
          editorWidget(0), editor(0), modified(false) { }
    const QString mimeType;
    HtmlEditorWidget* editorWidget;
    HtmlEditor* editor;
    QString fileName;
    bool modified;
};

#endif // HTMLFILE_H

HtmlFile的构造函数很简单吗,仅仅是初始化了HtmlFileData数据指针,目的是在HtmlFile的实例中,将用于编辑逻辑的HtmlEdit和 用于显示的HtmlEditWidget关联起来:

HtmlFile::HtmlFile(HtmlEditor* editor, HtmlEditorWidget* editorWidget)
         : Core::IFile(editor)
{
    d = new HtmlFileData;
    d->editor = editor;
    d->editorWidget = editorWidget;
}

析构函数不做任何操作,仅仅删除 d 指针:

HtmlFile::~HtmlFile()
{
    delete d;
}

setModified()函数设置内容改变的标志位,同时要发出changed()信号。注意这里的条件判断,避免出现changed()会一直发出的情况:

void HtmlFile::setModified(bool val)
{
    if(d->modified == val)
        return;
    d->modified = val;
    emit changed();
}

bool HtmlFile::isModified() const
{
    return d->modified;
}

mimeType()用于返回该类能够处理的 mime-type:

QString HtmlFile::mimeType() const
{
    return d->mimeType;
}

save()函数在 file->save (Ctrl+s) 动作发出时被调用。这个函数会保存HtmlEditorWidget中油纯文本编辑器显示的内容;在将修改内容保存到磁盘之后,modified标志设置成 false:

bool HtmlFile::save(const QString &fileName)
{
    QFile file(fileName);
    if(file.open(QFile::WriteOnly)) {
        d->fileName = fileName;
        QByteArray content = d->editorWidget->content();
        file.write(content);
        setModified(false);
        return true;
    }
    return false;
}

open()函数在 file->open 动作发出时被调用。这个函数打开一个文件,然后调用HtmlEditWidgetsetContent()函数,将文件内容显示在编辑器中。显示名字则被设置为 HTML 文件的 title。

bool HtmlFile::open(const QString &fileName)
{
    QFile file(fileName);
    if(file.open(QFile::ReadOnly)) {
        d->fileName = fileName;
        QString path = QFileInfo(fileName).absolutePath();
        d->editorWidget->setContent(file.readAll(), path);
        d->editor->setDisplayName(d->editorWidget->title());
        return true;
    }
    return false;
}

下面函数则是实现了fileName属性:

void HtmlFile::setFilename(const QString& filename)
{
    d->fileName = filename;
}

QString HtmlFile::fileName() const
{
    return d->fileName;
}

defaultPath()函数,suggestedFileName()函数,fileExtension()函数等,现阶段不作任何操作:

QString HtmlFile::defaultPath() const
{
    return QString();
}

QString HtmlFile::suggestedFileName() const
{
    return QString();
}

QString HtmlFile::fileExtension() const
{
    return QString();
}

因为我们想要保存修改文件,所以我们需要将readOnly设置为 false:

bool HtmlFile::isReadOnly() const
{
    return false;
}

bool HtmlFile::isSaveAsAllowed() const
{
    return true;
}

当用户在 Qt Creator 之外修改文件时,Qt Creator 需要重新加载文件。此时,我们可以定义 Qt Creator 的行为:是直接重新加载,还是询问用户是否加载?这一操作是在reloadBehavior()函数中完成的。最后,还有一个rename()函数,用于处理文件重命名。因为我们只是简单的演示 Qt Creator 的开发,所以这里我们仅仅保持这些函数的默认行为,什么都不做:

Core::IFile::ReloadBehavior HtmlFile::reloadBehavior(
    Core::IFile::ChangeTrigger state,
    Core::IFile::ChangeType type) const
{
    Q_UNUSED(state);
    Q_UNUSED(type);
    return BehaviorAsk;
}

void HtmlFile::reload(ReloadFlag flag, ChangeType type)
{
    Q_UNUSED(flag);
    Q_UNUSED(type);
}

void HtmlFile::rename(const QString &newName)
{
    Q_UNUSED(newName);
}

4 Comments

  1. kula 2012年5月18日
    • DevBean 2012年5月21日
      • kula 2012年5月21日
        • DevBean 2012年5月27日

Leave a Reply