NCL Composer  0.1.5
 All Classes Functions Variables Pages
NCLTextEditor.cpp
1 /*
2  * Copyright 2011 TeleMidia/PUC-Rio.
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library. If not, see
16  * <http://www.gnu.org/licenses/>.
17  */
18 #include "NCLTextEditor.h"
19 
20 #include <QDir>
21 #include <QUrl>
22 #include <QFileInfo>
23 #include <QStack>
24 #include <Qsci/qscistyledtext.h>
25 
26 NCLTextEditor::NCLTextEditor(QWidget *parent) :
27  QsciScintilla(parent)
28 {
29  initParameters();
30  nclexer = NULL;
31  apis = NULL;
32  textWithoutUserInter = "";
33  focusInIgnoringCurrentText = false;
34 
35  setAcceptDrops(true);
36 }
37 
38 NCLTextEditor::~NCLTextEditor()
39 {
40 // if(nclexer != NULL) delete nclexer;
41 // if(apis != NULL) delete apis;
42 }
43 
44 void NCLTextEditor::initParameters()
45 {
46  tabBehavior = TAB_BEHAVIOR_DEFAULT;
47 
48  setAutoIndent(true);
49  setFolding(QsciScintilla::CircledTreeFoldStyle);
50  setFoldMarginColors(PREF_FOLD_MARGIN_FORE_COLOR, PREF_FOLD_MARGIN_BACK_COLOR);
51 
52  setMarginLineNumbers(1, true);
53  setMarginWidth(1, 25);
54  setMarginsBackgroundColor(MARGINS_BACKGROUND_COLOR);
55 
56  setCaretWidth(20);
57  setCaretLineBackgroundColor(QColor("#e6fff0"));
58  setCaretLineVisible(true);
59 
60  ensureLineVisible(1);
61  setUtf8(true);
62  setWrapMode(WrapWord);
63  setWrapVisualFlags(WrapFlagByText);
64 
65  /* AutoCompletetion parameters */
66  setAutoCompletionThreshold(-1);
67  setAutoCompletionFillupsEnabled(false);
68  // setAutoIndent(true);
69  // setIndentationWidth(0);
70  // setIndentationGuides(true);
71  // setTabIndents(true);
72  setTabWidth(8);
73  // setIndentationsUseTabs(true);
74 
75 
76  setAnnotationDisplay(QsciScintilla::AnnotationBoxed);
77  //adding text partitions
78  /*MyLexer *mylexer = new MyLexer(this);
79 
80  QRegExp attrValueRegex ("\".*\"");
81  QsciStyle attrValueStyle ( 4, "ATTRIBUTE_VALUE", QColor(0x0, 0x0, 0xFF),
82  mylexer->defaultPaper(1),
83  mylexer->defaultFont(1));
84  mylexer->addTextPartition(4, attrValueRegex, attrValueStyle);
85 
86  QRegExp startTagRegex ("<.[^><.]+>");
87  QsciStyle startTagStyle (10, "START_TAG", QColor(0x0, 0x0, 0xFF),
88  mylexer->defaultPaper(1), mylexer->defaultFont(1));
89  mylexer->addTextPartition(10, startTagRegex, startTagStyle);
90  */
91 
92  nclexer = new QsciLexerNCL (0);
93  setLexer(nclexer);
94 
95  //APIS
96  apis = new QsciNCLAPIs(lexer());
97 
98  QFont font;
99  font.setFamily(QString::fromUtf8(PREF_FONT_FAMILY));
100  font.setPointSize(PREF_FONT_SIZE);
101  setFont(font);
102  setCaretLineBackgroundColor(QColor(PREF_CARET_LINE_BG_COLOR));
103 
104  // connect(this, SIGNAL(marginClicked(int,int,Qt::KeyboardModifiers)), this,
105  // SLOT(MarkLine(int,int,Qt::KeyboardModifiers)));
106 
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);
111 
112  // qDebug() << error_marker << " " << error_indicator;
113  // setWhitespaceVisibility(QsciScintilla::WsVisible);
114 }
115 
116 void NCLTextEditor::Increasefont()
117 {
118  zoomIn();
119 }
120 
121 void NCLTextEditor::Decreasefont()
122 {
123  zoomOut();
124 }
125 
126 void NCLTextEditor::clearErrorIndicators()
127 {
128  // clear markers
129  markerDeleteAll(error_marker);
130 
131  //clearIndicators
132  int nr_lines = lines();
133  QString tmp2 = this->text(nr_lines);
134  clearIndicatorRange (0,
135  0,
136  nr_lines,
137  tmp2.size(),
138  error_indicator);
139  clearAnnotations();
140 }
141 
142 void NCLTextEditor::markError ( QString description,
143  QString file,
144  int line,
145  int column,
146  int severity)
147 {
148  //TODO: Show Error Messages
149  QString tmp = this->text(line);
150 
151  // ADD MARKER
152  if (text() != "")
153  markerAdd(line, error_marker);
154 
155  //ADD INDICATOR
156  int indentation = 0;
157  while (tmp[indentation].isSpace())
158  indentation++;
159 
160  fillIndicatorRange(line,
161  indentation,
162  line,
163  tmp.size()-1,
164  error_indicator);
165  annotate(line, QsciStyledText(description, 0));
166 }
167 
168 void NCLTextEditor::wheelEvent (QWheelEvent *event)
169 {
170  if(event->modifiers() == Qt::ControlModifier){
171  if(event->delta() > 0)
172  zoomIn();
173  else
174  zoomOut();
175  }
176  QsciScintilla::wheelEvent(event);
177 }
178 
179 // TODO: Maybe move the mousePressEvent function content, and part of the
180 // keyPressEvent, to a function connected to selectionChanged signal.
181 void NCLTextEditor::mousePressEvent(QMouseEvent *event)
182 {
183  int selBegin = SendScintilla(SCI_GETSELECTIONSTART);
184  int selEnd = SendScintilla(SCI_GETSELECTIONEND);
185 
186  int clearBegin = SendScintilla(SCI_POSITIONFROMLINE, SendScintilla(SCI_LINEFROMPOSITION, selBegin));
187  int clearEnd = SendScintilla(SCI_GETLINEENDPOSITION, SendScintilla(SCI_LINEFROMPOSITION, selEnd));
188 
189  qDebug() << clearBegin << clearEnd;
190 
191  SendScintilla(SCI_INDICATORCLEARRANGE, clearBegin, clearEnd);
192 
193  QsciScintilla::mousePressEvent(event);
194 
195  int line, index, begin, end;
196  getCursorPosition(&line, &index);
197  int pos, style;
198  pos = SendScintilla(SCI_GETCURRENTPOS);
199  style = SendScintilla(SCI_GETSTYLEAT, pos);
200 
201  //FIXME: Attribute also can be between Single quotes
202  if (style == QsciLexerNCL::HTMLDoubleQuotedString)
203  {
204  //interaction_state = FILLING_ATTRIBUTES_STATE;
205  getCursorPosition (&line, &index);
206  updateVisualFillingAttributeField(line, index, begin, end);
207  }
208  else
209  {
210  interaction_state = DEFAULT_STATE;
211  }
212 }
213 
214 //\fixme I DONT KNOW WHY (or WHERE), BUT THE UNDO IS NOT WORKING EVERY TIME!
215 void NCLTextEditor::keyPressEvent(QKeyEvent *event)
216 {
217  //Ctrl + Space == Autocomplete
218  if((event->modifiers() & Qt::ControlModifier) &&
219  (event->key() == Qt::Key_Space))
220  {
221  event->accept();
222  autoCompleteFromAPIs();
223  return;
224  }
225  //Ctrl + Shift + F == format Text
226  if((event->modifiers() & Qt::ControlModifier) &&
227  (event->modifiers() & Qt::ShiftModifier) &&
228  (event->key() == Qt::Key_F))
229  {
230  event->accept();
231  formatText();
232  return;
233  }
234 
235  int begin, end;
236  int line, index;
237  getCursorPosition(&line, &index);
238  int pos, style, size;
239  pos = SendScintilla(SCI_GETCURRENTPOS);
240  size = SendScintilla(SCI_GETTEXTLENGTH);
241 
242  // If I receive a Qt::Key_Backtab
243  // change event to Shift+Tab
244  if(event->key() == Qt::Key_Backtab) {
245  event->accept();
246  event = new QKeyEvent(event->type(), Qt::Key_Tab, Qt::ShiftModifier);
247  }
248 
249  //check zoomin event.
250  //if((event->modifiers() & Qt::ControlModifier) &&
251  // (event->key() == Qt::Key_Plus))
252  if(event->key() == Qt::Key_ZoomIn)
253  {
254  event->accept();
255  Increasefont();
256  return;
257  }
258 
259  //check zoomout event.
260 
261  //if((event->modifiers() & Qt::ControlModifier) &&
262  // (event->key() == Qt::Key_Minus))
263  if(event->key() == Qt::Key_ZoomOut)
264  {
265  event->accept();
266  Decreasefont();
267  return;
268  }
269 
270  if (interaction_state == FILLING_ATTRIBUTES_STATE) {
271  QString strline = text(line);
272  clearIndicatorRange ( line,
273  0,
274  line,
275  strline.size(),
276  filling_attribute_indicator);
277 
278  if(event->key() == Qt::Key_Return){
279  interaction_state = DEFAULT_STATE;
280  setSelection(line, index, line, index);
281  QsciScintilla::keyPressEvent(event);
282  return;
283  }
284 
285  if(event->key() == Qt::Key_Tab){
286  QString strline = text(line);
287  pos = SendScintilla(SCI_GETCURRENTPOS);
288  style = SendScintilla(SCI_GETSTYLEAT, pos);
289  bool error = false;
290 
291  //SHIFT+TAB -> GO TO PREVIOUS ATRIBUTE
292  if(event->modifiers() & Qt::ShiftModifier) {
293  while (pos > 0 ) {
294  style = SendScintilla(SCI_GETSTYLEAT, pos);
295  if(style != QsciLexerNCL::HTMLDoubleQuotedString)
296  break;
297  pos--;
298  }
299 
300  if (pos >= 0)
301  userFillingPreviousAttribute(pos);
302  else
303  error = true;
304 
305  }
306  //JUST TAB -> GO TO NEXT ATTRIBUTE
307  else if(event->modifiers() == Qt::NoModifier) {
308  while (pos < size){
309  style = SendScintilla(SCI_GETSTYLEAT, pos);
310  if(style != QsciLexerNCL::HTMLDoubleQuotedString)
311  break;
312  pos++;
313  }
314 
315  if(pos < size)
316  userFillingNextAttribute(pos);
317  else
318  error = true;
319  }
320 
321  if (error) {
322  clearIndicatorRange( line,
323  0,
324  line,
325  strline.size(),
326  filling_attribute_indicator );
327  interaction_state = DEFAULT_STATE;
328  }
329  return;
330 
331  }
332  else
333  {
334  QsciScintilla::keyPressEvent ( event ) ;
335  getCursorPosition (&line, &index);
336  pos = SendScintilla(SCI_GETCURRENTPOS);
337  style = SendScintilla(SCI_GETSTYLEAT, pos);
338 
339  // Test if pos-1 is also inside the attribute, otherwise it will
340  // treat a text inside the end of previous Quote and the start of
341  // the current one as an attribute
342  if ( style == QsciLexerNCL::HTMLDoubleQuotedString
343  && pos-1 >=0 ) {
344  //TODO: IMPROVE PERFORMANCE
345  recolor();
346  style = SendScintilla(SCI_GETSTYLEAT, pos-1);
347 
348  if(style == QsciLexerNCL::HTMLDoubleQuotedString)
349  {
350  updateVisualFillingAttributeField(line, index, begin, end);
351  return;
352  }
353  }
354 
355  clearIndicatorRange( line,
356  0,
357  line,
358  strline.size(),
359  filling_attribute_indicator);
360 
361  interaction_state = DEFAULT_STATE;
362  }
363  }
364  else
365  {
366  QsciScintilla::keyPressEvent(event);
367  pos = SendScintilla(SCI_GETCURRENTPOS);
368  style = SendScintilla(SCI_GETSTYLEAT, pos);
369 
370  //Test if pos-1 is also inside the attribute, otherwise it will
371  // treat a text inside the end of previous Quote and the start of
372  // the current one as an attribute
373  if (style == QsciLexerNCL::HTMLDoubleQuotedString &&
374  pos-1 >=0 ) {
375  //TODO: IMPROVE PERFORMANCE
376  recolor();
377  style = SendScintilla(SCI_GETSTYLEAT, pos-1);
378 
379  //FIXME: Attribute also can be between Single quotes
380  if (tabBehavior == TAB_BEHAVIOR_NEXT_ATTR &&
381  (style == QsciLexerNCL::HTMLDoubleQuotedString)) {
382 
383  interaction_state = FILLING_ATTRIBUTES_STATE;
384  getCursorPosition (&line, &index);
385 
386  updateVisualFillingAttributeField(line, index, begin, end);
387  }
388  }
389  }
390 }
391 
392 void NCLTextEditor::keyReleaseEvent(QKeyEvent *event)
393 {
394  QsciScintilla::keyReleaseEvent(event);
395 }
396 
397 void NCLTextEditor::AutoCompleteCompleted()
398 {
399  //qDebug() << "NCLTextEditor::AutoCompleteCompleted()";
400 }
401 
402 void NCLTextEditor::MarkLine(int margin, int line, Qt::KeyboardModifiers state)
403 {
404  (void) margin;
405  (void) line;
406  (void) state;
407 }
408 
409 void NCLTextEditor::userFillingNextAttribute(int pos)
410 {
411  int begin, end, style, i = pos;
412  int size = SendScintilla(SCI_GETTEXTLENGTH);
413 
414  interaction_state = FILLING_ATTRIBUTES_STATE;
415 
416  qDebug() << pos;
417 
418  while( i < size ) {
419  style = SendScintilla(SCI_GETSTYLEAT, i);
420  if (style == QsciLexerNCL::HTMLDoubleQuotedString)
421  break;
422  i++;
423  }
424  i++;
425 
426  qDebug() << i;
427 
428  if( i >= size ) {
429  interaction_state = DEFAULT_STATE;
430  return;
431  }
432 
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);
438 }
439 
440 void NCLTextEditor::userFillingPreviousAttribute(int pos)
441 {
442  int begin, end, style;
443  int i = pos-1;
444  interaction_state = FILLING_ATTRIBUTES_STATE;
445 
446  while( i >= 0) {
447  style = SendScintilla(SCI_GETSTYLEAT, i);
448  if (style == QsciLexerHTML::HTMLDoubleQuotedString)
449  break;
450  i--;
451  }
452 
453  if( i < 0) {
454  interaction_state = DEFAULT_STATE;
455  return;
456  }
457 
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);
463 }
464 
465 //FIXME: ESTA INSERINDO UM ESPACO NO FINAL
466 void NCLTextEditor::updateVisualFillingAttributeField( int line,
467  int pos,
468  int &begin,
469  int &end)
470 {
471  QString strline = text(line);
472  begin = pos-1;
473  end = pos;
474  bool inserted_space = false;
475 
476  clearIndicatorRange( line,
477  0,
478  line,
479  strline.size(),
480  filling_attribute_indicator);
481 
482  while( begin >= 0 && strline[begin] != '\"')
483  begin--;
484 
485  if(begin < 0) {
486  interaction_state = DEFAULT_STATE;
487  return;
488  }
489  begin++;
490 
491  while( end < strline.size() && strline[end] != '\"')
492  end++;
493 
494  if(end >= strline.size() || begin == end) {
495  interaction_state = DEFAULT_STATE;
496  return;
497  }
498 
499  if(begin == end)
500  {
501  insert(" ");
502  end++;
503  inserted_space = true;
504  }
505  fillIndicatorRange(line, begin, line, end, filling_attribute_indicator);
506 
507  if(inserted_space) setSelection(line, begin, line, end);
508 }
509 
510 void NCLTextEditor::setTabBehavior(TAB_BEHAVIOR tabBehavior)
511 {
512  this->tabBehavior = tabBehavior;
513 }
514 
515 void NCLTextEditor::formatText()
516 {
517  qDebug() << "NCLTextEditor::formatText()";
518 }
519 
520 void NCLTextEditor::keepFocused()
521 {
522  focusInIgnoringCurrentText = true;
523  this->setFocus();
524  this->SendScintilla(QsciScintilla::SCI_SETFOCUS, true);
525 }
526 
527 void NCLTextEditor::focusOutEvent(QFocusEvent *event)
528 {
529  clearFillingAttributeIndicator();
530 
531  emit focusLosted(event);
532 }
533 
534 void NCLTextEditor::clearFillingAttributeIndicator()
535 {
536  int nr_lines = lines();
537  QString tmp2 = this->text(nr_lines);
538 
539  clearIndicatorRange (0,
540  0,
541  nr_lines,
542  tmp2.size(),
543  filling_attribute_indicator);
544 }
545 
546 void NCLTextEditor::focusInEvent(QFocusEvent *e)
547 {
548 #ifndef NCLEDITOR_STANDALONE
549  if(!focusInIgnoringCurrentText)
550  textWithoutUserInter = text();
551 
552  focusInIgnoringCurrentText = false;
553  this->SendScintilla(QsciScintilla::SCI_SETFOCUS, true);
554 #endif
555 }
556 
557 QString NCLTextEditor::textWithoutUserInteraction()
558 {
559  return textWithoutUserInter;
560 }
561 void NCLTextEditor::setTextWithoutUserInteraction(QString text)
562 {
563  textWithoutUserInter = text;
564 }
565 
566 void NCLTextEditor::setDocumentUrl(QString docURL)
567 {
568  this->docURL = docURL;
569 }
570 
571 QString NCLTextEditor::getDocumentUrl()
572 {
573  return this->docURL;
574 }
575 
576 bool NCLTextEditor::parseDocument(bool recursive)
577 {
578  domDocs.clear();
579  domDoc.clear();
580  // docs.clear();
581  if(!domDoc.setContent(this->text()))
582  {
583  // could not parse the document
584  return false;
585  }
586  // docs.insert("", doc);
587 
588  if(recursive)
589  {
590  domDocs.insert(docURL, domDoc);
591  return parseImportedDocuments(docURL, domDoc, true);
592  }
593  else
594  return true;
595 }
596 
597 bool NCLTextEditor::parseImportedDocuments(QString currentFileURI,
598  QDomDocument &doc, bool recursive)
599 {
600  qDebug() << "parseImportedDocument( " << currentFileURI;
601  QStack <QDomElement> stack;
602  QDomElement current = doc.firstChildElement();
603  bool ret = 1;
604  stack.push(current);
605 
606  while(stack.size())
607  {
608  current = stack.top();
609  stack.pop();
610  qDebug() << current.tagName() << "id = " << current.attribute("id");
611 
612  if(current.tagName() == "importBase" &&
613  current.hasAttribute("documentURI") &&
614  current.hasAttribute("alias"))
615  {
616  QString importedDocumentUri = current.attribute("documentURI");
617  QString fullpath = "";
618 
619  QFileInfo importedFI(importedDocumentUri), currentFI(currentFileURI);
620  if(importedFI.isAbsolute())
621  {
622  fullpath = importedDocumentUri;
623  }
624  else
625  {
626  importedFI.setFile( currentFI.absolutePath() + "/"
627  + importedDocumentUri);
628 
629  if(importedFI.exists())
630  {
631  qDebug() << importedFI.absoluteFilePath();
632  fullpath = importedFI.absoluteFilePath();
633  }
634  }
635 
636  if(fullpath != "")
637  {
638  qDebug() << "I will include the file " << fullpath;
639  QFile file(fullpath);
640  if (file.open(QIODevice::ReadOnly))
641  {
642  QDomDocument currentDomDoc;
643  if (currentDomDoc.setContent(&file))
644  {
645  updateElementsIDWithAlias(currentDomDoc,
646  current.attribute("alias"));
647  if(!parseImportedDocuments(fullpath, currentDomDoc, true))
648  {
649  ret = false;
650  qDebug() << "Could not import " << fullpath;
651  }
652  domDocs.insert(fullpath, currentDomDoc);
653  }
654  }
655  }
656  }
657 
658  QDomElement child = current.firstChildElement();
659  while(!child.isNull())
660  {
661  stack.push_back(child);
662  child = child.nextSiblingElement();
663  }
664  }
665  return ret;
666 }
667 
668 void NCLTextEditor::updateElementsIDWithAlias(QDomDocument doc, QString alias)
669 {
670  QStack <QDomElement> stack;
671  QDomElement current = doc.firstChildElement();
672  stack.push(current);
673  while(stack.size())
674  {
675  current = stack.top();
676  stack.pop();
677  if(current.hasAttribute("id"))
678  {
679  current.setAttribute("id", alias + "#" + current.attribute("id"));
680  }
681 
682  QDomElement child = current.firstChildElement();
683  while(!child.isNull())
684  {
685  stack.push_back(child);
686  child = child.nextSiblingElement();
687  }
688  }
689 }
690 
691 QDomElement NCLTextEditor::elementById(const QDomDocument &domDoc, QString id)
692 {
693  QStack <QDomNode> stack;
694  stack.push_front(domDoc.firstChildElement());
695  while(stack.size())
696  {
697  QDomNode current = stack.front();
698  stack.pop_front();
699  if(current.isElement())
700  {
701  if(current.toElement().attribute("id") == id)
702  return current.toElement();
703  }
704 
705  QDomNode child = current.firstChild();
706  while(!child.isNull())
707  {
708  stack.push_back(child);
709  child = child.nextSibling();
710  }
711  }
712 
713  // The function QDomDocument::elementById will always returns a NULL doc.
714  // That is why we have to reimplement this function.
715  return QDomElement();
716 }
717 
718 QDomElement NCLTextEditor::elementById(QString id, bool recursive)
719 {
720  if(!recursive)
721  return elementById(domDoc, id);
722 
723  QMapIterator<QString, QDomDocument> i(domDocs);
724  while (i.hasNext())
725  {
726  i.next();
727  QDomDocument currentDomDoc = i.value();
728  QDomElement element = elementById(currentDomDoc, id);
729  if(!element.isNull())
730  return element;
731  }
732 
733  return domDoc.elementById(id);
734 }
735 
736 QList <QDomElement> NCLTextEditor::elementsByTagname(const QDomDocument &domDoc,
737  QString tagname)
738 {
739  QDomNodeList elements = domDoc.elementsByTagName(tagname);
740  QList <QDomElement> ret;
741  for(int i = 0; i < elements.length(); i++)
742  {
743  ret.push_back(elements.at(i).toElement());
744  }
745  return ret;
746 }
747 
748 QList <QDomElement> NCLTextEditor::elementsByTagname(QString tagname)
749 {
750  QList <QDomElement> ret;
751  QMapIterator<QString, QDomDocument> i(domDocs);
752  while (i.hasNext())
753  {
754  i.next();
755  ret.append(elementsByTagname(i.value(), tagname));
756  }
757  return ret;
758 }
759 
760 QList <QDomElement> NCLTextEditor::elementsByTagname( QString tagname,
761  QString parentId )
762 {
763  QDomElement current = elementById(parentId);
764  QList <QDomElement> ret;
765 
766  QStack <QDomElement> stack;
767  stack.push(current);
768 
769  bool first = true;
770  while(stack.size())
771  {
772  current = stack.front();
773  stack.pop_front();
774 
775  QDomElement node = current.toElement();
776  if(node.tagName() == tagname)
777  ret.push_back(node);
778 
779  if(first || !NCLStructure::getInstance()->defineScope(node.tagName()))
780  {
781  first = false;
782  QDomElement child = current.firstChildElement();
783  while(!child.isNull())
784  {
785  // \todo We must not continue if the current element define a scope
786  stack.push_back(child);
787  child = child.nextSiblingElement();
788  }
789  }
790  }
791 
792  return ret;
793 }
794 
795 /*
796 bool NCLTextEditor::canInsertFromMimeData(const QMimeData *source) const
797 {
798  if(!QsciScintillaBase::canInsertFromMimeData(source))
799  {
800  foreach(QUrl url, source->urls())
801  if (QFileInfo(url.toLocalFile()).exists())
802  {
803  return true;
804  }
805  }
806 }
807 
808 // Create text from a MIME data object.
809 QByteArray NCLTextEditor::fromMimeData(const QMimeData *source, bool &rectangular) const
810 {
811  QByteArray array = QsciScintillaBase::fromMimeData(source, rectangular);
812  if(!array.size())
813  {
814  rectangular = false;
815  QString media = "<media src=\"";
816  media += source->urls().at(0).toString();
817  media += "\"></media>";
818  return media.toAscii();
819  }
820 }
821 
822 void NCLTextEditor::dropEvent(QDropEvent *event)
823 {
824  foreach(QUrl url, event->mimeData()->urls())
825  {
826  QString filename = url.toLocalFile();
827  event->acceptProposedAction();
828  QString media = "<media src=\"";
829  media += filename;
830  media += "\">\n</media>";
831  insert(media);
832  }
833 }*/