46 #include <QMouseEvent> 48 #include <QApplication> 49 #include <QTextDocumentFragment> 51 #include <QTextCursor> 54 #include <QStringListModel> 60 milxQtPythonConsole::milxQtPythonConsole(QWidget* parent,
const PythonQtObjectPtr& context, Qt::WindowFlags windowFlags)
64 setWindowFlags(windowFlags);
66 _defaultTextCharacterFormat = currentCharFormat();
71 _completer =
new QCompleter(
this);
72 _completer->setWidget(
this);
73 QObject::connect(_completer, SIGNAL(activated(
const QString&)),
74 this, SLOT(insertCompletion(
const QString&)));
77 consoleMessage(
"milxQt Python Console\nMain window is 'MainWindow' and displayed windows are 'rnd_<name>', 'img_<name>' and 'mdl_<name>'\nFile IO can be done using 'milxQtFile'.");
78 appendCommandPrompt();
93 while ((idx = _stdOut.indexOf(
'\n'))!=-1)
95 consoleMessage(_stdOut.left(idx));
97 _stdOut = _stdOut.mid(idx+1);
106 while ((idx = _stdErr.indexOf(
'\n'))!=-1)
108 consoleMessage(_stdErr.left(idx));
110 _stdErr = _stdErr.mid(idx+1);
116 if (!_stdOut.isEmpty())
120 if (!_stdErr.isEmpty())
128 milxQtPythonConsole::~milxQtPythonConsole()
141 appendCommandPrompt();
148 QTextCursor textCursor = this->textCursor();
149 textCursor.movePosition(QTextCursor::End);
153 textCursor.setPosition(commandPromptPosition());
154 textCursor.movePosition(QTextCursor::End, QTextCursor::KeepAnchor);
155 QString code = textCursor.selectedText();
158 if (code.endsWith(
" "))
160 code.truncate(code.length()-1);
167 _historyPosition = _history.count();
168 _currentMultiLineCode += code +
"\n";
172 executeCode(_currentMultiLineCode);
173 _currentMultiLineCode =
"";
177 appendCommandPrompt(storeOnly);
181 void milxQtPythonConsole::executeCode(
const QString& code)
184 QTextCursor cursor = QTextEdit::textCursor();
185 cursor.movePosition(QTextCursor::End);
186 setTextCursor(cursor);
194 PyObject* dict = NULL;
195 if (PyModule_Check(_context))
197 dict = PyModule_GetDict(_context);
199 else if (PyDict_Check(_context))
205 p.setNewRef(PyRun_String(code.toLatin1().data(), Py_single_input, dict, dict));
210 PythonQt::self()->handleError();
231 _commandPrompt =
"...> ";
235 _commandPrompt =
">>> ";
237 append(_commandPrompt);
239 QTextCursor cursor = textCursor();
240 cursor.movePosition(QTextCursor::End);
241 setTextCursor(cursor);
251 QTextCharFormat charFormat(_defaultTextCharacterFormat);
253 QFont font(charFormat.font());
255 charFormat.setFont(font);
257 QBrush brush(charFormat.foreground());
258 brush.setColor(color);
259 charFormat.setForeground(brush);
261 setCurrentCharFormat(charFormat);
271 QTextCursor textCursor(this->textCursor());
272 textCursor.movePosition(QTextCursor::End);
274 return textCursor.block().position() + _commandPrompt.length();
281 void milxQtPythonConsole::insertCompletion(
const QString& completion)
283 QTextCursor tc = textCursor();
284 tc.movePosition(QTextCursor::Left, QTextCursor::KeepAnchor);
285 if (tc.selectedText()==
".")
287 tc.insertText(QString(
".") + completion);
292 tc.movePosition(QTextCursor::StartOfWord, QTextCursor::MoveAnchor);
293 tc.movePosition(QTextCursor::EndOfWord, QTextCursor::KeepAnchor);
294 tc.insertText(completion);
302 QTextCursor textCursor = this->textCursor();
303 int pos = textCursor.position();
304 textCursor.setPosition(commandPromptPosition());
305 textCursor.movePosition(QTextCursor::End, QTextCursor::KeepAnchor);
306 int startPos = textCursor.selectionStart();
308 int offset = pos-startPos;
309 QString text = textCursor.selectedText();
311 QString textToComplete;
315 QChar c = text.at(cur);
316 if (c.isLetterOrNumber() || c ==
'.' || c ==
'_')
318 textToComplete.prepend(c);
328 QString compareText = textToComplete;
329 int dot = compareText.lastIndexOf(
'.');
332 lookup = compareText.mid(0, dot);
333 compareText = compareText.mid(dot+1, offset);
335 if (!lookup.isEmpty() || !compareText.isEmpty())
337 compareText = compareText.toLower();
339 QStringList l = PythonQt::self()->introspection(_context, lookup, PythonQt::Anything);
340 foreach (QString n, l)
342 if (n.toLower().startsWith(compareText))
348 if (!found.isEmpty())
350 _completer->setCompletionPrefix(compareText);
351 _completer->setCompletionMode(QCompleter::PopupCompletion);
352 _completer->setModel(
new QStringListModel(found, _completer));
353 _completer->setCaseSensitivity(Qt::CaseInsensitive);
354 QTextCursor c = this->textCursor();
355 c.movePosition(QTextCursor::StartOfWord);
356 QRect cr = cursorRect(c);
357 cr.setWidth(_completer->popup()->sizeHintForColumn(0)
358 + _completer->popup()->verticalScrollBar()->sizeHint().width());
360 _completer->complete(cr);
364 _completer->popup()->hide();
369 _completer->popup()->hide();
376 if (_completer && _completer->popup()->isVisible())
379 switch (event->key())
382 if (!_completer->popup()->currentIndex().isValid())
384 insertCompletion(_completer->currentCompletion());
385 _completer->popup()->hide();
394 case Qt::Key_Backtab:
402 bool eventHandled =
false;
403 QTextCursor textCursor = this->textCursor();
405 int key =
event->key();
414 if (textCursor.position() <= commandPromptPosition())
417 QApplication::beep();
425 if (_historyPosition>0)
437 if (_historyPosition+1<_history.count())
448 executeLine(event->modifiers() & Qt::ShiftModifier);
452 case Qt::Key_Backspace:
454 if (textCursor.hasSelection())
469 if (textCursor.position() <= commandPromptPosition())
472 QApplication::beep();
486 if (key >= Qt::Key_Space && key <= Qt::Key_division)
489 if (textCursor.hasSelection() && !verifySelectionBeforeDeletion())
503 int commandPromptPosition = this->commandPromptPosition();
504 if (textCursor.position() < commandPromptPosition)
507 textCursor.setPosition(commandPromptPosition);
508 setTextCursor(textCursor);
517 _completer->popup()->hide();
524 QTextEdit::keyPressEvent(event);
525 QString text =
event->text();
528 handleTabCompletion();
532 _completer->popup()->hide();
545 bool deletionAllowed = verifySelectionBeforeDeletion();
559 bool deletionAllowed =
true;
562 QTextCursor textCursor = this->textCursor();
564 int commandPromptPosition = this->commandPromptPosition();
565 int selectionStart = textCursor.selectionStart();
566 int selectionEnd = textCursor.selectionEnd();
568 if (textCursor.hasSelection())
576 if (selectionStart < commandPromptPosition ||
577 selectionEnd < commandPromptPosition)
581 if (selectionStart > selectionEnd)
583 int tmp = selectionEnd;
584 selectionEnd = selectionStart;
585 selectionStart = tmp;
588 if (selectionEnd < commandPromptPosition)
593 QApplication::beep();
594 deletionAllowed =
false;
602 selectionStart = commandPromptPosition;
603 textCursor.setPosition(selectionStart);
604 textCursor.setPosition(selectionStart, QTextCursor::KeepAnchor);
605 setTextCursor(textCursor);
615 if (textCursor.position() < commandPromptPosition)
618 QApplication::beep();
619 deletionAllowed =
false;
623 return deletionAllowed;
634 QTextCursor textCursor = this->textCursor();
635 textCursor.movePosition(QTextCursor::End);
636 textCursor.setPosition(commandPromptPosition(), QTextCursor::KeepAnchor);
639 textCursor.insertText(_history.value(_historyPosition));
641 textCursor.movePosition(QTextCursor::End);
642 setTextCursor(textCursor);
647 QSettings settings(
"Shekhar Chandra",
"milxQt");
649 settings.beginGroup(
"Python");
650 _history = settings.value(
"history").toStringList();
651 _historyPosition = _history.size();
658 const int maxHistorySize = 100;
660 QSettings settings(
"Shekhar Chandra",
"milxQt");
662 settings.beginGroup(
"Python");
664 QStringList savedHistory = settings.value(
"history").toStringList();
665 savedHistory.removeDuplicates();
666 _history.removeDuplicates();
667 savedHistory << _history;
668 for(
int j = 0; j < savedHistory.size()-maxHistorySize; j ++)
669 savedHistory.removeFirst();
670 settings.setValue(
"history", savedHistory);
680 insertPlainText(message);
683 setCurrentCharFormat(_defaultTextCharacterFormat);
688 copyAct =
new QAction(
this);
689 copyAct->setIcon(QIcon(
":/resources/toolbar/copy.png"));
690 copyAct->setText(QApplication::translate(
"Console",
"Copy", 0, QApplication::UnicodeUTF8));
691 copyAct->setShortcut(tr(
"Ctrl+c"));
693 cutAct =
new QAction(
this);
694 cutAct->setIcon(QIcon(
":/resources/toolbar/cut.png"));
695 cutAct->setText(QApplication::translate(
"Console",
"Cut", 0, QApplication::UnicodeUTF8));
696 cutAct->setShortcut(tr(
"Ctrl+x"));
698 pasteAct =
new QAction(
this);
699 pasteAct->setIcon(QIcon(
":/resources/toolbar/paste.png"));
700 pasteAct->setText(QApplication::translate(
"Console",
"Paste", 0, QApplication::UnicodeUTF8));
701 pasteAct->setShortcut(tr(
"Ctrl+v"));
703 clearAct =
new QAction(
this);
704 clearAct->setText(QApplication::translate(
"Console",
"Clear", 0, QApplication::UnicodeUTF8));
705 clearAct->setShortcut(tr(
"F5"));
711 connect(copyAct, SIGNAL(triggered()),
this, SLOT(copy()));
712 connect(cutAct, SIGNAL(triggered()),
this, SLOT(cut()));
713 connect(pasteAct, SIGNAL(triggered()),
this, SLOT(paste()));
714 connect(clearAct, SIGNAL(triggered()),
this, SLOT(clear()));
716 connect(PythonQt::self(), SIGNAL(pythonStdOut(
const QString&)),
this, SLOT(stdOut(
const QString&)));
717 connect(PythonQt::self(), SIGNAL(pythonStdErr(
const QString&)),
this, SLOT(stdErr(
const QString&)));
722 QMenu* contextMenu =
new QMenu(
this);
724 contextMenu->addAction(copyAct);
725 contextMenu->addAction(cutAct);
726 contextMenu->addAction(pasteAct);
727 contextMenu->addSeparator();
728 contextMenu->addAction(clearAct);
730 contextMenu->exec(currentEvent->globalPos());
void executeLine(bool storeOnly)
execute current line
void stdErr(const QString &s)
output redirection
bool verifySelectionBeforeDeletion()
void stdOut(const QString &s)
output redirection
void consoleMessage(const QString &message)
output from console
void appendCommandPrompt(bool storeOnly=false)
Appends a newline and command prompt at the end of the document.
void keyPressEvent(QKeyEvent *e)
derived key press event
void clear()
clear the console
void contextMenuEvent(QContextMenuEvent *currentEvent)
context menu
void writeSettings()
Write settings (mainly history)
void handleTabCompletion()
handle the pressing of tab
void setCurrentFont(const QColor &color=QColor(0, 0, 0), bool bold=false)
Sets the current font.
void createActions()
Create all the actions for the console.
void createConnections()
Create connections for the console.
void changeHistory()
change the history according to _historyPos
virtual void cut()
overridden to control which characters a user may delete
void flushStdOut()
flush output that was not yet printed
int commandPromptPosition()
Returns the position of the command prompt.
void readSettings()
Read settings (mainly history)