1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <svtools/simptabl.hxx>
21 #include <unotools/intlwrapper.hxx>
22 #include <vcl/svlbitm.hxx>
23 #include <vcl/treelistentry.hxx>
24 #include <vcl/builderfactory.hxx>
25 #include <vcl/svapp.hxx>
26 #include <vcl/settings.hxx>
27 #include <vcl/event.hxx>
28 #include <uitest/uiobject.hxx>
30 SvSimpleTableContainer::SvSimpleTableContainer(vcl::Window
* pParent
, WinBits nBits
)
31 : Control(pParent
, nBits
)
36 SvSimpleTableContainer::~SvSimpleTableContainer()
41 void SvSimpleTableContainer::dispose()
47 VCL_BUILDER_FACTORY_ARGS(SvSimpleTableContainer
,
48 WB_TABSTOP
| WB_DIALOGCONTROL
| WB_BORDER
)
50 void SvSimpleTableContainer::SetTable(SvSimpleTable
* pTable
)
55 SvSimpleTable
* SvSimpleTableContainer::GetTable()
57 return m_pTable
.get();
60 bool SvSimpleTableContainer::PreNotify( NotifyEvent
& rNEvt
)
63 if ( rNEvt
.GetType() == MouseNotifyEvent::KEYINPUT
)
65 const vcl::KeyCode
& aKeyCode
= rNEvt
.GetKeyEvent()->GetKeyCode();
66 sal_uInt16 nKey
= aKeyCode
.GetCode();
68 GetParent()->EventNotify( rNEvt
);
69 else if (m_pTable
&& m_pTable
->IsFocusOnCellEnabled() && ( nKey
== KEY_LEFT
|| nKey
== KEY_RIGHT
))
72 bResult
= Control::PreNotify( rNEvt
);
75 bResult
= Control::PreNotify( rNEvt
);
80 void SvSimpleTableContainer::Resize()
84 m_pTable
->UpdateViewSize();
87 void SvSimpleTableContainer::GetFocus()
91 m_pTable
->GrabFocus();
94 FactoryFunction
SvSimpleTableContainer::GetUITestFactory() const
96 return SimpleTableUIObject::createFromContainer
;
99 // SvSimpleTable ------------------------------------------------------------
101 SvSimpleTable::SvSimpleTable(SvSimpleTableContainer
& rParent
, WinBits nBits
):
102 SvHeaderTabListBox(&rParent
, nBits
| WB_CLIPCHILDREN
| WB_HSCROLL
| WB_TABSTOP
),
103 m_rParentTableContainer(rParent
),
104 aHeaderBar(VclPtr
<HeaderBar
>::Create(&rParent
,WB_BUTTONSTYLE
| WB_BORDER
| WB_TABSTOP
)),
107 aCollator(*(IntlWrapper(SvtSysLocale().GetUILanguageTag()).getCaseCollator()))
109 m_rParentTableContainer
.SetTable(this);
111 bSortDirection
= true;
115 aHeaderBar
->SetStartDragHdl(LINK( this, SvSimpleTable
, StartDragHdl
));
116 aHeaderBar
->SetDragHdl(LINK( this, SvSimpleTable
, DragHdl
));
117 aHeaderBar
->SetEndDragHdl(LINK( this, SvSimpleTable
, EndDragHdl
));
118 aHeaderBar
->SetSelectHdl(LINK( this, SvSimpleTable
, HeaderBarClick
));
122 DisableTransientChildren();
123 InitHeaderBar( aHeaderBar
);
128 SvHeaderTabListBox::Show();
131 SvSimpleTable::~SvSimpleTable()
136 void SvSimpleTable::dispose()
138 m_rParentTableContainer
.SetTable(nullptr);
139 aHeaderBar
.disposeAndClear();
140 SvHeaderTabListBox::dispose();
143 void SvSimpleTable::UpdateViewSize()
145 Size theWinSize
=m_rParentTableContainer
.GetOutputSizePixel();
146 Size HbSize
=aHeaderBar
->GetSizePixel();
148 HbSize
.setWidth(theWinSize
.Width() );
149 theWinSize
.AdjustHeight(-HbSize
.Height());
152 aHeaderBar
->SetPosPixel(thePos
);
153 aHeaderBar
->SetSizePixel(HbSize
);
155 thePos
.AdjustY(HbSize
.Height());
156 SvHeaderTabListBox::SetPosPixel(thePos
);
157 SvHeaderTabListBox::SetSizePixel(theWinSize
);
161 void SvSimpleTable::NotifyScrolled()
163 long nOffset
=-GetXOffset();
166 aHeaderBar
->SetOffset(nOffset
);
167 aHeaderBar
->Invalidate();
168 aHeaderBar
->Update();
171 SvHeaderTabListBox::NotifyScrolled();
174 void SvSimpleTable::SetTabs()
176 SvHeaderTabListBox::SetTabs();
178 sal_uInt16 nPrivTabCount
= TabCount();
179 if ( !nPrivTabCount
)
182 if ( nPrivTabCount
> aHeaderBar
->GetItemCount() )
183 nPrivTabCount
= aHeaderBar
->GetItemCount();
185 sal_uInt16 i
, nPos
= 0;
186 for ( i
= 1; i
< nPrivTabCount
; ++i
)
188 sal_uInt16 nNewSize
= static_cast< sal_uInt16
>( GetTab(i
) ) - nPos
;
189 aHeaderBar
->SetItemSize( i
, nNewSize
);
190 nPos
= static_cast<sal_uInt16
>(GetTab(i
));
193 aHeaderBar
->SetItemSize( i
, HEADERBAR_FULLSIZE
); // because no tab for last entry
196 void SvSimpleTable::Paint(vcl::RenderContext
& rRenderContext
, const tools::Rectangle
& rRect
)
198 SvHeaderTabListBox::Paint(rRenderContext
, rRect
);
200 sal_uInt16 nPrivTabCount
= TabCount();
202 long nOffset
=- GetXOffset();
205 aHeaderBar
->SetOffset(nOffset
);
206 aHeaderBar
->Invalidate();
208 if (nPrivTabCount
&& bPaintFlag
)
210 if (nPrivTabCount
>aHeaderBar
->GetItemCount())
211 nPrivTabCount
=aHeaderBar
->GetItemCount();
214 for (sal_uInt16 i
= 1; i
< nPrivTabCount
; i
++)
216 sal_uInt16 nNewSize
= static_cast<sal_uInt16
>(GetTab(i
)) - nPos
;
217 aHeaderBar
->SetItemSize(i
, nNewSize
);
218 nPos
= static_cast<sal_uInt16
>(GetTab(i
));
224 void SvSimpleTable::InsertHeaderEntry(const OUString
& rText
,
225 sal_uInt16 nCol
, HeaderBarItemBits nBits
)
227 sal_Int32 nEnd
= rText
.indexOf( '\t' );
230 aHeaderBar
->InsertItem(nHeaderItemId
++, rText
, 0, nBits
, nCol
);
234 sal_Int32 nIndex
= 0;
237 OUString aString
= rText
.getToken(0, '\t', nIndex
);
238 aHeaderBar
->InsertItem(nHeaderItemId
++, aString
, 0, nBits
, nCol
);
240 while ( nIndex
>= 0 );
245 void SvSimpleTable::EnableTable()
247 m_rParentTableContainer
.Enable();
250 void SvSimpleTable::DisableTable()
252 m_rParentTableContainer
.Disable();
255 bool SvSimpleTable::IsEnabled() const
257 return m_rParentTableContainer
.IsEnabled();
260 void SvSimpleTable::SortByCol(sal_uInt16 nCol
, bool bDir
)
263 aHeaderBar
->SetItemBits(nSortCol
+1,HeaderBarItemBits::STDSTYLE
);
267 if(bDir
|| nSortCol
!= nCol
)
269 aHeaderBar
->SetItemBits( nCol
+1, HeaderBarItemBits::STDSTYLE
| HeaderBarItemBits::DOWNARROW
);
270 GetModel()->SetSortMode(SortAscending
);
275 aHeaderBar
->SetItemBits( nCol
+1, HeaderBarItemBits::STDSTYLE
| HeaderBarItemBits::UPARROW
);
276 GetModel()->SetSortMode(SortDescending
);
279 GetModel()->SetCompareHdl( LINK( this, SvSimpleTable
, CompareHdl
));
283 GetModel()->Reverse();
284 Resize(); //update rows
289 GetModel()->Resort();
293 GetModel()->SetSortMode(SortNone
);
296 SetAlternatingRowColors( true );
299 void SvSimpleTable::HBarClick()
301 sal_uInt16 nId
=aHeaderBar
->GetCurItemId();
303 if (!(aHeaderBar
->GetItemBits(nId
) & HeaderBarItemBits::CLICKABLE
))
308 SortByCol(nId
-1,!bSortDirection
);
312 SortByCol(nId
-1,bSortDirection
);
316 void SvSimpleTable::HBarDrag()
319 if(!aHeaderBar
->IsItemMode())
321 tools::Rectangle
aSizeRect(Point(0,0),
322 SvHeaderTabListBox::GetOutputSizePixel());
323 aSizeRect
.SetLeft(-GetXOffset()+aHeaderBar
->GetDragPos() );
324 aSizeRect
.SetRight(-GetXOffset()+aHeaderBar
->GetDragPos() );
325 ShowTracking( aSizeRect
, ShowTrackFlags::Split
);
328 void SvSimpleTable::HBarEndDrag()
331 sal_uInt16 nPrivTabCount
=TabCount();
335 if(nPrivTabCount
>aHeaderBar
->GetItemCount())
336 nPrivTabCount
=aHeaderBar
->GetItemCount();
339 sal_uInt16 nNewSize
=0;
340 for(sal_uInt16 i
=1;i
<nPrivTabCount
;i
++)
342 nNewSize
= static_cast< sal_uInt16
>( aHeaderBar
->GetItemSize(i
) ) + nPos
;
343 SetTab( i
, nNewSize
, MapUnit::MapPixel
);
353 void SvSimpleTable::Command( const CommandEvent
& rCEvt
)
356 aCommandLink
.Call(this);
357 SvHeaderTabListBox::Command(rCEvt
);
360 IMPL_LINK( SvSimpleTable
, StartDragHdl
, HeaderBar
*, pCtr
, void)
362 if(pCtr
==aHeaderBar
.get())
364 if(!aHeaderBar
->IsItemMode())
366 tools::Rectangle
aSizeRect(Point(0,0),
367 SvHeaderTabListBox::GetOutputSizePixel());
368 aSizeRect
.SetLeft(-GetXOffset()+aHeaderBar
->GetDragPos() );
369 aSizeRect
.SetRight(-GetXOffset()+aHeaderBar
->GetDragPos() );
370 ShowTracking( aSizeRect
, ShowTrackFlags::Split
);
375 IMPL_LINK( SvSimpleTable
, DragHdl
, HeaderBar
*, pCtr
, void)
377 if(pCtr
==aHeaderBar
.get())
383 IMPL_LINK( SvSimpleTable
, EndDragHdl
, HeaderBar
*, pCtr
, void)
385 if(pCtr
==aHeaderBar
.get())
391 IMPL_LINK( SvSimpleTable
, HeaderBarClick
, HeaderBar
*, pCtr
, void)
393 if(pCtr
==aHeaderBar
.get())
399 SvLBoxItem
* SvSimpleTable::GetEntryAtPos( SvTreeListEntry
* pEntry
, sal_uInt16 nPos
) const
401 DBG_ASSERT(pEntry
,"GetEntryText:Invalid Entry");
402 SvLBoxItem
* pItem
= nullptr;
406 sal_uInt16 nCount
= pEntry
->ItemCount();
410 if( nTreeFlags
& SvTreeFlags::CHKBTN
) nPos
++;
414 pItem
= &pEntry
->GetItem( nPos
);
420 sal_Int32
SvSimpleTable::ColCompare(SvTreeListEntry
* pLeft
,SvTreeListEntry
* pRight
)
422 sal_Int32 nCompare
= 0;
424 SvLBoxItem
* pLeftItem
= GetEntryAtPos( pLeft
, nSortCol
);
425 SvLBoxItem
* pRightItem
= GetEntryAtPos( pRight
, nSortCol
);
428 if(pLeftItem
!= nullptr && pRightItem
!= nullptr)
430 SvLBoxItemType nLeftKind
= pLeftItem
->GetType();
431 SvLBoxItemType nRightKind
= pRightItem
->GetType();
433 if (nRightKind
== SvLBoxItemType::String
&&
434 nLeftKind
== SvLBoxItemType::String
)
435 nCompare
= aCollator
.compareString( static_cast<SvLBoxString
*>(pLeftItem
)->GetText(),
436 static_cast<SvLBoxString
*>(pRightItem
)->GetText());
441 IMPL_LINK( SvSimpleTable
, CompareHdl
, const SvSortData
&, rData
, sal_Int32
)
443 SvTreeListEntry
* pLeft
= const_cast<SvTreeListEntry
*>(rData
.pLeft
);
444 SvTreeListEntry
* pRight
= const_cast<SvTreeListEntry
*>(rData
.pRight
);
445 return ColCompare(pLeft
,pRight
);
448 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */