mirror of
https://github.com/qTox/qTox.git
synced 2024-03-22 14:00:36 +08:00
Text: Do not rely on QTextCursor for selection
This commit is contained in:
parent
f17ffdc491
commit
85764d5973
|
@ -70,13 +70,16 @@ void Text::setWidth(qreal w)
|
||||||
|
|
||||||
void Text::selectionMouseMove(QPointF scenePos)
|
void Text::selectionMouseMove(QPointF scenePos)
|
||||||
{
|
{
|
||||||
|
if(!doc)
|
||||||
|
return;
|
||||||
|
|
||||||
int cur = cursorFromPos(scenePos);
|
int cur = cursorFromPos(scenePos);
|
||||||
if(cur >= 0)
|
if(cur >= 0)
|
||||||
{
|
{
|
||||||
cursor.setPosition(cur, QTextCursor::KeepAnchor);
|
selectionEnd = cur;
|
||||||
selectedText.clear();
|
selectedText.clear();
|
||||||
|
|
||||||
QTextBlock block = cursor.block();
|
QTextBlock block = doc->firstBlock();
|
||||||
for(QTextBlock::Iterator itr = block.begin(); itr!=block.end(); ++itr)
|
for(QTextBlock::Iterator itr = block.begin(); itr!=block.end(); ++itr)
|
||||||
{
|
{
|
||||||
int pos = itr.fragment().position(); //fragment position -> position of the first character in the fragment
|
int pos = itr.fragment().position(); //fragment position -> position of the first character in the fragment
|
||||||
|
@ -87,7 +90,7 @@ void Text::selectionMouseMove(QPointF scenePos)
|
||||||
QString key = imgFmt.name(); //img key (eg. key::D for :D)
|
QString key = imgFmt.name(); //img key (eg. key::D for :D)
|
||||||
QString rune = key.mid(4);
|
QString rune = key.mid(4);
|
||||||
|
|
||||||
if(pos >= cursor.selectionStart() && pos < cursor.selectionEnd())
|
if(pos >= getSelectionStart() && pos < getSelectionEnd())
|
||||||
{
|
{
|
||||||
selectedText += rune;
|
selectedText += rune;
|
||||||
pos++;
|
pos++;
|
||||||
|
@ -97,7 +100,7 @@ void Text::selectionMouseMove(QPointF scenePos)
|
||||||
{
|
{
|
||||||
for(QChar c : itr.fragment().text())
|
for(QChar c : itr.fragment().text())
|
||||||
{
|
{
|
||||||
if(pos >= cursor.selectionStart() && pos < cursor.selectionEnd())
|
if(pos >= getSelectionStart() && pos < getSelectionEnd())
|
||||||
selectedText += c;
|
selectedText += c;
|
||||||
|
|
||||||
pos++;
|
pos++;
|
||||||
|
@ -113,22 +116,28 @@ void Text::selectionStarted(QPointF scenePos)
|
||||||
{
|
{
|
||||||
int cur = cursorFromPos(scenePos);
|
int cur = cursorFromPos(scenePos);
|
||||||
if(cur >= 0)
|
if(cur >= 0)
|
||||||
cursor.setPosition(cur);
|
{
|
||||||
|
selectionEnd = cur;
|
||||||
|
selectionAnchor = cur;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Text::selectionCleared()
|
void Text::selectionCleared()
|
||||||
{
|
{
|
||||||
cursor.clearSelection();
|
|
||||||
selectedText.clear();
|
selectedText.clear();
|
||||||
selectedText.squeeze();
|
selectedText.squeeze();
|
||||||
|
|
||||||
|
// Do not reset selectionAnchor!
|
||||||
|
selectionEnd = -1;
|
||||||
|
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Text::selectAll()
|
void Text::selectAll()
|
||||||
{
|
{
|
||||||
regenerate();
|
regenerate();
|
||||||
cursor.select(QTextCursor::Document);
|
selectionAnchor = 0;
|
||||||
|
selectionEnd = doc->toPlainText().size();
|
||||||
selectedText = text;
|
selectedText = text;
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
@ -136,7 +145,7 @@ void Text::selectAll()
|
||||||
bool Text::isOverSelection(QPointF scenePos) const
|
bool Text::isOverSelection(QPointF scenePos) const
|
||||||
{
|
{
|
||||||
int cur = cursorFromPos(scenePos);
|
int cur = cursorFromPos(scenePos);
|
||||||
if(cur >= 0 && cursor.selectionStart() < cur && cursor.selectionEnd() >= cur)
|
if(getSelectionStart() < cur && getSelectionEnd() >= cur)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
@ -164,7 +173,14 @@ void Text::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWid
|
||||||
// draw selection
|
// draw selection
|
||||||
QAbstractTextDocumentLayout::PaintContext ctx;
|
QAbstractTextDocumentLayout::PaintContext ctx;
|
||||||
QAbstractTextDocumentLayout::Selection sel;
|
QAbstractTextDocumentLayout::Selection sel;
|
||||||
sel.cursor = cursor;
|
|
||||||
|
if(hasSelection())
|
||||||
|
{
|
||||||
|
sel.cursor = QTextCursor(doc);
|
||||||
|
sel.cursor.setPosition(getSelectionStart());
|
||||||
|
sel.cursor.setPosition(getSelectionEnd(), QTextCursor::KeepAnchor);
|
||||||
|
}
|
||||||
|
|
||||||
sel.format.setBackground(QApplication::palette().color(QPalette::Highlight));
|
sel.format.setBackground(QApplication::palette().color(QPalette::Highlight));
|
||||||
sel.format.setForeground(QApplication::palette().color(QPalette::HighlightedText));
|
sel.format.setForeground(QApplication::palette().color(QPalette::HighlightedText));
|
||||||
ctx.selections.append(sel);
|
ctx.selections.append(sel);
|
||||||
|
@ -236,7 +252,6 @@ void Text::regenerate()
|
||||||
doc->setPlainText(elidedText);
|
doc->setPlainText(elidedText);
|
||||||
}
|
}
|
||||||
|
|
||||||
cursor = QTextCursor(doc);
|
|
||||||
dirty = false;
|
dirty = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -256,7 +271,7 @@ void Text::regenerate()
|
||||||
size = idealSize();
|
size = idealSize();
|
||||||
|
|
||||||
// if we are not visible -> free mem
|
// if we are not visible -> free mem
|
||||||
if(!isVisible && !cursor.hasSelection())
|
if(!isVisible)
|
||||||
freeResources();
|
freeResources();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -264,7 +279,6 @@ void Text::freeResources()
|
||||||
{
|
{
|
||||||
delete doc;
|
delete doc;
|
||||||
doc = nullptr;
|
doc = nullptr;
|
||||||
cursor = QTextCursor();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QSizeF Text::idealSize()
|
QSizeF Text::idealSize()
|
||||||
|
@ -282,3 +296,18 @@ int Text::cursorFromPos(QPointF scenePos) const
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int Text::getSelectionEnd() const
|
||||||
|
{
|
||||||
|
return qMax(selectionAnchor, selectionEnd);
|
||||||
|
}
|
||||||
|
|
||||||
|
int Text::getSelectionStart() const
|
||||||
|
{
|
||||||
|
return qMin(selectionAnchor, selectionEnd);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Text::hasSelection() const
|
||||||
|
{
|
||||||
|
return selectionEnd >= 0;
|
||||||
|
}
|
||||||
|
|
|
@ -60,6 +60,9 @@ protected:
|
||||||
|
|
||||||
QSizeF idealSize();
|
QSizeF idealSize();
|
||||||
int cursorFromPos(QPointF scenePos) const;
|
int cursorFromPos(QPointF scenePos) const;
|
||||||
|
int getSelectionEnd() const;
|
||||||
|
int getSelectionStart() const;
|
||||||
|
bool hasSelection() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CustomTextDocument* doc = nullptr;
|
CustomTextDocument* doc = nullptr;
|
||||||
|
@ -71,7 +74,8 @@ private:
|
||||||
bool isVisible = false;
|
bool isVisible = false;
|
||||||
bool elide = false;
|
bool elide = false;
|
||||||
bool dirty = false;
|
bool dirty = false;
|
||||||
QTextCursor cursor;
|
int selectionEnd = -1;
|
||||||
|
int selectionAnchor = -1;
|
||||||
qreal ascent = 0.0;
|
qreal ascent = 0.0;
|
||||||
qreal width = 0.0;
|
qreal width = 0.0;
|
||||||
QFont defFont;
|
QFont defFont;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user