Skip to content

New bold, italic and underline shortcuts for text box.#890

Merged
kaamui merged 10 commits intoOpenBoard-org:1.7.2-devfrom
sebojolais:text_shortcuts
Feb 29, 2024
Merged

New bold, italic and underline shortcuts for text box.#890
kaamui merged 10 commits intoOpenBoard-org:1.7.2-devfrom
sebojolais:text_shortcuts

Conversation

@sebojolais
Copy link
Copy Markdown
Contributor

@sebojolais sebojolais commented Feb 12, 2024

My usecase is :
I used to change the format of the text. For example, some words in bold or italic or underlined. And I want to go fast without opening the font dialog.

The idea is to implement the reception of events in the UBGraphicsTextItem. And we do the text modification if the event is a bold or italic or underline shortcut.
I do not know if it will be better to do it in UBGraphicsTextItemDelegate.

It works fine in my side on linux and Qt 5 and 6.
The only issue is due to other Ctrl+I shortcut to set the stylus. The italic shortcut set the text in italic but also switches in stylus mode and the Text box loses the focus.

@letsfindaway
Copy link
Copy Markdown
Collaborator

The idea is to implement the reception of events in the UBGraphicsTextItem. And we do the text modification if the event is a bold or italic or underline shortcut. I do not know if it will be better to do it in UBGraphicsTextItemDelegate.

I think the UBGraphicsTextItem is the right place.

It works fine in my side on linux and Qt 5 and 6. The only issue is due to other Ctrl+I shortcut to set the stylus. The italic shortcut set the text in italic but also switches in stylus mode and the Text box loses the focus.

Did you try to accept() the event after you handled it? According to the documentation this should allow to solve this issue. See https://doc.qt.io/qt-5/qkeyevent.html#details

@sebojolais
Copy link
Copy Markdown
Contributor Author

I think the UBGraphicsTextItem is the right place.

Thank you your confirmation.

Did you try to accept()

Yes I see it in the doc. I tried some tests with accept() and ignore() and it was not helpful. So I remove it from the PR.

@sebojolais
Copy link
Copy Markdown
Contributor Author

More investigations about the italic issue show me the points below:

  1. The italic shortcut is catched at first by UBGraphicsTextItem before the Pen shortcut slot void UBDrawingController::penToolSelected(). So if I add the call to QEvent::accept(), it fixes the issue.
  2. But a new issue appears. I do not know why but the Ctrl+I shortcut is also catch as a Zoom+ command in UBBoardView::keyPressEvent():
            switch (event->key ())
            {
            case Qt::Key_Plus:
            case Qt::Key_I:
            {
                mController->zoomIn ();
                event->accept ();
                break;
            }

So now, The italic shortcut does the italic job and make a zoom in the board also... It makes me crazy.
The code is 11 years old. Anyone knows why the the Ctrl+I is also used to zoom ? It is not compatible with already used Pen shortcut., is not it ?

@kaamui
Copy link
Copy Markdown
Member

kaamui commented Feb 16, 2024

You can remove it (and ctrl+o for zoom out too).

return font;
}

bool UBGraphicsTextItem::event(QEvent *ev)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can't you directly modify KeyPressEvent instead of checking every event to see if it's a KeyEvent ?

Comment on lines +146 to +158
QKeyEvent* keyEvent = static_cast<QKeyEvent*>(ev);
QKeySequence::StandardKey shortcuts[] = {QKeySequence::StandardKey::Bold,
QKeySequence::StandardKey::Italic,
QKeySequence::StandardKey::Underline};
QKeySequence::StandardKey key = QKeySequence::StandardKey::UnknownKey;
for(int i=0; i<3; i++)
if(keyEvent->matches(shortcuts[i]))
{
key = shortcuts[i];
break;
}
if(key != QKeySequence::StandardKey::UnknownKey)
{
Copy link
Copy Markdown
Member

@kaamui kaamui Feb 16, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please simplify this. In KeyPressEvent (didn't test it but something like following) :

// Is checking isSelected really necessary ? Isn't KeyPressEvent (or QGraphicsTextItem::event)
// called only when item is selected or at least on focus ?
if(event->type() == QEvent::ShortcutOverride && isSelected()) 
{
    if (event->matches(QKeySequence::StandardKey::Bold)
    || event->matches(QKeySequence::StandardKey::Italic)
    || event->matches( QKeySequence::StandardKey::Underline))
    {
        QTextCursor curCursor = textCursor();
        QTextCharFormat format;
        QFont ft(curCursor.charFormat().font());
        if(event->key() == QKeySequence::StandardKey::Bold)
            ft.setBold(!ft.bold());
         else if(event->key() == QKeySequence::StandardKey::Italic)
            ft.setItalic(!ft.italic());
        else
            ft.setUnderline(!ft.underline());
         format.setFont(ft);
         curCursor.mergeCharFormat(format);
         setTextCursor(curCursor);

         contentsChanged();
         event->accept();
         return true; //base class call should be avoided ?
    }
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, it is better in the keyPressEvent() method.
But now, for the Italic shortcut, the main 'Ctrl+I' action to set the Pen is throw at first and the keyPressEvent() method never receives the event. So the Italic modification is impossible.
I pushed the modifications to share them because I have no idea to manage this issue.
Currently, we can:

  • set bold, underline and italic in event() method
  • or only set bold and underline in keyPressEvent() method


contentsChanged();
ev->accept();
return true;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are you sure we want to avoid base class call ?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My understanding of the keyPressEvent() documentation leads me to remove the accept() call and do not call the base class method:

Note that QKeyEvent starts with isAccepted() == true, so you do not need to call QKeyEvent::accept() - just do not call the base class implementation if you act upon the key.

https://doc.qt.io/qt-6/qwidget.html#keyPressEvent

It seems we do not call the base class method if we intercept event also for the event() method. Have a look at the example of the documentation:
https://doc.qt.io/qt-6/qobject.html#event

@sebojolais sebojolais marked this pull request as draft February 26, 2024 12:03
@kaamui
Copy link
Copy Markdown
Member

kaamui commented Feb 28, 2024

Hi @sebojolais

Can you rebase your PR to 1.7.2-dev and change the Pen shortcut to Ctrl+P please ?

thank you !

@sebojolais sebojolais marked this pull request as ready for review February 28, 2024 19:58
@sebojolais sebojolais changed the base branch from dev to 1.7.2-dev February 28, 2024 19:59
@sebojolais
Copy link
Copy Markdown
Contributor Author

Thank you for your answer.
I rebase this PR to 1.7.2-dev and change the Pen shortcut to Ctrl+P.
Everything is fine in my side with no more issue.

@kaamui kaamui merged commit a853ac7 into OpenBoard-org:1.7.2-dev Feb 29, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants