Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/master' into master-loc
Browse files Browse the repository at this point in the history
  • Loading branch information
vwaurich committed Sep 21, 2016
2 parents 7da13ef + 3aded14 commit f4df9cc
Show file tree
Hide file tree
Showing 31 changed files with 750 additions and 397 deletions.
5 changes: 4 additions & 1 deletion OMEdit/OMEditGUI/Component/ComponentProperties.cpp
Expand Up @@ -783,7 +783,10 @@ void ComponentParameters::createTabsGroupBoxesAndParametersHelper(LibraryTreeIte
// get the group value
groupBox = StringHandler::removeFirstLastQuotes(dialogAnnotation.at(1));
// get the enable value
enable = (dialogAnnotation.at(2).compare("true") == 0);
/* Ticket #4008
* For now just display all parameters as enabled.
*/
//enable = (dialogAnnotation.at(2).compare("true") == 0);
// get the showStartAttribute value
if (dialogAnnotation.at(3).compare("-") != 0) {
showStartAttribute = (dialogAnnotation.at(3).compare("true") == 0);
Expand Down
263 changes: 263 additions & 0 deletions OMEdit/OMEditGUI/Editors/BaseEditor.cpp
Expand Up @@ -387,6 +387,89 @@ TextBlockUserData::MatchType TextBlockUserData::matchCursorForward(QTextCursor *
return NoMatch;
}

/*!
\class CommentDefinition
\brief Defines the single and multi line comments styles. The class implementation and logic is inspired from Qt Creator sources.
*/
CommentDefinition::CommentDefinition() :
m_afterWhiteSpaces(false),
m_singleLine(QLatin1String("//")),
m_multiLineStart(QLatin1String("/*")),
m_multiLineEnd(QLatin1String("*/"))
{}

CommentDefinition &CommentDefinition::setAfterWhiteSpaces(const bool afterWhiteSpaces)
{
m_afterWhiteSpaces = afterWhiteSpaces;
return *this;
}

CommentDefinition &CommentDefinition::setSingleLine(const QString &singleLine)
{
m_singleLine = singleLine;
return *this;
}

CommentDefinition &CommentDefinition::setMultiLineStart(const QString &multiLineStart)
{
m_multiLineStart = multiLineStart;
return *this;
}

CommentDefinition &CommentDefinition::setMultiLineEnd(const QString &multiLineEnd)
{
m_multiLineEnd = multiLineEnd;
return *this;
}

bool CommentDefinition::isAfterWhiteSpaces() const
{ return m_afterWhiteSpaces; }

const QString &CommentDefinition::singleLine() const
{ return m_singleLine; }

const QString &CommentDefinition::multiLineStart() const
{ return m_multiLineStart; }

const QString &CommentDefinition::multiLineEnd() const
{ return m_multiLineEnd; }

bool CommentDefinition::hasSingleLineStyle() const
{ return !m_singleLine.isEmpty(); }

bool CommentDefinition::hasMultiLineStyle() const
{ return !m_multiLineStart.isEmpty() && !m_multiLineEnd.isEmpty(); }

void CommentDefinition::clearCommentStyles()
{
m_singleLine.clear();
m_multiLineStart.clear();
m_multiLineEnd.clear();
}

namespace {

bool isComment(const QString &text,
int index,
const CommentDefinition &definition,
const QString & (CommentDefinition::* comment) () const)
{
const QString &commentType = ((definition).*(comment))();
const int length = commentType.length();

Q_ASSERT(text.length() - index >= length);

int i = 0;
while (i < length) {
if (text.at(index + i) != commentType.at(i))
return false;
++i;
}
return true;
}

}

/*!
* \class BaseEditorDocumentLayout
* Implements a custom text layout for BaseEditor to be able to work with QTextDocument::setDocumentLayout().
Expand Down Expand Up @@ -1628,6 +1711,186 @@ void BaseEditor::toggleBreakpoint()
}
}

/*!
* \brief BaseEditor::toggleCommentSelection
* Slot activated when toggle comment selection is seleteted from context menu or ctrl+k is pressed.
* The implementation and logic is inspired from Qt Creator sources.
*/
void BaseEditor::toggleCommentSelection()
{
CommentDefinition definition;
if (!definition.hasSingleLineStyle() && !definition.hasMultiLineStyle()) {
return;
}

QTextCursor cursor = mpPlainTextEdit->textCursor();
QTextDocument *doc = cursor.document();
cursor.beginEditBlock();

int pos = cursor.position();
int anchor = cursor.anchor();
int start = qMin(anchor, pos);
int end = qMax(anchor, pos);
bool anchorIsStart = (anchor == start);

QTextBlock startBlock = doc->findBlock(start);
QTextBlock endBlock = doc->findBlock(end);

if (end > start && endBlock.position() == end) {
--end;
endBlock = endBlock.previous();
}

bool doMultiLineStyleUncomment = false;
bool doMultiLineStyleComment = false;
bool doSingleLineStyleUncomment = false;

bool hasSelection = cursor.hasSelection();

if (hasSelection && definition.hasMultiLineStyle()) {

QString startText = startBlock.text();
int startPos = start - startBlock.position();
const int multiLineStartLength = definition.multiLineStart().length();
bool hasLeadingCharacters = !startText.left(startPos).trimmed().isEmpty();

if (startPos >= multiLineStartLength
&& isComment(startText,
startPos - multiLineStartLength,
definition,
&CommentDefinition::multiLineStart)) {
startPos -= multiLineStartLength;
start -= multiLineStartLength;
}

bool hasSelStart = (startPos <= startText.length() - multiLineStartLength
&& isComment(startText,
startPos,
definition,
&CommentDefinition::multiLineStart));

QString endText = endBlock.text();
int endPos = end - endBlock.position();
const int multiLineEndLength = definition.multiLineEnd().length();
bool hasTrailingCharacters =
!endText.left(endPos).remove(definition.singleLine()).trimmed().isEmpty()
&& !endText.mid(endPos).trimmed().isEmpty();

if (endPos <= endText.length() - multiLineEndLength
&& isComment(endText, endPos, definition, &CommentDefinition::multiLineEnd)) {
endPos += multiLineEndLength;
end += multiLineEndLength;
}

bool hasSelEnd = (endPos >= multiLineEndLength
&& isComment(endText,
endPos - multiLineEndLength,
definition,
&CommentDefinition::multiLineEnd));

doMultiLineStyleUncomment = hasSelStart && hasSelEnd;
doMultiLineStyleComment = !doMultiLineStyleUncomment
&& (hasLeadingCharacters
|| hasTrailingCharacters
|| !definition.hasSingleLineStyle());
} else if (!hasSelection && !definition.hasSingleLineStyle()) {

QString text = startBlock.text().trimmed();
doMultiLineStyleUncomment = text.startsWith(definition.multiLineStart())
&& text.endsWith(definition.multiLineEnd());
doMultiLineStyleComment = !doMultiLineStyleUncomment && !text.isEmpty();

start = startBlock.position();
end = endBlock.position() + endBlock.length() - 1;

if (doMultiLineStyleUncomment) {
int offset = 0;
text = startBlock.text();
const int length = text.length();
while (offset < length && text.at(offset).isSpace())
++offset;
start += offset;
}
}

if (doMultiLineStyleUncomment) {
cursor.setPosition(end);
cursor.movePosition(QTextCursor::PreviousCharacter,
QTextCursor::KeepAnchor,
definition.multiLineEnd().length());
cursor.removeSelectedText();
cursor.setPosition(start);
cursor.movePosition(QTextCursor::NextCharacter,
QTextCursor::KeepAnchor,
definition.multiLineStart().length());
cursor.removeSelectedText();
} else if (doMultiLineStyleComment) {
cursor.setPosition(end);
cursor.insertText(definition.multiLineEnd());
cursor.setPosition(start);
cursor.insertText(definition.multiLineStart());
} else {
endBlock = endBlock.next();
doSingleLineStyleUncomment = true;
for (QTextBlock block = startBlock; block != endBlock; block = block.next()) {
QString text = block.text().trimmed();
if (!text.isEmpty() && !text.startsWith(definition.singleLine())) {
doSingleLineStyleUncomment = false;
break;
}
}

const int singleLineLength = definition.singleLine().length();
for (QTextBlock block = startBlock; block != endBlock; block = block.next()) {
if (doSingleLineStyleUncomment) {
QString text = block.text();
int i = 0;
while (i <= text.size() - singleLineLength) {
if (isComment(text, i, definition, &CommentDefinition::singleLine)) {
cursor.setPosition(block.position() + i);
cursor.movePosition(QTextCursor::NextCharacter,
QTextCursor::KeepAnchor,
singleLineLength);
cursor.removeSelectedText();
break;
}
if (!text.at(i).isSpace())
break;
++i;
}
} else {
QString text = block.text();
foreach(QChar c, text) {
if (!c.isSpace()) {
if (definition.isAfterWhiteSpaces())
cursor.setPosition(block.position() + text.indexOf(c));
else
cursor.setPosition(block.position());
cursor.insertText(definition.singleLine());
break;
}
}
}
}
}
// adjust selection when commenting out
if (hasSelection && !doMultiLineStyleUncomment && !doSingleLineStyleUncomment) {
cursor = mpPlainTextEdit->textCursor();
if (!doMultiLineStyleComment)
start = startBlock.position(); // move the comment into the selection
int lastSelPos = anchorIsStart ? cursor.position() : cursor.anchor();
if (anchorIsStart) {
cursor.setPosition(start);
cursor.setPosition(lastSelPos, QTextCursor::KeepAnchor);
} else {
cursor.setPosition(lastSelPos);
cursor.setPosition(start, QTextCursor::KeepAnchor);
}
mpPlainTextEdit->setTextCursor(cursor);
}
cursor.endEditBlock();
}

/*!
* \brief BaseEditor::foldAll
* Folds all the foldings in the document.
Expand Down
24 changes: 23 additions & 1 deletion OMEdit/OMEditGUI/Editors/BaseEditor.h
Expand Up @@ -155,6 +155,28 @@ class TextBlockUserData : public QTextBlockUserData
int mLeadingSpaces;
};

class CommentDefinition
{
public:
CommentDefinition();
CommentDefinition &setAfterWhiteSpaces(const bool);
CommentDefinition &setSingleLine(const QString &singleLine);
CommentDefinition &setMultiLineStart(const QString &multiLineStart);
CommentDefinition &setMultiLineEnd(const QString &multiLineEnd);
bool isAfterWhiteSpaces() const;
const QString &singleLine() const;
const QString &multiLineStart() const;
const QString &multiLineEnd() const;
bool hasSingleLineStyle() const;
bool hasMultiLineStyle() const;
void clearCommentStyles();
private:
bool m_afterWhiteSpaces;
QString m_singleLine;
QString m_multiLineStart;
QString m_multiLineEnd;
};

class BaseEditorDocumentLayout : public QPlainTextDocumentLayout
{
Q_OBJECT
Expand Down Expand Up @@ -262,7 +284,7 @@ public slots:
void showGotoLineNumberDialog();
void showTabsAndSpaces(bool On);
void toggleBreakpoint();
virtual void toggleCommentSelection() = 0;
virtual void toggleCommentSelection();
void foldAll();
void unFoldAll();
};
Expand Down

0 comments on commit f4df9cc

Please sign in to comment.