QtCreatorのTODOプラグイン

そのため、長い間、尊敬されているEugene QtCreatorのハッキングについて私たちに書いてくれ、プラグインを作成するための詳細な手順が記載されたドキュメントも彼のブログに示しました。 そして今週末、文明とインターネットから引き裂かれた田舎の家にいたので、自分のプラグインを書くことにしました。 プラグインは非常にシンプルで、現在開いているドキュメントのすべてのTODO、FIXMEなどのコメントのリストを表示します。 以下に、このプラグインの作成方法、および一般的にQtCreatorのプラグインの作成について説明します。

TODO Plugin





開始する



プラグインを作成するために最初に必要なことは、QtCreatorのソースコードをダウンロードすることですここで実行できます 。 次に、結果のアーカイブを解凍し、/ src / plugins /フォルダーに新しい空のプロジェクトを作成する必要があります。



何もしないプラグインを作成する



これを行うには、プラグインのメインクラスとなる新しいクラスをプロジェクトに追加する必要があり、 ExtensionSystem :: IPluginインターフェイスから継承する必要があります

これを行うには、次の行を.proファイルに追加します。

含める(../../ qtcreatorplugin.pri)

include(../../ plugins / coreplugin / coreplugin.pri)



Corepluginは、すべてのユーザープラグインが依存しているため必要です;他のプラグインを作成するための基本的なインターフェイスを提供します。



また、xmlファイル<plugin name> .pluginspecを次の形式で作成する必要があります。

<プラグイン名= "todo"バージョン= "0.0.1" compatVersion = "2.0.0">

<ベンダー> vsorokin </ベンダー>

<copyright>著作権</ copyright>

<license>ライセンス</ license>

<description>プラグインの説明</ description>

<url>プロジェクトホームページ</ url>

<dependencyList>

<依存名= "コア"バージョン= "2.0.0" />

</ dependencyList>

</ plugin>



フィールドの意味は名前から明らかです。



したがって、何もしないプラグインのクラスは、次の構造を持つ必要があります。

#include <extensionsystem / iplugin.h>



クラス TodoPlugin: public ExtensionSystem :: IPlugin

{

Q_OBJECT

公開

TodoPlugin();

〜TodoPlugin();

void extensionsInitialized();

bool initialize( const QStringList&arguments、QString * errorString);

void shutdown();

};



*このソースコードは、 ソースコードハイライターで強調表示されました。


これの中心は、プラグインを初期化するinitializeメソッドです。 ただし、何もしないプラグインでは、すべてのメソッドが空です。



新しい出力ペインを作成する



私のプラグインでは、既存の出力領域の横に新しい出力領域が必要でした。非常に簡単に、 Core :: IOutputPaneインターフェイスから継承した新しいクラスを作成します 。このクラスのタイトルは次のとおりです。

#include <coreplugin / ioutputpane.h>

#include <QObject>

#include <QListWidget>



クラス TodoOutputPane: public Core :: IOutputPane

{

公開

TodoOutputPane(QObject * parent);

〜TodoOutputPane();



QWidget * outputWidget(QWidget * parent); //クラスのメインウィジェットを返します。ここではQListWidgetです

QList <QWidget *> toolBarWidgets() const ; //ツールバーウィジェットのリストを返します。これらはこのプラグインには含まれていません

QString name() const ; //パネルのテキスト名のみ



int priorityInStatusBar() const ; // 100から100までの数値を返します。数値が大きいほど、ペインが占める位置が高くなります



void clearContents(); //メインウィジェットのクリーンアップを実行します

void visibilityChanged( ブールを表示);



void setFocus();

bool hasFocus();

bool canFocus();



bool canNavigate();

bool canNext();

bool canPrevious();

void goToNext();

void goToPrev();



void addItem(QStringテキスト、QStringファイル、 int rowNumber); //新しいエントリをリストに挿入するメソッド

QListWidget * getTodoList() const ; //リストへのポインター



プライベート

QListWidget * todoList;

};



*このソースコードは、 ソースコードハイライターで強調表示されました。




ここで、新しく作成したtodoPaneを何らかの方法でシステムに登録する必要があります。そのために、 initializeメソッドに次のコードを記述します。

outPane = new TodoOutputPane( this );

addAutoReleasedObject(outPane);



*このソースコードは、 ソースコードハイライターで強調表示されました。


すべてが非常に単純で、outPaneが残りの部分に表示されるようになりましたが、今のところ何もできません。



開いているファイルに関する情報を取得して解析します



エディターで現在開いているファイルを確認するには、何らかの方法でエディターに連絡する必要があります...

これを行うには、次のヘッダーを追加します。

#include <coreplugin / editormanager / editormanager.h>

#include <coreplugin / editormanager / ieditor.h>



*このソースコードは、 ソースコードハイライターで強調表示されました。


そして、 initializeメソッドに次の行を追加します。

connect(コア:: EditorManager ::インスタンス()、SIGNAL(currentEditorChanged(コア:: IEditor *))、 this 、SLOT(currentEditorChanged(コア:: IEditor *)));



*このソースコードは、 ソースコードハイライターで強調表示されました。


そしてもちろん、スロットcurrentEditorChangedを宣言します(Core :: IEditor *)

このスロットは、現在のエディターが変更されるたびに呼び出されます。つまり、ユーザーがファイルを開いたり閉じたりするか、既に開いている別のファイルに切り替えます。

その実装は次のとおりです。

void TodoPlugin :: currentEditorChanged(コア:: IEditor *エディター)

