Initial support for emacs like fill-paragraph.

Merge-request: 882
Reviewed-by: Thorbjørn Lindeijer <thorbjorn.lindeijer@nokia.com>
This commit is contained in:
Henrik Abelsson
2009-07-21 10:37:00 +02:00
committed by Thorbjørn Lindeijer
parent 4eda7c27f3
commit f053ec8c14
5 changed files with 135 additions and 1 deletions

View File

@@ -3850,6 +3850,129 @@ void BaseTextEditor::format()
cursor.endEditBlock(); cursor.endEditBlock();
} }
void BaseTextEditor::rewrapParagraph()
{
const int paragraphWidth = displaySettings().m_wrapColumn;
const QRegExp anyLettersOrNumbers = QRegExp("\\w");
const int tabSize = tabSettings().m_tabSize;
QTextCursor cursor = textCursor();
cursor.beginEditBlock();
// Find start of paragraph.
while (cursor.movePosition(QTextCursor::PreviousBlock, QTextCursor::MoveAnchor)) {
QTextBlock block = cursor.block();
QString text = block.text();
// If this block is empty, move marker back to previous and terminate.
if (!text.contains(anyLettersOrNumbers)) {
cursor.movePosition(QTextCursor::NextBlock, QTextCursor::MoveAnchor);
break;
}
}
cursor.movePosition(QTextCursor::StartOfBlock, QTextCursor::MoveAnchor);
// Find indent level of current block.
int indentLevel = 0;
QString text = cursor.block().text();
for (int i = 0; i < text.length(); i++) {
const QChar ch = text.at(i);
if (ch == QLatin1Char(' '))
indentLevel++;
else if (ch == QLatin1Char('\t'))
indentLevel += tabSize - (indentLevel % tabSize);
else
break;
}
// If there is a common prefix, it should be kept and expanded to all lines.
// this allows nice reflowing of doxygen style comments.
QTextCursor nextBlock = cursor;
QString commonPrefix;
if (nextBlock.movePosition(QTextCursor::NextBlock))
{
QString nText = nextBlock.block().text();
int maxLength = qMin(text.length(), nText.length());
for (int i = 0; i < maxLength; ++i) {
const QChar ch = text.at(i);
if (ch != nText[i] || ch.isLetterOrNumber())
break;
commonPrefix.append(ch);
}
}
// Find end of paragraph.
while (cursor.movePosition(QTextCursor::NextBlock, QTextCursor::KeepAnchor)) {
QString text = cursor.block().text();
if (!text.contains(anyLettersOrNumbers))
break;
}
QString selectedText = cursor.selectedText();
// Preserve initial indent level.or common prefix.
QString spacing;
if (commonPrefix.isEmpty()) {
spacing = tabSettings().indentationString(0, indentLevel);
} else {
spacing = commonPrefix;
indentLevel = commonPrefix.length();
}
int currentLength = indentLevel;
QString result;
result.append(spacing);
// Remove existing instances of any common prefix from paragraph to
// reflow.
selectedText.remove(0, commonPrefix.length());
commonPrefix.prepend(QChar::ParagraphSeparator);
selectedText.replace(commonPrefix, QLatin1String("\n"));
// remove any repeated spaces, trim lines to PARAGRAPH_WIDTH width and
// keep the same indentation level as first line in paragraph.
QString currentWord;
for (int i = 0; i < selectedText.length(); ++i) {
QChar ch = selectedText.at(i);
if (ch.isSpace()) {
if (!currentWord.isEmpty()) {
currentLength += currentWord.length() + 1;
if (currentLength > paragraphWidth - indentLevel) {
currentLength = currentWord.length() + 1 + indentLevel;
result.append(QChar::ParagraphSeparator);
result.append(spacing);
}
result.append(currentWord);
result.append(QLatin1String(" "));
currentWord.clear();
}
continue;
}
currentWord.append(ch);
}
result.append(QChar::ParagraphSeparator);
cursor.insertText(result);
cursor.endEditBlock();
}
void BaseTextEditor::unCommentSelection() void BaseTextEditor::unCommentSelection()
{ {
} }

View File

@@ -483,6 +483,7 @@ public:
public slots: public slots:
virtual void format(); virtual void format();
virtual void rewrapParagraph();
virtual void unCommentSelection(); virtual void unCommentSelection();
virtual void setFontSettings(const TextEditor::FontSettings &); virtual void setFontSettings(const TextEditor::FontSettings &);
void setFontSettingsIfVisible(const TextEditor::FontSettings &); void setFontSettingsIfVisible(const TextEditor::FontSettings &);

View File

@@ -141,6 +141,12 @@ void TextEditorActionHandler::createActions()
advancedMenu->addAction(command, Core::Constants::G_EDIT_FORMAT); advancedMenu->addAction(command, Core::Constants::G_EDIT_FORMAT);
connect(m_formatAction, SIGNAL(triggered(bool)), this, SLOT(formatAction())); connect(m_formatAction, SIGNAL(triggered(bool)), this, SLOT(formatAction()));
m_rewrapParagraphAction = new QAction(tr("&Rewrap Paragraph"), this);
command = am->registerAction(m_rewrapParagraphAction, TextEditor::Constants::REWRAP_PARAGRAPH, m_contextId);
//command->setDefaultKeySequence(QKeySequence(tr("Alt+Q"))); (No default key sequence for now.)
advancedMenu->addAction(command, Core::Constants::G_EDIT_FORMAT);
connect(m_rewrapParagraphAction, SIGNAL(triggered(bool)), this, SLOT(rewrapParagraphAction()));
m_visualizeWhitespaceAction = new QAction(tr("&Visualize Whitespace"), this); m_visualizeWhitespaceAction = new QAction(tr("&Visualize Whitespace"), this);
m_visualizeWhitespaceAction->setCheckable(true); m_visualizeWhitespaceAction->setCheckable(true);
@@ -398,6 +404,7 @@ FUNCTION2(copyAction, copy)
FUNCTION2(cutAction, cut) FUNCTION2(cutAction, cut)
FUNCTION2(pasteAction, paste) FUNCTION2(pasteAction, paste)
FUNCTION2(formatAction, format) FUNCTION2(formatAction, format)
FUNCTION2(rewrapParagraphAction, rewrapParagraph)
FUNCTION2(selectAllAction, selectAll) FUNCTION2(selectAllAction, selectAll)
FUNCTION(cleanWhitespace) FUNCTION(cleanWhitespace)
FUNCTION(unCommentSelection) FUNCTION(unCommentSelection)

View File

@@ -91,6 +91,7 @@ private slots:
void gotoAction(); void gotoAction();
void printAction(); void printAction();
void formatAction(); void formatAction();
void rewrapParagraphAction();
void setVisualizeWhitespace(bool); void setVisualizeWhitespace(bool);
void cleanWhitespace(); void cleanWhitespace();
void setTextWrapping(bool); void setTextWrapping(bool);
@@ -125,6 +126,7 @@ private:
QAction *m_gotoAction; QAction *m_gotoAction;
QAction *m_printAction; QAction *m_printAction;
QAction *m_formatAction; QAction *m_formatAction;
QAction *m_rewrapParagraphAction;
QAction *m_visualizeWhitespaceAction; QAction *m_visualizeWhitespaceAction;
QAction *m_cleanWhitespaceAction; QAction *m_cleanWhitespaceAction;
QAction *m_textWrappingAction; QAction *m_textWrappingAction;

View File

@@ -60,8 +60,9 @@ const char * const CUT_LINE = "TextEditor.CutLine";
const char * const DELETE_LINE = "TextEditor.DeleteLine"; const char * const DELETE_LINE = "TextEditor.DeleteLine";
const char * const DELETE_WORD = "TextEditor.DeleteWord"; const char * const DELETE_WORD = "TextEditor.DeleteWord";
const char * const SELECT_ENCODING = "TextEditor.SelectEncoding"; const char * const SELECT_ENCODING = "TextEditor.SelectEncoding";
const char * const REWRAP_PARAGRAPH = "TextEditor.RewrapParagraph";
const char * const GOTO_OPENING_PARENTHESIS = "TextEditor.GotoOpeningParenthesis"; const char * const GOTO_OPENING_PARENTHESIS = "TextEditor.GotoOpeningParenthesis";
const char * const GOTO_CLOSING_PARENTHESIS = "TextEditor.GotoOpeningParenthesis"; const char * const GOTO_CLOSING_PARENTHESIS = "TextEditor.GotoClosingParenthesis";
const char * const C_TEXTEDITOR_MIMETYPE_TEXT = "text/plain"; const char * const C_TEXTEDITOR_MIMETYPE_TEXT = "text/plain";
const char * const C_TEXTEDITOR_MIMETYPE_XML = "application/xml"; const char * const C_TEXTEDITOR_MIMETYPE_XML = "application/xml";