<html>
  <head>
    <meta http-equiv="content-type" content="text/html; charset=UTF-8">
  </head>
  <body>
    <p>Dear LibreOffice Community,</p>
    <p>GSoC progress for week #4.<br>
    </p>
    <p>> Blog Posts:<br>
    </p>
    Blog post for week #2: <a moz-do-not-send="true"
href="https://bayramcicek.com.tr/libreoffice-dev/2021/07/04/week-02-gsoc.html">https://bayramcicek.com.tr/libreoffice-dev/2021/07/04/week-02-gsoc.html</a><br>
    <p>Blog post for week #3 and #4: <a moz-do-not-send="true"
href="https://bayramcicek.com.tr/libreoffice-dev/2021/07/05/week-03-04-gsoc.html">https://bayramcicek.com.tr/libreoffice-dev/2021/07/05/week-03-04-gsoc.html</a></p>
    <p>> Group selection works with Drawing objects, but doesn't work
      with raster images / Writer<br>
    </p>
    <p>Writer can group shapes(rectangles, circles), text boxes and draw
      images(from Draw/Calc); but this feature does not work on raster
      images because images in Writer handled as Frame
      objects(Graphics/holding images/bitmaps).<br>
    </p>
    <p>Last 2 weeks, I was working on "drawing objects" to understand
      how grouping works. I worked mainly on debugging and finding why
      raster images does not group with shapes. Here is what I found:</p>
    <p><i>(All code pointers are in the blog post)</i><br>
    </p>
    > All selected objects store in <i>rMrkList</i> list:<br>
    <i>const SdrMarkList &rMrkList =
      pDView->GetMarkedObjectList();</i><br>
    <p>> In <i>SwFEShell::SelectObj</i>,<i> SAL_DEBUG(
        rMrkList.GetMarkDescription() )</i> returns:</p>
    <p>For shapes: "<i>shapes</i>"<br>
      For 2+ shapes: "<i>2 shapes</i>"<br>
      For draw images: "<i>Image with transparency</i>"<br>
      For text box: "<i>Text Frame</i>"<br>
      For raster images: "<i>[Drawing object]</i>"</p>
    <p>"<i>[Drawing object]</i>" defined as <i>STR_ObjNameSingulNONE</i>.
      This means <i>GetMarkDescription()</i> doesn't know what the
      raster images?</p>
    <p>> Contents by position:</p>
    <p>Shape : <i>OBJCNT_SIMPLE</i><br>
      Raster images : <i>OBJCNT_GRF</i></p>
    <p>> Selection Type:</p>
    <p>Shape : <i>SelectionType::DrawObject</i><br>
      Raster images : <i>SelectionType::Graphic  (CNT_GRF)</i><br>
    </p>
    <p>> Selecting raster images via <i>SHIFT+CLICK </i>add them in
      <i>rMrkList</i>, but only <i>1</i> of them:</p>
    <p>While shapes added normally on the <i>rMrkList</i>, raster
      images added only once, then be <i>unmarked</i>, because <i>::GetFlyFromMarked(
        &rMrkList, this )</i> always returns an address which is
      caused to execute <i>pDView->UnmarkAll()</i>.<br>
    </p>
    <p>> Frame is not accessible</p>
    <p>Another interesting issue is when trying to add(select) a raster
      image to the shape list (unmarking disabled) debugging warns <i>
        "warn: /*...*/ frame is not accessible".</i></p>
    <p><i>SwAccessibleMap::InvalidateCursorPosition</i>:<br>
    </p>
    <p><i>bool bShapeSelected = false;</i><i><br>
      </i><i> // ...</i><i><br>
      </i><i>             else if( pFESh->IsObjSelected() > 0 )</i><i><br>
      </i><i>             {</i><i><br>
      </i><i>                 bShapeSelected = true;</i><i><br>
      </i><i>                 aFrameOrObj = static_cast<const SwFrame
        *>( nullptr );</i><i><br>
      </i><i>             }</i><i><br>
      </i><i> // ... </i><i><br>
      </i><i>     OSL_ENSURE( bShapeSelected ||
        aFrameOrObj.IsAccessible(GetShell()->IsPreview()),</i><i><br>
      </i><i>             "frame is not accessible" );</i><br>
    </p>
    <p>"<i>pFESh->IsObjSelected()</i>" should return <i>GetMarkCount()</i>,
      not <i>0</i>. Otherwise <i>bShapeSelected</i> stays <i>false</i>
      and <i>OSL_ENSURE</i> warns <i>"frame is not accessible"</i>:</p>
    <p><i>size_t SwFEShell::IsObjSelected() const</i><i><br>
      </i><i> {</i><i><br>
      </i><i>     if ( IsFrameSelected() || !Imp()->HasDrawView() )</i><i><br>
      </i><i>         return 0;</i><i><br>
      </i><i>     return
        Imp()->GetDrawView()->GetMarkedObjectList().GetMarkCount();</i><i><br>
      </i><i> }</i><i><br>
      </i><i> </i><i><br>
      </i><i> bool SwFEShell::IsFrameSelected() const</i><i><br>
      </i><i> {</i><i><br>
      </i><i>     if ( !Imp()->HasDrawView() )</i><i><br>
      </i><i>         return false;</i><i><br>
      </i><i>     else</i><i><br>
      </i><i>         return nullptr != ::GetFlyFromMarked(
        &Imp()->GetDrawView()->GetMarkedObjectList(),</i><i><br>
      </i><i>                                        
        const_cast<SwFEShell*>(this) );</i><i><br>
      </i><i> }</i><br>
    </p>
    <p>When selecting raster images, in <i>SwFEShell::IsFrameSelected()</i>:</p>
    <p><i>    return nullptr != ::GetFlyFromMarked(/*..*/);</i></p>
    <p><i>GetFlyFromMarked</i> should return false 0(null) (as like
      shapes do), not an <i>address</i> which make<i> nullptr !=
        0x01... true.</i></p>
    <p>I also looked at <i>Draw</i> and <i>Calc</i> to see how images
      are handled. Images are converted a drawing objects and have the
      same attributes like shapes. But in Writer, images have different
      attributes and handling.</p>
    <p>> Summary of last 2 weeks</p>
        - Tried to understand how shapes grouped together<br>
        - Debugging
    <div class="moz-signature">
      <p>> Next week TO-DO:</p>
    </div>
    <div class="moz-signature">     - Make raster images
      selectable(group) with SHIFT+CLICK </div>
    <div class="moz-signature"><br>
    </div>
    <div class="moz-signature">Please let me know if you have any
      suggestions about group selection of raster images.<br>
    </div>
    <div class="moz-signature">
      <p> </p>
      <p> </p>
    </div>
    <div class="moz-signature">
      <p>Thank you all.</p>
    </div>
    <div class="moz-signature">-- <br>
      <pre>Regards,
Bayram Çiçek
</pre>
    </div>
  </body>
</html>