18 #include "NCLTextEditor.h"
24 #include <Qsci/qscistyledtext.h>
26 NCLTextEditor::NCLTextEditor(QWidget *parent) :
32 textWithoutUserInter =
"";
33 focusInIgnoringCurrentText =
false;
38 NCLTextEditor::~NCLTextEditor()
44 void NCLTextEditor::initParameters()
46 tabBehavior = TAB_BEHAVIOR_DEFAULT;
49 setFolding(QsciScintilla::CircledTreeFoldStyle);
50 setFoldMarginColors(PREF_FOLD_MARGIN_FORE_COLOR, PREF_FOLD_MARGIN_BACK_COLOR);
52 setMarginLineNumbers(1,
true);
53 setMarginWidth(1, 25);
54 setMarginsBackgroundColor(MARGINS_BACKGROUND_COLOR);
57 setCaretLineBackgroundColor(QColor(
"#e6fff0"));
58 setCaretLineVisible(
true);
62 setWrapMode(WrapWord);
63 setWrapVisualFlags(WrapFlagByText);
66 setAutoCompletionThreshold(-1);
67 setAutoCompletionFillupsEnabled(
false);
76 setAnnotationDisplay(QsciScintilla::AnnotationBoxed);
99 font.setFamily(QString::fromUtf8(PREF_FONT_FAMILY));
100 font.setPointSize(PREF_FONT_SIZE);
102 setCaretLineBackgroundColor(QColor(PREF_CARET_LINE_BG_COLOR));
107 error_marker = markerDefine(QPixmap(
":/images/error-icon-16.png"), -1);
108 error_indicator = indicatorDefine(SquiggleIndicator, 1);
109 setIndicatorForegroundColor(QColor(
"#FF0000"), error_indicator);
110 filling_attribute_indicator = indicatorDefine (RoundBoxIndicator, 2);
116 void NCLTextEditor::Increasefont()
121 void NCLTextEditor::Decreasefont()
126 void NCLTextEditor::clearErrorIndicators()
129 markerDeleteAll(error_marker);
132 int nr_lines = lines();
133 QString tmp2 = this->text(nr_lines);
134 clearIndicatorRange (0,
142 void NCLTextEditor::markError ( QString description,
149 QString tmp = this->text(line);
153 markerAdd(line, error_marker);
157 while (tmp[indentation].isSpace())
160 fillIndicatorRange(line,
165 annotate(line, QsciStyledText(description, 0));
168 void NCLTextEditor::wheelEvent (QWheelEvent *event)
170 if(event->modifiers() == Qt::ControlModifier){
171 if(event->delta() > 0)
176 QsciScintilla::wheelEvent(event);
181 void NCLTextEditor::mousePressEvent(QMouseEvent *event)
183 int selBegin = SendScintilla(SCI_GETSELECTIONSTART);
184 int selEnd = SendScintilla(SCI_GETSELECTIONEND);
186 int clearBegin = SendScintilla(SCI_POSITIONFROMLINE, SendScintilla(SCI_LINEFROMPOSITION, selBegin));
187 int clearEnd = SendScintilla(SCI_GETLINEENDPOSITION, SendScintilla(SCI_LINEFROMPOSITION, selEnd));
189 qDebug() << clearBegin << clearEnd;
191 SendScintilla(SCI_INDICATORCLEARRANGE, clearBegin, clearEnd);
193 QsciScintilla::mousePressEvent(event);
195 int line, index, begin, end;
196 getCursorPosition(&line, &index);
198 pos = SendScintilla(SCI_GETCURRENTPOS);
199 style = SendScintilla(SCI_GETSTYLEAT, pos);
202 if (style == QsciLexerNCL::HTMLDoubleQuotedString)
205 getCursorPosition (&line, &index);
206 updateVisualFillingAttributeField(line, index, begin, end);
210 interaction_state = DEFAULT_STATE;
215 void NCLTextEditor::keyPressEvent(QKeyEvent *event)
218 if((event->modifiers() & Qt::ControlModifier) &&
219 (event->key() == Qt::Key_Space))
222 autoCompleteFromAPIs();
226 if((event->modifiers() & Qt::ControlModifier) &&
227 (event->modifiers() & Qt::ShiftModifier) &&
228 (event->key() == Qt::Key_F))
237 getCursorPosition(&line, &index);
238 int pos, style, size;
239 pos = SendScintilla(SCI_GETCURRENTPOS);
240 size = SendScintilla(SCI_GETTEXTLENGTH);
244 if(event->key() == Qt::Key_Backtab) {
246 event =
new QKeyEvent(event->type(), Qt::Key_Tab, Qt::ShiftModifier);
252 if(event->key() == Qt::Key_ZoomIn)
263 if(event->key() == Qt::Key_ZoomOut)
270 if (interaction_state == FILLING_ATTRIBUTES_STATE) {
271 QString strline = text(line);
272 clearIndicatorRange ( line,
276 filling_attribute_indicator);
278 if(event->key() == Qt::Key_Return){
279 interaction_state = DEFAULT_STATE;
280 setSelection(line, index, line, index);
281 QsciScintilla::keyPressEvent(event);
285 if(event->key() == Qt::Key_Tab){
286 QString strline = text(line);
287 pos = SendScintilla(SCI_GETCURRENTPOS);
288 style = SendScintilla(SCI_GETSTYLEAT, pos);
292 if(event->modifiers() & Qt::ShiftModifier) {
294 style = SendScintilla(SCI_GETSTYLEAT, pos);
295 if(style != QsciLexerNCL::HTMLDoubleQuotedString)
301 userFillingPreviousAttribute(pos);
307 else if(event->modifiers() == Qt::NoModifier) {
309 style = SendScintilla(SCI_GETSTYLEAT, pos);
310 if(style != QsciLexerNCL::HTMLDoubleQuotedString)
316 userFillingNextAttribute(pos);
322 clearIndicatorRange( line,
326 filling_attribute_indicator );
327 interaction_state = DEFAULT_STATE;
334 QsciScintilla::keyPressEvent ( event ) ;
335 getCursorPosition (&line, &index);
336 pos = SendScintilla(SCI_GETCURRENTPOS);
337 style = SendScintilla(SCI_GETSTYLEAT, pos);
342 if ( style == QsciLexerNCL::HTMLDoubleQuotedString
346 style = SendScintilla(SCI_GETSTYLEAT, pos-1);
348 if(style == QsciLexerNCL::HTMLDoubleQuotedString)
350 updateVisualFillingAttributeField(line, index, begin, end);
355 clearIndicatorRange( line,
359 filling_attribute_indicator);
361 interaction_state = DEFAULT_STATE;
366 QsciScintilla::keyPressEvent(event);
367 pos = SendScintilla(SCI_GETCURRENTPOS);
368 style = SendScintilla(SCI_GETSTYLEAT, pos);
373 if (style == QsciLexerNCL::HTMLDoubleQuotedString &&
377 style = SendScintilla(SCI_GETSTYLEAT, pos-1);
380 if (tabBehavior == TAB_BEHAVIOR_NEXT_ATTR &&
381 (style == QsciLexerNCL::HTMLDoubleQuotedString)) {
383 interaction_state = FILLING_ATTRIBUTES_STATE;
384 getCursorPosition (&line, &index);
386 updateVisualFillingAttributeField(line, index, begin, end);
392 void NCLTextEditor::keyReleaseEvent(QKeyEvent *event)
394 QsciScintilla::keyReleaseEvent(event);
397 void NCLTextEditor::AutoCompleteCompleted()
402 void NCLTextEditor::MarkLine(
int margin,
int line, Qt::KeyboardModifiers state)
409 void NCLTextEditor::userFillingNextAttribute(
int pos)
411 int begin, end, style, i = pos;
412 int size = SendScintilla(SCI_GETTEXTLENGTH);
414 interaction_state = FILLING_ATTRIBUTES_STATE;
419 style = SendScintilla(SCI_GETSTYLEAT, i);
420 if (style == QsciLexerNCL::HTMLDoubleQuotedString)
429 interaction_state = DEFAULT_STATE;
433 int newline, newindex;
434 lineIndexFromPosition(i, &newline, &newindex);
435 setCursorPosition(newline, newindex);
436 updateVisualFillingAttributeField (newline, newindex, begin, end);
437 setSelection(newline, begin, newline, end);
440 void NCLTextEditor::userFillingPreviousAttribute(
int pos)
442 int begin, end, style;
444 interaction_state = FILLING_ATTRIBUTES_STATE;
447 style = SendScintilla(SCI_GETSTYLEAT, i);
448 if (style == QsciLexerHTML::HTMLDoubleQuotedString)
454 interaction_state = DEFAULT_STATE;
458 int newline, newindex;
459 lineIndexFromPosition(i, &newline, &newindex);
460 setCursorPosition(newline, newindex);
461 updateVisualFillingAttributeField (newline, newindex, begin, end);
462 setSelection(newline, begin, newline, end);
466 void NCLTextEditor::updateVisualFillingAttributeField(
int line,
471 QString strline = text(line);
474 bool inserted_space =
false;
476 clearIndicatorRange( line,
480 filling_attribute_indicator);
482 while( begin >= 0 && strline[begin] !=
'\"')
486 interaction_state = DEFAULT_STATE;
491 while( end < strline.size() && strline[end] !=
'\"')
494 if(end >= strline.size() || begin == end) {
495 interaction_state = DEFAULT_STATE;
503 inserted_space =
true;
505 fillIndicatorRange(line, begin, line, end, filling_attribute_indicator);
507 if(inserted_space) setSelection(line, begin, line, end);
510 void NCLTextEditor::setTabBehavior(TAB_BEHAVIOR tabBehavior)
512 this->tabBehavior = tabBehavior;
515 void NCLTextEditor::formatText()
517 qDebug() <<
"NCLTextEditor::formatText()";
520 void NCLTextEditor::keepFocused()
522 focusInIgnoringCurrentText =
true;
524 this->SendScintilla(QsciScintilla::SCI_SETFOCUS,
true);
527 void NCLTextEditor::focusOutEvent(QFocusEvent *event)
529 clearFillingAttributeIndicator();
531 emit focusLosted(event);
534 void NCLTextEditor::clearFillingAttributeIndicator()
536 int nr_lines = lines();
537 QString tmp2 = this->text(nr_lines);
539 clearIndicatorRange (0,
543 filling_attribute_indicator);
546 void NCLTextEditor::focusInEvent(QFocusEvent *e)
548 #ifndef NCLEDITOR_STANDALONE
549 if(!focusInIgnoringCurrentText)
550 textWithoutUserInter = text();
552 focusInIgnoringCurrentText =
false;
553 this->SendScintilla(QsciScintilla::SCI_SETFOCUS,
true);
557 QString NCLTextEditor::textWithoutUserInteraction()
559 return textWithoutUserInter;
561 void NCLTextEditor::setTextWithoutUserInteraction(QString text)
563 textWithoutUserInter = text;
566 void NCLTextEditor::setDocumentUrl(QString docURL)
568 this->docURL = docURL;
571 QString NCLTextEditor::getDocumentUrl()
576 bool NCLTextEditor::parseDocument(
bool recursive)
581 if(!domDoc.setContent(this->text()))
590 domDocs.insert(docURL, domDoc);
591 return parseImportedDocuments(docURL, domDoc,
true);
597 bool NCLTextEditor::parseImportedDocuments(QString currentFileURI,
598 QDomDocument &doc,
bool recursive)
600 qDebug() <<
"parseImportedDocument( " << currentFileURI;
601 QStack <QDomElement> stack;
602 QDomElement current = doc.firstChildElement();
608 current = stack.top();
610 qDebug() << current.tagName() <<
"id = " << current.attribute(
"id");
612 if(current.tagName() ==
"importBase" &&
613 current.hasAttribute(
"documentURI") &&
614 current.hasAttribute(
"alias"))
616 QString importedDocumentUri = current.attribute(
"documentURI");
617 QString fullpath =
"";
619 QFileInfo importedFI(importedDocumentUri), currentFI(currentFileURI);
620 if(importedFI.isAbsolute())
622 fullpath = importedDocumentUri;
626 importedFI.setFile( currentFI.absolutePath() +
"/"
627 + importedDocumentUri);
629 if(importedFI.exists())
631 qDebug() << importedFI.absoluteFilePath();
632 fullpath = importedFI.absoluteFilePath();
638 qDebug() <<
"I will include the file " << fullpath;
639 QFile file(fullpath);
640 if (file.open(QIODevice::ReadOnly))
642 QDomDocument currentDomDoc;
643 if (currentDomDoc.setContent(&file))
645 updateElementsIDWithAlias(currentDomDoc,
646 current.attribute(
"alias"));
647 if(!parseImportedDocuments(fullpath, currentDomDoc,
true))
650 qDebug() <<
"Could not import " << fullpath;
652 domDocs.insert(fullpath, currentDomDoc);
658 QDomElement child = current.firstChildElement();
659 while(!child.isNull())
661 stack.push_back(child);
662 child = child.nextSiblingElement();
668 void NCLTextEditor::updateElementsIDWithAlias(QDomDocument doc, QString alias)
670 QStack <QDomElement> stack;
671 QDomElement current = doc.firstChildElement();
675 current = stack.top();
677 if(current.hasAttribute(
"id"))
679 current.setAttribute(
"id", alias +
"#" + current.attribute(
"id"));
682 QDomElement child = current.firstChildElement();
683 while(!child.isNull())
685 stack.push_back(child);
686 child = child.nextSiblingElement();
691 QDomElement NCLTextEditor::elementById(
const QDomDocument &domDoc, QString
id)
693 QStack <QDomNode> stack;
694 stack.push_front(domDoc.firstChildElement());
697 QDomNode current = stack.front();
699 if(current.isElement())
701 if(current.toElement().attribute(
"id") == id)
702 return current.toElement();
705 QDomNode child = current.firstChild();
706 while(!child.isNull())
708 stack.push_back(child);
709 child = child.nextSibling();
715 return QDomElement();
718 QDomElement NCLTextEditor::elementById(QString
id,
bool recursive)
721 return elementById(domDoc,
id);
723 QMapIterator<QString, QDomDocument> i(domDocs);
727 QDomDocument currentDomDoc = i.value();
728 QDomElement element = elementById(currentDomDoc,
id);
729 if(!element.isNull())
733 return domDoc.elementById(
id);
736 QList <QDomElement> NCLTextEditor::elementsByTagname(
const QDomDocument &domDoc,
739 QDomNodeList elements = domDoc.elementsByTagName(tagname);
740 QList <QDomElement> ret;
741 for(
int i = 0; i < elements.length(); i++)
743 ret.push_back(elements.at(i).toElement());
748 QList <QDomElement> NCLTextEditor::elementsByTagname(QString tagname)
750 QList <QDomElement> ret;
751 QMapIterator<QString, QDomDocument> i(domDocs);
755 ret.append(elementsByTagname(i.value(), tagname));
760 QList <QDomElement> NCLTextEditor::elementsByTagname( QString tagname,
763 QDomElement current = elementById(parentId);
764 QList <QDomElement> ret;
766 QStack <QDomElement> stack;
772 current = stack.front();
775 QDomElement node = current.toElement();
776 if(node.tagName() == tagname)
779 if(first || !NCLStructure::getInstance()->defineScope(node.tagName()))
782 QDomElement child = current.firstChildElement();
783 while(!child.isNull())
786 stack.push_back(child);
787 child = child.nextSiblingElement();