Esempio n. 1
0
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);
}
/*!
	\brief Completion callback
*/
void QCodeCompletionEngine::complete(const QDocumentCursor& c, const QString& trigger)
{
	#ifdef _QCODE_MODEL_
	// TODO :
	//	* use a more efficient design by avoiding deep copy of the data
	//	* only lex the requested part (stop at cursor or topmost frame required for proper class hierarchy)

	QDocumentCursor cc = c;
	cc.movePosition(1, QDocumentCursor::Start, QDocumentCursor::KeepAnchor);

	//qDebug("%s", qPrintable(cc.selectedText()));

	QCodeBuffer buffer(cc.selectedText());
	//QCodeBuffer buffer(c.document()->text());
	complete(&buffer, trigger);
	#else
	// remove unused argument warnings
	(void) c;
	(void) trigger;

	qWarning("From complete(QDocumentCursor, QString)");
	qWarning("QCodeCompletionEngine is not self-sufficient : subclasses should "
			"reimplement at least on of the complete() method...");
	#endif
}
Esempio n. 3
0
//tests if folded text can be edited
void QEditorTest::activeFolding(){
	QFETCH(QString, editorText);
	QFETCH(QList<int>, foldAt);
	QFETCH(QList<int>, hiddenLines);
	QFETCH(int, cursorAL);
	QFETCH(int, cursorAC);
	QFETCH(int, cursorL);
	QFETCH(int, cursorC);
	QFETCH(QString, textToInsert);
	QFETCH(QString, newEditorText);
	QFETCH(QList<int>, newHiddenLines);

	editor->setText(editorText, false);

	foreach(const int &i, foldAt)
		editor->document()->collapse(i);
	for (int i=0;i<editor->document()->lines();i++)
		QVERIFY2(editor->document()->line(i).isHidden() == hiddenLines.contains(i),qPrintable(QString::number(i)));
	compareLists(editor->document()->impl()->testGetHiddenLines(), hiddenLines);

	QDocumentCursor editCursor = editor->document()->cursor(cursorAL,cursorAC,cursorL,cursorC);
	editCursor.insertText(textToInsert);

	QEQUAL(editor->document()->text(), newEditorText);
	for (int i=0;i<editor->document()->lines();i++)
		QVERIFY2(editor->document()->line(i).isHidden() == newHiddenLines.contains(i),qPrintable(QString::number(i)));

	compareLists(editor->document()->impl()->testGetHiddenLines(), newHiddenLines);
}
/*!
	\internal
*/
bool QCodeCompletionEngine::eventFilter(QObject *o, QEvent *e)
{
	if ( !e || !o || (e->type() != QEvent::KeyPress) || (o != pEdit) )
		return false;
	
	//qDebug("should trigger completion?");
	
	QDocumentCursor cur = editor()->cursor();
	QKeyEvent *k = static_cast<QKeyEvent*>(e);
	
	QString s, txt = s = k->text();
	
	int count = txt.count();
	
	if ( txt.isEmpty() || m_triggers.isEmpty() )
		return false; // QThread::eventFilter(o, e);
	
	//qDebug("should trigger completion? (bis)");
	
	if ( count > m_max )
	{
		txt = txt.right(m_max);
		
	} else if ( count < m_max ) {
		
		QDocumentCursor c(cur);
		c.movePosition(m_max - count, QDocumentCursor::Left, QDocumentCursor::KeepAnchor);
		
		//qDebug("prev text : %s", qPrintable(c.selectedText()));
		
		txt.prepend(c.selectedText());
	}
	
	//qDebug("text : %s", qPrintable(txt));
	
	foreach ( QString trig, m_triggers )
	{
		if ( txt.endsWith(trig) )
		{
			editor()->write(s);
			
			cur = editor()->cursor();
			cur.movePosition(trig.count(), QDocumentCursor::PreviousCharacter);
			
			// notify completion trigger
			emit completionTriggered(trig);
			
			//get rid of previous calltips/completions
			editor()->setFocus();
			
			// trigger completion
			complete(cur, trig);
			
			return true;
		}
	}
	
	return false;
}
Esempio n. 5
0
/*!

*/
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;
}
Esempio n. 6
0
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;
}
Esempio n. 7
0
/*!

*/
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);
}
Esempio n. 8
0
	void simpleRestoreAutoOverride(const QString& written="????"){ //simple means without protecting the change from undo/redo
		if (!autoOverridenText.isEmpty() && !editor->isAutoOverrideText(written)) {
			int curpos = editor->cursor().columnNumber();
			if (curpos < maxWritten) {
				QDocumentCursor c = editor->cursor();
				c.movePosition(maxWritten-curpos, QDocumentCursor::Right);
				editor->setCursor(c);
			}
			editor->insertText(autoOverridenText);
			QDocumentCursor c = editor->cursor();
			c.movePosition(autoOverridenText.length() + (curpos<maxWritten?maxWritten-curpos:0), QDocumentCursor::Left);
			editor->setCursor(c);
			editor->resizeAutoOverridenPlaceholder(c, autoOverridenText.size());
		}
	}
