Commit 6195035b authored by Roberto Raggi's avatar Roberto Raggi
Browse files

Moved unCommentSelection() in creator/libs/util so we can use it for other...

Moved unCommentSelection() in creator/libs/util so we can use it for other C-like languages (e.g QML and JS).
parent 17a078d5
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Qt Software Information (qt-info@nokia.com)
**
** Commercial Usage
**
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Nokia.
**
** GNU Lesser General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** If you are unsure which license is appropriate for your use, please
** contact the sales department at qt-sales@nokia.com.
**
**************************************************************************/
#include "uncommentselection.h"
#include <QtGui/QPlainTextEdit>
#include <QtGui/QTextCursor>
#include <QtGui/QTextBlock>
#include <QtGui/QTextDocument>
void Core::Utils::unCommentSelection(QPlainTextEdit *edit)
{
QTextCursor cursor = edit->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 doCStyleUncomment = false;
bool doCStyleComment = false;
bool doCppStyleUncomment = false;
bool hasSelection = cursor.hasSelection();
if (hasSelection) {
QString startText = startBlock.text();
int startPos = start - startBlock.position();
bool hasLeadingCharacters = !startText.left(startPos).trimmed().isEmpty();
if ((startPos >= 2
&& startText.at(startPos-2) == QLatin1Char('/')
&& startText.at(startPos-1) == QLatin1Char('*'))) {
startPos -= 2;
start -= 2;
}
bool hasSelStart = (startPos < startText.length() - 2
&& startText.at(startPos) == QLatin1Char('/')
&& startText.at(startPos+1) == QLatin1Char('*'));
QString endText = endBlock.text();
int endPos = end - endBlock.position();
bool hasTrailingCharacters = !endText.left(endPos).remove(QLatin1String("//")).trimmed().isEmpty()
&& !endText.mid(endPos).trimmed().isEmpty();
if ((endPos <= endText.length() - 2
&& endText.at(endPos) == QLatin1Char('*')
&& endText.at(endPos+1) == QLatin1Char('/'))) {
endPos += 2;
end += 2;
}
bool hasSelEnd = (endPos >= 2
&& endText.at(endPos-2) == QLatin1Char('*')
&& endText.at(endPos-1) == QLatin1Char('/'));
doCStyleUncomment = hasSelStart && hasSelEnd;
doCStyleComment = !doCStyleUncomment && (hasLeadingCharacters || hasTrailingCharacters);
}
if (doCStyleUncomment) {
cursor.setPosition(end);
cursor.movePosition(QTextCursor::PreviousCharacter, QTextCursor::KeepAnchor, 2);
cursor.removeSelectedText();
cursor.setPosition(start);
cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor, 2);
cursor.removeSelectedText();
} else if (doCStyleComment) {
cursor.setPosition(end);
cursor.insertText(QLatin1String("*/"));
cursor.setPosition(start);
cursor.insertText(QLatin1String("/*"));
} else {
endBlock = endBlock.next();
doCppStyleUncomment = true;
for (QTextBlock block = startBlock; block != endBlock; block = block.next()) {
QString text = block.text();
if (!text.trimmed().startsWith(QLatin1String("//"))) {
doCppStyleUncomment = false;
break;
}
}
for (QTextBlock block = startBlock; block != endBlock; block = block.next()) {
if (doCppStyleUncomment) {
QString text = block.text();
int i = 0;
while (i < text.size() - 1) {
if (text.at(i) == QLatin1Char('/')
&& text.at(i + 1) == QLatin1Char('/')) {
cursor.setPosition(block.position() + i);
cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor, 2);
cursor.removeSelectedText();
break;
}
if (!text.at(i).isSpace())
break;
++i;
}
} else {
cursor.setPosition(block.position());
cursor.insertText(QLatin1String("//"));
}
}
}
// adjust selection when commenting out
if (hasSelection && !doCStyleUncomment && !doCppStyleUncomment) {
cursor = edit->textCursor();
if (!doCStyleComment)
start = startBlock.position(); // move the double slashes 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);
}
edit->setTextCursor(cursor);
}
cursor.endEditBlock();
}
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Qt Software Information (qt-info@nokia.com)
**
** Commercial Usage
**
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Nokia.
**
** GNU Lesser General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** If you are unsure which license is appropriate for your use, please
** contact the sales department at qt-sales@nokia.com.
**
**************************************************************************/
#ifndef UNCOMMENTSELECTION_H
#define UNCOMMENTSELECTION_H
#include "utils_global.h"
QT_BEGIN_NAMESPACE
class QPlainTextEdit;
QT_END_NAMESPACE
namespace Core {
namespace Utils {
QTCREATOR_UTILS_EXPORT void unCommentSelection(QPlainTextEdit *edit);
} // end of namespace Utils
} // end of namespace Core
#endif // UNCOMMENTSELECTION_H
......@@ -28,7 +28,8 @@ SOURCES += \
submiteditorwidget.cpp \
synchronousprocess.cpp \
submitfieldwidget.cpp \
consoleprocess.cpp
consoleprocess.cpp \
uncommentselection.cpp
win32 {
SOURCES += abstractprocess_win.cpp \
......@@ -64,7 +65,8 @@ HEADERS += \
abstractprocess.h \
consoleprocess.h \
synchronousprocess.h \
submitfieldwidget.h
submitfieldwidget.h \
uncommentselection.h
FORMS += filewizardpage.ui \
projectintropage.ui \
......
......@@ -59,6 +59,7 @@
#include <coreplugin/actionmanager/actionmanager.h>
#include <coreplugin/editormanager/ieditor.h>
#include <coreplugin/editormanager/editormanager.h>
#include <utils/uncommentselection.h>
#include <extensionsystem/pluginmanager.h>
#include <projectexplorer/projectexplorerconstants.h>
#include <texteditor/basetextdocument.h>
......@@ -1036,126 +1037,7 @@ void CPPEditor::setDisplaySettings(const TextEditor::DisplaySettings &ds)
void CPPEditor::unCommentSelection()
{
QTextCursor cursor = textCursor();
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 = document()->findBlock(start);
QTextBlock endBlock = document()->findBlock(end);
if (end > start && endBlock.position() == end) {
--end;
endBlock = endBlock.previous();
}
bool doCStyleUncomment = false;
bool doCStyleComment = false;
bool doCppStyleUncomment = false;
bool hasSelection = cursor.hasSelection();
if (hasSelection) {
QString startText = startBlock.text();
int startPos = start - startBlock.position();
bool hasLeadingCharacters = !startText.left(startPos).trimmed().isEmpty();
if ((startPos >= 2
&& startText.at(startPos-2) == QLatin1Char('/')
&& startText.at(startPos-1) == QLatin1Char('*'))) {
startPos -= 2;
start -= 2;
}
bool hasSelStart = (startPos < startText.length() - 2
&& startText.at(startPos) == QLatin1Char('/')
&& startText.at(startPos+1) == QLatin1Char('*'));
QString endText = endBlock.text();
int endPos = end - endBlock.position();
bool hasTrailingCharacters = !endText.left(endPos).remove(QLatin1String("//")).trimmed().isEmpty()
&& !endText.mid(endPos).trimmed().isEmpty();
if ((endPos <= endText.length() - 2
&& endText.at(endPos) == QLatin1Char('*')
&& endText.at(endPos+1) == QLatin1Char('/'))) {
endPos += 2;
end += 2;
}
bool hasSelEnd = (endPos >= 2
&& endText.at(endPos-2) == QLatin1Char('*')
&& endText.at(endPos-1) == QLatin1Char('/'));
doCStyleUncomment = hasSelStart && hasSelEnd;
doCStyleComment = !doCStyleUncomment && (hasLeadingCharacters || hasTrailingCharacters);
}
if (doCStyleUncomment) {
cursor.setPosition(end);
cursor.movePosition(QTextCursor::PreviousCharacter, QTextCursor::KeepAnchor, 2);
cursor.removeSelectedText();
cursor.setPosition(start);
cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor, 2);
cursor.removeSelectedText();
} else if (doCStyleComment) {
cursor.setPosition(end);
cursor.insertText(QLatin1String("*/"));
cursor.setPosition(start);
cursor.insertText(QLatin1String("/*"));
} else {
endBlock = endBlock.next();
doCppStyleUncomment = true;
for (QTextBlock block = startBlock; block != endBlock; block = block.next()) {
QString text = block.text();
if (!text.trimmed().startsWith(QLatin1String("//"))) {
doCppStyleUncomment = false;
break;
}
}
for (QTextBlock block = startBlock; block != endBlock; block = block.next()) {
if (doCppStyleUncomment) {
QString text = block.text();
int i = 0;
while (i < text.size() - 1) {
if (text.at(i) == QLatin1Char('/')
&& text.at(i + 1) == QLatin1Char('/')) {
cursor.setPosition(block.position() + i);
cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor, 2);
cursor.removeSelectedText();
break;
}
if (!text.at(i).isSpace())
break;
++i;
}
} else {
cursor.setPosition(block.position());
cursor.insertText(QLatin1String("//"));
}
}
}
// adjust selection when commenting out
if (hasSelection && !doCStyleUncomment && !doCppStyleUncomment) {
cursor = textCursor();
if (!doCStyleComment)
start = startBlock.position(); // move the double slashes 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);
}
setTextCursor(cursor);
}
cursor.endEditBlock();
Core::Utils::unCommentSelection(this);
}
CPPEditor::Link CPPEditor::linkToSymbol(CPlusPlus::Symbol *symbol)
......
......@@ -47,6 +47,8 @@
#include <texteditor/texteditorconstants.h>
#include <texteditor/texteditorsettings.h>
#include <utils/uncommentselection.h>
#include <QtCore/QTimer>
#include <QtCore/QtDebug>
......@@ -708,5 +710,10 @@ void ScriptEditor::contextMenuEvent(QContextMenuEvent *e)
menu->deleteLater();
}
void ScriptEditor::unCommentSelection()
{
Core::Utils::unCommentSelection(this);
}
} // namespace Internal
} // namespace DuiEditor
......@@ -104,6 +104,8 @@ public:
QList<JavaScript::DiagnosticMessage> diagnosticMessages() const
{ return m_diagnosticMessages; }
virtual void unCommentSelection();
public slots:
virtual void setFontSettings(const TextEditor::FontSettings &);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment