forked from qt-creator/qt-creator
C++: Automatic Doxygen comment blocks generation
This improves our completion support for documentation comments. It's now possible to have a Doxygen block generated when hitting enter after a /** or /*! comment start. A couple other related options are also available. Task-number: QTCREATORBUG-2752 Task-number: QTCREATORBUG-3165 Change-Id: I1c81c0b4b370eb1d409ef72a9c7f22c357f202f4 Reviewed-by: Leena Miettinen <riitta-leena.miettinen@nokia.com> Reviewed-by: Christian Kamm <christian.d.kamm@nokia.com>
This commit is contained in:
@@ -69,6 +69,8 @@
|
|||||||
#include <cpptools/cppcodestylesettings.h>
|
#include <cpptools/cppcodestylesettings.h>
|
||||||
#include <cpptools/cpprefactoringchanges.h>
|
#include <cpptools/cpprefactoringchanges.h>
|
||||||
#include <cpptools/cpptoolsreuse.h>
|
#include <cpptools/cpptoolsreuse.h>
|
||||||
|
#include <cpptools/doxygengenerator.h>
|
||||||
|
#include <cpptools/cpptoolssettings.h>
|
||||||
|
|
||||||
#include <coreplugin/icore.h>
|
#include <coreplugin/icore.h>
|
||||||
#include <coreplugin/actionmanager/actionmanager.h>
|
#include <coreplugin/actionmanager/actionmanager.h>
|
||||||
@@ -415,6 +417,7 @@ CPPEditorWidget::CPPEditorWidget(QWidget *parent)
|
|||||||
, m_inRenameChanged(false)
|
, m_inRenameChanged(false)
|
||||||
, m_firstRenameChange(false)
|
, m_firstRenameChange(false)
|
||||||
, m_objcEnabled(false)
|
, m_objcEnabled(false)
|
||||||
|
, m_commentsSettings(CppTools::CppToolsSettings::instance()->commentsSettings())
|
||||||
{
|
{
|
||||||
m_initialized = false;
|
m_initialized = false;
|
||||||
qRegisterMetaType<CppEditor::Internal::SemanticInfo>("CppEditor::Internal::SemanticInfo");
|
qRegisterMetaType<CppEditor::Internal::SemanticInfo>("CppEditor::Internal::SemanticInfo");
|
||||||
@@ -451,6 +454,11 @@ CPPEditorWidget::CPPEditorWidget(QWidget *parent)
|
|||||||
m_declDefLinkFinder = new FunctionDeclDefLinkFinder(this);
|
m_declDefLinkFinder = new FunctionDeclDefLinkFinder(this);
|
||||||
connect(m_declDefLinkFinder, SIGNAL(foundLink(QSharedPointer<FunctionDeclDefLink>)),
|
connect(m_declDefLinkFinder, SIGNAL(foundLink(QSharedPointer<FunctionDeclDefLink>)),
|
||||||
this, SLOT(onFunctionDeclDefLinkFound(QSharedPointer<FunctionDeclDefLink>)));
|
this, SLOT(onFunctionDeclDefLinkFound(QSharedPointer<FunctionDeclDefLink>)));
|
||||||
|
|
||||||
|
connect(CppTools::CppToolsSettings::instance(),
|
||||||
|
SIGNAL(commentsSettingsChanged(CppTools::CommentsSettings)),
|
||||||
|
this,
|
||||||
|
SLOT(onCommentsSettingsChanged(CppTools::CommentsSettings)));
|
||||||
}
|
}
|
||||||
|
|
||||||
CPPEditorWidget::~CPPEditorWidget()
|
CPPEditorWidget::~CPPEditorWidget()
|
||||||
@@ -1552,7 +1560,8 @@ void CPPEditorWidget::contextMenuEvent(QContextMenuEvent *e)
|
|||||||
void CPPEditorWidget::keyPressEvent(QKeyEvent *e)
|
void CPPEditorWidget::keyPressEvent(QKeyEvent *e)
|
||||||
{
|
{
|
||||||
if (m_currentRenameSelection == NoCurrentRenameSelection) {
|
if (m_currentRenameSelection == NoCurrentRenameSelection) {
|
||||||
TextEditor::BaseTextEditorWidget::keyPressEvent(e);
|
if (!handleDocumentationComment(e))
|
||||||
|
TextEditor::BaseTextEditorWidget::keyPressEvent(e);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2239,4 +2248,99 @@ void CPPEditorWidget::abortDeclDefLink()
|
|||||||
m_declDefLink.clear();
|
m_declDefLink.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CPPEditorWidget::handleDocumentationComment(QKeyEvent *e)
|
||||||
|
{
|
||||||
|
if (!m_commentsSettings.m_enableDoxygen
|
||||||
|
&& !m_commentsSettings.m_leadingAsterisks) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (e->key() == Qt::Key_Return
|
||||||
|
|| e->key() == Qt::Key_Enter) {
|
||||||
|
QTextCursor cursor = textCursor();
|
||||||
|
if (!autoCompleter()->isInComment(cursor))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// We are interested on two particular cases:
|
||||||
|
// 1) The cursor is right after a /** or /*! and the user pressed enter. If Doxygen
|
||||||
|
// is enabled we need to generate an entire comment block.
|
||||||
|
// 2) The cursor is already in the middle of a multi-line comment and the user pressed
|
||||||
|
// enter. If leading asterisk(s) is set we need to write a comment continuation
|
||||||
|
// with those.
|
||||||
|
|
||||||
|
if (m_commentsSettings.m_enableDoxygen
|
||||||
|
&& cursor.positionInBlock() >= 3) {
|
||||||
|
const int pos = cursor.position();
|
||||||
|
if (characterAt(pos - 3) == QChar('/')
|
||||||
|
&& characterAt(pos - 2) == QChar('*')
|
||||||
|
&& (characterAt(pos - 1) == QChar('*')
|
||||||
|
|| characterAt(pos - 1) == QChar('!'))) {
|
||||||
|
CppTools::DoxygenGenerator doxygen;
|
||||||
|
doxygen.setAddLeadingAsterisks(m_commentsSettings.m_leadingAsterisks);
|
||||||
|
doxygen.setGenerateBrief(m_commentsSettings.m_generateBrief);
|
||||||
|
doxygen.setStartComment(false);
|
||||||
|
if (characterAt(pos - 1) == QLatin1Char('!'))
|
||||||
|
doxygen.setStyle(CppTools::DoxygenGenerator::QtStyle);
|
||||||
|
else
|
||||||
|
doxygen.setStyle(CppTools::DoxygenGenerator::JavaStyle);
|
||||||
|
|
||||||
|
// Move until we reach any possibly meaningful content.
|
||||||
|
while (document()->characterAt(cursor.position()).isSpace())
|
||||||
|
cursor.movePosition(QTextCursor::NextCharacter);
|
||||||
|
|
||||||
|
const QString &comment = doxygen.generate(cursor);
|
||||||
|
if (!comment.isEmpty()) {
|
||||||
|
cursor.beginEditBlock();
|
||||||
|
cursor.setPosition(pos);
|
||||||
|
cursor.insertText(comment);
|
||||||
|
cursor.setPosition(pos - 3, QTextCursor::KeepAnchor);
|
||||||
|
indent(document(), cursor, QChar::Null);
|
||||||
|
cursor.endEditBlock();
|
||||||
|
e->accept();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
cursor.setPosition(pos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!m_commentsSettings.m_leadingAsterisks)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
const QString &text = cursor.block().text();
|
||||||
|
const int length = text.length();
|
||||||
|
int offset = 0;
|
||||||
|
for (; offset < length; ++offset) {
|
||||||
|
const QChar ¤t = text.at(offset);
|
||||||
|
if (!current.isSpace())
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (offset < length
|
||||||
|
&& (text.at(offset) == QLatin1Char('*')
|
||||||
|
|| (offset < length - 1
|
||||||
|
&& text.at(offset) == QLatin1Char('/')
|
||||||
|
&& text.at(offset + 1) == QLatin1Char('*')))) {
|
||||||
|
QString newLine(QLatin1Char('\n'));
|
||||||
|
newLine.append(QString(offset, QLatin1Char(' ')));
|
||||||
|
if (text.at(offset) == QLatin1Char('/')) {
|
||||||
|
newLine.append(QLatin1String(" *"));
|
||||||
|
} else {
|
||||||
|
int start = offset;
|
||||||
|
while (offset < length && text.at(offset) == QLatin1Char('*'))
|
||||||
|
++offset;
|
||||||
|
newLine.append(QString(offset - start, QLatin1Char('*')));
|
||||||
|
}
|
||||||
|
cursor.insertText(newLine);
|
||||||
|
e->accept();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CPPEditorWidget::onCommentsSettingsChanged(const CppTools::CommentsSettings &settings)
|
||||||
|
{
|
||||||
|
m_commentsSettings = settings;
|
||||||
|
}
|
||||||
|
|
||||||
#include "cppeditor.moc"
|
#include "cppeditor.moc"
|
||||||
|
|||||||
@@ -42,6 +42,7 @@
|
|||||||
#include <cplusplus/LookupContext.h>
|
#include <cplusplus/LookupContext.h>
|
||||||
#include <texteditor/basetexteditor.h>
|
#include <texteditor/basetexteditor.h>
|
||||||
#include <texteditor/quickfix.h>
|
#include <texteditor/quickfix.h>
|
||||||
|
#include <cpptools/commentssettings.h>
|
||||||
|
|
||||||
#include <QtCore/QThread>
|
#include <QtCore/QThread>
|
||||||
#include <QtCore/QMutex>
|
#include <QtCore/QMutex>
|
||||||
@@ -250,6 +251,8 @@ private Q_SLOTS:
|
|||||||
|
|
||||||
void onRefactorMarkerClicked(const TextEditor::RefactorMarker &marker);
|
void onRefactorMarkerClicked(const TextEditor::RefactorMarker &marker);
|
||||||
|
|
||||||
|
void onCommentsSettingsChanged(const CppTools::CommentsSettings &settings);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void markSymbols(const QTextCursor &tc, const SemanticInfo &info);
|
void markSymbols(const QTextCursor &tc, const SemanticInfo &info);
|
||||||
bool sortedOutline() const;
|
bool sortedOutline() const;
|
||||||
@@ -284,6 +287,8 @@ private:
|
|||||||
|
|
||||||
QModelIndex indexForPosition(int line, int column, const QModelIndex &rootIndex = QModelIndex()) const;
|
QModelIndex indexForPosition(int line, int column, const QModelIndex &rootIndex = QModelIndex()) const;
|
||||||
|
|
||||||
|
bool handleDocumentationComment(QKeyEvent *e);
|
||||||
|
|
||||||
CPlusPlus::CppModelManagerInterface *m_modelManager;
|
CPlusPlus::CppModelManagerInterface *m_modelManager;
|
||||||
|
|
||||||
QComboBox *m_outlineCombo;
|
QComboBox *m_outlineCombo;
|
||||||
@@ -325,6 +330,8 @@ private:
|
|||||||
|
|
||||||
FunctionDeclDefLinkFinder *m_declDefLinkFinder;
|
FunctionDeclDefLinkFinder *m_declDefLinkFinder;
|
||||||
QSharedPointer<FunctionDeclDefLink> m_declDefLink;
|
QSharedPointer<FunctionDeclDefLink> m_declDefLink;
|
||||||
|
|
||||||
|
CppTools::CommentsSettings m_commentsSettings;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
46
src/plugins/cpptools/commentssettings.cpp
Normal file
46
src/plugins/cpptools/commentssettings.cpp
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
#include "commentssettings.h"
|
||||||
|
|
||||||
|
#include <QtCore/QSettings>
|
||||||
|
|
||||||
|
using namespace CppTools;
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
const char kDocumentationCommentsGroup[] = "DocumentationComments";
|
||||||
|
const char kEnableDoxygenBlocks[] = "EnableDoxygenBlocks";
|
||||||
|
const char kGenerateBrief[] = "GenerateBrief";
|
||||||
|
const char kAddLeadingAsterisks[] = "AddLeadingAsterisks";
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
CommentsSettings::CommentsSettings()
|
||||||
|
: m_enableDoxygen(true)
|
||||||
|
, m_generateBrief(true)
|
||||||
|
, m_leadingAsterisks(true)
|
||||||
|
{}
|
||||||
|
|
||||||
|
void CommentsSettings::toSettings(const QString &category, QSettings *s) const
|
||||||
|
{
|
||||||
|
s->beginGroup(category + QLatin1String(kDocumentationCommentsGroup));
|
||||||
|
s->setValue(QLatin1String(kEnableDoxygenBlocks), m_enableDoxygen);
|
||||||
|
s->setValue(QLatin1String(kGenerateBrief), m_generateBrief);
|
||||||
|
s->setValue(QLatin1String(kAddLeadingAsterisks), m_leadingAsterisks);
|
||||||
|
s->endGroup();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CommentsSettings::fromSettings(const QString &category, QSettings *s)
|
||||||
|
{
|
||||||
|
s->beginGroup(category + QLatin1String(kDocumentationCommentsGroup));
|
||||||
|
m_enableDoxygen = s->value(QLatin1String(kEnableDoxygenBlocks), true).toBool();
|
||||||
|
m_generateBrief = m_enableDoxygen
|
||||||
|
&& s->value(QLatin1String(kGenerateBrief), true).toBool();
|
||||||
|
m_leadingAsterisks = s->value(QLatin1String(kAddLeadingAsterisks), true).toBool();
|
||||||
|
s->endGroup();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CommentsSettings::equals(const CommentsSettings &other) const
|
||||||
|
{
|
||||||
|
return m_enableDoxygen == other.m_enableDoxygen
|
||||||
|
&& m_generateBrief == other.m_generateBrief
|
||||||
|
&& m_leadingAsterisks == other.m_leadingAsterisks;
|
||||||
|
}
|
||||||
35
src/plugins/cpptools/commentssettings.h
Normal file
35
src/plugins/cpptools/commentssettings.h
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
#ifndef COMMENTSSETTINGS_H
|
||||||
|
#define COMMENTSSETTINGS_H
|
||||||
|
|
||||||
|
#include "cpptools_global.h"
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
class QSettings;
|
||||||
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
|
namespace CppTools {
|
||||||
|
|
||||||
|
class CPPTOOLS_EXPORT CommentsSettings
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CommentsSettings();
|
||||||
|
|
||||||
|
void toSettings(const QString &category, QSettings *s) const;
|
||||||
|
void fromSettings(const QString &category, QSettings *s);
|
||||||
|
|
||||||
|
bool equals(const CommentsSettings &other) const;
|
||||||
|
|
||||||
|
bool m_enableDoxygen;
|
||||||
|
bool m_generateBrief;
|
||||||
|
bool m_leadingAsterisks;
|
||||||
|
};
|
||||||
|
|
||||||
|
inline bool operator==(const CommentsSettings &a, const CommentsSettings &b)
|
||||||
|
{ return a.equals(b); }
|
||||||
|
|
||||||
|
inline bool operator!=(const CommentsSettings &a, const CommentsSettings &b)
|
||||||
|
{ return !(a == b); }
|
||||||
|
|
||||||
|
} // namespace CppTools
|
||||||
|
|
||||||
|
#endif // COMMENTSSETTINGS_H
|
||||||
@@ -32,6 +32,7 @@
|
|||||||
|
|
||||||
#include "completionsettingspage.h"
|
#include "completionsettingspage.h"
|
||||||
#include "ui_completionsettingspage.h"
|
#include "ui_completionsettingspage.h"
|
||||||
|
#include "cpptoolsconstants.h"
|
||||||
|
|
||||||
#include <coreplugin/icore.h>
|
#include <coreplugin/icore.h>
|
||||||
#include <extensionsystem/pluginmanager.h>
|
#include <extensionsystem/pluginmanager.h>
|
||||||
@@ -40,11 +41,16 @@
|
|||||||
#include <QtCore/QTextStream>
|
#include <QtCore/QTextStream>
|
||||||
#include <QtCore/QCoreApplication>
|
#include <QtCore/QCoreApplication>
|
||||||
|
|
||||||
|
using namespace CppTools;
|
||||||
using namespace CppTools::Internal;
|
using namespace CppTools::Internal;
|
||||||
|
using namespace CppTools::Constants;
|
||||||
|
|
||||||
CompletionSettingsPage::CompletionSettingsPage()
|
CompletionSettingsPage::CompletionSettingsPage(QObject *parent)
|
||||||
: m_page(0)
|
: TextEditor::TextEditorOptionsPage(parent)
|
||||||
|
, m_page(0)
|
||||||
{
|
{
|
||||||
|
if (QSettings *s = Core::ICore::instance()->settings())
|
||||||
|
m_commentsSettings.fromSettings(QLatin1String(CPPTOOLS_SETTINGSGROUP), s);
|
||||||
}
|
}
|
||||||
|
|
||||||
CompletionSettingsPage::~CompletionSettingsPage()
|
CompletionSettingsPage::~CompletionSettingsPage()
|
||||||
@@ -103,6 +109,9 @@ QWidget *CompletionSettingsPage::createPage(QWidget *parent)
|
|||||||
m_page->surroundSelectedText->setChecked(settings.m_surroundingAutoBrackets);
|
m_page->surroundSelectedText->setChecked(settings.m_surroundingAutoBrackets);
|
||||||
m_page->partiallyComplete->setChecked(settings.m_partiallyComplete);
|
m_page->partiallyComplete->setChecked(settings.m_partiallyComplete);
|
||||||
m_page->spaceAfterFunctionName->setChecked(settings.m_spaceAfterFunctionName);
|
m_page->spaceAfterFunctionName->setChecked(settings.m_spaceAfterFunctionName);
|
||||||
|
m_page->enableDoxygenCheckBox->setChecked(m_commentsSettings.m_enableDoxygen);
|
||||||
|
m_page->generateBriefCheckBox->setChecked(m_commentsSettings.m_generateBrief);
|
||||||
|
m_page->leadingAsterisksCheckBox->setChecked(m_commentsSettings.m_leadingAsterisks);
|
||||||
|
|
||||||
if (m_searchKeywords.isEmpty()) {
|
if (m_searchKeywords.isEmpty()) {
|
||||||
QTextStream(&m_searchKeywords) << m_page->caseSensitivityLabel->text()
|
QTextStream(&m_searchKeywords) << m_page->caseSensitivityLabel->text()
|
||||||
@@ -110,10 +119,15 @@ QWidget *CompletionSettingsPage::createPage(QWidget *parent)
|
|||||||
<< ' ' << m_page->surroundSelectedText->text()
|
<< ' ' << m_page->surroundSelectedText->text()
|
||||||
<< ' ' << m_page->completionTriggerLabel->text()
|
<< ' ' << m_page->completionTriggerLabel->text()
|
||||||
<< ' ' << m_page->partiallyComplete->text()
|
<< ' ' << m_page->partiallyComplete->text()
|
||||||
<< ' ' << m_page->spaceAfterFunctionName->text();
|
<< ' ' << m_page->spaceAfterFunctionName->text()
|
||||||
|
<< ' ' << m_page->enableDoxygenCheckBox->text()
|
||||||
|
<< ' ' << m_page->generateBriefCheckBox->text()
|
||||||
|
<< ' ' << m_page->leadingAsterisksCheckBox->text();
|
||||||
m_searchKeywords.remove(QLatin1Char('&'));
|
m_searchKeywords.remove(QLatin1Char('&'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_page->generateBriefCheckBox->setEnabled(m_page->enableDoxygenCheckBox->isChecked());
|
||||||
|
|
||||||
return w;
|
return w;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -130,6 +144,17 @@ void CompletionSettingsPage::apply()
|
|||||||
settings.m_spaceAfterFunctionName = m_page->spaceAfterFunctionName->isChecked();
|
settings.m_spaceAfterFunctionName = m_page->spaceAfterFunctionName->isChecked();
|
||||||
|
|
||||||
TextEditor::TextEditorSettings::instance()->setCompletionSettings(settings);
|
TextEditor::TextEditorSettings::instance()->setCompletionSettings(settings);
|
||||||
|
|
||||||
|
if (!requireCommentsSettingsUpdate())
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_commentsSettings.m_enableDoxygen = m_page->enableDoxygenCheckBox->isChecked();
|
||||||
|
m_commentsSettings.m_generateBrief = m_page->generateBriefCheckBox->isChecked();
|
||||||
|
m_commentsSettings.m_leadingAsterisks = m_page->leadingAsterisksCheckBox->isChecked();
|
||||||
|
if (QSettings *s = Core::ICore::instance()->settings())
|
||||||
|
m_commentsSettings.toSettings(QLatin1String(CPPTOOLS_SETTINGSGROUP), s);
|
||||||
|
|
||||||
|
emit commentsSettingsChanged(m_commentsSettings);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CompletionSettingsPage::matches(const QString &s) const
|
bool CompletionSettingsPage::matches(const QString &s) const
|
||||||
@@ -168,3 +193,15 @@ void CompletionSettingsPage::finish()
|
|||||||
delete m_page;
|
delete m_page;
|
||||||
m_page = 0;
|
m_page = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const CommentsSettings &CompletionSettingsPage::commentsSettings() const
|
||||||
|
{
|
||||||
|
return m_commentsSettings;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CompletionSettingsPage::requireCommentsSettingsUpdate() const
|
||||||
|
{
|
||||||
|
return m_commentsSettings.m_enableDoxygen != m_page->enableDoxygenCheckBox->isChecked()
|
||||||
|
|| m_commentsSettings.m_generateBrief != m_page->generateBriefCheckBox->isChecked()
|
||||||
|
|| m_commentsSettings.m_leadingAsterisks != m_page->leadingAsterisksCheckBox->isChecked();
|
||||||
|
}
|
||||||
|
|||||||
@@ -33,13 +33,17 @@
|
|||||||
#ifndef COMPLETIONSETTINGSPAGE_H
|
#ifndef COMPLETIONSETTINGSPAGE_H
|
||||||
#define COMPLETIONSETTINGSPAGE_H
|
#define COMPLETIONSETTINGSPAGE_H
|
||||||
|
|
||||||
|
#include "commentssettings.h"
|
||||||
|
|
||||||
#include <texteditor/completionsettings.h>
|
#include <texteditor/completionsettings.h>
|
||||||
#include <texteditor/texteditoroptionspage.h>
|
#include <texteditor/texteditoroptionspage.h>
|
||||||
|
|
||||||
namespace CppTools {
|
namespace CppTools {
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
|
|
||||||
namespace Ui { class CompletionSettingsPage; }
|
namespace Ui {
|
||||||
|
class CompletionSettingsPage;
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: Move this class to the text editor plugin
|
// TODO: Move this class to the text editor plugin
|
||||||
|
|
||||||
@@ -48,7 +52,7 @@ class CompletionSettingsPage : public TextEditor::TextEditorOptionsPage
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CompletionSettingsPage();
|
CompletionSettingsPage(QObject *parent);
|
||||||
~CompletionSettingsPage();
|
~CompletionSettingsPage();
|
||||||
|
|
||||||
QString id() const;
|
QString id() const;
|
||||||
@@ -59,12 +63,20 @@ public:
|
|||||||
void finish();
|
void finish();
|
||||||
virtual bool matches(const QString &) const;
|
virtual bool matches(const QString &) const;
|
||||||
|
|
||||||
|
const CommentsSettings &commentsSettings() const;
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void commentsSettingsChanged(const CppTools::CommentsSettings &settings);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
TextEditor::CaseSensitivity caseSensitivity() const;
|
TextEditor::CaseSensitivity caseSensitivity() const;
|
||||||
TextEditor::CompletionTrigger completionTrigger() const;
|
TextEditor::CompletionTrigger completionTrigger() const;
|
||||||
|
|
||||||
|
bool requireCommentsSettingsUpdate() const;
|
||||||
|
|
||||||
Ui::CompletionSettingsPage *m_page;
|
Ui::CompletionSettingsPage *m_page;
|
||||||
QString m_searchKeywords;
|
QString m_searchKeywords;
|
||||||
|
CommentsSettings m_commentsSettings;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
|
|||||||
@@ -6,11 +6,11 @@
|
|||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>393</width>
|
<width>484</width>
|
||||||
<height>241</height>
|
<height>376</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QVBoxLayout" name="verticalLayout">
|
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||||
<item>
|
<item>
|
||||||
<widget class="QGroupBox" name="groupBox">
|
<widget class="QGroupBox" name="groupBox">
|
||||||
<property name="title">
|
<property name="title">
|
||||||
@@ -196,6 +196,65 @@
|
|||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QGroupBox" name="docCommentsGroup">
|
||||||
|
<property name="title">
|
||||||
|
<string>Documentation Comments</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
|
<item>
|
||||||
|
<widget class="QCheckBox" name="enableDoxygenCheckBox">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Automatically create a Doxygen comment upon pressing enter after a /** or /*!</string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Enable Doxygen blocks</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||||
|
<item>
|
||||||
|
<spacer name="horizontalSpacer_5">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeType">
|
||||||
|
<enum>QSizePolicy::Fixed</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>30</width>
|
||||||
|
<height>20</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QCheckBox" name="generateBriefCheckBox">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Generate a <i>brief</i> command with an initial description for the corresponding declaration</string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Generate brief description</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QCheckBox" name="leadingAsterisksCheckBox">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Add leading asterisks when continuing comments on new lines</string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Add leading asterisks</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<spacer name="verticalSpacer">
|
<spacer name="verticalSpacer">
|
||||||
<property name="orientation">
|
<property name="orientation">
|
||||||
@@ -224,8 +283,8 @@
|
|||||||
<y>131</y>
|
<y>131</y>
|
||||||
</hint>
|
</hint>
|
||||||
<hint type="destinationlabel">
|
<hint type="destinationlabel">
|
||||||
<x>265</x>
|
<x>333</x>
|
||||||
<y>182</y>
|
<y>206</y>
|
||||||
</hint>
|
</hint>
|
||||||
</hints>
|
</hints>
|
||||||
</connection>
|
</connection>
|
||||||
@@ -245,5 +304,21 @@
|
|||||||
</hint>
|
</hint>
|
||||||
</hints>
|
</hints>
|
||||||
</connection>
|
</connection>
|
||||||
|
<connection>
|
||||||
|
<sender>enableDoxygenCheckBox</sender>
|
||||||
|
<signal>toggled(bool)</signal>
|
||||||
|
<receiver>generateBriefCheckBox</receiver>
|
||||||
|
<slot>setEnabled(bool)</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>153</x>
|
||||||
|
<y>272</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>204</x>
|
||||||
|
<y>293</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
</connections>
|
</connections>
|
||||||
</ui>
|
</ui>
|
||||||
|
|||||||
@@ -35,7 +35,9 @@ HEADERS += completionsettingspage.h \
|
|||||||
cppcodestylesettings.h \
|
cppcodestylesettings.h \
|
||||||
cppcodestylepreferencesfactory.h \
|
cppcodestylepreferencesfactory.h \
|
||||||
cppcodestylepreferences.h \
|
cppcodestylepreferences.h \
|
||||||
cpptoolsreuse.h
|
cpptoolsreuse.h \
|
||||||
|
doxygengenerator.h \
|
||||||
|
commentssettings.h
|
||||||
|
|
||||||
SOURCES += completionsettingspage.cpp \
|
SOURCES += completionsettingspage.cpp \
|
||||||
cppclassesfilter.cpp \
|
cppclassesfilter.cpp \
|
||||||
@@ -62,7 +64,9 @@ SOURCES += completionsettingspage.cpp \
|
|||||||
cppcodestylesettings.cpp \
|
cppcodestylesettings.cpp \
|
||||||
cppcodestylepreferencesfactory.cpp \
|
cppcodestylepreferencesfactory.cpp \
|
||||||
cppcodestylepreferences.cpp \
|
cppcodestylepreferences.cpp \
|
||||||
cpptoolsreuse.cpp
|
cpptoolsreuse.cpp \
|
||||||
|
doxygengenerator.cpp \
|
||||||
|
commentssettings.cpp
|
||||||
|
|
||||||
FORMS += completionsettingspage.ui \
|
FORMS += completionsettingspage.ui \
|
||||||
cppfilesettingspage.ui \
|
cppfilesettingspage.ui \
|
||||||
|
|||||||
@@ -122,7 +122,6 @@ bool CppToolsPlugin::initialize(const QStringList &arguments, QString *error)
|
|||||||
addAutoReleasedObject(new CppClassesFilter(m_modelManager));
|
addAutoReleasedObject(new CppClassesFilter(m_modelManager));
|
||||||
addAutoReleasedObject(new CppFunctionsFilter(m_modelManager));
|
addAutoReleasedObject(new CppFunctionsFilter(m_modelManager));
|
||||||
addAutoReleasedObject(new CppCurrentDocumentFilter(m_modelManager, core->editorManager()));
|
addAutoReleasedObject(new CppCurrentDocumentFilter(m_modelManager, core->editorManager()));
|
||||||
addAutoReleasedObject(new CompletionSettingsPage);
|
|
||||||
addAutoReleasedObject(new CppFileSettingsPage(m_fileSettings));
|
addAutoReleasedObject(new CppFileSettingsPage(m_fileSettings));
|
||||||
addAutoReleasedObject(new SymbolsFindFilter(m_modelManager));
|
addAutoReleasedObject(new SymbolsFindFilter(m_modelManager));
|
||||||
addAutoReleasedObject(new CppCodeStyleSettingsPage);
|
addAutoReleasedObject(new CppCodeStyleSettingsPage);
|
||||||
|
|||||||
@@ -34,11 +34,14 @@
|
|||||||
#include "cpptoolsconstants.h"
|
#include "cpptoolsconstants.h"
|
||||||
#include "cppcodestylepreferences.h"
|
#include "cppcodestylepreferences.h"
|
||||||
#include "cppcodestylepreferencesfactory.h"
|
#include "cppcodestylepreferencesfactory.h"
|
||||||
|
#include "commentssettings.h"
|
||||||
|
#include "completionsettingspage.h"
|
||||||
|
|
||||||
#include <texteditor/texteditorsettings.h>
|
#include <texteditor/texteditorsettings.h>
|
||||||
#include <texteditor/texteditorsettings.h>
|
#include <texteditor/texteditorsettings.h>
|
||||||
#include <texteditor/tabsettings.h>
|
#include <texteditor/tabsettings.h>
|
||||||
#include <texteditor/codestylepool.h>
|
#include <texteditor/codestylepool.h>
|
||||||
|
#include <extensionsystem/pluginmanager.h>
|
||||||
|
|
||||||
#include <utils/settingsutils.h>
|
#include <utils/settingsutils.h>
|
||||||
#include <utils/qtcassert.h>
|
#include <utils/qtcassert.h>
|
||||||
@@ -48,6 +51,7 @@
|
|||||||
static const char *idKey = "CppGlobal";
|
static const char *idKey = "CppGlobal";
|
||||||
|
|
||||||
using namespace CppTools;
|
using namespace CppTools;
|
||||||
|
using namespace CppTools::Internal;
|
||||||
using TextEditor::TabSettings;
|
using TextEditor::TabSettings;
|
||||||
|
|
||||||
namespace CppTools {
|
namespace CppTools {
|
||||||
@@ -56,7 +60,13 @@ namespace Internal {
|
|||||||
class CppToolsSettingsPrivate
|
class CppToolsSettingsPrivate
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
CppToolsSettingsPrivate()
|
||||||
|
: m_globalCodeStyle(0)
|
||||||
|
, m_completionSettingsPage(0)
|
||||||
|
{}
|
||||||
|
|
||||||
CppCodeStylePreferences *m_globalCodeStyle;
|
CppCodeStylePreferences *m_globalCodeStyle;
|
||||||
|
CompletionSettingsPage *m_completionSettingsPage;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
@@ -70,8 +80,17 @@ CppToolsSettings::CppToolsSettings(QObject *parent)
|
|||||||
{
|
{
|
||||||
QTC_ASSERT(!m_instance, return);
|
QTC_ASSERT(!m_instance, return);
|
||||||
m_instance = this;
|
m_instance = this;
|
||||||
|
|
||||||
qRegisterMetaType<CppTools::CppCodeStyleSettings>("CppTools::CppCodeStyleSettings");
|
qRegisterMetaType<CppTools::CppCodeStyleSettings>("CppTools::CppCodeStyleSettings");
|
||||||
|
|
||||||
|
d->m_completionSettingsPage = new CompletionSettingsPage(this);
|
||||||
|
ExtensionSystem::PluginManager::instance()->addObject(d->m_completionSettingsPage);
|
||||||
|
|
||||||
|
connect(d->m_completionSettingsPage,
|
||||||
|
SIGNAL(commentsSettingsChanged(CppTools::CommentsSettings)),
|
||||||
|
this,
|
||||||
|
SIGNAL(commentsSettingsChanged(CppTools::CommentsSettings)));
|
||||||
|
|
||||||
TextEditor::TextEditorSettings *textEditorSettings = TextEditor::TextEditorSettings::instance();
|
TextEditor::TextEditorSettings *textEditorSettings = TextEditor::TextEditorSettings::instance();
|
||||||
|
|
||||||
// code style factory
|
// code style factory
|
||||||
@@ -224,6 +243,8 @@ CppToolsSettings::CppToolsSettings(QObject *parent)
|
|||||||
|
|
||||||
CppToolsSettings::~CppToolsSettings()
|
CppToolsSettings::~CppToolsSettings()
|
||||||
{
|
{
|
||||||
|
ExtensionSystem::PluginManager::instance()->removeObject(d->m_completionSettingsPage);
|
||||||
|
|
||||||
delete d;
|
delete d;
|
||||||
|
|
||||||
m_instance = 0;
|
m_instance = 0;
|
||||||
@@ -239,3 +260,7 @@ CppCodeStylePreferences *CppToolsSettings::cppCodeStyle() const
|
|||||||
return d->m_globalCodeStyle;
|
return d->m_globalCodeStyle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const CommentsSettings &CppToolsSettings::commentsSettings() const
|
||||||
|
{
|
||||||
|
return d->m_completionSettingsPage->commentsSettings();
|
||||||
|
}
|
||||||
|
|||||||
@@ -40,7 +40,7 @@
|
|||||||
namespace CppTools
|
namespace CppTools
|
||||||
{
|
{
|
||||||
class CppCodeStylePreferences;
|
class CppCodeStylePreferences;
|
||||||
|
class CommentsSettings;
|
||||||
|
|
||||||
namespace Internal
|
namespace Internal
|
||||||
{
|
{
|
||||||
@@ -61,6 +61,10 @@ public:
|
|||||||
static CppToolsSettings *instance();
|
static CppToolsSettings *instance();
|
||||||
|
|
||||||
CppCodeStylePreferences *cppCodeStyle() const;
|
CppCodeStylePreferences *cppCodeStyle() const;
|
||||||
|
const CommentsSettings &commentsSettings() const;
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void commentsSettingsChanged(const CppTools::CommentsSettings &settings);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Internal::CppToolsSettingsPrivate *d;
|
Internal::CppToolsSettingsPrivate *d;
|
||||||
|
|||||||
289
src/plugins/cpptools/doxygengenerator.cpp
Normal file
289
src/plugins/cpptools/doxygengenerator.cpp
Normal file
@@ -0,0 +1,289 @@
|
|||||||
|
#include "doxygengenerator.h"
|
||||||
|
|
||||||
|
#include <cplusplus/SimpleLexer.h>
|
||||||
|
#include <cplusplus/BackwardsScanner.h>
|
||||||
|
#include <cplusplus/Token.h>
|
||||||
|
#include <cplusplus/TranslationUnit.h>
|
||||||
|
#include <cplusplus/AST.h>
|
||||||
|
#include <cplusplus/Symbols.h>
|
||||||
|
#include <cplusplus/CppDocument.h>
|
||||||
|
#include <cplusplus/Scope.h>
|
||||||
|
#include <cplusplus/LookupContext.h>
|
||||||
|
|
||||||
|
#include <QtCore/QStringBuilder>
|
||||||
|
#include <QtGui/QTextDocument>
|
||||||
|
#include <QDebug>
|
||||||
|
|
||||||
|
using namespace CppTools;
|
||||||
|
using namespace CPlusPlus;
|
||||||
|
|
||||||
|
DoxygenGenerator::DoxygenGenerator()
|
||||||
|
: m_addLeadingAsterisks(true)
|
||||||
|
, m_generateBrief(true)
|
||||||
|
, m_startComment(true)
|
||||||
|
, m_style(QtStyle)
|
||||||
|
, m_commentOffset(0)
|
||||||
|
{}
|
||||||
|
|
||||||
|
void DoxygenGenerator::setStyle(DocumentationStyle style)
|
||||||
|
{
|
||||||
|
m_style = style;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DoxygenGenerator::setStartComment(bool start)
|
||||||
|
{
|
||||||
|
m_startComment = start;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DoxygenGenerator::setGenerateBrief(bool get)
|
||||||
|
{
|
||||||
|
m_generateBrief = get;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DoxygenGenerator::setAddLeadingAsterisks(bool add)
|
||||||
|
{
|
||||||
|
m_addLeadingAsterisks = add;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString DoxygenGenerator::generate(QTextCursor cursor)
|
||||||
|
{
|
||||||
|
const QChar &c = cursor.document()->characterAt(cursor.position());
|
||||||
|
if (!c.isLetter() && c != QLatin1Char('_'))
|
||||||
|
return QString();
|
||||||
|
|
||||||
|
// Try to find what would be the declaration we are interested in.
|
||||||
|
SimpleLexer lexer;
|
||||||
|
QTextBlock block = cursor.block();
|
||||||
|
while (block.isValid()) {
|
||||||
|
const QString &text = block.text();
|
||||||
|
const QList<Token> &tks = lexer(text);
|
||||||
|
foreach (const Token &tk, tks) {
|
||||||
|
if (tk.is(T_SEMICOLON) || tk.is(T_LBRACE)) {
|
||||||
|
// No need to continue beyond this, we might already have something meaningful.
|
||||||
|
cursor.setPosition(block.position() + tk.end(), QTextCursor::KeepAnchor);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cursor.hasSelection())
|
||||||
|
break;
|
||||||
|
|
||||||
|
block = block.next();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!cursor.hasSelection())
|
||||||
|
return QString();
|
||||||
|
|
||||||
|
QString declCandidate = cursor.selectedText();
|
||||||
|
declCandidate.replace(QChar::ParagraphSeparator, QLatin1Char('\n'));
|
||||||
|
|
||||||
|
// Let's append a closing brace in the case we got content like 'class MyType {'
|
||||||
|
if (declCandidate.endsWith(QLatin1Char('{')))
|
||||||
|
declCandidate.append(QLatin1Char('}'));
|
||||||
|
|
||||||
|
Document::Ptr doc = Document::create(QLatin1String("<doxygen>"));
|
||||||
|
doc->setSource(declCandidate.toUtf8());
|
||||||
|
doc->parse(Document::ParseDeclaration);
|
||||||
|
doc->check(Document::FastCheck);
|
||||||
|
|
||||||
|
if (!doc->translationUnit()
|
||||||
|
|| !doc->translationUnit()->ast()
|
||||||
|
|| !doc->translationUnit()->ast()->asDeclaration()) {
|
||||||
|
return QString();
|
||||||
|
}
|
||||||
|
|
||||||
|
return generate(cursor, doc->translationUnit()->ast()->asDeclaration());
|
||||||
|
}
|
||||||
|
|
||||||
|
QString DoxygenGenerator::generate(QTextCursor cursor, CPlusPlus::DeclarationAST *decl)
|
||||||
|
{
|
||||||
|
SpecifierAST *spec = 0;
|
||||||
|
DeclaratorAST *decltr = 0;
|
||||||
|
if (SimpleDeclarationAST *simpleDecl = decl->asSimpleDeclaration()) {
|
||||||
|
if (simpleDecl->declarator_list
|
||||||
|
&& simpleDecl->declarator_list->value) {
|
||||||
|
decltr = simpleDecl->declarator_list->value;
|
||||||
|
} else if (simpleDecl->decl_specifier_list
|
||||||
|
&& simpleDecl->decl_specifier_list->value) {
|
||||||
|
spec = simpleDecl->decl_specifier_list->value;
|
||||||
|
}
|
||||||
|
} else if (FunctionDefinitionAST * defDecl = decl->asFunctionDefinition()) {
|
||||||
|
decltr = defDecl->declarator;
|
||||||
|
}
|
||||||
|
|
||||||
|
assignCommentOffset(cursor);
|
||||||
|
|
||||||
|
QString comment;
|
||||||
|
if (m_startComment)
|
||||||
|
writeStart(&comment);
|
||||||
|
writeNewLine(&comment);
|
||||||
|
writeContinuation(&comment);
|
||||||
|
|
||||||
|
if (decltr
|
||||||
|
&& decltr->core_declarator
|
||||||
|
&& decltr->core_declarator->asDeclaratorId()
|
||||||
|
&& decltr->core_declarator->asDeclaratorId()->name) {
|
||||||
|
CoreDeclaratorAST *coreDecl = decltr->core_declarator;
|
||||||
|
if (m_generateBrief)
|
||||||
|
writeBrief(&comment, m_printer.prettyName(coreDecl->asDeclaratorId()->name->name));
|
||||||
|
else
|
||||||
|
writeNewLine(&comment);
|
||||||
|
|
||||||
|
if (decltr->postfix_declarator_list
|
||||||
|
&& decltr->postfix_declarator_list->value
|
||||||
|
&& decltr->postfix_declarator_list->value->asFunctionDeclarator()) {
|
||||||
|
FunctionDeclaratorAST *funcDecltr =
|
||||||
|
decltr->postfix_declarator_list->value->asFunctionDeclarator();
|
||||||
|
if (funcDecltr->parameter_declaration_clause
|
||||||
|
&& funcDecltr->parameter_declaration_clause->parameter_declaration_list) {
|
||||||
|
for (ParameterDeclarationListAST *it =
|
||||||
|
funcDecltr->parameter_declaration_clause->parameter_declaration_list;
|
||||||
|
it;
|
||||||
|
it = it->next) {
|
||||||
|
ParameterDeclarationAST *paramDecl = it->value;
|
||||||
|
if (paramDecl->declarator
|
||||||
|
&& paramDecl->declarator->core_declarator
|
||||||
|
&& paramDecl->declarator->core_declarator->asDeclaratorId()
|
||||||
|
&& paramDecl->declarator->core_declarator->asDeclaratorId()->name) {
|
||||||
|
DeclaratorIdAST *paramId =
|
||||||
|
paramDecl->declarator->core_declarator->asDeclaratorId();
|
||||||
|
writeContinuation(&comment);
|
||||||
|
writeCommand(&comment,
|
||||||
|
ParamCommand,
|
||||||
|
m_printer.prettyName(paramId->name->name));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (funcDecltr->symbol
|
||||||
|
&& funcDecltr->symbol->returnType().type()
|
||||||
|
&& !funcDecltr->symbol->returnType()->isVoidType()
|
||||||
|
&& !funcDecltr->symbol->returnType()->isUndefinedType()) {
|
||||||
|
writeContinuation(&comment);
|
||||||
|
writeCommand(&comment, ReturnCommand);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (spec && m_generateBrief) {
|
||||||
|
bool briefWritten = false;
|
||||||
|
if (ClassSpecifierAST *classSpec = spec->asClassSpecifier()) {
|
||||||
|
if (classSpec->name) {
|
||||||
|
QString aggregate;
|
||||||
|
if (classSpec->symbol->isClass())
|
||||||
|
aggregate = QLatin1String("class");
|
||||||
|
else if (classSpec->symbol->isStruct())
|
||||||
|
aggregate = QLatin1String("struct");
|
||||||
|
else
|
||||||
|
aggregate = QLatin1String("union");
|
||||||
|
writeBrief(&comment,
|
||||||
|
m_printer.prettyName(classSpec->name->name),
|
||||||
|
QLatin1String("The"),
|
||||||
|
aggregate);
|
||||||
|
briefWritten = true;
|
||||||
|
}
|
||||||
|
} else if (EnumSpecifierAST *enumSpec = spec->asEnumSpecifier()) {
|
||||||
|
if (enumSpec->name) {
|
||||||
|
writeBrief(&comment,
|
||||||
|
m_printer.prettyName(enumSpec->name->name),
|
||||||
|
QLatin1String("The"),
|
||||||
|
QLatin1String("enum"));
|
||||||
|
briefWritten = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!briefWritten)
|
||||||
|
writeNewLine(&comment);
|
||||||
|
} else {
|
||||||
|
writeNewLine(&comment);
|
||||||
|
}
|
||||||
|
|
||||||
|
writeEnd(&comment);
|
||||||
|
|
||||||
|
return comment;
|
||||||
|
}
|
||||||
|
|
||||||
|
QChar DoxygenGenerator::startMark() const
|
||||||
|
{
|
||||||
|
if (m_style == QtStyle)
|
||||||
|
return QLatin1Char('!');
|
||||||
|
return QLatin1Char('*');
|
||||||
|
}
|
||||||
|
|
||||||
|
QChar DoxygenGenerator::styleMark() const
|
||||||
|
{
|
||||||
|
if (m_style == QtStyle)
|
||||||
|
return QLatin1Char('\\');
|
||||||
|
return QLatin1Char('@');
|
||||||
|
}
|
||||||
|
|
||||||
|
QString DoxygenGenerator::commandSpelling(Command command)
|
||||||
|
{
|
||||||
|
if (command == ParamCommand)
|
||||||
|
return QLatin1String("param ");
|
||||||
|
if (command == ReturnCommand)
|
||||||
|
return QLatin1String("return ");
|
||||||
|
|
||||||
|
Q_ASSERT(command == BriefCommand);
|
||||||
|
return QLatin1String("brief ");
|
||||||
|
}
|
||||||
|
|
||||||
|
void DoxygenGenerator::writeStart(QString *comment) const
|
||||||
|
{
|
||||||
|
comment->append(offsetString() % QLatin1String("/*") % startMark());
|
||||||
|
}
|
||||||
|
|
||||||
|
void DoxygenGenerator::writeEnd(QString *comment) const
|
||||||
|
{
|
||||||
|
comment->append(offsetString() % QLatin1String(" */"));
|
||||||
|
}
|
||||||
|
|
||||||
|
void DoxygenGenerator::writeContinuation(QString *comment) const
|
||||||
|
{
|
||||||
|
if (m_addLeadingAsterisks)
|
||||||
|
comment->append(offsetString() % QLatin1String(" *"));
|
||||||
|
else
|
||||||
|
comment->append(offsetString() % QLatin1String(" "));
|
||||||
|
}
|
||||||
|
|
||||||
|
void DoxygenGenerator::writeNewLine(QString *comment) const
|
||||||
|
{
|
||||||
|
comment->append(QLatin1Char('\n'));
|
||||||
|
}
|
||||||
|
|
||||||
|
void DoxygenGenerator::writeCommand(QString *comment,
|
||||||
|
Command command,
|
||||||
|
const QString &commandContent) const
|
||||||
|
{
|
||||||
|
comment->append(QLatin1Char(' ')
|
||||||
|
% styleMark()
|
||||||
|
% commandSpelling(command)
|
||||||
|
% commandContent
|
||||||
|
% QLatin1Char('\n'));
|
||||||
|
}
|
||||||
|
|
||||||
|
void DoxygenGenerator::writeBrief(QString *comment,
|
||||||
|
const QString &brief,
|
||||||
|
const QString &prefix,
|
||||||
|
const QString &suffix)
|
||||||
|
{
|
||||||
|
QString content = prefix % QLatin1Char(' ') % brief % QLatin1Char(' ') % suffix;
|
||||||
|
writeCommand(comment, BriefCommand, content.trimmed());
|
||||||
|
}
|
||||||
|
|
||||||
|
void DoxygenGenerator::assignCommentOffset(QTextCursor cursor)
|
||||||
|
{
|
||||||
|
if (cursor.hasSelection()) {
|
||||||
|
if (cursor.anchor() < cursor.position())
|
||||||
|
cursor.setPosition(cursor.anchor());
|
||||||
|
}
|
||||||
|
|
||||||
|
m_commentOffset = cursor.positionInBlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
QString DoxygenGenerator::offsetString() const
|
||||||
|
{
|
||||||
|
// Note: Currently we don't indent comments, but simply preserve them in the original
|
||||||
|
// relative positions. What we do here is just to make sure that such positions are correct,
|
||||||
|
// although they might still be wrong from an indentation point of view (for instance,
|
||||||
|
// using spaces instead of tabs). Therefore, the content generated should still have
|
||||||
|
// the indentation strings fixed.
|
||||||
|
|
||||||
|
return QString(m_commentOffset, QLatin1Char(' '));
|
||||||
|
}
|
||||||
71
src/plugins/cpptools/doxygengenerator.h
Normal file
71
src/plugins/cpptools/doxygengenerator.h
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
#ifndef DOXYGEGENERATOR_H
|
||||||
|
#define DOXYGEGENERATOR_H
|
||||||
|
|
||||||
|
#include "cpptools_global.h"
|
||||||
|
|
||||||
|
#include <cplusplus/Overview.h>
|
||||||
|
|
||||||
|
#include <QtCore/QLatin1String>
|
||||||
|
#include <QtGui/QTextCursor>
|
||||||
|
|
||||||
|
namespace CPlusPlus {
|
||||||
|
class DeclarationAST;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace CppTools {
|
||||||
|
|
||||||
|
class CPPTOOLS_EXPORT DoxygenGenerator
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
DoxygenGenerator();
|
||||||
|
|
||||||
|
enum DocumentationStyle {
|
||||||
|
JavaStyle,
|
||||||
|
QtStyle
|
||||||
|
};
|
||||||
|
|
||||||
|
void setStyle(DocumentationStyle style);
|
||||||
|
void setStartComment(bool start);
|
||||||
|
void setGenerateBrief(bool gen);
|
||||||
|
void setAddLeadingAsterisks(bool add);
|
||||||
|
|
||||||
|
QString generate(QTextCursor cursor);
|
||||||
|
QString generate(QTextCursor cursor, CPlusPlus::DeclarationAST *decl);
|
||||||
|
|
||||||
|
private:
|
||||||
|
QChar startMark() const;
|
||||||
|
QChar styleMark() const;
|
||||||
|
|
||||||
|
enum Command {
|
||||||
|
BriefCommand,
|
||||||
|
ParamCommand,
|
||||||
|
ReturnCommand
|
||||||
|
};
|
||||||
|
static QString commandSpelling(Command command);
|
||||||
|
|
||||||
|
void writeStart(QString *comment) const;
|
||||||
|
void writeEnd(QString *comment) const;
|
||||||
|
void writeContinuation(QString *comment) const;
|
||||||
|
void writeNewLine(QString *comment) const;
|
||||||
|
void writeCommand(QString *comment,
|
||||||
|
Command command,
|
||||||
|
const QString &commandContent = QString()) const;
|
||||||
|
void writeBrief(QString *comment,
|
||||||
|
const QString &brief,
|
||||||
|
const QString &prefix = QString(),
|
||||||
|
const QString &suffix = QString());
|
||||||
|
|
||||||
|
void assignCommentOffset(QTextCursor cursor);
|
||||||
|
QString offsetString() const;
|
||||||
|
|
||||||
|
bool m_addLeadingAsterisks;
|
||||||
|
bool m_generateBrief;
|
||||||
|
bool m_startComment;
|
||||||
|
DocumentationStyle m_style;
|
||||||
|
CPlusPlus::Overview m_printer;
|
||||||
|
int m_commentOffset;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // CppTools
|
||||||
|
|
||||||
|
#endif // DOXYGEGENERATOR_H
|
||||||
Reference in New Issue
Block a user