1
/**************************************************************************
3
** This file is part of Qt Creator
5
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
7
** Contact: Nokia Corporation (qt-info@nokia.com)
11
** Licensees holding valid Qt Commercial licenses may use this file in
12
** accordance with the Qt Commercial License Agreement provided with the
13
** Software or, alternatively, in accordance with the terms contained in
14
** a written agreement between you and Nokia.
16
** GNU Lesser General Public License Usage
18
** Alternatively, this file may be used under the terms of the GNU Lesser
19
** General Public License version 2.1 as published by the Free Software
20
** Foundation and appearing in the file LICENSE.LGPL included in the
21
** packaging of this file. Please review the following information to
22
** ensure the GNU Lesser General Public License version 2.1 requirements
23
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
25
** If you are unsure which license is appropriate for your use, please
26
** contact the sales department at http://www.qtsoftware.com/contact.
28
**************************************************************************/
30
#include "uncommentselection.h"
31
#include <QtGui/QPlainTextEdit>
32
#include <QtGui/QTextCursor>
33
#include <QtGui/QTextBlock>
34
#include <QtGui/QTextDocument>
36
void Core::Utils::unCommentSelection(QPlainTextEdit *edit)
38
QTextCursor cursor = edit->textCursor();
39
QTextDocument *doc = cursor.document();
40
cursor.beginEditBlock();
42
int pos = cursor.position();
43
int anchor = cursor.anchor();
44
int start = qMin(anchor, pos);
45
int end = qMax(anchor, pos);
46
bool anchorIsStart = (anchor == start);
48
QTextBlock startBlock = doc->findBlock(start);
49
QTextBlock endBlock = doc->findBlock(end);
51
if (end > start && endBlock.position() == end) {
53
endBlock = endBlock.previous();
56
bool doCStyleUncomment = false;
57
bool doCStyleComment = false;
58
bool doCppStyleUncomment = false;
60
bool hasSelection = cursor.hasSelection();
63
QString startText = startBlock.text();
64
int startPos = start - startBlock.position();
65
bool hasLeadingCharacters = !startText.left(startPos).trimmed().isEmpty();
67
&& startText.at(startPos-2) == QLatin1Char('/')
68
&& startText.at(startPos-1) == QLatin1Char('*'))) {
73
bool hasSelStart = (startPos < startText.length() - 2
74
&& startText.at(startPos) == QLatin1Char('/')
75
&& startText.at(startPos+1) == QLatin1Char('*'));
78
QString endText = endBlock.text();
79
int endPos = end - endBlock.position();
80
bool hasTrailingCharacters = !endText.left(endPos).remove(QLatin1String("//")).trimmed().isEmpty()
81
&& !endText.mid(endPos).trimmed().isEmpty();
82
if ((endPos <= endText.length() - 2
83
&& endText.at(endPos) == QLatin1Char('*')
84
&& endText.at(endPos+1) == QLatin1Char('/'))) {
89
bool hasSelEnd = (endPos >= 2
90
&& endText.at(endPos-2) == QLatin1Char('*')
91
&& endText.at(endPos-1) == QLatin1Char('/'));
93
doCStyleUncomment = hasSelStart && hasSelEnd;
94
doCStyleComment = !doCStyleUncomment && (hasLeadingCharacters || hasTrailingCharacters);
97
if (doCStyleUncomment) {
98
cursor.setPosition(end);
99
cursor.movePosition(QTextCursor::PreviousCharacter, QTextCursor::KeepAnchor, 2);
100
cursor.removeSelectedText();
101
cursor.setPosition(start);
102
cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor, 2);
103
cursor.removeSelectedText();
104
} else if (doCStyleComment) {
105
cursor.setPosition(end);
106
cursor.insertText(QLatin1String("*/"));
107
cursor.setPosition(start);
108
cursor.insertText(QLatin1String("/*"));
110
endBlock = endBlock.next();
111
doCppStyleUncomment = true;
112
for (QTextBlock block = startBlock; block != endBlock; block = block.next()) {
113
QString text = block.text();
114
if (!text.trimmed().startsWith(QLatin1String("//"))) {
115
doCppStyleUncomment = false;
119
for (QTextBlock block = startBlock; block != endBlock; block = block.next()) {
120
if (doCppStyleUncomment) {
121
QString text = block.text();
123
while (i < text.size() - 1) {
124
if (text.at(i) == QLatin1Char('/')
125
&& text.at(i + 1) == QLatin1Char('/')) {
126
cursor.setPosition(block.position() + i);
127
cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor, 2);
128
cursor.removeSelectedText();
131
if (!text.at(i).isSpace())
136
cursor.setPosition(block.position());
137
cursor.insertText(QLatin1String("//"));
142
// adjust selection when commenting out
143
if (hasSelection && !doCStyleUncomment && !doCppStyleUncomment) {
144
cursor = edit->textCursor();
145
if (!doCStyleComment)
146
start = startBlock.position(); // move the double slashes into the selection
147
int lastSelPos = anchorIsStart ? cursor.position() : cursor.anchor();
149
cursor.setPosition(start);
150
cursor.setPosition(lastSelPos, QTextCursor::KeepAnchor);
152
cursor.setPosition(lastSelPos);
153
cursor.setPosition(start, QTextCursor::KeepAnchor);
155
edit->setTextCursor(cursor);
158
cursor.endEditBlock();