Coverage Report

Created: 2026-04-09 11:41

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/svtools/source/brwbox/editbrowsebox.cxx
Line
Count
Source
1
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
/*
3
 * This file is part of the LibreOffice project.
4
 *
5
 * This Source Code Form is subject to the terms of the Mozilla Public
6
 * License, v. 2.0. If a copy of the MPL was not distributed with this
7
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8
 *
9
 * This file incorporates work covered by the following license notice:
10
 *
11
 *   Licensed to the Apache Software Foundation (ASF) under one or more
12
 *   contributor license agreements. See the NOTICE file distributed
13
 *   with this work for additional information regarding copyright
14
 *   ownership. The ASF licenses this file to you under the Apache
15
 *   License, Version 2.0 (the "License"); you may not use this file
16
 *   except in compliance with the License. You may obtain a copy of
17
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
18
 */
19
20
#include <svtools/editbrowsebox.hxx>
21
22
#include <tools/debug.hxx>
23
#include <vcl/accessibility/AccessibleBrowseBox.hxx>
24
#include <vcl/image.hxx>
25
#include <vcl/rendercontext/SystemTextColorFlags.hxx>
26
#include <vcl/settings.hxx>
27
#include <vcl/window.hxx>
28
#include <vcl/svapp.hxx>
29
#include <vcl/weld/Builder.hxx>
30
31
#include <bitmaps.hlst>
32
33
#include <algorithm>
34
#include <com/sun/star/accessibility/AccessibleEventId.hpp>
35
36
37
namespace svt
38
{
39
40
namespace
41
{
42
43
    GetFocusFlags getRealGetFocusFlags( vcl::Window* _pWindow )
44
0
    {
45
0
        GetFocusFlags nFlags = GetFocusFlags::NONE;
46
0
        while ( _pWindow && nFlags == GetFocusFlags::NONE )
47
0
        {
48
0
            nFlags = _pWindow->GetGetFocusFlags( );
49
0
            _pWindow = _pWindow->GetParent();
50
0
        }
51
0
        return nFlags;
52
0
    }
53
}
54
55
using namespace com::sun::star::accessibility;
56
using namespace ::com::sun::star::uno;
57
58
59
60
IEditImplementation::~IEditImplementation()
61
0
{
62
0
}
63
64
//= EditBrowserHeader
65
66
void EditBrowserHeader::DoubleClick()
67
0
{
68
0
    sal_uInt16 nColId = GetCurItemId();
69
0
    if (nColId)
70
0
    {
71
0
        tools::Long nAutoWidth = static_cast<EditBrowseBox*>(GetParent())->GetAutoColumnWidth(nColId);
72
0
        if (nAutoWidth != static_cast<EditBrowseBox*>(GetParent())->GetColumnWidth(nColId))
73
0
        {
74
0
            static_cast<EditBrowseBox*>(GetParent())->SetColumnWidth(nColId, nAutoWidth);
75
0
            static_cast<EditBrowseBox*>(GetParent())->ColumnResized(nColId);
76
0
        }
77
0
    }
78
0
}
79
80
//= EditBrowseBox
81
82
void EditBrowseBox::BrowserMouseEventPtr::Clear()
83
0
{
84
0
    pEvent.reset();
85
0
}
86
87
void EditBrowseBox::BrowserMouseEventPtr::Set(const BrowserMouseEvent* pEvt, bool bIsDown)
88
0
{
89
0
    if (pEvt == pEvent.get())
90
0
    {
91
0
        bDown = bIsDown;
92
0
        return;
93
0
    }
94
0
    pEvent.reset();
95
0
    if (pEvt)
96
0
    {
97
0
        pEvent.reset(new BrowserMouseEvent(pEvt->GetWindow(),
98
0
                                       *pEvt,
99
0
                                       pEvt->GetRow(),
100
0
                                       pEvt->GetColumn(),
101
0
                                       pEvt->GetColumnId(),
102
0
                                       pEvt->GetRect()));
103
0
        bDown = bIsDown;
104
0
    }
105
0
}
106
107
EditBrowseBox::EditBrowseBox( vcl::Window* pParent, EditBrowseBoxFlags nBrowserFlags, WinBits nBits, BrowserMode _nMode )
108
0
              :BrowseBox( pParent, nBits, _nMode )
109
0
              ,nStartEvent(nullptr)
110
0
              ,nEndEvent(nullptr)
111
0
              ,nCellModifiedEvent(nullptr)
112
0
              ,m_pFocusWhileRequest(nullptr)
113
0
              ,nPaintRow(-1)
114
0
              ,nEditRow(-1)
115
0
              ,nEditCol(0)
116
0
              ,bHasFocus(false)
117
0
              ,bPaintStatus(true)
118
0
              ,bActiveBeforeTracking( false )
119
0
              ,m_nBrowserFlags(nBrowserFlags)
120
0
              ,pHeader(nullptr)
121
0
{
122
0
    SetCompoundControl(true);
123
124
0
    ImplInitSettings(true, true, true);
125
126
0
    pCheckBoxPaint = VclPtr<CheckBoxControl>::Create(&GetDataWindow());
127
0
    pCheckBoxPaint->SetPaintTransparent( true );
128
0
    pCheckBoxPaint->SetBackground();
129
0
}
130
131
void EditBrowseBox::Init()
132
0
{
133
    // late construction
134
0
}
135
136
EditBrowseBox::~EditBrowseBox()
137
0
{
138
0
    disposeOnce();
139
0
}
140
141
void EditBrowseBox::dispose()
142
0
{
143
0
    if (nStartEvent)
144
0
        Application::RemoveUserEvent(nStartEvent);
145
0
    if (nEndEvent)
146
0
        Application::RemoveUserEvent(nEndEvent);
147
0
    if (nCellModifiedEvent)
148
0
        Application::RemoveUserEvent(nCellModifiedEvent);
149
150
0
    pCheckBoxPaint.disposeAndClear();
151
0
    m_pFocusWhileRequest.reset();
152
0
    pHeader.reset();
153
0
    BrowseBox::dispose();
154
0
}
155
156
157
void EditBrowseBox::RemoveRows()
158
0
{
159
0
    BrowseBox::Clear();
160
0
    nEditRow = nPaintRow = -1;
161
0
    nEditCol = 0;
162
0
}
163
164
VclPtr<BrowserHeader> EditBrowseBox::CreateHeaderBar(BrowseBox* pParent)
165
0
{
166
0
    pHeader = imp_CreateHeaderBar(pParent);
167
0
    if (!IsUpdateMode())
168
0
        pHeader->SetUpdateMode(false);
169
0
    return pHeader;
170
0
}
171
172
VclPtr<BrowserHeader> EditBrowseBox::imp_CreateHeaderBar(BrowseBox* pParent)
173
0
{
174
0
    return VclPtr<EditBrowserHeader>::Create(pParent);
175
0
}
176
177
void EditBrowseBox::LoseFocus()
178
0
{
179
0
    BrowseBox::LoseFocus();
180
0
    DetermineFocus();
181
0
}
182
183
void EditBrowseBox::GetFocus()
184
0
{
185
0
    BrowseBox::GetFocus();
186
187
    // This should handle the case that the BrowseBox (or one of its children)
188
    // gets the focus from outside by pressing Tab
189
0
    if (IsEditing() && Controller()->GetWindow().IsVisible())
190
0
        Controller()->GetWindow().GrabFocus();
191
192
0
    DetermineFocus(getRealGetFocusFlags(this));
193
0
}
194
195
bool EditBrowseBox::SeekRow(sal_Int32 nRow)
196
0
{
197
0
    nPaintRow = nRow;
198
0
    return true;
199
0
}
200
201
IMPL_LINK_NOARG(EditBrowseBox, StartEditHdl, void*, void)
202
0
{
203
0
    nStartEvent = nullptr;
204
0
    if (IsEditing())
205
0
    {
206
0
        EnableAndShow();
207
0
        if (!ControlHasFocus() && (m_pFocusWhileRequest.get() == Application::GetFocusWindow()))
208
0
            aController->GetWindow().GrabFocus();
209
0
    }
210
0
}
211
212
void EditBrowseBox::PaintField( vcl::RenderContext& rDev, const tools::Rectangle& rRect,
213
                                sal_uInt16 nColumnId ) const
214
0
{
215
0
    if (nColumnId == HandleColumnId)
216
0
    {
217
0
         if (bPaintStatus)
218
0
            PaintStatusCell(rDev, rRect);
219
0
    }
220
0
    else
221
0
    {
222
        // don't paint the current cell
223
0
        if (rDev.GetOwnerWindow() == &GetDataWindow())
224
            // but only if we're painting onto our data win (which is the usual painting)
225
0
            if (nPaintRow == nEditRow)
226
0
            {
227
0
                if (IsEditing() && nEditCol == nColumnId && aController->GetWindow().IsVisible())
228
0
                    return;
229
0
            }
230
0
        PaintCell(rDev, rRect, nColumnId);
231
0
    }
232
0
}
233
234
Image EditBrowseBox::GetImage(RowStatus eStatus) const
235
0
{
236
0
    Bitmap aBitmap;
237
0
    bool bNeedMirror = IsRTLEnabled();
238
0
    switch (eStatus)
239
0
    {
240
0
        case CURRENT:
241
0
            aBitmap = Bitmap(BMP_CURRENT);
242
0
            break;
243
0
        case CURRENTNEW:
244
0
            aBitmap = Bitmap(BMP_CURRENTNEW);
245
0
            break;
246
0
        case MODIFIED:
247
0
            aBitmap = Bitmap(BMP_MODIFIED);
248
0
            bNeedMirror = false;    // the pen is not mirrored
249
0
            break;
250
0
        case NEW:
251
0
            aBitmap = Bitmap(BMP_NEW);
252
0
            break;
253
0
        case DELETED:
254
0
            aBitmap = Bitmap(BMP_DELETED);
255
0
            break;
256
0
        case PRIMARYKEY:
257
0
            aBitmap = Bitmap(BMP_PRIMARYKEY);
258
0
            break;
259
0
        case CURRENT_PRIMARYKEY:
260
0
            aBitmap = Bitmap(BMP_CURRENT_PRIMARYKEY);
261
0
            break;
262
0
        case FILTER:
263
0
            aBitmap = Bitmap(BMP_FILTER);
264
0
            break;
265
0
        case HEADERFOOTER:
266
0
            aBitmap = Bitmap(BMP_HEADERFOOTER);
267
0
            break;
268
0
        case CLEAN:
269
0
            break;
270
0
    }
271
0
    if ( bNeedMirror )
272
0
    {
273
0
        aBitmap.Mirror( BmpMirrorFlags::Horizontal );
274
0
    }
275
0
    return Image(aBitmap);
276
0
}
277
278
void EditBrowseBox::PaintStatusCell(OutputDevice& rDev, const tools::Rectangle& rRect) const
279
0
{
280
0
    if (nPaintRow < 0)
281
0
        return;
282
283
0
    RowStatus eStatus = GetRowStatus( nPaintRow );
284
0
    EditBrowseBoxFlags nBrowserFlags = GetBrowserFlags();
285
286
0
    if (nBrowserFlags & EditBrowseBoxFlags::NO_HANDLE_COLUMN_CONTENT)
287
0
        return;
288
289
    // draw the text of the header column
290
0
    if (nBrowserFlags & EditBrowseBoxFlags::HANDLE_COLUMN_TEXT )
291
0
    {
292
0
        rDev.DrawText( rRect, GetCellText( nPaintRow, 0 ),
293
0
                       DrawTextFlags::Center | DrawTextFlags::VCenter | DrawTextFlags::Clip );
294
0
    }
295
    // draw an image
296
0
    else if (eStatus != CLEAN && rDev.GetOutDevType() == OUTDEV_WINDOW)
297
0
    {
298
0
        Image aImage(GetImage(eStatus));
299
        // calc the image position
300
0
        Size aImageSize(aImage.GetSizePixel());
301
0
        aImageSize.setWidth( CalcZoom(aImageSize.Width()) );
302
0
        aImageSize.setHeight( CalcZoom(aImageSize.Height()) );
303
0
        Point aPos( rRect.TopLeft() );
304
305
0
        if ( ( aImageSize.Width() > rRect.GetWidth() ) || ( aImageSize.Height() > rRect.GetHeight() ) )
306
0
            rDev.SetClipRegion(vcl::Region(rRect));
307
308
0
        if ( aImageSize.Width() < rRect.GetWidth() )
309
0
            aPos.AdjustX(( rRect.GetWidth() - aImageSize.Width() ) / 2 );
310
311
0
        if ( aImageSize.Height() < rRect.GetHeight() )
312
0
            aPos.AdjustY(( rRect.GetHeight() - aImageSize.Height() ) / 2 );
313
314
0
        if ( IsZoom() )
315
0
            rDev.DrawImage( aPos, aImageSize, aImage );
316
0
        else
317
0
            rDev.DrawImage( aPos, aImage );
318
319
0
        if (rDev.IsClipRegion())
320
0
            rDev.SetClipRegion();
321
0
    }
322
0
}
323
324
325
void EditBrowseBox::ImplStartTracking()
326
0
{
327
0
    bActiveBeforeTracking = IsEditing();
328
0
    if ( bActiveBeforeTracking )
329
0
    {
330
0
        DeactivateCell();
331
0
        PaintImmediately();
332
0
    }
333
334
0
    BrowseBox::ImplStartTracking();
335
0
}
336
337
338
void EditBrowseBox::ImplEndTracking()
339
0
{
340
0
    if ( bActiveBeforeTracking )
341
0
        ActivateCell();
342
0
    bActiveBeforeTracking = false;
343
344
0
    BrowseBox::ImplEndTracking();
345
0
}
346
347
348
void EditBrowseBox::RowHeightChanged()
349
0
{
350
0
    if ( IsEditing() )
351
0
    {
352
0
        tools::Rectangle aRect( GetCellRect( nEditRow, nEditCol, false ) );
353
0
        CellControllerRef aCellController( Controller() );
354
0
        ResizeController( aCellController, aRect );
355
0
        aCellController->GetWindow().GrabFocus();
356
0
    }
357
358
0
    BrowseBox::RowHeightChanged();
359
0
}
360
361
362
EditBrowseBox::RowStatus EditBrowseBox::GetRowStatus(sal_Int32) const
363
0
{
364
0
    return CLEAN;
365
0
}
366
367
368
void EditBrowseBox::KeyInput( const KeyEvent& rEvt )
369
0
{
370
0
    sal_uInt16 nCode = rEvt.GetKeyCode().GetCode();
371
0
    bool   bShift = rEvt.GetKeyCode().IsShift();
372
0
    bool   bCtrl = rEvt.GetKeyCode().IsMod1();
373
374
0
    switch (nCode)
375
0
    {
376
0
        case KEY_RETURN:
377
0
            if (!bCtrl && !bShift && IsTabAllowed(true))
378
0
            {
379
0
                Dispatch(BrowserDispatchId::CURSORRIGHT);
380
0
            }
381
0
            else
382
0
                BrowseBox::KeyInput(rEvt);
383
0
            return;
384
0
        case KEY_TAB:
385
0
            if (!bCtrl && !bShift)
386
0
            {
387
0
                if (IsTabAllowed(true))
388
0
                    Dispatch(BrowserDispatchId::CURSORRIGHT);
389
0
                else
390
                    // do NOT call BrowseBox::KeyInput : this would handle the tab, but we already now
391
                    // that tab isn't allowed here. So give the Control class a chance
392
0
                    Control::KeyInput(rEvt);
393
0
                return;
394
0
            }
395
0
            else if (!bCtrl && bShift)
396
0
            {
397
0
                if (IsTabAllowed(false))
398
0
                    Dispatch(BrowserDispatchId::CURSORLEFT);
399
0
                else
400
                    // do NOT call BrowseBox::KeyInput : this would handle the tab, but we already now
401
                    // that tab isn't allowed here. So give the Control class a chance
402
0
                    Control::KeyInput(rEvt);
403
0
                return;
404
0
            }
405
0
            [[fallthrough]];
406
0
        default:
407
0
            BrowseBox::KeyInput(rEvt);
408
0
    }
409
0
}
410
411
void EditBrowseBox::ChildFocusIn()
412
0
{
413
0
    DetermineFocus(getRealGetFocusFlags(this));
414
0
}
415
416
void EditBrowseBox::ChildFocusOut()
417
0
{
418
0
    DetermineFocus();
419
0
}
420
421
void EditBrowseBox::MouseButtonDown(const BrowserMouseEvent& rEvt)
422
0
{
423
    // absorb double clicks
424
0
    if (rEvt.GetClicks() > 1 && rEvt.GetRow() >= 0)
425
0
        return;
426
427
    // we are about to leave the current cell. If there is a "this cell has been modified" notification
428
    // pending (asynchronously), this may be deadly -> do it synchronously
429
0
    if ( nCellModifiedEvent )
430
0
    {
431
0
        Application::RemoveUserEvent( nCellModifiedEvent );
432
0
        nCellModifiedEvent = nullptr;
433
0
        LINK( this, EditBrowseBox, CellModifiedHdl ).Call( nullptr );
434
0
    }
435
436
0
    if (rEvt.GetColumnId() == HandleColumnId)
437
0
    {   // it was the handle column. save the current cell content if necessary
438
        // (clicking on the handle column results in selecting the current row)
439
0
        if (IsEditing() && aController->IsValueChangedFromSaved())
440
0
            SaveModified();
441
0
    }
442
443
0
    aMouseEvent.Set(&rEvt,true);
444
0
    BrowseBox::MouseButtonDown(rEvt);
445
0
    aMouseEvent.Clear();
446
447
0
    if (m_nBrowserFlags & EditBrowseBoxFlags::ACTIVATE_ON_BUTTONDOWN)
448
0
    {
449
        // the base class does not travel upon MouseButtonDown, but implActivateCellOnMouseEvent assumes we traveled ...
450
0
        GoToRowColumnId( rEvt.GetRow(), rEvt.GetColumnId() );
451
0
        if (rEvt.GetRow() >= 0)
452
0
            implActivateCellOnMouseEvent(rEvt, false);
453
0
    }
454
0
}
455
456
void EditBrowseBox::MouseButtonUp( const BrowserMouseEvent& rEvt )
457
0
{
458
    // absorb double clicks
459
0
    if (rEvt.GetClicks() > 1 && rEvt.GetRow() >= 0)
460
0
        return;
461
462
0
    aMouseEvent.Set(&rEvt,false);
463
0
    BrowseBox::MouseButtonUp(rEvt);
464
0
    aMouseEvent.Clear();
465
466
0
    if (!(m_nBrowserFlags & EditBrowseBoxFlags::ACTIVATE_ON_BUTTONDOWN))
467
0
        if (rEvt.GetRow() >= 0)
468
0
            implActivateCellOnMouseEvent(rEvt, true);
469
0
}
470
471
bool EditBrowseBox::ControlHasFocus() const
472
0
{
473
0
    Window* pControlWindow = aController ? &aController->GetWindow() : nullptr;
474
0
    if (ControlBase* pControlBase = dynamic_cast<ControlBase*>(pControlWindow))
475
0
        return pControlBase->ControlHasFocus();
476
0
    return pControlWindow && pControlWindow->HasChildPathFocus();
477
0
}
478
479
void EditBrowseBox::implActivateCellOnMouseEvent(const BrowserMouseEvent& _rEvt, bool _bUp)
480
0
{
481
0
    if (!IsEditing())
482
0
        ActivateCell();
483
0
    else if (IsEditing() && !aController->GetWindow().IsEnabled())
484
0
        DeactivateCell();
485
0
    else if (IsEditing() && !ControlHasFocus())
486
0
        AsynchGetFocus();
487
488
0
    if (!IsEditing() || !aController->GetWindow().IsEnabled())
489
0
        return;
490
491
    // forwards the event to the control
492
0
    aController->ActivatingMouseEvent(_rEvt, _bUp);
493
0
}
494
495
void EditBrowseBox::Dispatch(BrowserDispatchId eId)
496
0
{
497
0
    if (eId == BrowserDispatchId::ENHANCESELECTION)
498
0
    {   // this is a workaround for the bug in the base class:
499
        // if the row selection is to be extended (which is what BrowserDispatchId::ENHANCESELECTION tells us)
500
        // then the base class does not revert any column selections, while, for doing a "simple"
501
        // selection (BrowserDispatchId::SELECT), it does. In fact, it does not only revert the col selection then,
502
        // but also any current row selections.
503
        // This clearly tells me that the both ids are for row selection only - there this behaviour does
504
        // make sense.
505
        // But here, where we have column selection, too, we take care of this ourself.
506
0
        if ( GetSelectColumnCount( ) )
507
0
        {
508
0
            while ( GetSelectColumnCount( ) )
509
0
                SelectColumnPos(
510
0
                    sal::static_int_cast< sal_uInt16 >(FirstSelectedColumn()),
511
0
                    false );
512
0
            Select();
513
0
        }
514
0
    }
515
0
    BrowseBox::Dispatch(eId);
516
0
}
517
518
bool EditBrowseBox::ProcessKey(const KeyEvent& rKeyEvent)
519
0
{
520
0
    sal_uInt16 nCode  = rKeyEvent.GetKeyCode().GetCode();
521
0
    bool       bShift = rKeyEvent.GetKeyCode().IsShift();
522
0
    bool       bCtrl  = rKeyEvent.GetKeyCode().IsMod1();
523
0
    bool       bAlt =   rKeyEvent.GetKeyCode().IsMod2();
524
0
    bool       bLocalSelect = false;
525
0
    bool       bNonEditOnly = false;
526
0
    BrowserDispatchId eId = BrowserDispatchId::NONE;
527
528
0
    if (!bAlt && !bCtrl && !bShift )
529
0
        switch ( nCode )
530
0
        {
531
0
            case KEY_DOWN:
532
0
                eId = BrowserDispatchId::CURSORDOWN;
533
0
                break;
534
0
            case KEY_UP:
535
0
                eId = BrowserDispatchId::CURSORUP;
536
0
                break;
537
0
            case KEY_PAGEDOWN:
538
0
                eId = BrowserDispatchId::CURSORPAGEDOWN;
539
0
                break;
540
0
            case KEY_PAGEUP:
541
0
                eId = BrowserDispatchId::CURSORPAGEUP;
542
0
                break;
543
0
            case KEY_HOME:
544
0
                eId = BrowserDispatchId::CURSORHOME;
545
0
                break;
546
0
            case KEY_END:
547
0
                eId = BrowserDispatchId::CURSOREND;
548
0
                break;
549
550
0
            case KEY_TAB:
551
                // ask if traveling to the next cell is allowed
552
0
                if (IsTabAllowed(true))
553
0
                    eId = BrowserDispatchId::CURSORRIGHT;
554
0
                break;
555
556
0
            case KEY_RETURN:
557
                // save the cell content (if necessary)
558
0
                if (IsEditing() && aController->IsValueChangedFromSaved() && !SaveModified())
559
0
                {
560
                    // maybe we're not visible ...
561
0
                    EnableAndShow();
562
0
                    aController->GetWindow().GrabFocus();
563
0
                    return true;
564
0
                }
565
                // ask if traveling to the next cell is allowed
566
0
                if (IsTabAllowed(true))
567
0
                    eId = BrowserDispatchId::CURSORRIGHT;
568
569
0
                break;
570
0
            case KEY_RIGHT:
571
0
                eId = BrowserDispatchId::CURSORRIGHT;
572
0
                break;
573
0
            case KEY_LEFT:
574
0
                eId = BrowserDispatchId::CURSORLEFT;
575
0
                break;
576
0
            case KEY_SPACE:
577
0
                eId = BrowserDispatchId::SELECT;
578
0
                bNonEditOnly = bLocalSelect = true;
579
0
                break;
580
0
        }
581
582
0
    if ( !bAlt && !bCtrl && bShift )
583
0
        switch ( nCode )
584
0
        {
585
0
            case KEY_DOWN:
586
0
                eId = BrowserDispatchId::SELECTDOWN;
587
0
                bLocalSelect = true;
588
0
                break;
589
0
            case KEY_UP:
590
0
                eId = BrowserDispatchId::SELECTUP;
591
0
                bLocalSelect = true;
592
0
                break;
593
0
            case KEY_HOME:
594
0
                eId = BrowserDispatchId::SELECTHOME;
595
0
                bLocalSelect = true;
596
0
                break;
597
0
            case KEY_END:
598
0
                eId = BrowserDispatchId::SELECTEND;
599
0
                bLocalSelect = true;
600
0
                break;
601
0
            case KEY_TAB:
602
0
                if (IsTabAllowed(false))
603
0
                    eId = BrowserDispatchId::CURSORLEFT;
604
0
                break;
605
0
        }
606
607
0
    if ( !bAlt && bCtrl && bShift )
608
0
        switch ( nCode )
609
0
        {
610
0
            case KEY_SPACE:
611
0
                eId = BrowserDispatchId::SELECTCOLUMN;
612
0
                bLocalSelect = true;
613
0
                break;
614
0
        }
615
616
617
0
    if ( !bAlt && bCtrl && !bShift )
618
0
        switch ( nCode )
619
0
        {
620
0
            case KEY_DOWN:
621
0
                eId = BrowserDispatchId::SCROLLUP;
622
0
                break;
623
0
            case KEY_UP:
624
0
                eId = BrowserDispatchId::SCROLLDOWN;
625
0
                break;
626
0
            case KEY_PAGEDOWN:
627
0
                eId = BrowserDispatchId::CURSORENDOFFILE;
628
0
                break;
629
0
            case KEY_PAGEUP:
630
0
                eId = BrowserDispatchId::CURSORTOPOFFILE;
631
0
                break;
632
0
            case KEY_HOME:
633
0
                eId = BrowserDispatchId::CURSORTOPOFSCREEN;
634
0
                break;
635
0
            case KEY_END:
636
0
                eId = BrowserDispatchId::CURSORENDOFSCREEN;
637
0
                break;
638
0
            case KEY_SPACE:
639
0
                eId = BrowserDispatchId::ENHANCESELECTION;
640
0
                bLocalSelect = true;
641
0
                break;
642
0
        }
643
644
0
    if ((eId != BrowserDispatchId::NONE)
645
0
        && (!IsEditing() || (!bNonEditOnly && aController->MoveAllowed(rKeyEvent))))
646
0
    {
647
0
        if (eId == BrowserDispatchId::SELECT || BrowserDispatchId::SELECTCOLUMN == eId)
648
0
        {
649
            // save the cell content (if necessary)
650
0
            if (IsEditing() && aController->IsValueChangedFromSaved() && !SaveModified())
651
0
            {
652
                // maybe we're not visible ...
653
0
                EnableAndShow();
654
0
                aController->GetWindow().GrabFocus();
655
0
                return true;
656
0
            }
657
0
        }
658
659
0
        Dispatch(eId);
660
661
0
        if (bLocalSelect && (GetSelectRowCount() || GetSelection() != nullptr))
662
0
            DeactivateCell();
663
0
        return true;
664
0
    }
665
0
    return false;
666
0
}
667
668
bool EditBrowseBox::PreNotify(NotifyEvent& rEvt)
669
0
{
670
0
    if (rEvt.GetType() == NotifyEventType::KEYINPUT)
671
0
    {
672
0
        if  (   (IsEditing() && ControlHasFocus())
673
0
            ||  rEvt.GetWindow() == &GetDataWindow()
674
0
            ||  (!IsEditing() && HasChildPathFocus())
675
0
            )
676
0
        {
677
0
            if (ProcessKey(*rEvt.GetKeyEvent()))
678
0
                return true;
679
0
        }
680
0
    }
681
0
    return BrowseBox::PreNotify(rEvt);
682
0
}
683
684
bool EditBrowseBox::IsTabAllowed(bool) const
685
0
{
686
0
    return true;
687
0
}
688
689
690
bool EditBrowseBox::EventNotify(NotifyEvent& rEvt)
691
0
{
692
0
    switch (rEvt.GetType())
693
0
    {
694
0
        case NotifyEventType::GETFOCUS:
695
0
            DetermineFocus(getRealGetFocusFlags(this));
696
0
            break;
697
698
0
        case NotifyEventType::LOSEFOCUS:
699
0
            DetermineFocus();
700
0
            break;
701
702
0
        default:
703
0
            break;
704
0
    }
705
0
    return BrowseBox::EventNotify(rEvt);
706
0
}
707
708
709
void EditBrowseBox::StateChanged( StateChangedType nType )
710
0
{
711
0
    BrowseBox::StateChanged( nType );
712
713
0
    bool bNeedCellReActivation = false;
714
0
    if ( nType == StateChangedType::Mirroring )
715
0
    {
716
0
        bNeedCellReActivation = true;
717
0
    }
718
0
    else if ( nType == StateChangedType::Zoom )
719
0
    {
720
0
        ImplInitSettings( true, false, false );
721
0
        bNeedCellReActivation = true;
722
0
    }
723
0
    else if ( nType == StateChangedType::ControlFont )
724
0
    {
725
0
        ImplInitSettings( true, false, false );
726
0
        Invalidate();
727
0
    }
728
0
    else if ( nType == StateChangedType::ControlForeground )
729
0
    {
730
0
        ImplInitSettings( false, true, false );
731
0
        Invalidate();
732
0
    }
733
0
    else if ( nType == StateChangedType::ControlBackground )
734
0
    {
735
0
        ImplInitSettings( false, false, true );
736
0
        Invalidate();
737
0
    }
738
0
    else if (nType == StateChangedType::Style)
739
0
    {
740
0
        WinBits nStyle = GetStyle();
741
0
        if (!(nStyle & WB_NOTABSTOP) )
742
0
            nStyle |= WB_TABSTOP;
743
744
0
        SetStyle(nStyle);
745
0
    }
746
0
    if ( bNeedCellReActivation )
747
0
    {
748
0
        if ( IsEditing() )
749
0
        {
750
0
            DeactivateCell();
751
0
            ActivateCell();
752
0
        }
753
0
    }
754
0
}
755
756
757
void EditBrowseBox::DataChanged( const DataChangedEvent& rDCEvt )
758
0
{
759
0
    BrowseBox::DataChanged( rDCEvt );
760
761
0
    if ((( rDCEvt.GetType() == DataChangedEventType::SETTINGS )   ||
762
0
        ( rDCEvt.GetType() == DataChangedEventType::DISPLAY   ))  &&
763
0
        ( rDCEvt.GetFlags() & AllSettingsFlags::STYLE        ))
764
0
    {
765
0
        ImplInitSettings( true, true, true );
766
0
        Invalidate();
767
0
    }
768
0
}
769
770
void EditBrowseBox::ImplInitSettings( bool bFont, bool bForeground, bool bBackground )
771
0
{
772
0
    const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
773
774
0
    if (bFont)
775
0
    {
776
0
        vcl::Font aFont = rStyleSettings.GetFieldFont();
777
0
        if (IsControlFont())
778
0
        {
779
0
            GetDataWindow().SetControlFont(GetControlFont());
780
0
            aFont.Merge(GetControlFont());
781
0
        }
782
0
        else
783
0
            GetDataWindow().SetControlFont();
784
785
0
        GetDataWindow().SetZoomedPointFont(*GetDataWindow().GetOutDev(), aFont);
786
0
    }
787
788
0
    if (bFont || bForeground)
789
0
    {
790
0
        Color aTextColor = rStyleSettings.GetFieldTextColor();
791
0
        if (IsControlForeground())
792
0
        {
793
0
            aTextColor = GetControlForeground();
794
0
            GetDataWindow().SetControlForeground(aTextColor);
795
0
        }
796
0
        else
797
0
            GetDataWindow().SetControlForeground();
798
799
0
        GetDataWindow().SetTextColor( aTextColor );
800
0
    }
801
802
0
    if (!bBackground) // FIXME: Outside of Paint Hierarchy
803
0
        return;
804
805
0
    if (GetDataWindow().IsControlBackground())
806
0
    {
807
0
        GetDataWindow().SetControlBackground(GetControlBackground());
808
0
        GetDataWindow().SetBackground(GetDataWindow().GetControlBackground());
809
0
        GetDataWindow().GetOutDev()->SetFillColor(GetDataWindow().GetControlBackground());
810
0
    }
811
0
    else
812
0
    {
813
0
        GetDataWindow().SetControlBackground();
814
0
        GetDataWindow().SetBackground(rStyleSettings.GetFieldColor());
815
0
        GetDataWindow().GetOutDev()->SetFillColor(rStyleSettings.GetFieldColor());
816
0
    }
817
0
}
818
819
820
bool EditBrowseBox::IsCursorMoveAllowed(sal_Int32 nNewRow, sal_uInt16 nNewColId) const
821
0
{
822
0
    sal_uInt16 nInfo = 0;
823
824
0
    if (GetSelectColumnCount() || (aMouseEvent.Is() && aMouseEvent->GetRow() < 0))
825
0
        nInfo |= COLSELECT;
826
0
    if ((GetSelection() != nullptr && GetSelectRowCount()) ||
827
0
        (aMouseEvent.Is() && aMouseEvent->GetColumnId() == HandleColumnId))
828
0
        nInfo |= ROWSELECT;
829
0
    if (!nInfo && nNewRow != nEditRow)
830
0
        nInfo |= ROWCHANGE;
831
0
    if (!nInfo && nNewColId != nEditCol)
832
0
        nInfo |= COLCHANGE;
833
834
0
    if (nInfo == 0)   // nothing happened
835
0
        return true;
836
837
    // save the cell content
838
0
    if (IsEditing() && aController->IsValueChangedFromSaved() && !const_cast<EditBrowseBox *>(this)->SaveModified())
839
0
    {
840
        // maybe we're not visible ...
841
0
        EnableAndShow();
842
0
        aController->GetWindow().GrabFocus();
843
0
        return false;
844
0
    }
845
846
0
    EditBrowseBox * pTHIS = const_cast<EditBrowseBox *> (this);
847
848
    // save the cell content if
849
    // a) a selection is being made
850
    // b) the row is changing
851
0
    if (IsModified() && (nInfo & (ROWCHANGE | COLSELECT | ROWSELECT)) &&
852
0
        !pTHIS->SaveRow())
853
0
    {
854
0
        if (nInfo & COLSELECT ||
855
0
            nInfo & ROWSELECT)
856
0
        {
857
            // cancel selected
858
0
            pTHIS->SetNoSelection();
859
0
        }
860
861
0
        if (IsEditing())
862
0
        {
863
0
            if (!Controller()->GetWindow().IsVisible())
864
0
            {
865
0
                EnableAndShow();
866
0
            }
867
0
            aController->GetWindow().GrabFocus();
868
0
        }
869
0
        return false;
870
0
    }
871
872
0
    if (nNewRow != nEditRow)
873
0
    {
874
0
        vcl::Window& rWindow = GetDataWindow();
875
0
        if ((nEditRow >= 0) && !(GetBrowserFlags() & EditBrowseBoxFlags::NO_HANDLE_COLUMN_CONTENT))
876
0
        {
877
0
            tools::Rectangle aRect = GetFieldRectPixel(nEditRow, 0, false );
878
            // status cell should be painted if and only if text is displayed
879
0
            pTHIS->bPaintStatus = ( GetBrowserFlags() & EditBrowseBoxFlags::HANDLE_COLUMN_TEXT ) == EditBrowseBoxFlags::HANDLE_COLUMN_TEXT;
880
0
            rWindow.Invalidate(aRect);
881
0
            pTHIS->bPaintStatus = true;
882
0
        }
883
884
        // don't paint during row change
885
0
        rWindow.EnablePaint(false);
886
887
        // the last veto chance for derived classes
888
0
        if (!pTHIS->CursorMoving(nNewRow, nNewColId))
889
0
        {
890
0
            pTHIS->InvalidateStatusCell(nEditRow);
891
0
            rWindow.EnablePaint(true);
892
0
            return false;
893
0
        }
894
0
        else
895
0
        {
896
0
            rWindow.EnablePaint(true);
897
0
            return true;
898
0
        }
899
0
    }
900
0
    else
901
0
        return pTHIS->CursorMoving(nNewRow, nNewColId);
902
0
}
903
904
905
void EditBrowseBox::ColumnMoved(sal_uInt16 nId)
906
0
{
907
0
    BrowseBox::ColumnMoved(nId);
908
0
    if (IsEditing())
909
0
    {
910
0
        tools::Rectangle aRect( GetCellRect(nEditRow, nEditCol, false));
911
0
        CellControllerRef aControllerRef = Controller();
912
0
        ResizeController(aControllerRef, aRect);
913
0
        Controller()->GetWindow().GrabFocus();
914
0
    }
915
0
}
916
917
918
bool EditBrowseBox::SaveRow()
919
0
{
920
0
    return true;
921
0
}
922
923
924
bool EditBrowseBox::CursorMoving(sal_Int32, sal_uInt16)
925
0
{
926
0
    DeactivateCell(false);
927
0
    return true;
928
0
}
929
930
931
void EditBrowseBox::CursorMoved()
932
0
{
933
0
    sal_Int32 nNewRow = GetCurRow();
934
0
    if (nEditRow != nNewRow)
935
0
    {
936
0
        if (!(GetBrowserFlags() & EditBrowseBoxFlags::NO_HANDLE_COLUMN_CONTENT))
937
0
            InvalidateStatusCell(nNewRow);
938
0
        nEditRow = nNewRow;
939
0
    }
940
0
    ActivateCell();
941
0
    GetDataWindow().EnablePaint(true);
942
    // should not be called here because the descant event is not needed here
943
    //BrowseBox::CursorMoved();
944
0
}
945
946
947
void EditBrowseBox::EndScroll()
948
0
{
949
0
    if (IsEditing())
950
0
    {
951
0
        tools::Rectangle aRect = GetCellRect(nEditRow, nEditCol, false);
952
0
        ResizeController(aController,aRect);
953
0
        AsynchGetFocus();
954
0
    }
955
0
    BrowseBox::EndScroll();
956
0
}
957
958
959
void EditBrowseBox::ActivateCell(sal_Int32 nRow, sal_uInt16 nCol, bool bCellFocus)
960
0
{
961
0
    if (IsEditing())
962
0
        return;
963
964
0
    nEditCol = nCol;
965
966
0
    if ((GetSelectRowCount() && GetSelection() != nullptr) || GetSelectColumnCount() ||
967
0
        (aMouseEvent.Is() && (aMouseEvent.IsDown() || aMouseEvent->GetClicks() > 1))) // nothing happens on MouseDown
968
0
    {
969
0
        return;
970
0
    }
971
972
0
    if (nEditRow < 0 || nEditCol <= HandleColumnId)
973
0
        return;
974
975
0
    aController = GetController(nRow, nCol);
976
0
    if (aController.is())
977
0
    {
978
0
        tools::Rectangle aRect( GetCellRect(nEditRow, nEditCol, false));
979
0
        ResizeController(aController, aRect);
980
981
0
        InitController(aController, nEditRow, nEditCol);
982
983
0
        aController->SaveValue();
984
0
        aController->SetModifyHdl(LINK(this,EditBrowseBox,ModifyHdl));
985
0
        EnableAndShow();
986
987
0
        if ( isAccessibleAlive() )
988
0
            implCreateActiveAccessible();
989
990
        // activate the cell only of the browser has the focus
991
0
        if ( bHasFocus && bCellFocus )
992
0
            AsynchGetFocus();
993
0
    }
994
0
    else
995
0
    {
996
        // no controller -> we have a new "active descendant"
997
0
        if ( isAccessibleAlive() && HasFocus() )
998
0
        {
999
0
            commitTableEvent(AccessibleEventId::ACTIVE_DESCENDANT_CHANGED,
1000
0
                             Any(css::uno::Reference<XAccessible>(
1001
0
                                 CreateAccessibleCell(nRow, GetColumnPos(nCol - 1)))),
1002
0
                             Any());
1003
0
        }
1004
0
    }
1005
0
}
1006
1007
1008
void EditBrowseBox::DeactivateCell(bool bUpdate)
1009
0
{
1010
0
    if (!IsEditing())
1011
0
        return;
1012
1013
0
    if (isAccessibleAlive() && m_pActiveCell.is())
1014
0
    {
1015
0
        commitBrowseBoxEvent(AccessibleEventId::CHILD, Any(),
1016
0
                             Any(css::uno::Reference<XAccessible>(m_pActiveCell)));
1017
0
        clearActiveCell();
1018
0
    }
1019
1020
0
    aOldController = aController;
1021
0
    aController.clear();
1022
1023
    // reset the modify handler
1024
0
    aOldController->SetModifyHdl(Link<LinkParamNone*,void>());
1025
1026
0
    if (bHasFocus)
1027
0
        GrabFocus(); // ensure that we have (and keep) the focus
1028
1029
0
    aOldController->suspend();
1030
1031
    // update if requested
1032
0
    if (bUpdate)
1033
0
        PaintImmediately();
1034
1035
    // release the controller (asynchronously)
1036
0
    if (nEndEvent)
1037
0
        Application::RemoveUserEvent(nEndEvent);
1038
0
    nEndEvent = Application::PostUserEvent(LINK(this,EditBrowseBox,EndEditHdl), nullptr, true);
1039
0
}
1040
1041
1042
tools::Rectangle EditBrowseBox::GetCellRect(sal_Int32 nRow, sal_uInt16 nColId, bool bRel) const
1043
0
{
1044
0
    tools::Rectangle aRect( GetFieldRectPixel(nRow, nColId, bRel));
1045
0
    if ((GetMode()  & BrowserMode::CURSOR_WO_FOCUS) == BrowserMode::CURSOR_WO_FOCUS)
1046
0
    {
1047
0
        aRect.AdjustTop(1 );
1048
0
        aRect.AdjustBottom( -1 );
1049
0
    }
1050
0
    return aRect;
1051
0
}
1052
1053
1054
IMPL_LINK_NOARG(EditBrowseBox, EndEditHdl, void*, void)
1055
0
{
1056
0
    nEndEvent = nullptr;
1057
1058
0
    aOldController  = CellControllerRef();
1059
0
}
1060
1061
1062
IMPL_LINK_NOARG(EditBrowseBox, ModifyHdl, LinkParamNone*, void)
1063
0
{
1064
0
    if (nCellModifiedEvent)
1065
0
        Application::RemoveUserEvent(nCellModifiedEvent);
1066
0
    nCellModifiedEvent = Application::PostUserEvent(LINK(this,EditBrowseBox,CellModifiedHdl), nullptr, true);
1067
0
}
1068
1069
1070
IMPL_LINK_NOARG(EditBrowseBox, CellModifiedHdl, void*, void)
1071
0
{
1072
0
    nCellModifiedEvent = nullptr;
1073
0
    CellModified();
1074
0
}
1075
1076
void EditBrowseBox::ColumnResized( sal_uInt16 )
1077
0
{
1078
0
    if (IsEditing())
1079
0
    {
1080
0
        tools::Rectangle aRect( GetCellRect(nEditRow, nEditCol, false));
1081
0
        CellControllerRef aControllerRef = Controller();
1082
0
        ResizeController(aControllerRef, aRect);
1083
        // don't grab focus if Field Properties panel is being
1084
        // resized by split pane drag resizing
1085
0
        if (Application::IsUICaptured())
1086
0
            return;
1087
0
        Controller()->GetWindow().GrabFocus();
1088
0
    }
1089
0
}
1090
1091
sal_uInt16 EditBrowseBox::AppendColumn(const OUString& rName, sal_uInt16 nWidth, sal_uInt16 nPos, sal_uInt16 nId)
1092
0
{
1093
0
    if (nId == BROWSER_INVALIDID)
1094
0
    {
1095
        // look for the next free id
1096
0
        for (nId = ColCount(); nId > 0 && GetColumnPos(nId) != BROWSER_INVALIDID; nId--)
1097
0
            ;
1098
1099
0
        if (!nId)
1100
0
        {
1101
            // if there is no handle column
1102
            // increment the id
1103
0
            if ( ColCount() == 0 || GetColumnId(0) != HandleColumnId )
1104
0
                nId = ColCount() + 1;
1105
0
        }
1106
0
    }
1107
1108
0
    DBG_ASSERT(nId, "EditBrowseBox::AppendColumn: invalid id!");
1109
1110
0
    tools::Long w = nWidth;
1111
0
    if (!w)
1112
0
        w = GetDefaultColumnWidth(rName);
1113
1114
0
    InsertDataColumn(nId, rName, w, (HeaderBarItemBits::CENTER | HeaderBarItemBits::CLICKABLE), nPos);
1115
0
    return nId;
1116
0
}
1117
1118
void EditBrowseBox::Resize()
1119
0
{
1120
0
    BrowseBox::Resize();
1121
1122
    // if the window is smaller than "title line height" + "control area",
1123
    // do nothing
1124
0
    if (GetOutputSizePixel().Height() <
1125
0
       (GetControlArea().GetHeight() + GetDataWindow().GetPosPixel().Y()))
1126
0
        return;
1127
1128
    // the size of the control area
1129
0
    Point aPoint(GetControlArea().TopLeft());
1130
0
    sal_uInt16 nX = static_cast<sal_uInt16>(aPoint.X());
1131
1132
0
    ArrangeControls(nX, static_cast<sal_uInt16>(aPoint.Y()));
1133
1134
0
    if (!nX)
1135
0
        nX = USHRT_MAX;
1136
1137
0
    bool bChanged = ReserveControlArea(nX);
1138
1139
    //tdf#97731 if the reserved area changed size, give the controls a
1140
    //chance to adapt to the new size
1141
0
    if (bChanged)
1142
0
    {
1143
0
        nX = static_cast<sal_uInt16>(aPoint.X());
1144
0
        ArrangeControls(nX, static_cast<sal_uInt16>(aPoint.Y()));
1145
0
    }
1146
0
}
1147
1148
void EditBrowseBox::ArrangeControls(sal_uInt16&, sal_uInt16)
1149
0
{
1150
0
}
1151
1152
CellController* EditBrowseBox::GetController(sal_Int32, sal_uInt16)
1153
0
{
1154
0
    return nullptr;
1155
0
}
1156
1157
void EditBrowseBox::ResizeController(CellControllerRef const & rController, const tools::Rectangle& rRect)
1158
0
{
1159
0
    Point aPoint(rRect.TopLeft());
1160
0
    Size aSize(rRect.GetSize());
1161
0
    Control& rControl = rController->GetWindow();
1162
0
    auto nMinHeight = rControl.get_preferred_size().Height();
1163
0
    if (nMinHeight > aSize.Height())
1164
0
    {
1165
0
        auto nOffset = (nMinHeight - aSize.Height()) / 2;
1166
0
        aPoint.AdjustY(-nOffset);
1167
0
        aSize.setHeight(nMinHeight);
1168
0
    }
1169
0
    rControl.SetPosSizePixel(aPoint, aSize);
1170
0
}
1171
1172
void EditBrowseBox::InitController(CellControllerRef&, sal_Int32, sal_uInt16)
1173
0
{
1174
0
}
1175
1176
1177
void EditBrowseBox::CellModified()
1178
0
{
1179
0
}
1180
1181
1182
bool EditBrowseBox::SaveModified()
1183
0
{
1184
0
    return true;
1185
0
}
1186
1187
1188
void EditBrowseBox::DoubleClick(const BrowserMouseEvent& rEvt)
1189
0
{
1190
    // when double clicking on the column, the optimum size will be calculated
1191
0
    sal_uInt16 nColId = rEvt.GetColumnId();
1192
0
    if (nColId != HandleColumnId)
1193
0
        SetColumnWidth(nColId, GetAutoColumnWidth(nColId));
1194
0
}
1195
1196
1197
sal_uInt32 EditBrowseBox::GetAutoColumnWidth(sal_uInt16 nColId)
1198
0
{
1199
0
    sal_uInt32 nCurColWidth  = GetColumnWidth(nColId);
1200
0
    sal_uInt32 nMinColWidth = CalcZoom(20); // minimum
1201
0
    sal_uInt32 nNewColWidth = nMinColWidth;
1202
0
    sal_Int32 nMaxRows      = std::min(sal_Int32(GetVisibleRows()), GetRowCount());
1203
0
    sal_Int32 nLastVisRow   = GetTopRow() + nMaxRows - 1;
1204
1205
0
    if (GetTopRow() <= nLastVisRow) // calc the column with using the cell contents
1206
0
    {
1207
0
        for (tools::Long i = GetTopRow(); i <= nLastVisRow; ++i)
1208
0
            nNewColWidth = std::max(nNewColWidth,GetTotalCellWidth(i,nColId) + 12);
1209
1210
0
        if (nNewColWidth == nCurColWidth)   // size has not changed
1211
0
            nNewColWidth = GetDefaultColumnWidth(GetColumnTitle(nColId));
1212
0
    }
1213
0
    else
1214
0
        nNewColWidth = GetDefaultColumnWidth(GetColumnTitle(nColId));
1215
0
    return nNewColWidth;
1216
0
}
1217
1218
sal_uInt32 EditBrowseBox::GetTotalCellWidth(sal_Int32, sal_uInt16)
1219
0
{
1220
0
    return 0;
1221
0
}
1222
1223
void EditBrowseBox::InvalidateHandleColumn()
1224
0
{
1225
0
    tools::Rectangle aHdlFieldRect( GetFieldRectPixel( 0, 0 ));
1226
0
    tools::Rectangle aInvalidRect( Point(0,0), GetOutputSizePixel() );
1227
0
    aInvalidRect.SetRight( aHdlFieldRect.Right() );
1228
0
    Invalidate( aInvalidRect );
1229
0
}
1230
1231
void EditBrowseBox::PaintTristate(const tools::Rectangle& rRect, const TriState& eState, bool _bEnabled) const
1232
0
{
1233
0
    pCheckBoxPaint->SetState(eState);
1234
1235
0
    pCheckBoxPaint->GetBox().set_sensitive(_bEnabled);
1236
1237
0
    Size aBoxSize = pCheckBoxPaint->GetBox().get_preferred_size();
1238
0
    tools::Rectangle aRect(Point(rRect.Left() + ((rRect.GetWidth() - aBoxSize.Width()) / 2),
1239
0
                                 rRect.Top() + ((rRect.GetHeight() - aBoxSize.Height()) / 2)),
1240
0
                           aBoxSize);
1241
0
    pCheckBoxPaint->SetPosSizePixel(aRect.TopLeft(), aRect.GetSize());
1242
1243
0
    pCheckBoxPaint->Draw(GetDataWindow().GetOutDev(), aRect.TopLeft(), SystemTextColorFlags::NONE);
1244
0
}
1245
1246
void EditBrowseBox::AsynchGetFocus()
1247
0
{
1248
0
    if (nStartEvent)
1249
0
        Application::RemoveUserEvent(nStartEvent);
1250
1251
0
    m_pFocusWhileRequest = Application::GetFocusWindow();
1252
0
    nStartEvent = Application::PostUserEvent(LINK(this,EditBrowseBox,StartEditHdl), nullptr, true);
1253
0
}
1254
1255
1256
void EditBrowseBox::SetBrowserFlags(EditBrowseBoxFlags nFlags)
1257
0
{
1258
0
    if (m_nBrowserFlags == nFlags)
1259
0
        return;
1260
1261
0
    bool RowPicturesChanges = ((m_nBrowserFlags & EditBrowseBoxFlags::NO_HANDLE_COLUMN_CONTENT) !=
1262
0
                                   (nFlags & EditBrowseBoxFlags::NO_HANDLE_COLUMN_CONTENT));
1263
0
    m_nBrowserFlags = nFlags;
1264
1265
0
    if (RowPicturesChanges)
1266
0
        InvalidateStatusCell(GetCurRow());
1267
0
}
1268
1269
inline void EditBrowseBox::EnableAndShow() const
1270
0
{
1271
0
    Controller()->resume();
1272
0
}
1273
1274
CellController::CellController(ControlBase* pW)
1275
0
    : pWindow(pW)
1276
0
    , bSuspended( true )
1277
0
{
1278
1279
0
    DBG_ASSERT(pWindow, "CellController::CellController: missing the window!");
1280
0
    DBG_ASSERT(!pWindow->IsVisible(), "CellController::CellController: window should not be visible!");
1281
0
}
1282
1283
CellController::~CellController()
1284
0
{
1285
0
}
1286
1287
void CellController::suspend( )
1288
0
{
1289
0
    DBG_ASSERT( bSuspended == !GetWindow().IsVisible(), "CellController::suspend: inconsistence!" );
1290
0
    if ( !isSuspended( ) )
1291
0
    {
1292
0
        CommitModifications();
1293
0
        GetWindow().Hide( );
1294
0
        GetWindow().Disable( );
1295
0
        bSuspended = true;
1296
0
    }
1297
0
}
1298
1299
void CellController::resume( )
1300
0
{
1301
0
    DBG_ASSERT( bSuspended == !GetWindow().IsVisible(), "CellController::resume: inconsistence!" );
1302
0
    if ( isSuspended( ) )
1303
0
    {
1304
0
        GetWindow().Enable( );
1305
0
        GetWindow().Show( );
1306
0
        bSuspended = false;
1307
0
    }
1308
0
}
1309
1310
void CellController::CommitModifications()
1311
0
{
1312
    // nothing to do in this base class
1313
0
}
1314
1315
void CellController::ActivatingMouseEvent(const BrowserMouseEvent& /*rEvt*/, bool /*bUp*/)
1316
0
{
1317
    // nothing to do in this base class
1318
0
}
1319
1320
bool CellController::MoveAllowed(const KeyEvent&) const
1321
0
{
1322
0
    return true;
1323
0
}
1324
1325
}   // namespace svt
1326
1327
1328
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */