PDA

View Full Version : QTextEdit with QCompleter



No-Nonsense
20th February 2007, 15:04
I am developing a simple code editor for a language that mainly constists of assignments in the form:
key=value

I already archived syntax highlighting using a custom QSyntaxHighlighter. Now I want to add simple auto completion using QCompleter as shown in the Qt example "Custom Completer Example" that comes with Qt 4.2.

I got this to work but I still have three questions:

1. Could somebody please explain me the following marked lines of code from the textedit.cpp example file?


void TextEdit::keyPressEvent(QKeyEvent *e)
{
if (c && c->popup()->isVisible()) {
// The following keys are forwarded by the completer to the widget
switch (e->key()) {
case Qt::Key_Enter:
case Qt::Key_Return:
case Qt::Key_Escape:
case Qt::Key_Tab:
case Qt::Key_Backtab:
e->ignore();
return; // let the completer do default behavior
default:
break;
}
}

When the completer popup is visible the above keys are forwarded to the completer (by ignoring them in the text edit)?



bool isShortcut = ((e->modifiers() & Qt::ControlModifier) && e->key() == Qt::Key_E); // CTRL+E
if (!c || !isShortcut) // dont process the shortcut when we have a completer
QTextEdit::keyPressEvent(e);

The comment is somewhat misleading!? If there is no completer installed or the shortcut was not triggered by the key event then they let the original QTextEdit event handlder handle the event?



const bool ctrlOrShift = e->modifiers() & (Qt::ControlModifier | Qt::ShiftModifier);
if (!c || (ctrlOrShift && e->text().isEmpty()))
return;

Hmm? What is ctrlOrShift needed for? What do they do here?



static QString eow("~!@#$%^&*()_+{}|:\"<>?,./;'[]\\-="); // end of word
bool hasModifier = (e->modifiers() != Qt::NoModifier) && !ctrlOrShift;
QString completionPrefix = textUnderCursor();

What is hasModifier needed for?



if (!isShortcut && (hasModifier || e->text().isEmpty()|| completionPrefix.length() < 3
|| eow.contains(e->text().right(1)))) {
c->popup()->hide();
return;
}

Hide the popup is the completion length is fallen below or the key is contained inside the end-of-word string (for my problem this would only contain "="?). Why are they looking at hasModifier and e->text().isEmpty()?



if (completionPrefix != c->completionPrefix()) {
c->setCompletionPrefix(completionPrefix);
c->popup()->setCurrentIndex(c->completionModel()->index(0, 0));
}
QRect cr = cursorRect();
cr.setWidth(c->popup()->sizeHintForColumn(0)
+ c->popup()->verticalScrollBar()->sizeHint().width());
c->complete(cr); // popup it up!
}

Initialize the completer with the current completionPrefix and show it at the position cr (the cursor position?).

2. The key sequence to pop up the completer is hardcoded in the example. How would I implement a configurable key sequence? I found QKeySequence, but no way to match it in the keyEvent. The QKeyEvent itself can only match against standard sequences defined by Qt.

3. I would like to add completion based on the key string (context). How would I implement this? The Trolls mention QSyntaxHighlighter::setCurrentBlockUserData as a way to do parenthesis matching and highlighting without giving a full example. I think I could use this technique to store the key/context while highlighting and use this information when showing the completer? How would I do this? Are there examples on how to do this (must not be completion, maybe parenthesis matching/highlighting)?

Thanks in advance,
-Jens

No-Nonsense
20th February 2007, 15:48
And another question reguarding the Custom Completer Example:

I type at least three letters to have the completer pop up (e.g. add) then I enter a point that will hide the completer as wished. I enter some charater and delete it until the point. The completer will now pop up again giving me hints that do not make sense as I already typed the point (end of word char). If I select one of the hints that is longer than "add." it will complete "add.ing".

I assume I would have to do some changes to QString TextEdit::textUnderCursor() const to return only the chars after an end of word char?
Or can I set the completer to be strict and not to show hints when the completionPrefix does not match any string? (This happens also with other chatrs like =, ?, ...)

-Jens