Selecting non-alpha chars with QTextCursor - qt

I'm trying to add syntax completion to a QTextEdit base editor and I'd like to support non-alpha characters to trigger the QCompleter popup. I'm using QTextCursor::select to get the current word but it is always filtering out non-alpha characters. Is there an option I need to use for this ?
Here's the code I use to get the text:
QTextCursor tc = textCursor();
tc.select(QTextCursor::WordUnderCursor);
QString t = tc.selectedText();
thanks

Words actually do not contain alpha characters. To select the last input character:
QTextCursor tc = textCursor();
tc.movePosition ( QTextCursor::Left, QTextCursor::KeepAnchor);
QChar lastChar = tc.selectedText().at(0);
if (!lastChar.isLetterOrNumber())
{
do something;
}
Replace the isLetterOrNumber() with whatever characters you might check for.

Related

JavaFX: Select a single line of text in a textarea where .getCaretPosition()

Platform: Intellij IDEA
Language: JavaFX
I would like to be able to select a line of text where the cursor lies. Similar to SQL Developer, I have a textarea that allows multiples lines of input or queries. It is nice to be able to use the textarea as a query bank while testing queries.
Using the txtOutput.getCaretPosition(), I would like to get the current integer index of the line where the cursor resides and then be able to select all of the text that is within that same line with the same keyboard shortcut as SQL Developer (Ctrl + Enter). Using the .selectForward() or .selectBackward() will not work if there are multiple lines.
Any help or suggestions as to how to limit the selection of text to one line or select text up until a specific character (e.g. ";") would be much appreciated.
public void executeEvent(KeyEvent event) {
//int cursorLine = txtInput.getCaretPosition();
if (event.isControlDown() == true && event.getCode() == KeyCode.ENTER) {
//select line of text where integer equals cursorLine
//txtInput.selectBackward();
//txtInput.selectForward();
}
}
Just search the text for the relevant delimiting character (e.g. a newline character), and select the relevant portion. The only thing you have to be careful of here is if the user selects the last line, in which case there will be subsequent newline character:
int caretPos = txtInput.getCaretPosition();
int previousNewline = txtInput.getText().lastIndexOf('\n', caretPos);
int nextNewline = txtInput.getText().indexOf('\n', caretPos);
if (nextNewline == -1) nextNewline = txtInput.getText().length();
txtInput.selectRange(previousNewLine + 1, nextNewLine);

Getting char value from ComboBox in JavaFX

I need to get the selected value in a combobox as of a data type char. I know how to get the selected item it's the conversion which I've got stuck on. Any suggestions?
This is the combobox and it content:
idCharCombo = new ComboBox<>();
idCharCombo.getItems().addAll("A","B","G","H","L","M","P","Z");
Now i will be using this data in a method which passes an int and a char (bellow is the use of the method where the second element is still an object rather than a char):
if (checkStaffMemberById(Integer.parseInt(idNoTxtFld.getText()), idCharCombo.getValue()) == true){
AlertBox.display("ID Validation", "ERROR! ID Already Exists.");
hope i arranged adequately
Since your combo box appears to only hold single-character strings, and you want to treat them as chars, the most obvious thing to do is to use a ComboBox<Character> instead of a ComboBox<String>. I.e. replace your declaration, which presumably looks like
ComboBox<String> idCharCombo ;
with
ComboBox<Character> idCharCombo ;
and then you can do
idCharCombo.getItems().addAll('A','B','G','H','L','M','P','Z');
Then
idCharCombo.getValue()
will return a Character which will be autounboxed to a char as needed, so your method call
checkStaffMemberById(Integer.parseInt(idNoTxtFld.getText()), idCharCombo.getValue())
should work as-is.

Remove parentheses in QString

I have a QString containing "(M001)" and I want to remove the parentheses in text. The result should be "M001". How should I use a QRegExp for this?
I see two possible way to do it:
1.Using QString::remove() like this:
str.remove("(");
str.remove(")");
2.Using QRegExp class like this:
str.remove(QRegExp("[()]"));
In both of variants I get "M001" string.
Of course, there are some restrictions: all parentheses will be removed.But seems like it's what you want, don't you?
If you know your string always has parenthesis, you could just do something like:
str = str.mid(1); // Remove first character
str.chop(1); // Remove last character
Otherwise you could also do this instead of using a regular expression:
if (str.startsWith('(') && str.endsWith(')')) {
str = str.mid(1); // Remove first character
str.chop(1); // Remove last character
}
But if you insist using a QRegExp, try this:
str.remove(QRegExp("^\\(|\\)$"));
or this:
str.replace(QRegExp("^\\((.*)\\)$"), "\\1");
EDIT: If you want to remove ALL parenthesis from the string you can try:
str.remove('(').remove(')');
or
str.remove(QRegExp("[()]"));

QRegExp: individual quantifiers can't be non-greedy, but what good alternatives then?

I'm trying to write code that appends ending _my_ending to the filename, and does not change file extension.
Examples of what I need to get:
"test.bmp" -> "test_my_ending.bmp"
"test.foo.bar.bmp" -> "test.foo.bar_my_ending.bmp"
"test" -> "test_my_ending"
I have some experience in PCRE, and that's trivial task using it. Because of the lack of experience in Qt, initially I wrote the following code:
QString new_string = old_string.replace(
QRegExp("^(.+?)(\\.[^.]+)?$"),
"\\1_my_ending\\2"
);
This code does not work (no match at all), and then I found in the docs that
Non-greedy matching cannot be applied to individual quantifiers, but can be applied to all the quantifiers in the pattern
As you see, in my regexp I tried to reduce greediness of the first quantifier + by adding ? after it. This isn't supported in QRegExp.
This is really disappointing for me, and so, I have to write the following ugly but working code:
//-- write regexp that matches only filenames with extension
QRegExp r = QRegExp("^(.+)(\\.[^.]+)$");
r.setMinimal(true);
QString new_string;
if (old_string.contains(r)){
//-- filename contains extension, so, insert ending just before it
new_string = old_string.replace(r, "\\1_my_ending\\2");
} else {
//-- filename does not contain extension, so, just append ending
new_string = old_string + time_add;
}
But is there some better solution? I like Qt, but some things that I see in it seem to be discouraging.
How about using QFileInfo? This is shorter than your 'ugly' code:
QFileInfo fi(old_string);
QString new_string = fi.completeBaseName() + "_my_ending"
+ (fi.suffix().isEmpty() ? "" : ".") + fi.suffix();

removing whitespaces from a QRegExpValidator

I have a code someone wrote and there
this->llBankCode = new widgetLineEditWithLabel(tr("Bankleitzahl"), "", Qt::AlignTop, this);
QRegExpValidator *validatorBLZ = new QRegExpValidator(this);
validatorBLZ->setRegExp(QRegExp( "[0-9]*", Qt::CaseSensitive));
this->llBankCode->lineEdit->setValidator(validatorBLZ);
as it can be seen from this code, is that validatorBLZ can accept only numbers between 0 and 9. I would like to change it, that validatorBLZ would be able to get as an input whitespace as well (but not to start with a whitespace), but it wont be shown.
Example:
if i try to copy & paste a string of the format '22 34 44', the result would be an empty field. What i would like to happen is that the string '22 34 44' will be shown in the field as '223444'.
How could i do it?
You could try using:
QString string = "22 34 44";
string.replace(QString(" "), QString(""));
That will replace any spaces with a non-space.
Write your own QValidator subclass and reimplement validate and fixup. Fixup does what you ask for: changes the input in a way that makes it intermediate/acceptable.
In your case, consider the following code-snippet for fixup:
fixup (QString &input) const
{
QString fixed;
fixed.reserve(input.size());
for (int i=0; i<input.size(); ++i)
if (input.at(i).isDigit()) fixed.append(input.at(i));
input = fixed;
}
(this is not tested)
The validate function will obviously look similar, returning QValidator::Invalid when it encounters a non-digit character and returning the according position in pos.
If your BLZ is limited to Germany, you could easily add the validation feature that it only returns QValidator::Acceptable when there are eight digits, and QValidator::Intermediate else.
Anyhow, writing an own QValidator, which often is very easy and straight forward, is the best (and most future-proof) solution most of the time. RegExes are great, but C++ clearly is the more powerful language here, which in addition results in a much more readable validator ;).

Resources