Esempio n. 9
0
void LatexTables::removeRow(QDocumentCursor &c){
	QDocumentCursor cur(c);
	const QStringList tokens("\\\\");
	if(cur.hasSelection()){
		if(cur.lineNumber()>cur.anchorLineNumber()||(cur.lineNumber()==cur.anchorLineNumber() && cur.columnNumber()>cur.anchorColumnNumber())){
			cur.moveTo(cur.anchorLineNumber(),cur.anchorColumnNumber());
		}
	}
	int result=findNextToken(cur,tokens,false,true);
	if(result==0) cur.movePosition(2,QDocumentCursor::Right);
	if(result==-2) cur.movePosition(1,QDocumentCursor::EndOfLine);
	bool breakLoop=false;
	while(!(breakLoop=(findNextToken(cur,tokens,true)==-1)) && c.isWithinSelection(cur) ){
	}
	if(!breakLoop) {
		// check if end of cursor is at line end
		QDocumentCursor c2(cur.document(),cur.anchorLineNumber(),cur.anchorColumnNumber());
		if(c2.atLineEnd()) {
			c2.movePosition(1,QDocumentCursor::Right);
			cur.moveTo(c2,QDocumentCursor::KeepAnchor);
		}
		// remove text
		cur.beginEditBlock();
		cur.removeSelectedText();
		if(cur.line().text().isEmpty()) cur.deleteChar(); // don't leave empty lines
		cur.endEditBlock();
	}
}
Esempio n. 10
0
/*!
 \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;
}
Esempio n. 11
0
QString LatexTables::getTableText(QDocumentCursor &cur){
	int result=findNextToken(cur,QStringList(),false,true);
	if(result!=-2) return QString();
	QString line=cur.line().text();
	int i=line.indexOf("\\begin");
	if(i>=0)
		cur.setColumnNumber(i);
	result=findNextToken(cur,QStringList(),true,false);
	if(result!=-2) return QString();
	line=cur.line().text();
	QRegExp rx("\\\\end\\{.*\\}");
	i=rx.indexIn(line);
	if(i>=0)
		cur.setColumnNumber(i+rx.cap(0).length(),QDocumentCursor::KeepAnchor);
	QString res=cur.selectedText();
	return res;
}
/*!
	\brief Standard completion entry point for QEditor
	\param e QKeyEvent that caused a modification of the text
	
	\note This slot is only called when editing happens without
	any cursor mirrors
*/
void QCodeCompletionEngine::textEdited(QKeyEvent *k)
{
	QString s, txt = s = k->text();
	QDocumentCursor cur = editor()->cursor();
	
	int count = txt.count();
	
	if ( txt.isEmpty() || m_triggers.isEmpty() )
		return;
	
	//qDebug("should trigger completion? (bis)");
	
	if ( count > m_max )
	{
		txt = txt.right(m_max);
		
	} else if ( count < m_max ) {
		
		QDocumentCursor c(cur);
		c.movePosition(m_max, QDocumentCursor::Left, QDocumentCursor::KeepAnchor);
		
		//qDebug("prev text : %s", qPrintable(c.selectedText()));
		
		txt = c.selectedText();
	}
	
	//qDebug("text : %s", qPrintable(txt));
	
	foreach ( QString trig, m_triggers )
	{
		if ( txt.endsWith(trig) )
		{
			cur = editor()->cursor();
			cur.movePosition(trig.count(), QDocumentCursor::PreviousCharacter);
			
			// notify completion trigger
			emit completionTriggered(trig);
			
			//get rid of previous calltips/completions
			editor()->setFocus();
			
			// trigger completion
			complete(cur, trig);
		}
	}
}
Esempio n. 13
0
bool QSnippetBinding::keyPressEvent(QKeyEvent *event, QEditor *editor)
{
	/*
	if ( event->modifiers() & Qt::ControlModifier )
	{
		for ( int i = 0; i < qMin(10, m->snippetCount()); ++i )
		{
			if ( event->key() == (Qt::Key_F1 + i) )
			{
				m->snippet(i)->insert(editor);
				return true;
			}
		}
	}
	*/
	
	if ( (event->modifiers() & Qt::AltModifier) && (event->key() == Qt::Key_Space || event->text() == " ") )
	{
		QDocumentCursor c = editor->cursor();
		
		//c.select(QDocumentCursor::SelectWord);
		
		if ( !c.hasSelection() )
		{
			c.movePosition(1, QDocumentCursor::PreviousWord, QDocumentCursor::KeepAnchor);
			editor->setCursor(c);
		}
		
		QString s = c.selectedText();
		
		for ( int i = 0; i < m_manager->snippetCount(); ++i )
		{
			QSnippet *snip = m_manager->snippet(i);
			
			if ( snip->name() == s )
			{
				snip->insert(editor);
				return true;
			}
		}
	}
	
	return QEditorInputBinding::keyPressEvent(event, editor);
}
Esempio n. 14
0
void LatexTables::alignTableCols(QDocumentCursor &cur){
	QString text = getTableText(cur);
	if (!cur.hasSelection()) return;
	QString indentation = cur.selectionStart().line().indentation();
	
	// split off \begin and \end parts
	int index = text.indexOf("\\begin{")+6;
	int cellsStart;
	QList<CommandArgument> args = getCommandOptions(text, index, &cellsStart);
	if (args.count() < 2) return;
	QString tableType = args.at(0).value;
	
	
	
	// assume alignment in second arg except for the following environments (which have it in the third one)
	QString alignment;
	if (tabularNames.contains(tableType)) {
		alignment = args.at(1).value;
	} else if (tabularNamesWithOneOption.contains(tableType)) {
		if (args.count()<3) alignment = ""; // incomplete definition -> fall back to defaults
		else alignment = args.at(2).value;
	} else return; // not a registered table environment
	
	int cellsEnd = text.indexOf("\\end{"+tableType);
	if (cellsEnd<0) return;
	QString beginPart = text.left(cellsStart);
	QString endPart = text.mid(cellsEnd);
	
	
	LatexTableModel ltm;
	ltm.setContent(text.mid(cellsStart, cellsEnd-cellsStart));
	
	QStringList l_defs=splitColDef(alignment);
	simplifyColDefs(l_defs);
	QStringList content(ltm.getAlignedLines(l_defs));
	
	QString result = beginPart + '\n';
	for (int i=0; i<content.count(); i++) {
		result.append(indentation + content.at(i));
	}
	result.append(indentation + endPart);
	cur.replaceSelectedText(result);
}
Esempio n. 15
0
bool LatexTables::inTableEnv(QDocumentCursor &cur){
	QDocumentCursor c(cur);
	int result=findNextToken(c,QStringList(),false,true);
	if(result!=-2) return false;
	if(c.lineNumber()==cur.lineNumber()) return false;
	QString line=c.line().text();
	int pos=line.indexOf("\\begin");
	if(pos>-1){
		QStringList values;
		LatexParser::resolveCommandOptions(line,pos,values);
		QString env=values.takeFirst();
		if(!env.startsWith("{")||!env.endsWith("}")) return -1;
		env=env.mid(1);
		env.chop(1);
		if(tabularNames.contains(env,Qt::CaseSensitive)||tabularNamesWithOneOption.contains(env,Qt::CaseSensitive)){
			int result=findNextToken(c,QStringList());
			if(result!=-2) return false;
			if(c.lineNumber()>cur.lineNumber()) return true;
		}
	}
	return false;
}
Esempio n. 16
0
QString LatexTables::getDef(QDocumentCursor &cur){
	QDocumentCursor c(cur);
	int result=findNextToken(c,QStringList(),false,true);
	if(result!=-2) return QString();
	QString line=c.line().text();
	QString opt;
	int pos=line.indexOf("\\begin");
	if(pos>-1){
		QStringList values;
		QList<int> starts;
		LatexParser::resolveCommandOptions(line,pos,values,&starts);
		QString env=values.takeFirst();
		pos=starts.takeFirst();
		if(!env.startsWith("{")||!env.endsWith("}")) return QString();
		env=env.mid(1);
		env.chop(1);
		int numberOfOptions=-1;
		if(tabularNames.contains(env)) numberOfOptions=0;
		if(tabularNamesWithOneOption.contains(env)) numberOfOptions=1;
		if(numberOfOptions>=0){
			while(!values.isEmpty()){
				opt=values.takeFirst();
				pos=starts.takeFirst();
				if(opt.startsWith("[")&&opt.endsWith("]")) continue;
				if(numberOfOptions>0) {
					numberOfOptions--;
					continue;
				}
				if(!opt.startsWith("{")||!opt.endsWith("}")) return QString();
				opt=opt.mid(1);
				opt.chop(1);
				cur.moveTo(c.line(),pos+1);
				cur.movePosition(opt.length(),QDocumentCursor::NextCharacter,QDocumentCursor::KeepAnchor);
			}
		}
	}
	return opt;
}
Esempio n. 17
0
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;
}
Esempio n. 18
0
QDocumentCursor CursorHistory::back(const QDocumentCursor &currentCursor) {
	if (currentEntry == history.begin()) {
		updateNavActions();
		return QDocumentCursor();
	}

	// insert currentCursor to be able to go back
	if (currentCursor.isValid() && insertPos(currentCursor, false)) {
		currentEntry--;
	}

	CursorPosition pos(currentCursor);
	if (pos.isValid() && !pos.equals(*currentEntry)) {
		updateNavActions();
		return currentPos();
	}

	currentEntry = prevValidEntry(currentEntry);
	updateNavActions();
	return currentPos();
}
Esempio n. 19
0
/*!
  Inserts the cursor behind the current entry
*/
bool CursorHistory::insertPos(QDocumentCursor cur, bool deleteBehindCurrent) {
	if (!m_insertionEnabled) return false;
	if (!cur.isValid()) return false;

	CursorPosition pos(cur);
	connectUnique(pos.doc(), SIGNAL(destroyed(QObject*)), this, SLOT(documentClosed(QObject*)));
	// TODO destroyed() may be duplicate to aboutToDeleteDocument() - needs more testing. anyway it does not harm
	connectUnique(pos.doc(), SIGNAL(lineDeleted(QDocumentLineHandle*)), this, SLOT(lineDeleted(QDocumentLineHandle*)));
	connectUnique(pos.doc(), SIGNAL(lineRemoved(QDocumentLineHandle*)), this, SLOT(lineDeleted(QDocumentLineHandle*)));

	if (deleteBehindCurrent && currentEntry != history.end()) {
		currentEntry++;
		currentEntry = history.erase(currentEntry, history.end());
	}
	if (currentEntry == history.end() && currentEntry != history.begin()) currentEntry--;

	// do not insert neighboring duplicates
	if (currentEntryValid() && (*currentEntry).equals(pos)) {
		updateNavActions();
		return false;
	}
	CursorPosList::iterator it = prevValidEntry(currentEntry);
	if (it != history.end() && (*it).isValid() && (*it).equals(pos)) {
		updateNavActions();
		return false;
	}

	if (history.count() >= m_maxLength) {
		if (currentEntry == history.begin()) {
			history.removeLast();
		} else {
			history.removeFirst();
		}
	}

	currentEntry++;
	history.insert(currentEntry, pos);
	updateNavActions();
	return true;
}
Esempio n. 20
0
/*!
 \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

}
Esempio n. 21
0
void QEditorInputBinding::MotionCommand::exec(QEditor *e)
{
	QDocumentCursor c = e->cursor();
	c.movePosition(count, operation, mode);
	e->setCursor(c);
}
Esempio n. 22
0
void QEditorInputBinding::EditCommand::exec(QEditor *e)
{
	QDocumentCursor c = e->cursor();
	
	switch ( operation )
	{
		case ClearSelection :
			c.clearSelection();
			break;
			
		case SelectWord :
			c.select(QDocumentCursor::WordUnderCursor);
			break;
			
		case SelectLine :
			c.select(QDocumentCursor::LineUnderCursor);
			break;
			
		case SelectDocument :
			c.movePosition(1, QDocumentCursor::Start, QDocumentCursor::MoveAnchor);
			c.movePosition(1, QDocumentCursor::End, QDocumentCursor::KeepAnchor);
			break;
			
		case DeleteChar :
			c.deleteChar();
			break;
			
		case DeletePreviousChar :
			c.deletePreviousChar();
			break;
			
		case DeleteLine :
			c.eraseLine();
			break;
			
		case DeleteSelection :
			c.removeSelectedText();
			break;
			
		case InsertLine :
			c.insertLine();
			break;
			
		case InsertClipBoard :
			e->paste();
			return;
			
		default:
			
			break;
	}
	
	e->setCursor(c);
}
Esempio n. 23
0
QScriptValue searchReplaceFunction(QScriptContext *context, QScriptEngine *engine, bool replace){
	QEditor *editor = qobject_cast<QEditor*>(context->thisObject().toQObject());
	//read arguments
	SCRIPT_REQUIRE(editor, "invalid object");
	SCRIPT_REQUIRE(!replace || context->argumentCount()>=2, "at least two arguments are required");
	SCRIPT_REQUIRE(context->argumentCount()>=1, "at least one argument is required");
	SCRIPT_REQUIRE(context->argumentCount()<=4, "too many arguments");
	SCRIPT_REQUIRE(context->argument(0).isString()||context->argument(0).isRegExp(), "first argument must be a string or regexp");
	QDocumentSearch::Options flags = QDocumentSearch::Silent;
	bool global = false, caseInsensitive = false;
	QString searchFor;
	if (context->argument(0).isRegExp()) {
		flags |= QDocumentSearch::RegExp;
		QRegExp r = context->argument(0).toRegExp();
		searchFor = r.pattern();
		caseInsensitive = r.caseSensitivity() == Qt::CaseInsensitive;
		Q_ASSERT(caseInsensitive == context->argument(0).property("ignoreCase").toBool()); //check assumption about javascript core
		global = context->argument(0).property("global").toBool();
	} else searchFor = context->argument(0).toString();
	QScriptValue handler;
	QDocumentCursor scope = editor->document()->cursor(0,0,editor->document()->lineCount(),0);
	int handlerCount = 0;
	for (int i=1; i<context->argumentCount();i++)
		if (context->argument(i).isString() || context->argument(i).isFunction()) handlerCount++;
	SCRIPT_REQUIRE(handlerCount <= (replace?2:1), "too many string or function arguments");
	for (int i=1; i<context->argumentCount();i++) {
		QScriptValue a = context->argument(i);
		if (a.isFunction()) {
			SCRIPT_REQUIRE(!handler.isValid(), "Multiple callbacks");
			handler = a;
		} else if (a.isString()) {
			if (!replace || handlerCount > 1) {
				QString s = a.toString().toLower();
				global = s.contains("g");
				caseInsensitive = s.contains("i");
				if (s.contains("w")) flags |= QDocumentSearch::WholeWords;
			} else {
				SCRIPT_REQUIRE(!handler.isValid(), "Multiple callbacks");
				handler = a;
			}
			handlerCount--;
		} else if (a.isNumber()) flags |= QDocumentSearch::Options((int)a.toNumber());
		else if (a.isObject()) scope = cursorFromValue(a);
		else SCRIPT_REQUIRE(false, "Invalid argument");
	}
	SCRIPT_REQUIRE(handler.isValid() || !replace, "No callback given");
	if (!caseInsensitive) flags |= QDocumentSearch::CaseSensitive;
	
	//search/replace
	QDocumentSearch search(editor, searchFor, flags);
	search.setScope(scope);
	if (replace && handler.isString()) {
		search.setReplaceText(handler.toString());
		search.setOption(QDocumentSearch::Replace,true);
		return search.next(false, global, false, false);
	}
	if (!handler.isValid())
		return search.next(false,global,true,false);
	int count=0;
	while (search.next(false, false, true, false) && search.cursor().isValid()) {
		count++;
		QDocumentCursor temp = search.cursor();
		QScriptValue cb = handler.call(QScriptValue(), QScriptValueList() << engine->newQObject(&temp));
		if (replace && cb.isValid()){
			QDocumentCursor tmp = search.cursor();
			tmp.replaceSelectedText(cb.toString());
			search.setCursor(tmp.selectionEnd());
		}
		if (!global) break;
	}
	return count;
}
Esempio n. 24
0
void scriptengine::run(){
	if (globalObject) delete globalObject;
	globalObject = new ScriptObject(m_script,buildManager,app);
    if(m_allowWrite){
        globalObject->registerAllowedWrite();
    }
	QScriptValue globalValue = engine->newQObject(globalObject);
	globalValue.setPrototype(engine->globalObject());
	engine->setGlobalObject(globalValue);
	
	QDocumentCursor c;
	QScriptValue cursorValue;
	if (m_editorView)
		engine->globalObject().setProperty("editorView", engine->newQObject(m_editorView));
	
	if (m_editor) {
		engine->globalObject().setProperty("editor", engine->newQObject(m_editor));
		
		c=m_editor->cursor();
		c.setAutoUpdated(true); //auto updated so the editor text insert functions actually move the cursor		
		cursorValue = engine->newQObject(&c);
		engine->globalObject().setProperty("cursor", cursorValue);
		
		QScriptValue matches = engine->newArray(triggerMatches.size());
		for (int i=0;i<triggerMatches.size();i++) matches.setProperty(i, triggerMatches[i]);
		engine->globalObject().setProperty("triggerMatches", matches);
	} 
	engine->globalObject().setProperty("triggerId", engine->newVariant(triggerId));

	engine->globalObject().setProperty("include", engine->newFunction(include));

	engine->globalObject().setProperty("setTimeout", engine->newFunction(setTimeout));
	
	QScriptValue qsMetaObject = engine->newQMetaObject(&QDocumentCursor::staticMetaObject);
	engine->globalObject().setProperty("cursorEnums", qsMetaObject);
	
	QScriptValue uidClass = engine->scriptValueFromQMetaObject<UniversalInputDialogScript>();
	engine->globalObject().setProperty("UniversalInputDialog", uidClass);
	
	FileChooser flchooser(0,scriptengine::tr("File Chooser"));
	engine->globalObject().setProperty("fileChooser", engine->newQObject(&flchooser));
	
	engine->globalObject().setProperty("documentManager", engine->newQObject(&app->documents));
	engine->globalObject().setProperty("documents", qScriptValueFromQList(engine, app->documents.documents));
#ifndef NO_POPPLER_PREVIEW
	engine->globalObject().setProperty("pdfs", qScriptValueFromQList(engine, PDFDocument::documentList()));
#endif
	QScriptValue bm = engine->newQObject(&app->buildManager);
	bm.setProperty("runCommand", engine->newFunction(buildManagerRunCommandWrapper));	
	//bm.setProperty("commandLineRequested", engine->globalObject().property("buildManagerCommandLineRequestedWrapper"));
	engine->globalObject().setProperty("buildManager", bm);
	//connect(buildManager, SIGNAL(commandLineRequested(QString,QString*)), SLOT(buildManagerCommandLineRequestedWrapperSlot(const QString&, QString*)));
	
	engine->evaluate(m_script);
	
	if(engine->hasUncaughtException()){
		QString error = QString(tr("Uncaught exception at line %1: %2\n")).arg(engine->uncaughtExceptionLineNumber()).arg(engine->uncaughtException().toString());
		error += "\n"+QString(tr("Backtrace %1")).arg(engine->uncaughtExceptionBacktrace().join(", "));
		qDebug() << error;
		QMessageBox::critical(0, tr("Script-Error"), error);
	}
	
	if (m_editor) {
		if (engine->globalObject().property("cursor").strictlyEquals(cursorValue)) m_editor->setCursor(c);
		else m_editor->setCursor(cursorFromValue(engine->globalObject().property("cursor")));
	}
	
	if (!globalObject->backgroundScript) {
		delete globalObject;
		globalObject = 0;
	}
}
Esempio n. 25
0
/*!

*/
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;
}
Esempio n. 26
0
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());
}
Esempio n. 27
0
void CodeSnippet::insertAt(QEditor* editor, QDocumentCursor* cursor, bool usePlaceholders, bool byCompleter) const{
	if (lines.empty()||!editor||!cursor) return;
	
	//find filechooser escape %(   %)
	QString line=lines.join("\n");
	QRegExp rx("%\\((.+)%\\)");
	int pos=rx.indexIn(line,0);
	if(pos>-1){
		FileChooser sfDlg(0,QApplication::tr("Select a File"));
		sfDlg.setFilter(rx.cap(1));
		LatexDocument *doc=qobject_cast<LatexDocument*>(cursor->document());
		QString path=doc->parent->getCompileFileName();
		path=getPathfromFilename(path);
		QString directory;
		if(path.isEmpty()) directory=QDir::homePath();
		else directory=path;
		sfDlg.setDir(directory);
		if (sfDlg.exec()) {
			QString fn=sfDlg.fileName();
			line.replace(rx,getRelativeBaseNameToPath(fn,path));
		} else return;
	}


	QString savedSelection;
	bool alwaysSelect = false;
	bool editBlockOpened = false;
	if (cursor->hasSelection()) {
		savedSelection=cursor->selectedText();
		editBlockOpened = true;
		cursor->beginEditBlock();
		cursor->removeSelectedText();
	}else if(!editor->cutBuffer.isEmpty()){
		savedSelection=editor->cutBuffer;
		editor->cutBuffer.clear();
		alwaysSelect = true;
	}
	bool multiLineSavedSelection = savedSelection.contains("\n");
	QDocumentCursor selector=*cursor;
	QDocumentLine curLine=cursor->line();

	// on multi line commands, replace environments only
	if(autoReplaceCommands && lines.size()>1 && line.contains("\\begin{")){
		QString curLine=cursor->line().text();
		int wordBreak=curLine.indexOf(QRegExp("\\W"),cursor->columnNumber());
		int closeCurl=curLine.indexOf("}",cursor->columnNumber());
		int openCurl=curLine.indexOf("{",cursor->columnNumber());
		int openBracket=curLine.indexOf("[",cursor->columnNumber());
		if(closeCurl>0){
			if(openBracket<0) openBracket=1e9;
			if(openCurl<0) openCurl=1e9;
			if(wordBreak<0) wordBreak=1e9;
			if(closeCurl<openBracket && (closeCurl<=wordBreak || openCurl<=wordBreak)){
				QString oldEnv;
				if(closeCurl<openCurl)
					oldEnv=curLine.mid(cursor->columnNumber(),closeCurl-cursor->columnNumber());
				else
					oldEnv=curLine.mid(openCurl+1,closeCurl-openCurl-1);
				QRegExp rx("\\\\begin\\{(.+)\\}");
				rx.setMinimal(true);
				rx.indexIn(line);
				QString newEnv=rx.cap(1);
				// remove curly brakets as well
				QDocument* doc=cursor->document();
				QString searchWord="\\end{"+oldEnv+"}";
				QString inhibitor="\\begin{"+oldEnv+"}";
				bool backward=false;
				int step=1;
				int startLine=cursor->lineNumber();
				//int startCol=cursor.columnNumber();
				int endLine=doc->findLineContaining(searchWord,startLine+step,Qt::CaseSensitive,backward);
				int inhibitLine=doc->findLineContaining(inhibitor,startLine+step,Qt::CaseSensitive,backward); // not perfect (same line end/start ...)
				while (inhibitLine>0 && endLine>0 && inhibitLine*step<endLine*step) {
					endLine=doc->findLineContaining(searchWord,endLine+step,Qt::CaseSensitive,backward); // not perfect (same line end/start ...)
					inhibitLine=doc->findLineContaining(inhibitor,inhibitLine+step,Qt::CaseSensitive,backward);
				}
				QString endText=doc->line(endLine).text();
				int start=endText.indexOf(searchWord);
				int offset=searchWord.indexOf("{");
				int length=searchWord.length()-offset-1;
				selector.moveTo(endLine,start+1+offset);
				selector.movePosition(length-1,QDocumentCursor::Right,QDocumentCursor::KeepAnchor);
				selector.replaceSelectedText(newEnv);
				cursor->movePosition(closeCurl-cursor->columnNumber()+1,QDocumentCursor::Right,QDocumentCursor::KeepAnchor);
				QString first=lines.first();
				int pos=first.indexOf('{');
				pos=first.indexOf('{',pos+1); //pos of second {
				if(pos>-1)
				    first.remove(pos,first.length()-pos);
				editor->insertText(*cursor,first);
				if (editBlockOpened) cursor->endEditBlock();
				return;
			}
		}
	}

	int baseLine=cursor->lineNumber();
	int baseLineIndent = cursor->columnNumber(); //text before inserted word moves placeholders to the right
	int lastLineRemainingLength = curLine.text().length()-baseLineIndent; //last line will has length: indentation + codesnippet + lastLineRemainingLength
	editor->insertText(*cursor,line); //don't use cursor->insertText to keep autoindentation working

	if (editBlockOpened) cursor->endEditBlock();

	// on single line commands only: replace command
	if(byCompleter && autoReplaceCommands && lines.size()==1 && line.startsWith('\\')){
		if(cursor->nextChar().isLetterOrNumber()||cursor->nextChar()==QChar('{')){
			QString curLine=cursor->line().text();
			int wordBreak=curLine.indexOf(QRegExp("\\W"),cursor->columnNumber());
			int closeCurl=curLine.indexOf("}",cursor->columnNumber());
			int openCurl=curLine.indexOf("{",cursor->columnNumber());
			int openBracket=curLine.indexOf("[",cursor->columnNumber());
			if(!line.contains("{")){
				if(openBracket<0) openBracket=1e9;
				if(closeCurl<0) closeCurl=1e9;
				if(openCurl<0) openCurl=1e9;
				if(wordBreak<openBracket && wordBreak<closeCurl &&wordBreak<openCurl){
					if(wordBreak<0)
						cursor->movePosition(wordBreak-cursor->columnNumber(),QDocumentCursor::EndOfLine,QDocumentCursor::KeepAnchor);
					else
						cursor->movePosition(wordBreak-cursor->columnNumber(),QDocumentCursor::Right,QDocumentCursor::KeepAnchor);
					cursor->removeSelectedText();
					return;
				}
			}else{
				if(openCurl>-1){
					if(openBracket<0) openBracket=1e9;
					if(closeCurl<0) closeCurl=1e9;
					if(openCurl<openBracket && openCurl<closeCurl &&openCurl<=wordBreak){
						cursor->movePosition(openCurl-cursor->columnNumber(),QDocumentCursor::Right,QDocumentCursor::KeepAnchor);
						cursor->removeSelectedText();
						int curl=line.length()-line.indexOf("{");
						cursor->movePosition(curl,QDocumentCursor::Left,QDocumentCursor::KeepAnchor);
						cursor->removeSelectedText();
						return;
					}
				}
			}
		}
	}


	Q_ASSERT(placeHolders.size()==lines.count());
	if (usePlaceholders) {
		//check if there actually are placeholders to insert
		usePlaceholders=false;
		for (int l=0;l< lines.count();l++)
			usePlaceholders|=placeHolders[l].size();
	}
	int autoSelectPlaceholder = -1;
	if (usePlaceholders) {
		if (editor->currentPlaceHolder()!=-1 && 
			editor->getPlaceHolder(editor->currentPlaceHolder()).cursor.isWithinSelection(*cursor))
			editor->removePlaceHolder(editor->currentPlaceHolder()); //remove currentplaceholder to prevent nesting
		for (int l=0;l< lines.count();l++){
			//if (l<mLines.count()-1) cursor->insertLine();
			for (int i=0; i<placeHolders[l].size(); i++) {
				if (placeHolders[l][i].flags & CodeSnippetPlaceHolder::Mirror) continue;
				PlaceHolder ph;
				ph.length=placeHolders[l][i].length;
				ph.cursor = getCursor(editor, placeHolders[l][i], l, baseLine, baseLineIndent, lastLineRemainingLength);
				ph.autoRemove = !(placeHolders[l][i].flags & CodeSnippetPlaceHolder::Persistent);
				if (!ph.cursor.isValid()) continue;
				editor->addPlaceHolder(ph);
				if (placeHolders[l][i].flags & CodeSnippetPlaceHolder::Mirrored) {
					int phId = editor->placeHolderCount()-1;
					for (int lm=0; lm<placeHolders.size(); lm++)
						for (int im=0; im < placeHolders[lm].size(); im++)
							if (placeHolders[lm][im].flags & CodeSnippetPlaceHolder::Mirror &&
							    placeHolders[lm][im].id == placeHolders[l][i].id)
							editor->addPlaceHolderMirror(phId, getCursor(editor, placeHolders[lm][im], lm, baseLine, baseLineIndent, lastLineRemainingLength));
				}
				if ((placeHolders[l][i].flags & CodeSnippetPlaceHolder::AutoSelect) &&
				      ((autoSelectPlaceholder == -1) ||
					(multiLineSavedSelection && (placeHolders[l][i].flags & CodeSnippetPlaceHolder::PreferredMultilineAutoSelect))))
					autoSelectPlaceholder = editor->placeHolderCount()-1;

			}
		}
	}
	//place cursor/add \end
	if (cursorOffset!=-1) {
		int realAnchorOffset=anchorOffset; //will be moved to the right if text is already inserted on this line
		if (cursorLine>0) {
			if (cursorLine>=lines.size()) return;
			if (!selector.movePosition(cursorLine,QDocumentCursor::Down,QDocumentCursor::MoveAnchor))
				return;
			//if (editor->flag(QEditor::AutoIndent))
			realAnchorOffset += selector.line().length()-lines[cursorLine].length();
			if (cursorLine + 1 == lines.size())
				realAnchorOffset-=lastLineRemainingLength;
		} else realAnchorOffset += baseLineIndent;
		selector.setColumnNumber(realAnchorOffset);
		bool ok=true;
		if (cursorOffset>anchorOffset) 
			ok=selector.movePosition(cursorOffset-anchorOffset,QDocumentCursor::Right,QDocumentCursor::KeepAnchor);
		else if (cursorOffset<anchorOffset)
			ok=selector.movePosition(anchorOffset-cursorOffset,QDocumentCursor::Left,QDocumentCursor::KeepAnchor);
		if (!ok) return;
		editor->setCursor(selector);
	} else if (autoSelectPlaceholder!=-1) editor->setPlaceHolder(autoSelectPlaceholder, true); //this moves the cursor to that placeholder
	else {
		editor->setCursor(*cursor); //place after insertion
		return;
	}
	if (!savedSelection.isEmpty()) {
		QDocumentCursor oldCursor = editor->cursor();
		editor->cursor().insertText(savedSelection,true);
		if (!editor->cursor().hasSelection() && alwaysSelect) {
			oldCursor.movePosition(savedSelection.length(), QDocumentCursor::Right, QDocumentCursor::KeepAnchor);
			editor->setCursor(oldCursor);
		}
		if (autoSelectPlaceholder!=-1) editor->setPlaceHolder(autoSelectPlaceholder, true); //this synchronizes the placeholder mirrors with the current placeholder text
	}
}
Esempio n. 28
0
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);
}
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());
        }
}