/** ****************************************************************************** * * @file uncommentselection.cpp * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. * Parts by Nokia Corporation (qt-info@nokia.com) Copyright (C) 2009. * @brief * @see The GNU Public License (GPL) Version 3 * @defgroup * @{ * *****************************************************************************/ /* * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "uncommentselection.h" #include #include #include #include void 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(); }