void FlatTextarea::onDocumentContentsChange(int position, int charsRemoved, int charsAdded) { if (!_links.isEmpty()) { bool changed = false; for (LinkRanges::iterator i = _links.begin(); i != _links.end();) { if (i->first + i->second <= position) { ++i; } else if (i->first >= position + charsRemoved) { i->first += charsAdded - charsRemoved; ++i; } else { i = _links.erase(i); changed = true; } } if (changed) emit linksChanged(); } if (_replacingEmojis || document()->availableRedoSteps() > 0) return; const int takeBack = 3; position -= takeBack; charsAdded += takeBack; if (position < 0) { charsAdded += position; position = 0; } if (charsAdded <= 0) return; _insertions.push_back(Insertion(position, charsAdded)); }
void ShotgunField::setLink(Node *l) { if (m_links.length() != 1 || m_links[0] != l) { m_links.clear(); m_links << l; emit linksChanged(); } }
bool OutputLink::unlink(InputLink *input) { input->unlink(); auto it = std::find(begin(m_inputLinks), end(m_inputLinks), input); if(it==m_inputLinks.end())return false; m_inputLinks.erase(it); linksChanged(*this); return true; }
bool OutputLink::addLink(InputLink &input) { if(!input.getModuleInput().getSignalType().isConvertibleTo(c_moduleOutput.getSignalType())) { return false; } input.link(*this); //TODO make sure there isn't already an input for this moduleinput m_inputLinks.push_back(&input); linksChanged(*this); return true; }
void FlatTextarea::parseLinks() { // some code is duplicated in text.cpp! LinkRanges newLinks; QString text(toPlainText()); if (text.isEmpty()) { if (!_links.isEmpty()) { _links.clear(); emit linksChanged(); } return; } initLinkSets(); int32 len = text.size(); const QChar *start = text.unicode(), *end = start + text.size(); for (int32 offset = 0, matchOffset = offset; offset < len;) { QRegularExpressionMatch m = reDomain().match(text, matchOffset); if (!m.hasMatch()) break; int32 domainOffset = m.capturedStart(); QString protocol = m.captured(1).toLower(); QString topDomain = m.captured(3).toLower(); bool isProtocolValid = protocol.isEmpty() || validProtocols().contains(hashCrc32(protocol.constData(), protocol.size() * sizeof(QChar))); bool isTopDomainValid = !protocol.isEmpty() || validTopDomains().contains(hashCrc32(topDomain.constData(), topDomain.size() * sizeof(QChar))); if (protocol.isEmpty() && domainOffset > offset + 1 && *(start + domainOffset - 1) == QChar('@')) { QString forMailName = text.mid(offset, domainOffset - offset - 1); QRegularExpressionMatch mMailName = reMailName().match(forMailName); if (mMailName.hasMatch()) { offset = matchOffset = m.capturedEnd(); continue; } } if (!isProtocolValid || !isTopDomainValid) { offset = matchOffset = m.capturedEnd(); continue; } QStack<const QChar*> parenth; const QChar *domainEnd = start + m.capturedEnd(), *p = domainEnd; for (; p < end; ++p) { QChar ch(*p); if (chIsLinkEnd(ch)) break; // link finished if (chIsAlmostLinkEnd(ch)) { const QChar *endTest = p + 1; while (endTest < end && chIsAlmostLinkEnd(*endTest)) { ++endTest; } if (endTest >= end || chIsLinkEnd(*endTest)) { break; // link finished at p } p = endTest; ch = *p; } if (ch == '(' || ch == '[' || ch == '{' || ch == '<') { parenth.push(p); } else if (ch == ')' || ch == ']' || ch == '}' || ch == '>') { if (parenth.isEmpty()) break; const QChar *q = parenth.pop(), open(*q); if ((ch == ')' && open != '(') || (ch == ']' && open != '[') || (ch == '}' && open != '{') || (ch == '>' && open != '<')) { p = q; break; } } } if (p > domainEnd) { // check, that domain ended if (domainEnd->unicode() != '/' && domainEnd->unicode() != '?') { matchOffset = domainEnd - start; continue; } } newLinks.push_back(qMakePair(domainOffset - 1, p - start - domainOffset + 2)); offset = matchOffset = p - start; } if (newLinks != _links) { _links = newLinks; emit linksChanged(); } }
void FlatTextarea::onDocumentContentsChange(int position, int charsRemoved, int charsAdded) { if (_correcting) return; QTextCursor(document()->docHandle(), 0).joinPreviousEditBlock(); _correcting = true; if (_maxLength >= 0) { QTextCursor c(document()->docHandle(), 0); c.movePosition(QTextCursor::End); int32 fullSize = c.position(), toRemove = fullSize - _maxLength; if (toRemove > 0) { if (toRemove > charsAdded) { if (charsAdded) { c.setPosition(position); c.setPosition((position + charsAdded), QTextCursor::KeepAnchor); c.removeSelectedText(); } c.setPosition(fullSize - (toRemove - charsAdded)); c.setPosition(fullSize, QTextCursor::KeepAnchor); c.removeSelectedText(); } else { c.setPosition(position + (charsAdded - toRemove)); c.setPosition(position + charsAdded, QTextCursor::KeepAnchor); c.removeSelectedText(); } } } _correcting = false; if (!_links.isEmpty()) { bool changed = false; for (LinkRanges::iterator i = _links.begin(); i != _links.end();) { if (i->first + i->second <= position) { ++i; } else if (i->first >= position + charsRemoved) { i->first += charsAdded - charsRemoved; ++i; } else { i = _links.erase(i); changed = true; } } if (changed) emit linksChanged(); } if (document()->availableRedoSteps() > 0) { QTextCursor(document()->docHandle(), 0).endEditBlock(); return; } const int takeBack = 3; position -= takeBack; charsAdded += takeBack; if (position < 0) { charsAdded += position; position = 0; } if (charsAdded <= 0) { QTextCursor(document()->docHandle(), 0).endEditBlock(); return; } _correcting = true; QSizeF s = document()->pageSize(); processDocumentContentsChange(position, charsAdded); if (document()->pageSize() != s) { document()->setPageSize(s); } _correcting = false; QTextCursor(document()->docHandle(), 0).endEditBlock(); }