void qceEqual(const QDocumentCursor& c, const QDocumentCursor& expected, const QString& message){ QEQUAL2(c.hasSelection(),expected.hasSelection(), " got-total: "+cur2str(c)+" expected-total: "+cur2str(expected)+" more: "+message); QEQUAL2(c.anchorLineNumber(),expected.anchorLineNumber(), " got-total: "+cur2str(c)+" expected-total: "+cur2str(expected)+" more: "+message); QEQUAL2(c.anchorColumnNumber(),expected.anchorColumnNumber(), " got-total: "+cur2str(c)+" expected-total: "+cur2str(expected)+" more: "+message); QEQUAL2(c.lineNumber(),expected.lineNumber(), " got-total: "+cur2str(c)+" expected-total: "+cur2str(expected)+" more: "+message); QEQUAL2(c.columnNumber(),expected.columnNumber(), " got-total: "+cur2str(c)+" expected-total: "+cur2str(expected)+" more: "+message); }
int LatexTables::findNextToken(QDocumentCursor &cur,QStringList tokens,bool keepAnchor,bool backwards){ int pos=-1; int nextToken=-1; int offset=0; QDocumentCursor::MoveOperation mvNextLine= backwards ? QDocumentCursor::PreviousLine : QDocumentCursor::NextLine; QDocumentCursor::MoveOperation mvNextChar= backwards ? QDocumentCursor::Left : QDocumentCursor::Right; QDocumentCursor::MoveOperation mvStartOfLine= backwards ? QDocumentCursor::EndOfLine : QDocumentCursor::StartOfLine; QDocumentCursor::MoveFlag mvFlag= keepAnchor ? QDocumentCursor::KeepAnchor : QDocumentCursor::MoveAnchor; do{ QString line=cur.line().text(); if(backwards){ offset=line.length(); } line=LatexParser::cutComment(line); if(backwards){ offset=offset-line.length(); QString help; foreach(const QChar& elem,line) help.prepend(elem); line=help; } if(line.contains("\\end{")&&!backwards) { nextToken=-2; break; } if(line.contains("{nigeb\\")&&backwards) { nextToken=-2; break; } pos=-1; for(int i=0;i<tokens.count();i++){ QString elem=tokens.at(i); int colNumber= cur.columnNumber(); if(backwards) colNumber=line.length()+offset-colNumber ; int zw=line.indexOf(elem,colNumber); if(zw>-1) { if(pos>zw || pos==-1){ pos=zw; nextToken=i; } } } if(pos<0){ if(!backwards&&cur.lineNumber()>=cur.document()->lineCount()-1) break; if(backwards&&cur.lineNumber()<=0) break; cur.movePosition(1,mvNextLine,mvFlag); cur.movePosition(1,mvStartOfLine,mvFlag); } }while(pos<0); if(pos>-1) { cur.movePosition(1,mvStartOfLine,mvFlag); cur.movePosition(pos+tokens.at(nextToken).length()+offset,mvNextChar,mvFlag); } return nextToken; }
/*! */ bool QHexPanel::paint(QPainter *p, QEditor *e) { // qWarning("drawing Hex panel... [%i, %i, %i, %i]", // geometry().x(), // geometry().y(), // geometry().width(), // geometry().height()); #if 1 //hexeditor->resize(geometry().size()); #else static QPixmap _warn(":/warning.png"), _mod(":/save.png"); QString s; int xpos = 10; QDocumentCursor c = e->cursor(); const QFontMetrics fm(fontMetrics()); const int ls = fm.lineSpacing(); const int ascent = fm.ascent() + 3; s = tr("Line : %1 Visual column : %2 Text column : %3") .arg(c.lineNumber() + 1) .arg(c.visualColumnNumber()) .arg(c.columnNumber()); p->drawText(xpos, ascent, s); xpos += fm.width(s) + 10; int sz = qMin(height(), _mod.height()); //int lastMod = d->lastModified().secsTo(QDateTime::currentDateTime()); //QString timeDiff = tr("(%1 min %2 s ago)").arg(lastMod / 60).arg(lastMod % 60); //xpos += 10; if ( e->isContentModified() ) { p->drawPixmap(xpos, (height() - sz) / 2, sz, sz, _mod); //xpos += sz; //xpos += 10; //p->drawText(xpos, ascent, timeDiff); } xpos += sz + 10; //xpos += fm.width(timeDiff); //xpos += 20; // s = editor()->flag(QEditor::Overwrite) ? tr("OVERWRITE") : tr("INSERT"); // p->drawText(xpos, ascent, s); // xpos += fm.width(s) + 10; #endif return true; }
/*! */ void QStatusPanel::paint(QPainter *p, QEditor *e) { //qDebug("drawing status panel... [%i, %i, %i, %i]", // geometry().x(), // geometry().y(), // geometry().width(), // geometry().height()); static QPixmap _warn(":/warning.png"); QString s; int xpos = 10; QDocumentCursor c = e->cursor(); const QFontMetrics fm(fontMetrics()); const int ls = fm.lineSpacing(); const int ascent = fm.ascent() + 3; s = tr("Line : %1 Visual column : %2 Text column : %3") .arg(c.lineNumber() + 1) .arg(c.visualColumnNumber()) .arg(c.columnNumber()); p->drawText(xpos, ascent, s); xpos += fm.width(s) + 10; // TODO : draw icon to show mod status s = editor()->flag(QEditor::Overwrite) ? tr("OVERWRITE") : tr("INSERT"); p->drawText(xpos, ascent, s); xpos += fm.width(s) + 10; m_conflictSpot = 0; if ( editor()->isInConflict() ) { s = tr("Conflict"); int w = fm.width(s) + 30; if ( xpos + w + _warn.width() < width() ) { m_conflictSpot = width() - (w + _warn.width()); p->drawText(width() - w + 15, ascent, s); p->drawPixmap(m_conflictSpot, (ls - _warn.height()) / 2 + 2, _warn); } else if ( xpos + _warn.width() < width() ) { m_conflictSpot = width() - _warn.width(); p->drawPixmap(m_conflictSpot, (ls - _warn.height()) / 2 + 2, _warn); } } setFixedHeight(ls + 4); }
/*! \brief \fn CCompletion::getLastToken \param c \return QString */ QString CCompletion::getLastToken(const QDocumentCursor &c) { QString line = c.line().text(); QString Token = c.selectedText(); if (Token.isEmpty()) { if (line.size()>1) { int i = c.columnNumber()-1; while (QString("_0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ").contains(line.at(i).toUpper())) { Token = line.at(i)+Token; i--; if (i<0) break; } } } return Token; }
/*! \brief \fn CCompletion::complete \param c \param trigger */ void CCompletion::complete(const QDocumentCursor &c, const QString &trigger) { // test if there is selected text // etendre le texte selectionner au mot complet // si il a pour next char une ( alors afficher un calltips if ( (trigger == "(" ) || !c.selectedText().isEmpty()) { QStringList tips; //qDebug("fn %s", fn.constData()); QList<QCodeNode*> nodes = mainwindow->windowide->completionScan(editor()); tips = mainwindow->windowide->getProc(getLastToken(c)); if ( tips.count() ) { CDOxyItem * di = mainwindow->windowide->getDOxygenInfo(getLastToken(c).trimmed()); if (di) { tips[0] += QString("\n")+di->brief; if (di->params.count()) { for (int j=0;j<di->params.size();j++) { tips[0] += QString("\n")+di->params.at(j); } } if (!(di->returnTyp.isEmpty())) tips[0]+=QString("\nReturn value : ")+di->returnTyp; if (tips[0].right(1)=="\n") tips[0].chop(1); } QRect r = editor()->cursorRect(); QDocumentCursor cursor = editor()->cursor(); QDocumentLine line = cursor.line(); int hx = editor()->horizontalOffset(), cx = line.cursorToX(cursor.columnNumber()); QCallTip *ct = new QCallTip(editor()->viewport()); ct->move(cx - hx, r.y() + r.height()); ct->setTips(tips); ct->show(); ct->setFocus(); #ifdef TRACE_COMPLETION qDebug("parsing + scoping + search + pre-display : elapsed %i ms", time.elapsed()); #endif } } else { if ( pPopup && pPopup->editor() != editor() ) { delete pPopup; pPopup = 0; } if ( !pPopup ) { pPopup = new QCodeCompletionWidget(editor()); } pPopup->clear(); pPopup->setCursor(editor()->cursor()); QTime time; time.start(); QList<QCodeNode*> nodes = mainwindow->windowide->completionScan(editor()); pPopup->setPrefix(getLastToken(c)); pPopup->setCompletions(nodes); pPopup->update(); pPopup->popup(); } #if 1 #endif }
/*! */ bool QStatusPanel::paint(QPainter *p, QEditor *e) { //qDebug("drawing status panel... [%i, %i, %i, %i]", // geometry().x(), // geometry().y(), // geometry().width(), // geometry().height()); static QPixmap _warn(":/warning.png"), _mod(":/save.png"); QString s; int xpos = 10; QDocumentCursor c = e->cursor(); const QFontMetrics fm(fontMetrics()); const int ls = fm.lineSpacing(); const int ascent = fm.ascent() + 3; s = tr("Line : %1 Visual column : %2 Text column : %3") .arg(c.lineNumber() + 1) .arg(c.visualColumnNumber()) .arg(c.columnNumber()); p->drawText(xpos, ascent, s); xpos += fm.width(s) + 10; int sz = qMin(height(), _mod.height()); //int lastMod = d->lastModified().secsTo(QDateTime::currentDateTime()); //QString timeDiff = tr("(%1 min %2 s ago)").arg(lastMod / 60).arg(lastMod % 60); //xpos += 10; if ( e->isContentModified() ) { p->drawPixmap(xpos, (height() - sz) / 2, sz, sz, _mod); //xpos += sz; //xpos += 10; //p->drawText(xpos, ascent, timeDiff); } xpos += sz + 10; //xpos += fm.width(timeDiff); //xpos += 20; s = editor()->flag(QEditor::Overwrite) ? tr("OVERWRITE") : tr("INSERT"); p->drawText(xpos, ascent, s); xpos += fm.width(s) + 10; m_conflictSpot = 0; if ( editor()->isInConflict() ) { s = tr("Conflict"); int w = fm.width(s) + 30; if ( xpos + w + _warn.width() < width() ) { m_conflictSpot = width() - (w + _warn.width()); p->drawText(width() - w + 15, ascent, s); p->drawPixmap(m_conflictSpot, (ls - _warn.height()) / 2 + 2, _warn); } else if ( xpos + _warn.width() < width() ) { m_conflictSpot = width() - _warn.width(); p->drawPixmap(m_conflictSpot, (ls - _warn.height()) / 2 + 2, _warn); } } setFixedHeight(ls + 4); QTimer::singleShot(1000, this, SLOT( update() ) ); return true; }
QString cur2str(const QDocumentCursor &c){ if (c.hasSelection()) return QString("%1|%2|%3|%4").arg(c.anchorLineNumber()).arg(c.anchorColumnNumber()).arg(c.lineNumber()).arg(c.columnNumber()); return QString("%1|%2").arg(c.lineNumber()).arg(c.columnNumber()); }
void CompletionWord::insertAt(QEditor* editor, QDocumentCursor cursor){ QString savedSelection; int multilines=shownWord.count('\n'); QVector<QDocumentLine> documentlines; if (cursor.hasSelection()) { savedSelection=cursor.selectedText(); cursor.removeSelectedText(); } QDocumentCursor selector=cursor; int curStart=cursor.columnNumber(); QDocumentLine curLine=cursor.line(); cursor.insertText(shownWord); if (multilines) { documentlines.resize(multilines+1); documentlines[0]=curLine; for (int i=1;i<documentlines.count()-1;i++) documentlines[i]=documentlines[i-1].next(); //todo: optimize } if (QDocument::formatFactory()) for (int i=0;i<descriptiveParts.size();i++) { QFormatRange fr(descriptiveParts[i].first+curStart,descriptiveParts[i].second,QDocument::formatFactory()->id("temporaryCodeCompletion")); if (multilines) { QString temp= shownWord; temp.truncate(descriptiveParts[i].first); int linetoadd=temp.count('\n'); if (linetoadd==0) curLine.addOverlay(fr); else if (linetoadd<documentlines.size()) { fr.offset=temp.size()-temp.lastIndexOf('\n')-1; documentlines[linetoadd].addOverlay(fr); } } else curLine.addOverlay(fr); } //place cursor/add \end int selectFrom=-1; int selectTo=-1; int deltaLine=0; if (shownWord.startsWith("\\begin")&&!multilines) { //int curColumnNumber=cursor.columnNumber(); QString indent=curLine.indentation(); int p=shownWord.indexOf("{"); QString content="content..."; if (editor->flag(QEditor::AutoIndent)){ cursor.insertText( "\n"+indent+"\t"+content+"\n"+indent+"\\end"+shownWord.mid(p,shownWord.indexOf("}")-p+1)); indent+="\t"; } else cursor.insertText( "\n"+indent+content+"\n"+indent+"\\end"+shownWord.mid(p,shownWord.indexOf("}")-p+1)); if (QDocument::formatFactory()) for (int i=0;i<descriptiveParts.size();i++) curLine.next().addOverlay(QFormatRange(indent.size(),content.size(),QDocument::formatFactory()->id("temporaryCodeCompletion"))); if (cursorPos==-1) { deltaLine=1; selectFrom=indent.length(); selectTo=indent.length()+content.size(); } else { selectFrom=anchorPos+curStart; selectTo=cursorPos+curStart; } } else if (cursorPos>-1) { if (multilines) { //todo: add support for selected multilines QString temp= shownWord; temp.truncate(cursorPos); deltaLine=temp.count('\n'); if (!deltaLine) { selectFrom=anchorPos+curStart; selectTo=cursorPos+curStart; } else { selectTo=temp.size()-temp.lastIndexOf('\n')-1; selectFrom=anchorPos-cursorPos+selectTo; } } else { selectFrom=anchorPos+curStart; selectTo=cursorPos+curStart; } } else editor->setCursor(cursor); //place after insertion if (selectFrom!=-1){ if (deltaLine>0) selector.movePosition(deltaLine,QDocumentCursor::Down,QDocumentCursor::MoveAnchor); selector.setColumnNumber(selectFrom); if (selectTo>selectFrom) selector.movePosition(selectTo-selectFrom,QDocumentCursor::Right,QDocumentCursor::KeepAnchor); else if (selectTo<selectFrom) selector.movePosition(selectFrom-selectTo,QDocumentCursor::Left,QDocumentCursor::KeepAnchor); editor->setCursor(selector); } if (!savedSelection.isEmpty() && cursorPos>0) editor->cursor().insertText(savedSelection); }
int LatexTables::getColumn(QDocumentCursor &cur){ QDocumentCursor c(cur); QStringList tokens("\\\\"); int result=findNextToken(c,tokens,true,true); if(result==0) c.movePosition(2,QDocumentCursor::Right,QDocumentCursor::KeepAnchor); if(c.lineNumber()==cur.lineNumber() && c.selectedText().contains(QRegExp("^\\s*$"))){ c.movePosition(1,QDocumentCursor::EndOfLine,QDocumentCursor::KeepAnchor); QString zw=c.selectedText(); if(zw.contains(QRegExp("^\\s*$"))) return -1; } c.clearSelection(); tokens << "\\&" << "&"; int col=0; do{ result=findNextToken(c,tokens); if(c.lineNumber()>cur.lineNumber()|| (c.lineNumber()==cur.lineNumber() && c.columnNumber()>cur.columnNumber())) break; if(result==2) col++; }while(result>0); return col; }
void QSearchReplacePanel::on_leFind_textEdited(const QString& text) { bool hadSearch = m_search; QDocumentCursor cur = editor()->cursor(); if ( m_search ) { cur = m_search->cursor(); m_search->setSearchText(text); if ( cbCursor->isChecked() ) { QDocumentCursor c = cur; c.setColumnNumber(qMin(c.anchorColumnNumber(), c.columnNumber())); m_search->setCursor(c); } } else { // TODO : make incremental search optional init(); } if ( text.isEmpty() ) { leFind->setStyleSheet(QString()); return; } m_search->setOption(QDocumentSearch::Silent, true); find(0); m_search->setOption(QDocumentSearch::Silent, false); if ( m_search->cursor().isNull() ) { leFind->setStyleSheet("QLineEdit { background: red; color : white; }"); if ( hadSearch ) { m_search->setCursor(cur); // figure out whether other matches are availables QDocumentSearch::Options opts = m_search->options(); opts &= ~QDocumentSearch::HighlightAll; opts |= QDocumentSearch::Silent; QDocumentSearch temp(editor(), text, opts); temp.setOrigin(QDocumentCursor()); temp.setScope(m_search->scope()); temp.next(true); if ( temp.cursor().isValid() ) { // other match found from doc start leFind->setStyleSheet("QLineEdit { background: yellow; color : black; }"); m_search->setCursor(cur.document()->cursor(0,0)); find(0); } } } else { leFind->setStyleSheet(QString()); editor()->setCursor(m_search->cursor()); } }