TikzEditor::TikzEditor(QWidget *parent) : QPlainTextEdit(parent) { m_showWhiteSpaces = true; m_showTabulators = true; m_showMatchingBrackets = true; m_whiteSpacesColor = Qt::gray; m_tabulatorsColor = Qt::gray; m_matchingColor = Qt::yellow; m_highlightCurrentLineColor = Qt::yellow;; m_completer = 0; // setLineWidth(0); // setFrameShape(QFrame::NoFrame); const QColor lineColor(QApplication::style()->standardPalette().color(QPalette::Normal, QPalette::Base)); const QColor altLineColor(QApplication::style()->standardPalette().color(QPalette::Normal, QPalette::AlternateBase)); // if (lineColor == altLineColor) // m_highlightCurrentLineColor = lineColor.darker(105); // else // m_highlightCurrentLineColor = altLineColor; connect(this, SIGNAL(cursorPositionChanged()), this, SLOT(highlightCurrentLine())); highlightCurrentLine(); connect(this, SIGNAL(cursorPositionChanged()), this, SLOT(showCursorPosition())); connect(this, SIGNAL(cursorPositionChanged()), this, SLOT(matchBrackets())); }
/* Adapted from OSC-pattern-match.c, by Matt Wright Adapted from oscpattern.c, by Matt Wright and Amar Chaudhury */ bool OscPattern::match(const char * pattern, const char * test) { // theWholePattern = pattern; if (pattern == 0 || pattern[0] == 0) { return test[0] == 0; } if (test[0] == 0) { if (pattern[0] == '*') return match(pattern+1,test); else return false; } switch (pattern[0]) { case 0: return test[0] == 0; case '?': return match(pattern + 1, test + 1); case '*': if (match(pattern+1, test)) return true; else return match(pattern, test+1); case ']': case '}': // OSCWarning("Spurious %c in pattern \".../%s/...\"",pattern[0], theWholePattern); return false; case '[': return matchBrackets (pattern,test); case '{': return matchList (pattern,test); case '\\': if (pattern[1] == 0) return test[0] == 0; else { if (pattern[1] == test[0]) return match(pattern+2,test+1); else return false; } default: if (pattern[0] == test[0]) return match(pattern+1,test+1); else return false; } }
bf_command* ParseBF(const char* file, int* num, int* read, int* error){ /* Our own counters */ int prse_error = 0, prse_read = 0, prse_num = 0; /* Loading the file */ FILE* fp = fopen(file, "r"); if (!fp) { printf("Parse error: could not read file.\n"); return NULL; } /* Initializations */ bf_command* prgm = NULL; bf_command* tmp; int end = 0, halt = 0; int current = -1; char c = getc(fp); char last = 'A'; while (!end && !halt) { switch (c) { case EOF: end = 1; break; case '+': prse_read++; if (last == c) { prgm[current].val++; } else { tmp = realloc(prgm, (prse_num + 1) * sizeof(bf_command)); if (!tmp) { printf("Parser error! Ran out of memory at command %d.\n", prse_num); prse_error = PARSE_MEMORY; prgm[current].type = bf_end; halt = 1; } else { prgm = tmp; prse_num++; current = prse_num - 1; prgm[current].type = bf_add; prgm[current].val = 1; } } last = c; break; case '-': prse_read++; if (last == c) { prgm[current].val++; } else { tmp = realloc(prgm, (prse_num + 1) * sizeof(bf_command)); if (!tmp) { printf("Parser error! Ran out of memory at command %d.\n", prse_num); prse_error = PARSE_MEMORY; prgm[current].type = bf_end; halt = 1; } else { prgm = tmp; prse_num++; current = prse_num - 1; prgm[current].type = bf_subtract; prgm[current].val = 1; } } last = c; break; case '>': prse_read++; if (last == c) { prgm[current].val++; } else { tmp = realloc(prgm, (prse_num + 1) * sizeof(bf_command)); if (!tmp) { printf("Parser error! Ran out of memory at command %d.\n", prse_num); prse_error = PARSE_MEMORY; prgm[current].type = bf_end; halt = 1; } else { prgm = tmp; prse_num++; current = prse_num - 1; prgm[current].type = bf_right; prgm[current].val = 1; } } last = c; break; case '<': prse_read++; if (last == c) { prgm[current].val++; } else { tmp = realloc(prgm, (prse_num + 1) * sizeof(bf_command)); if (!tmp) { printf("Parser error! Ran out of memory at command %d.\n", prse_num); prse_error = PARSE_MEMORY; prgm[current].type = bf_end; halt = 1; } else { prgm = tmp; prse_num++; current = prse_num - 1; prgm[current].type = bf_left; prgm[current].val = 1; } } last = c; break; case ',': prse_read++; tmp = realloc(prgm, (prse_num + 1) * sizeof(bf_command)); if (!tmp) { printf("Parser error! Ran out of memory at command %d.\n", prse_num); prse_error = PARSE_MEMORY; prgm[current].type = bf_end; halt = 1; } else { prgm = tmp; prse_num++; current = prse_num - 1; prgm[current].type = bf_input; prgm[current].val = -1; } last = c; break; case '.': prse_read++; tmp = realloc(prgm, (prse_num + 1) * sizeof(bf_command)); if (!tmp) { printf("Parser error! Ran out of memory at command %d.\n", prse_num); prse_error = PARSE_MEMORY; prgm[current].type = bf_end; halt = 1; } else { prgm = tmp; prse_num++; current = prse_num - 1; prgm[current].type = bf_output; prgm[current].val = -1; } last = c; break; case '[': prse_read++; tmp = realloc(prgm, (prse_num + 1) * sizeof(bf_command)); if (!tmp) { printf("Parser error! Ran out of memory at command %d.\n", prse_num); prse_error = PARSE_MEMORY; prgm[current].type = bf_end; halt = 1; } else { prgm = tmp; prse_num++; current = prse_num - 1; prgm[current].type = bf_open; prgm[current].val = -1; } last = c; break; case ']': prse_read++; tmp = realloc(prgm, (prse_num + 1) * sizeof(bf_command)); if (!tmp) { printf("Parser error! Ran out of memory at command %d.\n", prse_num); prse_error = PARSE_MEMORY; prgm[current].type = bf_end; halt = 1; } else { prgm = tmp; prse_num++; current = prse_num - 1; prgm[current].type = bf_close; prgm[current].val = -1; } last = c; break; case '~': tmp = realloc(prgm, (prse_num + 1) * sizeof(bf_command)); if (!tmp) { printf("Parser error! Ran out of memory at command %d.\n", prse_num); prse_error = PARSE_MEMORY; prgm[current].type = bf_end; halt = 1; } else { prgm = tmp; prse_num++; current = prse_num - 1; prgm[current].type = bf_debug; prgm[current].val = -1; } last = c; break; default: break; } c = getc(fp); } if (!halt) { tmp = realloc(prgm, (prse_num + 1) * sizeof(bf_command)); if (!tmp) { printf("Parser error! Ran out of memory at command %d.\n", prse_num); prse_error = PARSE_MEMORY; prgm[current].type = bf_end; halt = 1; } else { prgm = tmp; prse_num++; current = prse_num - 1; prgm[current].type = bf_end; prgm[current].val = 1; } } prse_error |= matchBrackets(prgm); if (read) { *read = prse_read; } if (num) { *num = prse_num; } if (error) { *error = prse_error; } return prgm; }
void TikzEditor::keyPressEvent(QKeyEvent *event) { const Qt::KeyboardModifiers modifier = QApplication::keyboardModifiers(); /* completer */ if (m_completer && m_completer->popup()->isVisible()) { // the following keys are forwarded by the completer to the widget switch (event->key()) { case Qt::Key_Enter: case Qt::Key_Return: case Qt::Key_Escape: case Qt::Key_Tab: case Qt::Key_Backtab: event->ignore(); return; } } /* scroll viewport when Ctrl+Up and Ctrl+Down are pressed */ if (event->modifiers() == Qt::ControlModifier && event->key() == Qt::Key_Up) { const int dy = -1 + verticalScrollBar()->value(); verticalScrollBar()->setValue(dy); } else if (event->modifiers() == Qt::ControlModifier && event->key() == Qt::Key_Down) { const int dy = 1 + verticalScrollBar()->value(); verticalScrollBar()->setValue(dy); } /* ensure that PageUp and PageDown keep the cursor at the same visible place */ /* else if (event->key() == Qt::Key_PageUp || event->key() == Qt::Key_PageDown) { const QTextCursor::MoveOperation moveOperation = (event->key() == Qt::Key_PageUp) ? QTextCursor::Up : QTextCursor::Down; QTextCursor cursor = textCursor(); const QFontMetrics fontMetrics(document()->defaultFont()); const int repeat = viewport()->height() / fontMetrics.lineSpacing() - 1; const int oldPosition = cursorRect().top(); if (modifier & Qt::ShiftModifier) cursor.movePosition(moveOperation, QTextCursor::KeepAnchor, repeat); else cursor.movePosition(moveOperation, QTextCursor::MoveAnchor, repeat); setTextCursor(cursor); const int newPosition = verticalScrollBar()->value() + cursorRect().top() - oldPosition; verticalScrollBar()->setValue(newPosition); ensureCursorVisible(); } */ /* the first time End is pressed moves the cursor to the end of the line, the second time to the end of the block */ else if (event->key() == Qt::Key_Home && !(modifier & Qt::ControlModifier) && !(modifier & Qt::ShiftModifier)) { QTextCursor cursor = textCursor(); const int oldPosition = cursor.position(); cursor.movePosition(QTextCursor::StartOfLine); if (cursor.position() == oldPosition) cursor.movePosition(QTextCursor::StartOfBlock); setTextCursor(cursor); ensureCursorVisible(); } else if (event->key() == Qt::Key_End && !(modifier & Qt::ControlModifier) && !(modifier & Qt::ShiftModifier)) { QTextCursor cursor = textCursor(); const int oldPosition = cursor.position(); cursor.movePosition(QTextCursor::EndOfLine); if (cursor.position() == oldPosition) cursor.movePosition(QTextCursor::EndOfBlock); setTextCursor(cursor); ensureCursorVisible(); } /* keys that change the content without moving the cursor may alter the brackets too */ else if (event->key() == Qt::Key_Delete || (event->key() == Qt::Key_Z && (modifier & Qt::ControlModifier))) { QPlainTextEdit::keyPressEvent(event); highlightCurrentLine(); matchBrackets(); // calculate new bracket highlighting } /* go to next argument in text inserted with code completion */ else if (event->key() == Qt::Key_Tab || event->key() == Qt::Key_Backtab) { QTextCursor cursor = textCursor(); QTextBlock block = cursor.block(); QTextDocument::FindFlags flags = 0; if (event->key() == Qt::Key_Backtab) flags = QTextDocument::FindBackward; if (block.isValid() && block.text().contains(s_completionPlaceHolder)) { cursor = document()->find(s_completionPlaceHolder, cursor, flags); if (!cursor.isNull()) setTextCursor(cursor); else QPlainTextEdit::keyPressEvent(event); } else QPlainTextEdit::keyPressEvent(event); } else QPlainTextEdit::keyPressEvent(event); /* completer */ if (m_completer) { // const QString endOfWord("~!@#$%^&*()_+{}|:\"<>?,./;'[]-= "); const QString completionPrefix = textUnderCursor(); if ((event->modifiers() & (Qt::ControlModifier | Qt::AltModifier)) || (event->text().isEmpty() && event->key() != Qt::Key_AltGr) || completionPrefix.length() < 3) // || endOfWord.contains(event->text().right(1))) { m_completer->popup()->hide(); } else { if (completionPrefix != m_completer->completionPrefix()) { m_completer->setCompletionPrefix(completionPrefix); m_completer->popup()->setCurrentIndex(m_completer->completionModel()->index(0, 0)); } if (m_completer->completionPrefix() != m_completer->currentCompletion()) // || m_completer->completionCount() > 1) { QTextCursor cursor = textCursor(); // cursor.movePosition(QTextCursor::StartOfWord); cursor.movePosition(QTextCursor::Left, QTextCursor::MoveAnchor, m_completer->completionPrefix().length()); QRect rect = cursorRect(cursor); rect.translate(5, 5); rect.setWidth(m_completer->popup()->sizeHintForColumn(0) + m_completer->popup()->verticalScrollBar()->sizeHint().width()); m_completer->complete(rect); // show popup } else m_completer->popup()->hide(); } } }