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 <svx/simptabl.hxx>
21 : #include <vcl/builder.hxx>
22 : #include <vcl/svapp.hxx>
23 :
24 : #include <comphelper/processfactory.hxx>
25 : #include <unotools/intlwrapper.hxx>
26 : #include <svtools/svlbitm.hxx>
27 : #include "svtools/treelistentry.hxx"
28 :
29 : // SvxSimpleTableContainer ------------------------------------------------------
30 :
31 0 : SvxSimpleTableContainer::SvxSimpleTableContainer(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 : SvxSimpleTableContainer::SvxSimpleTableContainer(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 makeSvxSimpleTableContainer(Window *pParent,
45 : VclBuilder::stringmap &)
46 : {
47 0 : return new SvxSimpleTableContainer(pParent);
48 : }
49 :
50 0 : void SvxSimpleTableContainer::SetTable(SvxSimpleTable* pTable)
51 : {
52 0 : m_pTable = pTable;
53 0 : }
54 :
55 0 : long SvxSimpleTableContainer::PreNotify( NotifyEvent& rNEvt )
56 : {
57 0 : long nResult = sal_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 0;
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 SvxSimpleTableContainer::Resize()
76 : {
77 0 : Control::Resize();
78 0 : if (m_pTable)
79 0 : m_pTable->UpdateViewSize();
80 0 : }
81 :
82 0 : void SvxSimpleTableContainer::GetFocus()
83 : {
84 0 : Control::GetFocus();
85 0 : if (m_pTable)
86 0 : m_pTable->GrabFocus();
87 0 : }
88 :
89 : // SvxSimpleTable ------------------------------------------------------------
90 :
91 0 : SvxSimpleTable::SvxSimpleTable(SvxSimpleTableContainer& 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 : bResizeFlag(sal_False),
97 0 : bPaintFlag(sal_True)
98 : {
99 0 : m_rParentTableContainer.SetTable(this);
100 :
101 0 : bSortDirection=sal_True;
102 0 : nSortCol=0xFFFF;
103 0 : nOldPos=0;
104 :
105 0 : aHeaderBar.SetStartDragHdl(LINK( this, SvxSimpleTable, StartDragHdl));
106 0 : aHeaderBar.SetDragHdl(LINK( this, SvxSimpleTable, DragHdl));
107 0 : aHeaderBar.SetEndDragHdl(LINK( this, SvxSimpleTable, EndDragHdl));
108 0 : aHeaderBar.SetSelectHdl(LINK( this, SvxSimpleTable, HeaderBarClick));
109 0 : aHeaderBar.SetDoubleClickHdl(LINK( this, SvxSimpleTable, HeaderBarDblClick));
110 :
111 0 : EnableCellFocus();
112 0 : DisableTransientChildren();
113 0 : InitHeaderBar( &aHeaderBar );
114 :
115 0 : UpdateViewSize();
116 :
117 0 : aHeaderBar.Show();
118 0 : SvHeaderTabListBox::Show();
119 0 : }
120 :
121 0 : SvxSimpleTable::~SvxSimpleTable()
122 : {
123 0 : m_rParentTableContainer.SetTable(NULL);
124 0 : }
125 :
126 0 : void SvxSimpleTable::UpdateViewSize()
127 : {
128 0 : Size theWinSize=m_rParentTableContainer.GetOutputSizePixel();
129 0 : Size HbSize=aHeaderBar.GetSizePixel();
130 :
131 0 : HbSize.Width()=theWinSize.Width();
132 0 : theWinSize.Height()-=HbSize.Height();
133 0 : Point thePos(0,0);
134 :
135 0 : aHeaderBar.SetPosPixel(thePos);
136 0 : aHeaderBar.SetSizePixel(HbSize);
137 :
138 0 : thePos.Y()+=HbSize.Height();
139 0 : SvHeaderTabListBox::SetPosPixel(thePos);
140 0 : SvHeaderTabListBox::SetSizePixel(theWinSize);
141 0 : Invalidate();
142 0 : }
143 :
144 0 : void SvxSimpleTable::NotifyScrolled()
145 : {
146 0 : long nOffset=-GetXOffset();
147 0 : if(nOldPos!=nOffset)
148 : {
149 0 : aHeaderBar.SetOffset(nOffset);
150 0 : aHeaderBar.Invalidate();
151 0 : aHeaderBar.Update();
152 0 : nOldPos=nOffset;
153 : }
154 0 : SvHeaderTabListBox::NotifyScrolled();
155 0 : }
156 :
157 0 : void SvxSimpleTable::SetTabs()
158 : {
159 0 : SvHeaderTabListBox::SetTabs();
160 :
161 0 : sal_uInt16 nPrivTabCount = TabCount();
162 0 : if ( nPrivTabCount )
163 : {
164 0 : if ( nPrivTabCount > aHeaderBar.GetItemCount() )
165 0 : nPrivTabCount = aHeaderBar.GetItemCount();
166 :
167 0 : sal_uInt16 i, nNewSize = static_cast< sal_uInt16 >( GetTab(0) ), nPos = 0;
168 0 : for ( i = 1; i < nPrivTabCount; ++i )
169 : {
170 0 : nNewSize = static_cast< sal_uInt16 >( GetTab(i) ) - nPos;
171 0 : aHeaderBar.SetItemSize( i, nNewSize );
172 0 : nPos = (sal_uInt16)GetTab(i);
173 : }
174 :
175 0 : aHeaderBar.SetItemSize( i, HEADERBAR_FULLSIZE ); // because no tab for last entry
176 : }
177 0 : }
178 :
179 0 : void SvxSimpleTable::SetTabs( long* pTabs, MapUnit eMapUnit)
180 : {
181 0 : SvHeaderTabListBox::SetTabs(pTabs,eMapUnit);
182 0 : }
183 :
184 0 : void SvxSimpleTable::Paint( const Rectangle& rRect )
185 : {
186 0 : SvHeaderTabListBox::Paint(rRect );
187 :
188 0 : sal_uInt16 nPrivTabCount = TabCount();
189 0 : sal_uInt16 nNewSize = ( nPrivTabCount > 0 ) ? (sal_uInt16)GetTab(0) : 0;
190 :
191 0 : long nOffset=-GetXOffset();
192 0 : nOldPos=nOffset;
193 :
194 0 : aHeaderBar.SetOffset(nOffset);
195 0 : aHeaderBar.Invalidate();
196 :
197 0 : if(nPrivTabCount && bPaintFlag)
198 : {
199 0 : if(nPrivTabCount>aHeaderBar.GetItemCount())
200 0 : nPrivTabCount=aHeaderBar.GetItemCount();
201 :
202 0 : sal_uInt16 nPos = 0;
203 0 : for(sal_uInt16 i=1;i<nPrivTabCount;i++)
204 : {
205 0 : nNewSize = static_cast< sal_uInt16 >( GetTab(i) ) - nPos;
206 0 : aHeaderBar.SetItemSize( i, nNewSize );
207 0 : nPos= static_cast< sal_uInt16 >( GetTab(i) );
208 : }
209 : }
210 0 : bPaintFlag=sal_True;
211 0 : }
212 0 : void SvxSimpleTable::InsertHeaderEntry(const OUString& rText,
213 : sal_uInt16 nCol, HeaderBarItemBits nBits)
214 : {
215 0 : sal_Int32 nEnd = rText.indexOf( sal_Unicode( '\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 SvxSimpleTable::ClearHeader()
234 : {
235 0 : aHeaderBar.Clear();
236 0 : }
237 :
238 0 : void SvxSimpleTable::ShowTable()
239 : {
240 0 : m_rParentTableContainer.Show();
241 0 : }
242 :
243 0 : void SvxSimpleTable::HideTable()
244 : {
245 0 : m_rParentTableContainer.Hide();
246 0 : }
247 :
248 0 : sal_Bool SvxSimpleTable::IsVisible() const
249 : {
250 0 : return m_rParentTableContainer.IsVisible();
251 : }
252 :
253 0 : void SvxSimpleTable::EnableTable()
254 : {
255 0 : m_rParentTableContainer.Enable();
256 0 : }
257 :
258 0 : void SvxSimpleTable::DisableTable()
259 : {
260 0 : m_rParentTableContainer.Disable();
261 0 : }
262 :
263 0 : sal_Bool SvxSimpleTable::IsEnabled() const
264 : {
265 0 : return m_rParentTableContainer.IsEnabled();
266 : }
267 :
268 0 : sal_uInt16 SvxSimpleTable::GetSelectedCol()
269 : {
270 0 : return (aHeaderBar.GetCurItemId()-1);
271 : }
272 :
273 0 : void SvxSimpleTable::SortByCol(sal_uInt16 nCol,sal_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, SvxSimpleTable, CompareHdl));
293 0 : GetModel()->Resort();
294 : }
295 : else
296 0 : GetModel()->SetSortMode(SortNone);
297 0 : nSortCol=nCol;
298 0 : }
299 :
300 0 : void SvxSimpleTable::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 SvxSimpleTable::HBarDblClick()
320 : {
321 0 : aHeaderBarDblClickLink.Call(this);
322 0 : }
323 :
324 0 : void SvxSimpleTable::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 SvxSimpleTable::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 SvxSimpleTable::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=sal_False;
367 0 : Invalidate();
368 0 : Update();
369 0 : }
370 :
371 0 : CommandEvent SvxSimpleTable::GetCommandEvent() const
372 : {
373 0 : return aCEvt;
374 : }
375 :
376 0 : void SvxSimpleTable::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( SvxSimpleTable, StartDragHdl, HeaderBar*, pCtr)
384 : {
385 0 : if(pCtr==&aHeaderBar)
386 : {
387 0 : HBarStartDrag();
388 : }
389 0 : return 0;
390 : }
391 :
392 0 : IMPL_LINK( SvxSimpleTable, DragHdl, HeaderBar*, pCtr)
393 : {
394 0 : if(pCtr==&aHeaderBar)
395 : {
396 0 : HBarDrag();
397 : }
398 0 : return 0;
399 : }
400 :
401 0 : IMPL_LINK( SvxSimpleTable, EndDragHdl, HeaderBar*, pCtr)
402 : {
403 0 : if(pCtr==&aHeaderBar)
404 : {
405 0 : HBarEndDrag();
406 : }
407 0 : return 0;
408 : }
409 :
410 0 : IMPL_LINK( SvxSimpleTable, HeaderBarClick, HeaderBar*, pCtr)
411 : {
412 0 : if(pCtr==&aHeaderBar)
413 : {
414 0 : HBarClick();
415 : }
416 0 : return 0;
417 : }
418 :
419 0 : IMPL_LINK( SvxSimpleTable, HeaderBarDblClick, HeaderBar*, pCtr)
420 : {
421 0 : if(pCtr==&aHeaderBar)
422 : {
423 0 : HBarDblClick();
424 : }
425 0 : return 0;
426 : }
427 :
428 0 : SvLBoxItem* SvxSimpleTable::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 : StringCompare SvxSimpleTable::ColCompare(SvTreeListEntry* pLeft,SvTreeListEntry* pRight)
450 : {
451 0 : StringCompare eCompare=COMPARE_EQUAL;
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 : eCompare=(StringCompare)pCollator->compareString( ((SvLBoxString*)pLeftItem)->GetText(),
469 0 : ((SvLBoxString*)pRightItem)->GetText());
470 :
471 0 : if(eCompare==COMPARE_EQUAL) eCompare=COMPARE_LESS;
472 : }
473 : }
474 0 : return eCompare;
475 : }
476 :
477 0 : IMPL_LINK( SvxSimpleTable, CompareHdl, SvSortData*, pData)
478 : {
479 0 : SvTreeListEntry* pLeft = (SvTreeListEntry*)(pData->pLeft );
480 0 : SvTreeListEntry* pRight = (SvTreeListEntry*)(pData->pRight );
481 0 : return (long) ColCompare(pLeft,pRight);
482 258 : }
483 :
484 :
485 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|