{

outPane-> clearContents(); //クリア

if (!editor) //エディターがあるかどうかを確認しますか? 一般的に

{

帰る

}

/ *細い点、現在のエディターにアタッチされたファイルのクラスを変更する信号を接続します。これにより、ユーザーがCtrl + Sを押した後にファイルを再度読み取ることができます* /

connect(editor-> file()、SIGNAL(changed())、 this 、SLOT(fileChanged()));

QString fileName = editor-> file()-> fileName(); //ファイル名を取得します

readFile(fileName); //ファイルを読み取って解析します。

}



*このソースコードは、 ソースコードハイライターで強調表示されました。


解析メソッドはここで呼び出されます、それは簡単です:

void TodoPlugin :: readFile(QString fileName)

{

QFileファイル(fileName);

if (!file.open(QFile :: ReadOnly | QFile :: Text))

帰る

int i = 1;

while (!file.atEnd())

{

QString currentLine = file.readLine();

if (currentLine.contains(QRegExp(patternString、Qt :: CaseInsensitive)))

{

outPane-> addItem(currentLine、fileName、i);

}

++ i;

}

}



*このソースコードは、 ソースコードハイライターで強調表示されました。




また、ファイルが保存された場合に呼び出される新しいスロットを記述する必要があります。ここでは、

void TodoPlugin :: fileChanged()

{

outPane-> clearContents();

Core :: IFile * file =(Core :: IFile *)sender(); //これはやや非正統的な方法ですが、このスロットには信号が接続されていないため、非常に安全に動作します。

if (ファイル)

{

readFile(file-> fileName());

}

}



*このソースコードは、 ソースコードハイライターで強調表示されました。




行を追加する



次に、行の追加、つまりメソッドを説明する必要があります。

void TodoOutputPane :: addItem(QStringテキスト、QStringファイル、 int rowNumber)

{

QListWidgetItem * newItem = new QListWidgetItem(); //新しいエントリを作成します

QRegExp todoExp( "// \\ s * TODO(:| \\ s)" 、Qt :: CaseInsensitive); //正規表現を準備します

QRegExp noteExp( "// \\ s * NOTE(:| \\ s)" 、Qt :: CaseInsensitive);

QRegExp fixmeExp( "// \\ s * FIXME( :| \\ s)" 、Qt :: CaseInsensitive);

QRegExp bugExp( "// \\ s * BUG(:| \\ s)" 、Qt :: CaseInsensitive);

QRegExp hackExp( "// \\ s * HACK(:| \\ s)" 、Qt :: CaseInsensitive);



text = text.replace( "\ n""" );

text = text.replace( "\ r""" );



newItem-> setTextColor(QColor( "#2F2F2F" ));

if (text.contains(todoExp)) //正規表現を探す

{

newItem-> setBackgroundColor(QColor( "#BFFFC8" )); //レコードの色を設定します

text = text.replace(todoExp、 “ TODO:„ ); //ラベルの「曲がっている可能性のある」スペルを正しいものに置き換えます

newItem-> setIcon(QIcon( ":/ warning" )); //アイコンを設定します

}

else if (text.contains(noteExp))

{

newItem-> setBackgroundColor(QColor( "#E2DFFF" ));

text = text.replace(noteExp、 “ NOTE:„ );

newItem-> setIcon(QIcon( “:/ info” ));

}

else if (text.contains(bugExp))

{

newItem-> setBackgroundColor(QColor( "#FFBFBF" ));

text = text.replace(bugExp、 “ BUG:„ );

newItem-> setIcon(QIcon( “:/ error” ));

}

else if (text.contains(fixmeExp))

{

newItem-> setBackgroundColor(QColor( "#FFDFDF" ));

text = text.replace(fixmeExp、 FIXME :„ );

newItem-> setIcon(QIcon( “:/ error” ));

}

else if (text.contains(hackExp))

{

newItem-> setBackgroundColor(QColor( "#FFFFAA" ));

text = text.replace(hackExp、 “ HACK:„ );

newItem-> setIcon(QIcon( “:/ info” ));

}



newItem-> setText(text.trimmed()+ "(" + tr( "line„ )+ QString :: number(rowNumber)+ “)" ); //レコードテキストを設定します

newItem-> setToolTip(file + ":" + QString :: number(rowNumber)); //ツールチップにはファイル名と行番号が保存されますが、それはそのようなものではありません。その理由を以下で説明します。

todoList-> addItem(newItem); //エントリをリストに追加します

}



*このソースコードは、 ソースコードハイライターで強調表示されました。




レコードをクリックして目的の行に移動します



あとは、目的の行への移行を実装するだけです。

これを行うには、リストアイテムが選択されたときに実行される別のスロットが必要です。

void TodoPlugin :: gotoToRowInFile(QListWidgetItem * item)

{

int row = 0; //行番号

QStringファイル= "" ; //ファイル名



/ *プロンプトから情報を取得* /

QStringList tmpList = item-> toolTip()。Split( ":" );

if (tmpList.size()== 2)

{

file = tmpList.at(0);

bool ok;

row = tmpList.at(1).toInt(&ok);

if (!ok)

{

行= 0;

}

}

if (QFileInfo(file).exists()) //ファイルが存在するかどうかを確認します。

{

TextEditor :: BaseTextEditor :: openEditorAt(ファイル、行); //行番号の行にカーソルを置いて、ファイルを強制的に表示します。 この行が機能するためには、依存関係でTextEditorプラグインを指定し、適切なヘッダーを追加する必要があります

コア:: EditorManager ::インスタンス()-> ensureEditorManagerVisible();

}

}



*このソースコードは、 ソースコードハイライターで強調表示されました。




おわりに



さて、それですべてです。プラグインの準備ができました。読んだ人のおかげです。

ここからプラグインをダウンロードできます。



All Articles