[Libreoffice] [GSOC] Multi line input bar

Kohei Yoshida kyoshida at novell.com
Mon May 16 09:38:58 PDT 2011

On Sun, 2011-05-15 at 05:30 +0530, Anurag Jain wrote:
> Hello there,
> I've been trying to work on getting the word wrap work in the input
> bar of ScTextWnd and come up with following inferences.
> In the Paint() function the 'if' part is executed when we the focus is
> on input bar after mouse button down event,  which invokes the
> StartEditEngine() function creating objects necessary for making use
> of the EditEngine class. EditEngine stops as the focus shifts from the
> input bar to spreadsheet cells. Incase if we click on the cell and
> type the string the else part is executed where the OutputDevice's
> DrawText() method is called and EditEngine will not be used.
> Since the logic for wrapping the text is to set the paper size using
> the function SetPaperSize() in EditEngine which takes width and height
> parameters. I tried passing the width and height of the inputbar but
> I'm not able to get the proper scroll height offered by it, i.e. after
> wrapping the cursor shifts a bit down showing the lower portion of the
> upper line and hiding that of the current line. That's what I've
> modified, but Couldn't get the desired result.
>  Size barSize=GetOutputSizePixel();
>         Size pSize  =LogicToPixel(pEditEngine->GetPaperSize());
>         long barHeight=barSize.Height();
>         long textHeight=LogicToPixel( Size( 0, GetTextHeight() ) ).Height();
>         long nDiff = (barHeight - textHeight)/2;
>         barSize.Height()+=2*nDiff + barHeight;
>         barSize.Width() -= 2*TEXT_STARTPOS-4;
>         pEditEngine->SetUpdateMode( false );
>         pEditEngine->SetPaperSize( PixelToLogic(Size(barSize)) );
> @Kohei as you suggested to use the upper corner of the input bar to
> draw the string, which I guess is the same as set by the DrawText in
> Paint itself. Also I tried going for using the EditEngine completely
> so I replaced everything inside Paint() with this code.
> void ScTextWnd::Paint( const Rectangle& rRec )
> {
>       SetFont( aTextFont );
>         long a =    GetOutputSizePixel().Height();
>         long b =    GetOutputSizePixel().Width();
>         long c =    LogicToPixel( Size( 0, GetTextHeight() ) ).Height();
>         long d =    LogicToPixel( Size( 0, GetTextHeight() ) ).Width();
>         long nDiff =  GetOutputSizePixel().Height()
>                     - LogicToPixel( Size( 0, GetTextHeight() ) ).Height();
>         long nStartPos = TEXT_STARTPOS;
>         if ( bIsRTL )
>         {
>             //	right-align
>             nStartPos += GetOutputSizePixel().Width() - 2*TEXT_STARTPOS -
>                         LogicToPixel( Size( GetTextWidth( aString ), 0
> ) ).Width();
>         }
>            StartEditEngine();                             //starting edit engine
>             pEditEngine->Draw(this, rRec, Point( nStartPos, nDiff/2 ),false);
> }
> After doing so, the wrap happens for the first line only without
> scroll and things turned messy afterwards
> I think I'm missing something here, may be I need to work on some more
> methods and manipulate them accordingly. I'd like to have suggestions
> about this thing, so that I can improvise more and more.

So, what I suggested was to set the position of the edit engine text
based on the current scroll level; that is, when the text is not
scrolled at all, then the top-left position of the text equals that of
the input bar.  But when the text is scrolled downward, you need to
calculate the correct text position such that only the current line be
shown (which line becomes the current line depends on the scroll level).

When the current line is, say, the 2nd line, then the vertical text
position (y) would be the top position of the input box *minus* the
height of the 1st line.  If the current line is the 3rd line, then the
vertical offset would be the height of the 1st and 2nd line combined,
(or the height of the 1st line times 2, if we assume that the height be
identical in all lines).

Set the height of the paper size to be large enough so that the entire
text fits, even when you only need to show a single line.
EditEngine::Draw() takes a clipping region which should only encompass
the line that needs to be shown.

With regard to making changes so that EditEngine would be always used,
check who actually calls StartEditEngine() and StopEditEngine() and
eliminate the need to call these two methods.  From what I can see,
ScInputHandler which handles key input into cells, is the main consumer
of these methods.

BTW good to hear you are making progress.  Just be assured that code in
this area is a bit messy, so don't feel bad if you have hard time
understanding the logic of the current code.



Kohei Yoshida, LibreOffice hacker, Calc
<kyoshida at novell.com>

More information about the LibreOffice mailing list