예제 #1
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;
}
예제 #2
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);
}
예제 #3
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());
		}
	}
/*!
	\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
}
예제 #5
0
/*!
	\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;
}
예제 #6
0
/*!
	\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);
		}
	}
}
예제 #7
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);
}
예제 #8
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;
}
예제 #9
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
	}
}
예제 #10
0
void QEditorInputBinding::MotionCommand::exec(QEditor *e)
{
	QDocumentCursor c = e->cursor();
	c.movePosition(count, operation, mode);
	e->setCursor(c);
}