Newer
Older
void BaseTextEditor::setReadOnly(bool b)
{
QPlainTextEdit::setReadOnly(b);
if (b)
setTextInteractionFlags(textInteractionFlags() | Qt::TextSelectableByKeyboard);
}
void BaseTextEditor::cut()
{
if (d->m_inBlockSelectionMode) {
copy();
d->removeBlockSelection();
return;
}
QPlainTextEdit::cut();
}
void BaseTextEditor::paste()
{
if (d->m_inBlockSelectionMode) {
d->removeBlockSelection();
}
QPlainTextEdit::paste();
}
QMimeData *BaseTextEditor::createMimeDataFromSelection() const
{
if (d->m_inBlockSelectionMode) {
QMimeData *mimeData = new QMimeData;
QString text = d->copyBlockSelection();
mimeData->setData(QLatin1String("application/vnd.nokia.qtcreator.vblocktext"), text.toUtf8());
mimeData->setText(text); // for exchangeability
return mimeData;
} else if (textCursor().hasSelection()) {
QTextCursor cursor = textCursor();
QMimeData *mimeData = new QMimeData;
// Copy the selected text as plain text
convertToPlainText(text);
5044
5045
5046
5047
5048
5049
5050
5051
5052
5053
5054
5055
5056
5057
5058
5059
5060
5061
5062
5063
5064
5065
5066
5067
5068
5069
5070
5071
5072
5073
5074
5075
5076
5077
5078
5079
5080
5081
5082
5083
5084
5085
// Copy the selected text as HTML
{
// Create a new document from the selected text document fragment
QTextDocument *tempDocument = new QTextDocument;
QTextCursor tempCursor(tempDocument);
tempCursor.insertFragment(cursor.selection());
// Apply the additional formats set by the syntax highlighter
QTextBlock start = document()->findBlock(cursor.selectionStart());
QTextBlock end = document()->findBlock(cursor.selectionEnd());
end = end.next();
const int selectionStart = cursor.selectionStart();
const int endOfDocument = tempDocument->characterCount() - 1;
for (QTextBlock current = start; current.isValid() && current != end; current = current.next()) {
const QTextLayout *layout = current.layout();
foreach (const QTextLayout::FormatRange &range, layout->additionalFormats()) {
const int start = current.position() + range.start - selectionStart;
const int end = start + range.length;
if (end <= 0 || start >= endOfDocument)
continue;
tempCursor.setPosition(qMax(start, 0));
tempCursor.setPosition(qMin(end, endOfDocument), QTextCursor::KeepAnchor);
tempCursor.setCharFormat(range.format);
}
}
// Reset the user states since they are not interesting
for (QTextBlock block = tempDocument->begin(); block.isValid(); block = block.next())
block.setUserState(-1);
// Make sure the text appears pre-formatted
tempCursor.setPosition(0);
tempCursor.movePosition(QTextCursor::End, QTextCursor::KeepAnchor);
QTextBlockFormat blockFormat = tempCursor.blockFormat();
blockFormat.setNonBreakableLines(true);
tempCursor.setBlockFormat(blockFormat);
mimeData->setHtml(tempCursor.selection().toHtml());
delete tempDocument;
}
/*
Try to figure out whether we are copying an entire block, and store the complete block
including indentation in the qtcreator.blocktext mimetype.
*/
QTextCursor selstart = cursor;
selstart.setPosition(cursor.selectionStart());
QTextCursor selend = cursor;
selend.setPosition(cursor.selectionEnd());
const TabSettings &ts = d->m_document->tabSettings();
bool startOk = ts.cursorIsAtBeginningOfLine(selstart);
bool multipleBlocks = (selend.block() != selstart.block());
selstart.movePosition(QTextCursor::StartOfBlock);
if (ts.cursorIsAtBeginningOfLine(selend))
selend.movePosition(QTextCursor::StartOfBlock);
cursor.setPosition(selstart.position());
cursor.setPosition(selend.position(), QTextCursor::KeepAnchor);
text = cursor.selectedText();
mimeData->setData(QLatin1String("application/vnd.nokia.qtcreator.blocktext"), text.toUtf8());
}
return mimeData;
}
bool BaseTextEditor::canInsertFromMimeData(const QMimeData *source) const
{
return QPlainTextEdit::canInsertFromMimeData(source);
}
void BaseTextEditor::insertFromMimeData(const QMimeData *source)
{
if (isReadOnly())
return;
if (source->hasFormat(QLatin1String("application/vnd.nokia.qtcreator.vblocktext"))) {
QString text = QString::fromUtf8(source->data(QLatin1String("application/vnd.nokia.qtcreator.vblocktext")));
5125
5126
5127
5128
5129
5130
5131
5132
5133
5134
5135
5136
5137
5138
5139
5140
5141
5142
5143
5144
5145
5146
5147
5148
5149
5150
5151
5152
if (text.isEmpty())
return;
QStringList lines = text.split(QLatin1Char('\n'));
QTextCursor cursor = textCursor();
cursor.beginEditBlock();
int initialCursorPosition = cursor.position();
int column = cursor.position() - cursor.block().position();
cursor.insertText(lines.first());
for (int i = 1; i < lines.count(); ++i) {
QTextBlock next = cursor.block().next();
if (next.isValid()) {
cursor.setPosition(next.position() + qMin(column, next.length()-1));
} else {
cursor.movePosition(QTextCursor::EndOfBlock);
cursor.insertBlock();
}
int actualColumn = cursor.position() - cursor.block().position();
if (actualColumn < column)
cursor.insertText(QString(column - actualColumn, QLatin1Char(' ')));
cursor.insertText(lines.at(i));
}
cursor.setPosition(initialCursorPosition);
cursor.endEditBlock();
setTextCursor(cursor);
ensureCursorVisible();
return;
}
QString text = source->text();
if (text.isEmpty())
return;
const TabSettings &ts = d->m_document->tabSettings();
QTextCursor cursor = textCursor();
cursor.beginEditBlock();
cursor.insertText(text);
cursor.endEditBlock();
setTextCursor(cursor);
return;
}
cursor.beginEditBlock();
bool insertAtBeginningOfLine = ts.cursorIsAtBeginningOfLine(cursor);
if (insertAtBeginningOfLine
&& source->hasFormat(QLatin1String("application/vnd.nokia.qtcreator.blocktext"))) {
text = QString::fromUtf8(source->data(QLatin1String("application/vnd.nokia.qtcreator.blocktext")));
if (text.isEmpty())
return;
int reindentBlockStart = cursor.blockNumber() + (insertAtBeginningOfLine?0:1);
bool hasFinalNewline = (text.endsWith(QLatin1Char('\n'))
|| text.endsWith(QChar::ParagraphSeparator)
|| text.endsWith(QLatin1Char('\r')));
if (insertAtBeginningOfLine
&& hasFinalNewline) // since we'll add a final newline, preserve current line's indentation
cursor.setPosition(cursor.block().position());
int cursorPosition = cursor.position();
cursor.insertText(text);
int reindentBlockEnd = cursor.blockNumber() - (hasFinalNewline?1:0);
if (reindentBlockStart < reindentBlockEnd
|| (reindentBlockStart == reindentBlockEnd
&& (!insertAtBeginningOfLine || hasFinalNewline))) {
if (insertAtBeginningOfLine && !hasFinalNewline) {
QTextCursor unnecessaryWhitespace = cursor;
unnecessaryWhitespace.setPosition(cursorPosition);
unnecessaryWhitespace.movePosition(QTextCursor::StartOfBlock, QTextCursor::KeepAnchor);
unnecessaryWhitespace.removeSelectedText();
QTextCursor c = cursor;
c.setPosition(cursor.document()->findBlockByNumber(reindentBlockStart).position());
c.setPosition(cursor.document()->findBlockByNumber(reindentBlockEnd).position(),
QTextCursor::KeepAnchor);
reindent(document(), c);
}
cursor.endEditBlock();
setTextCursor(cursor);
void BaseTextEditor::appendStandardContextMenuActions(QMenu *menu)
{
menu->addSeparator();
Core::ActionManager *am = Core::ICore::instance()->actionManager();
QAction *a = am->command(Core::Constants::CUT)->action();
if (a && a->isEnabled())
menu->addAction(a);
a = am->command(Core::Constants::COPY)->action();
if (a && a->isEnabled())
menu->addAction(a);
a = am->command(Core::Constants::PASTE)->action();
if (a && a->isEnabled())
menu->addAction(a);
}
BaseTextEditorEditable::BaseTextEditorEditable(BaseTextEditor *editor)
: e(editor)
{
using namespace Find;
Aggregation::Aggregate *aggregate = new Aggregation::Aggregate;
BaseTextFind *baseTextFind = new BaseTextFind(editor);
connect(baseTextFind, SIGNAL(highlightAll(QString, Find::IFindSupport::FindFlags)),
editor, SLOT(highlightSearchResults(QString, Find::IFindSupport::FindFlags)));
connect(baseTextFind, SIGNAL(findScopeChanged(QTextCursor, QTextCursor, int)),
editor, SLOT(setFindScope(QTextCursor, QTextCursor, int)));
m_cursorPositionLabel = new Utils::LineColumnLabel;
QHBoxLayout *l = new QHBoxLayout;
QWidget *w = new QWidget;
l->setMargin(0);
l->setContentsMargins(5, 0, 5, 0);
l->addStretch(0);
l->addWidget(m_cursorPositionLabel);
w->setLayout(l);
m_toolBar = new QToolBar;
m_toolBar->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
m_toolBar->addWidget(w);
connect(editor, SIGNAL(cursorPositionChanged()), this, SLOT(updateCursorPosition()));
}
BaseTextEditorEditable::~BaseTextEditorEditable()
{
delete m_toolBar;
delete e;
}
5271
5272
5273
5274
5275
5276
5277
5278
5279
5280
5281
5282
5283
5284
5285
5286
5287
5288
5289
5290
5291
5292
5293
5294
5295
5296
5297
5298
5299
5300
5301
5302
5303
5304
5305
5306
5307
5308
5309
5310
5311
5312
5313
5314
5315
5316
5317
5318
5319
5320
5321
5322
5323
5324
5325
5326
5327
5328
5329
5330
5331
5332
5333
5334
5335
5336
5337
5338
5339
5340
5341
5342
5343
5344
5345
5346
5347
5348
5349
5350
5351
5352
5353
5354
5355
5356
5357
5358
5359
5360
5361
5362
5363
5364
5365
5366
5367
{
return m_toolBar;
}
int BaseTextEditorEditable::find(const QString &) const
{
return 0;
}
int BaseTextEditorEditable::currentLine() const
{
return e->textCursor().blockNumber() + 1;
}
int BaseTextEditorEditable::currentColumn() const
{
QTextCursor cursor = e->textCursor();
return cursor.position() - cursor.block().position() + 1;
}
QRect BaseTextEditorEditable::cursorRect(int pos) const
{
QTextCursor tc = e->textCursor();
if (pos >= 0)
tc.setPosition(pos);
QRect result = e->cursorRect(tc);
result.moveTo(e->viewport()->mapToGlobal(result.topLeft()));
return result;
}
QString BaseTextEditorEditable::contents() const
{
return e->toPlainText();
}
QString BaseTextEditorEditable::selectedText() const
{
if (e->textCursor().hasSelection())
return e->textCursor().selectedText();
return QString();
}
QString BaseTextEditorEditable::textAt(int pos, int length) const
{
QTextCursor c = e->textCursor();
if (pos < 0)
pos = 0;
c.movePosition(QTextCursor::End);
if (pos + length > c.position())
length = c.position() - pos;
c.setPosition(pos);
c.setPosition(pos + length, QTextCursor::KeepAnchor);
return c.selectedText();
}
void BaseTextEditorEditable::remove(int length)
{
QTextCursor tc = e->textCursor();
tc.setPosition(tc.position() + length, QTextCursor::KeepAnchor);
tc.removeSelectedText();
}
void BaseTextEditorEditable::insert(const QString &string)
{
QTextCursor tc = e->textCursor();
tc.insertText(string);
}
void BaseTextEditorEditable::replace(int length, const QString &string)
{
QTextCursor tc = e->textCursor();
tc.setPosition(tc.position() + length, QTextCursor::KeepAnchor);
tc.insertText(string);
}
void BaseTextEditorEditable::setCurPos(int pos)
{
QTextCursor tc = e->textCursor();
tc.setPosition(pos);
e->setTextCursor(tc);
}
void BaseTextEditorEditable::select(int toPos)
{
QTextCursor tc = e->textCursor();
tc.setPosition(toPos, QTextCursor::KeepAnchor);
e->setTextCursor(tc);
}
void BaseTextEditorEditable::updateCursorPosition()
{
const QTextCursor cursor = e->textCursor();
const QTextBlock block = cursor.block();
const int line = block.blockNumber() + 1;
const int column = cursor.position() - block.position();
m_cursorPositionLabel->setText(tr("Line: %1, Col: %2").arg(line).arg(e->tabSettings().columnAt(block.text(), column)+1),
tr("Line: %1, Col: 999").arg(e->blockCount()));
m_contextHelpId.clear();
if (!block.isVisible())
e->ensureCursorVisible();
}
QString BaseTextEditorEditable::contextHelpId() const
{
if (m_contextHelpId.isEmpty())
emit const_cast<BaseTextEditorEditable*>(this)->contextHelpIdRequested(e->editableInterface(),
e->textCursor().position());
return m_contextHelpId;
}