Line data Source code
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 <comphelper/processfactory.hxx>
21 : #include <svtools/simptabl.hxx>
22 : #include <svtools/svlbitm.hxx>
23 : #include <svtools/treelistentry.hxx>
24 : #include <unotools/intlwrapper.hxx>
25 : #include <vcl/builder.hxx>
26 : #include <vcl/svapp.hxx>
27 : #include <vcl/settings.hxx>
28 :
29 : // SvSimpleTableContainer ------------------------------------------------------
30 :
31 0 : SvSimpleTableContainer::SvSimpleTableContainer(Window* pParent, const ResId& rResId)
32 : : Control(pParent, rResId)
33 0 : , m_pTable(NULL)
34 : {
35 0 : SetBorderStyle(WINDOW_BORDER_NOBORDER);
36 0 : }
37 :
38 0 : SvSimpleTableContainer::SvSimpleTableContainer(Window* pParent, WinBits nBits)
39 : : Control(pParent, nBits)
40 0 : , m_pTable(NULL)
41 : {
42 0 : }
43 :
44 0 : extern "C" SAL_DLLPUBLIC_EXPORT Window* SAL_CALL makeSvSimpleTableContainer(Window *pParent,
45 : VclBuilder::stringmap &)
46 : {
47 0 : return new SvSimpleTableContainer(pParent, WB_TABSTOP | WB_DIALOGCONTROL | WB_BORDER);
48 : }
49 :
50 0 : void SvSimpleTableContainer::SetTable(SvSimpleTable* pTable)
51 : {
52 0 : m_pTable = pTable;
53 0 : }
54 :
55 0 : bool SvSimpleTableContainer::PreNotify( NotifyEvent& rNEvt )
56 : {
57 0 : bool nResult = true;
58 0 : if ( rNEvt.GetType() == EVENT_KEYINPUT )
59 : {
60 0 : const KeyCode& aKeyCode = rNEvt.GetKeyEvent()->GetKeyCode();
61 0 : sal_uInt16 nKey = aKeyCode.GetCode();
62 0 : if (nKey == KEY_TAB)
63 0 : GetParent()->Notify( rNEvt );
64 0 : else if (m_pTable && m_pTable->IsFocusOnCellEnabled() && ( nKey == KEY_LEFT || nKey == KEY_RIGHT))
65 0 : return false;
66 : else
67 0 : nResult = Control::PreNotify( rNEvt );
68 : }
69 : else
70 0 : nResult = Control::PreNotify( rNEvt );
71 :
72 0 : return nResult;
73 : }
74 :
75 0 : void SvSimpleTableContainer::Resize()
76 : {
77 0 : Control::Resize();
78 0 : if (m_pTable)
79 0 : m_pTable->UpdateViewSize();
80 0 : }
81 :
82 0 : void SvSimpleTableContainer::GetFocus()
83 : {
84 0 : Control::GetFocus();
85 0 : if (m_pTable)
86 0 : m_pTable->GrabFocus();
87 0 : }
88 :
89 : // SvSimpleTable ------------------------------------------------------------
90 :
91 0 : SvSimpleTable::SvSimpleTable(SvSimpleTableContainer& rParent, WinBits nBits):
92 : SvHeaderTabListBox(&rParent, nBits | WB_CLIPCHILDREN | WB_HSCROLL | WB_TABSTOP),
93 : m_rParentTableContainer(rParent),
94 : aHeaderBar(&rParent,WB_BUTTONSTYLE | WB_BORDER | WB_TABSTOP),
95 : nHeaderItemId(1),
96 0 : bPaintFlag(true)
97 : {
98 0 : m_rParentTableContainer.SetTable(this);
99 :
100 0 : bSortDirection = true;
101 0 : nSortCol = 0xFFFF;
102 0 : nOldPos = 0;
103 :
104 0 : aHeaderBar.SetStartDragHdl(LINK( this, SvSimpleTable, StartDragHdl));
105 0 : aHeaderBar.SetDragHdl(LINK( this, SvSimpleTable, DragHdl));
106 0 : aHeaderBar.SetEndDragHdl(LINK( this, SvSimpleTable, EndDragHdl));
107 0 : aHeaderBar.SetSelectHdl(LINK( this, SvSimpleTable, HeaderBarClick));
108 0 : aHeaderBar.SetDoubleClickHdl(LINK( this, SvSimpleTable, HeaderBarDblClick));
109 :
110 0 : EnableCellFocus();
111 0 : DisableTransientChildren();
112 0 : InitHeaderBar( &aHeaderBar );
113 :
114 0 : UpdateViewSize();
115 :
116 0 : aHeaderBar.Show();
117 0 : SvHeaderTabListBox::Show();
118 0 : }
119 :
120 0 : SvSimpleTable::~SvSimpleTable()
121 : {
122 0 : m_rParentTableContainer.SetTable(NULL);
123 0 : }
124 :
125 0 : void SvSimpleTable::UpdateViewSize()
126 : {
127 0 : Size theWinSize=m_rParentTableContainer.GetOutputSizePixel();
128 0 : Size HbSize=aHeaderBar.GetSizePixel();
129 :
130 0 : HbSize.Width()=theWinSize.Width();
131 0 : theWinSize.Height()-=HbSize.Height();
132 0 : Point thePos(0,0);
133 :
134 0 : aHeaderBar.SetPosPixel(thePos);
135 0 : aHeaderBar.SetSizePixel(HbSize);
136 :
137 0 : thePos.Y()+=HbSize.Height();
138 0 : SvHeaderTabListBox::SetPosPixel(thePos);
139 0 : SvHeaderTabListBox::SetSizePixel(theWinSize);
140 0 : Invalidate();
141 0 : }
142 :
143 0 : void SvSimpleTable::NotifyScrolled()
144 : {
145 0 : long nOffset=-GetXOffset();
146 0 : if(nOldPos!=nOffset)
147 : {
148 0 : aHeaderBar.SetOffset(nOffset);
149 0 : aHeaderBar.Invalidate();
150 0 : aHeaderBar.Update();
151 0 : nOldPos=nOffset;
152 : }
153 0 : SvHeaderTabListBox::NotifyScrolled();
154 0 : }
155 :
156 0 : void SvSimpleTable::SetTabs()
157 : {
158 0 : SvHeaderTabListBox::SetTabs();
159 :
160 0 : sal_uInt16 nPrivTabCount = TabCount();
161 0 : if ( nPrivTabCount )
162 : {
163 0 : if ( nPrivTabCount > aHeaderBar.GetItemCount() )
164 0 : nPrivTabCount = aHeaderBar.GetItemCount();
165 :
166 0 : sal_uInt16 i, nNewSize = static_cast< sal_uInt16 >( GetTab(0) ), nPos = 0;
167 0 : for ( i = 1; i < nPrivTabCount; ++i )
168 : {
169 0 : nNewSize = static_cast< sal_uInt16 >( GetTab(i) ) - nPos;
170 0 : aHeaderBar.SetItemSize( i, nNewSize );
171 0 : nPos = (sal_uInt16)GetTab(i);
172 : }
173 :
174 0 : aHeaderBar.SetItemSize( i, HEADERBAR_FULLSIZE ); // because no tab for last entry
175 : }
176 0 : }
177 :
178 0 : void SvSimpleTable::SetTabs( long* pTabs, MapUnit eMapUnit)
179 : {
180 0 : SvHeaderTabListBox::SetTabs(pTabs,eMapUnit);
181 0 : }
182 :
183 0 : void SvSimpleTable::Paint( const Rectangle& rRect )
184 : {
185 0 : SvHeaderTabListBox::Paint(rRect );
186 :
187 0 : sal_uInt16 nPrivTabCount = TabCount();
188 0 : sal_uInt16 nNewSize = ( nPrivTabCount > 0 ) ? (sal_uInt16)GetTab(0) : 0;
189 :
190 0 : long nOffset=-GetXOffset();
191 0 : nOldPos=nOffset;
192 :
193 0 : aHeaderBar.SetOffset(nOffset);
194 0 : aHeaderBar.Invalidate();
195 :
196 0 : if(nPrivTabCount && bPaintFlag)
197 : {
198 0 : if(nPrivTabCount>aHeaderBar.GetItemCount())
199 0 : nPrivTabCount=aHeaderBar.GetItemCount();
200 :
201 0 : sal_uInt16 nPos = 0;
202 0 : for(sal_uInt16 i=1;i<nPrivTabCount;i++)
203 : {
204 0 : nNewSize = static_cast< sal_uInt16 >( GetTab(i) ) - nPos;
205 0 : aHeaderBar.SetItemSize( i, nNewSize );
206 0 : nPos= static_cast< sal_uInt16 >( GetTab(i) );
207 : }
208 : }
209 0 : bPaintFlag = true;
210 0 : }
211 :
212 0 : void SvSimpleTable::InsertHeaderEntry(const OUString& rText,
213 : sal_uInt16 nCol, HeaderBarItemBits nBits)
214 : {
215 0 : sal_Int32 nEnd = rText.indexOf( '\t' );
216 0 : if( nEnd == -1 )
217 : {
218 0 : aHeaderBar.InsertItem(nHeaderItemId++, rText, 0, nBits, nCol);
219 : }
220 : else
221 : {
222 0 : sal_Int32 nIndex = 0;
223 0 : do
224 : {
225 0 : OUString aString = rText.getToken(0, '\t', nIndex);
226 0 : aHeaderBar.InsertItem(nHeaderItemId++, aString, 0, nBits, nCol);
227 : }
228 0 : while ( nIndex >= 0 );
229 : }
230 0 : SetTabs();
231 0 : }
232 :
233 0 : void SvSimpleTable::ClearHeader()
234 : {
235 0 : aHeaderBar.Clear();
236 0 : }
237 :
238 0 : void SvSimpleTable::ShowTable()
239 : {
240 0 : m_rParentTableContainer.Show();
241 0 : }
242 :
243 0 : void SvSimpleTable::HideTable()
244 : {
245 0 : m_rParentTableContainer.Hide();
246 0 : }
247 :
248 0 : bool SvSimpleTable::IsVisible() const
249 : {
250 0 : return m_rParentTableContainer.IsVisible();
251 : }
252 :
253 0 : void SvSimpleTable::EnableTable()
254 : {
255 0 : m_rParentTableContainer.Enable();
256 0 : }
257 :
258 0 : void SvSimpleTable::DisableTable()
259 : {
260 0 : m_rParentTableContainer.Disable();
261 0 : }
262 :
263 0 : bool SvSimpleTable::IsEnabled() const
264 : {
265 0 : return m_rParentTableContainer.IsEnabled();
266 : }
267 :
268 0 : sal_uInt16 SvSimpleTable::GetSelectedCol()
269 : {
270 0 : return (aHeaderBar.GetCurItemId()-1);
271 : }
272 :
273 0 : void SvSimpleTable::SortByCol(sal_uInt16 nCol, bool bDir)
274 : {
275 0 : bSortDirection=bDir;
276 0 : if(nSortCol!=0xFFFF)
277 0 : aHeaderBar.SetItemBits(nSortCol+1,HIB_STDSTYLE);
278 :
279 0 : if (nCol != 0xFFFF)
280 : {
281 0 : if(bDir)
282 : {
283 0 : aHeaderBar.SetItemBits( nCol+1, HIB_STDSTYLE | HIB_DOWNARROW);
284 0 : GetModel()->SetSortMode(SortAscending);
285 : }
286 : else
287 : {
288 0 : aHeaderBar.SetItemBits( nCol+1, HIB_STDSTYLE | HIB_UPARROW);
289 0 : GetModel()->SetSortMode(SortDescending);
290 : }
291 0 : nSortCol=nCol;
292 0 : GetModel()->SetCompareHdl( LINK( this, SvSimpleTable, CompareHdl));
293 0 : GetModel()->Resort();
294 : }
295 : else
296 0 : GetModel()->SetSortMode(SortNone);
297 0 : nSortCol=nCol;
298 0 : }
299 :
300 0 : void SvSimpleTable::HBarClick()
301 : {
302 0 : sal_uInt16 nId=aHeaderBar.GetCurItemId();
303 :
304 0 : if (aHeaderBar.GetItemBits(nId) & HIB_CLICKABLE)
305 : {
306 0 : if(nId==nSortCol+1)
307 : {
308 0 : SortByCol(nId-1,!bSortDirection);
309 : }
310 : else
311 : {
312 0 : SortByCol(nId-1,bSortDirection);
313 : }
314 :
315 0 : aHeaderBarClickLink.Call(this);
316 : }
317 0 : }
318 :
319 0 : void SvSimpleTable::HBarDblClick()
320 : {
321 0 : aHeaderBarDblClickLink.Call(this);
322 0 : }
323 :
324 0 : void SvSimpleTable::HBarStartDrag()
325 : {
326 0 : if(!aHeaderBar.IsItemMode())
327 : {
328 : Rectangle aSizeRect(Point(0,0),
329 0 : SvHeaderTabListBox::GetOutputSizePixel());
330 0 : aSizeRect.Left()=-GetXOffset()+aHeaderBar.GetDragPos();
331 0 : aSizeRect.Right()=-GetXOffset()+aHeaderBar.GetDragPos();
332 0 : ShowTracking( aSizeRect, SHOWTRACK_SPLIT );
333 : }
334 0 : }
335 0 : void SvSimpleTable::HBarDrag()
336 : {
337 0 : HideTracking();
338 0 : if(!aHeaderBar.IsItemMode())
339 : {
340 : Rectangle aSizeRect(Point(0,0),
341 0 : SvHeaderTabListBox::GetOutputSizePixel());
342 0 : aSizeRect.Left()=-GetXOffset()+aHeaderBar.GetDragPos();
343 0 : aSizeRect.Right()=-GetXOffset()+aHeaderBar.GetDragPos();
344 0 : ShowTracking( aSizeRect, SHOWTRACK_SPLIT );
345 : }
346 0 : }
347 0 : void SvSimpleTable::HBarEndDrag()
348 : {
349 0 : HideTracking();
350 0 : sal_uInt16 nPrivTabCount=TabCount();
351 :
352 0 : if(nPrivTabCount)
353 : {
354 0 : if(nPrivTabCount>aHeaderBar.GetItemCount())
355 0 : nPrivTabCount=aHeaderBar.GetItemCount();
356 :
357 0 : sal_uInt16 nPos=0;
358 0 : sal_uInt16 nNewSize=0;
359 0 : for(sal_uInt16 i=1;i<nPrivTabCount;i++)
360 : {
361 0 : nNewSize = static_cast< sal_uInt16 >( aHeaderBar.GetItemSize(i) ) + nPos;
362 0 : SetTab( i, nNewSize, MAP_PIXEL );
363 0 : nPos = nNewSize;
364 : }
365 : }
366 0 : bPaintFlag = false;
367 0 : Invalidate();
368 0 : Update();
369 0 : }
370 :
371 0 : CommandEvent SvSimpleTable::GetCommandEvent() const
372 : {
373 0 : return aCEvt;
374 : }
375 :
376 0 : void SvSimpleTable::Command( const CommandEvent& rCEvt )
377 : {
378 0 : aCEvt=rCEvt;
379 0 : aCommandLink.Call(this);
380 0 : SvHeaderTabListBox::Command(rCEvt);
381 0 : }
382 :
383 0 : IMPL_LINK( SvSimpleTable, StartDragHdl, HeaderBar*, pCtr)
384 : {
385 0 : if(pCtr==&aHeaderBar)
386 : {
387 0 : HBarStartDrag();
388 : }
389 0 : return 0;
390 : }
391 :
392 0 : IMPL_LINK( SvSimpleTable, DragHdl, HeaderBar*, pCtr)
393 : {
394 0 : if(pCtr==&aHeaderBar)
395 : {
396 0 : HBarDrag();
397 : }
398 0 : return 0;
399 : }
400 :
401 0 : IMPL_LINK( SvSimpleTable, EndDragHdl, HeaderBar*, pCtr)
402 : {
403 0 : if(pCtr==&aHeaderBar)
404 : {
405 0 : HBarEndDrag();
406 : }
407 0 : return 0;
408 : }
409 :
410 0 : IMPL_LINK( SvSimpleTable, HeaderBarClick, HeaderBar*, pCtr)
411 : {
412 0 : if(pCtr==&aHeaderBar)
413 : {
414 0 : HBarClick();
415 : }
416 0 : return 0;
417 : }
418 :
419 0 : IMPL_LINK( SvSimpleTable, HeaderBarDblClick, HeaderBar*, pCtr)
420 : {
421 0 : if(pCtr==&aHeaderBar)
422 : {
423 0 : HBarDblClick();
424 : }
425 0 : return 0;
426 : }
427 :
428 0 : SvLBoxItem* SvSimpleTable::GetEntryAtPos( SvTreeListEntry* pEntry, sal_uInt16 nPos ) const
429 : {
430 : DBG_ASSERT(pEntry,"GetEntryText:Invalid Entry");
431 0 : SvLBoxItem* pItem = NULL;
432 :
433 0 : if( pEntry )
434 : {
435 0 : sal_uInt16 nCount = pEntry->ItemCount();
436 :
437 0 : nPos++;
438 :
439 0 : if( nTreeFlags & TREEFLAG_CHKBTN ) nPos++;
440 :
441 0 : if( nPos < nCount )
442 : {
443 0 : pItem = pEntry->GetItem( nPos);
444 : }
445 : }
446 0 : return pItem;
447 : }
448 :
449 0 : sal_Int32 SvSimpleTable::ColCompare(SvTreeListEntry* pLeft,SvTreeListEntry* pRight)
450 : {
451 0 : sal_Int32 nCompare = 0;
452 :
453 0 : SvLBoxItem* pLeftItem = GetEntryAtPos( pLeft, nSortCol);
454 0 : SvLBoxItem* pRightItem = GetEntryAtPos( pRight, nSortCol);
455 :
456 :
457 0 : if(pLeftItem != NULL && pRightItem != NULL)
458 : {
459 0 : sal_uInt16 nLeftKind = pLeftItem->GetType();
460 0 : sal_uInt16 nRightKind = pRightItem->GetType();
461 :
462 0 : if(nRightKind == SV_ITEM_ID_LBOXSTRING &&
463 : nLeftKind == SV_ITEM_ID_LBOXSTRING )
464 : {
465 0 : IntlWrapper aIntlWrapper( Application::GetSettings().GetLanguageTag() );
466 0 : const CollatorWrapper* pCollator = aIntlWrapper.getCaseCollator();
467 :
468 : nCompare = pCollator->compareString( ((SvLBoxString*)pLeftItem)->GetText(),
469 0 : ((SvLBoxString*)pRightItem)->GetText());
470 :
471 0 : if (nCompare == 0)
472 0 : nCompare = -1;
473 : }
474 : }
475 0 : return nCompare;
476 : }
477 :
478 0 : IMPL_LINK( SvSimpleTable, CompareHdl, SvSortData*, pData)
479 : {
480 0 : SvTreeListEntry* pLeft = (SvTreeListEntry*)(pData->pLeft );
481 0 : SvTreeListEntry* pRight = (SvTreeListEntry*)(pData->pRight );
482 0 : return (long) ColCompare(pLeft,pRight);
483 : }
484 :
485 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|