Uploaded image for project: 'Qt'
  1. Qt
  2. QTBUG-108208

QTextDocument notify about contentsChange for whole TextBlock when I use InputMethod

    XMLWordPrintable

Details

    • Bug
    • Resolution: Unresolved
    • P2: Important
    • None
    • 5.15.7, 6.4.0, 6.5.0
    • GUI: Text handling
    • None
    • Windows

    Description

      QTextDocument has signal contentsChange 

      And when you enter or change anything this signal will let you know how many characters are added and removed and where

      But this don't work when I use some imput method (for example japanies IME on windows) 

      contentsChange contains position 0 and added removed is whole text lenght

       

      I spend some time to debug source of this problem and I found that 

      void QWidgetTextControlPrivate::inputMethodEvent(QInputMethodEvent *e)

      https://code.qt.io/cgit/qt/qtbase.git/tree/src/widgets/widgets/qwidgettextcontrol.cpp#n2013

      call setPreeditArea

      https://code.qt.io/cgit/qt/qtbase.git/tree/src/gui/text/qtextlayout.cpp#n459

      and in setPreeditArea there is call for documentChange for whole block

      Any idea why for whole block and not just only for part that actualy contais preedit text?

       

       

      if (QTextDocumentPrivate::get(d->block) != nullptr)
              QTextDocumentPrivate::get(d->block)->documentChange(d->block.position() + position, text.length());
      

       

      This don't fix problem as there is  call layout->setFormats(overrides);

      https://code.qt.io/cgit/qt/qtbase.git/tree/src/gui/text/qtextlayout.cpp#n498

       

      That also generate documentChange for whole block

      But I think that this check will be good enough

      void QTextLayout::setFormats(const QList<FormatRange> &formats)
      {
          auto computeDocumentChangePositions = [](const QList<FormatRange> &formats, int &changeStart,
                                                   int &changeEnd) {
              for (const auto &format : qAsConst(formats)) {
                  if (changeStart < 0) {
                      changeStart = format.start;
                      changeEnd = format.start + format.length;
                  } else {
                      changeStart = qMin(changeStart, format.start);
                      changeEnd = qMax(changeEnd, format.start + format.length);
                  }
              }
          };
          int documentChangeStartPos = -1;
          int documentChangeEndPos = -1;
          if (QTextDocumentPrivate::get(d->block) != nullptr) {
              computeDocumentChangePositions(d->formats(), documentChangeStartPos, documentChangeEndPos);
              computeDocumentChangePositions(formats, documentChangeStartPos, documentChangeEndPos);
          }    d->setFormats(formats);    if (QTextDocumentPrivate::get(d->block) != nullptr) {
              if (documentChangeStartPos >= 0) {
                  QTextDocumentPrivate::get(d->block)->documentChange(
                          d->block.position() + documentChangeStartPos,
                          documentChangeEndPos - documentChangeStartPos);
              }
          }
      }
      

      So any suggestions ?

      Attachments

        No reviews matched the request. Check your Options in the drop-down menu of this sections header.

        Activity

          People

            esabraha Eskil Abrahamsen Blomfeldt
            miskol MICHAL LAZO
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

            Dates

              Created:
              Updated:

              Gerrit Reviews

                There are no open Gerrit changes