1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: indexfieldscontrol.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_dbaccess.hxx"
34 #ifndef _DBAUI_INDEXFIELDSCONTROL_HXX_
35 #include "indexfieldscontrol.hxx"
38 #include "dbu_dlg.hrc"
40 #ifndef _OSL_DIAGNOSE_H_
41 #include <osl/diagnose.h>
43 #ifndef _DBA_DBACCESS_HELPID_HRC_
44 #include "dbaccess_helpid.hrc"
47 //......................................................................
50 //......................................................................
52 #define BROWSER_STANDARD_FLAGS BROWSER_COLUMNSELECTION | BROWSER_HLINESFULL | BROWSER_VLINESFULL | \
53 BROWSER_HIDECURSOR | BROWSER_HIDESELECT | BROWSER_AUTO_HSCROLL | BROWSER_AUTO_VSCROLL
55 #define COLUMN_ID_FIELDNAME 1
56 #define COLUMN_ID_ORDER 2
58 using namespace ::com::sun::star::uno
;
59 using namespace ::svt
;
61 //==================================================================
62 //= DbaMouseDownListBoxController
63 //==================================================================
64 class DbaMouseDownListBoxController
: public ListBoxCellController
67 Link m_aOriginalModifyHdl
;
68 Link m_aAdditionalModifyHdl
;
71 DbaMouseDownListBoxController(ListBoxControl
* _pParent
)
72 :ListBoxCellController(_pParent
)
76 void SetAdditionalModifyHdl(const Link
& _rHdl
);
79 virtual sal_Bool
WantMouseEvent() const { return sal_True
; }
80 virtual void SetModifyHdl(const Link
& _rHdl
);
83 void implCheckLinks();
84 DECL_LINK( OnMultiplexModify
, void* );
87 //------------------------------------------------------------------
88 void DbaMouseDownListBoxController::SetAdditionalModifyHdl(const Link
& _rHdl
)
90 m_aAdditionalModifyHdl
= _rHdl
;
94 //------------------------------------------------------------------
95 void DbaMouseDownListBoxController::SetModifyHdl(const Link
& _rHdl
)
97 m_aOriginalModifyHdl
= _rHdl
;
101 //------------------------------------------------------------------
102 IMPL_LINK( DbaMouseDownListBoxController
, OnMultiplexModify
, void*, _pArg
)
104 if (m_aAdditionalModifyHdl
.IsSet())
105 m_aAdditionalModifyHdl
.Call(_pArg
);
106 if (m_aOriginalModifyHdl
.IsSet())
107 m_aOriginalModifyHdl
.Call(_pArg
);
111 //------------------------------------------------------------------
112 void DbaMouseDownListBoxController::implCheckLinks()
114 if (m_aAdditionalModifyHdl
.IsSet() || m_aOriginalModifyHdl
.IsSet())
115 ListBoxCellController::SetModifyHdl(LINK(this, DbaMouseDownListBoxController
, OnMultiplexModify
));
117 ListBoxCellController::SetModifyHdl(Link());
120 //==================================================================
121 //= IndexFieldsControl
122 //==================================================================
123 DBG_NAME(IndexFieldsControl
)
124 //------------------------------------------------------------------
125 IndexFieldsControl::IndexFieldsControl( Window
* _pParent
, const ResId
& _rId
,sal_Int32 _nMaxColumnsInIndex
)
126 :EditBrowseBox(_pParent
, _rId
, EBBF_SMART_TAB_TRAVEL
| EBBF_ACTIVATE_ON_BUTTONDOWN
, BROWSER_STANDARD_FLAGS
)
127 ,m_aSeekRow(m_aFields
.end())
128 ,m_pSortingCell(NULL
)
129 ,m_pFieldNameCell(NULL
)
130 ,m_nMaxColumnsInIndex(_nMaxColumnsInIndex
)
132 DBG_CTOR(IndexFieldsControl
,NULL
);
134 SetUniqueId( UID_DLGINDEX_INDEXDETAILS_BACK
);
135 GetDataWindow().SetUniqueId( UID_DLGINDEX_INDEXDETAILS_MAIN
);
138 //------------------------------------------------------------------
139 IndexFieldsControl::~IndexFieldsControl()
141 delete m_pSortingCell
;
142 delete m_pFieldNameCell
;
144 DBG_DTOR(IndexFieldsControl
,NULL
);
147 //------------------------------------------------------------------
148 sal_Bool
IndexFieldsControl::SeekRow(long nRow
)
150 if (!EditBrowseBox::SeekRow(nRow
))
155 m_aSeekRow
= m_aFields
.end();
159 m_aSeekRow
= m_aFields
.begin() + nRow
;
160 OSL_ENSURE(m_aSeekRow
<= m_aFields
.end(), "IndexFieldsControl::SeekRow: invalid row!");
166 //------------------------------------------------------------------
167 void IndexFieldsControl::PaintCell( OutputDevice
& _rDev
, const Rectangle
& _rRect
, sal_uInt16 _nColumnId
) const
169 Point
aPos(_rRect
.TopLeft());
172 String aText
= GetRowCellText(m_aSeekRow
,_nColumnId
);
173 Size
TxtSize(GetDataWindow().GetTextWidth(aText
), GetDataWindow().GetTextHeight());
176 if (aPos
.X() < _rRect
.Right() || aPos
.X() + TxtSize
.Width() > _rRect
.Right() ||
177 aPos
.Y() < _rRect
.Top() || aPos
.Y() + TxtSize
.Height() > _rRect
.Bottom())
178 _rDev
.SetClipRegion( _rRect
);
180 // allow for a disabled control ...
181 sal_Bool bEnabled
= IsEnabled();
182 Color aOriginalColor
= _rDev
.GetTextColor();
184 _rDev
.SetTextColor(GetSettings().GetStyleSettings().GetDisableColor());
187 _rDev
.DrawText(aPos
, aText
);
189 // reset the color (if necessary)
191 _rDev
.SetTextColor(aOriginalColor
);
193 if (_rDev
.IsClipRegion())
194 _rDev
.SetClipRegion();
197 //------------------------------------------------------------------
198 void IndexFieldsControl::initializeFrom(const IndexFields
& _rFields
)
200 // copy the field descriptions
201 m_aFields
= _rFields
;
202 m_aSeekRow
= m_aFields
.end();
204 SetUpdateMode(sal_False
);
206 RowRemoved(1, GetRowCount());
207 // insert rows for the the fields
208 RowInserted(GetRowCount(), m_aFields
.size(), sal_False
);
209 // insert an additional row for a new field for that index
210 // if(!m_nMaxColumnsInIndex || GetRowCount() < m_nMaxColumnsInIndex )
211 RowInserted(GetRowCount(), 1, sal_False
);
212 SetUpdateMode(sal_True
);
214 GoToRowColumnId(0, COLUMN_ID_FIELDNAME
);
217 //------------------------------------------------------------------
218 void IndexFieldsControl::commitTo(IndexFields
& _rFields
)
220 // do not just copy the array, we may have empty field names (which should not be copied)
221 _rFields
.resize(m_aFields
.size());
222 ConstIndexFieldsIterator aSource
= m_aFields
.begin();
223 ConstIndexFieldsIterator aSourceEnd
= m_aFields
.end();
224 IndexFieldsIterator aDest
= _rFields
.begin();
225 for (; aSource
< aSourceEnd
; ++aSource
)
226 if (0 != aSource
->sFieldName
.Len())
232 _rFields
.resize(aDest
- _rFields
.begin());
235 //------------------------------------------------------------------
236 sal_uInt32
IndexFieldsControl::GetTotalCellWidth(long _nRow
, sal_uInt16 _nColId
)
238 if (COLUMN_ID_ORDER
== _nColId
)
240 sal_Int32 nWidthAsc
= GetTextWidth(m_sAscendingText
) + GetSettings().GetStyleSettings().GetScrollBarSize();
241 sal_Int32 nWidthDesc
= GetTextWidth(m_sDescendingText
) + GetSettings().GetStyleSettings().GetScrollBarSize();
242 // maximum plus some additional space
243 return (nWidthAsc
> nWidthDesc
? nWidthAsc
: nWidthDesc
) + GetTextWidth('0') * 2;
245 return EditBrowseBox::GetTotalCellWidth(_nRow
, _nColId
);
248 //------------------------------------------------------------------
249 void IndexFieldsControl::Init(const Sequence
< ::rtl::OUString
>& _rAvailableFields
)
253 m_sAscendingText
= String(ModuleRes(STR_ORDER_ASCENDING
));
254 m_sDescendingText
= String(ModuleRes(STR_ORDER_DESCENDING
));
256 // the "sort order" column
257 String sColumnName
= String(ModuleRes(STR_TAB_INDEX_SORTORDER
));
258 // the width of the order column is the maximum widths of the texts used
259 // (the title of the column)
260 sal_Int32 nSortOrderColumnWidth
= GetTextWidth(sColumnName
);
261 // ("ascending" + scrollbar width)
262 sal_Int32 nOther
= GetTextWidth(m_sAscendingText
) + GetSettings().GetStyleSettings().GetScrollBarSize();
263 nSortOrderColumnWidth
= nSortOrderColumnWidth
> nOther
? nSortOrderColumnWidth
: nOther
;
264 // ("descending" + scrollbar width)
265 nOther
= GetTextWidth(m_sDescendingText
) + GetSettings().GetStyleSettings().GetScrollBarSize();
266 nSortOrderColumnWidth
= nSortOrderColumnWidth
> nOther
? nSortOrderColumnWidth
: nOther
;
267 // (plus some additional space)
268 nSortOrderColumnWidth
+= GetTextWidth('0') * 2;
269 InsertDataColumn(COLUMN_ID_ORDER
, sColumnName
, nSortOrderColumnWidth
, HIB_STDSTYLE
, 1);
271 // for the width: both columns together should be somewhat smaller than the whole window (without the scrollbar)
272 sal_Int32 nFieldNameWidth
= GetSizePixel().Width();
273 nFieldNameWidth
-= nSortOrderColumnWidth
;
275 StyleSettings aSystemStyle
= Application::GetSettings().GetStyleSettings();
276 nFieldNameWidth
-= aSystemStyle
.GetScrollBarSize();
277 nFieldNameWidth
-= 8;
279 // the "field name" column
280 sColumnName
= String(ModuleRes(STR_TAB_INDEX_FIELD
));
281 InsertDataColumn(COLUMN_ID_FIELDNAME
, sColumnName
, nFieldNameWidth
, HIB_STDSTYLE
, 0);
283 // create the cell controllers
284 // for the field name cell
285 m_pFieldNameCell
= new ListBoxControl(&GetDataWindow());
286 m_pFieldNameCell
->InsertEntry(String());
287 const ::rtl::OUString
* pFields
= _rAvailableFields
.getConstArray();
288 const ::rtl::OUString
* pFieldsEnd
= pFields
+ _rAvailableFields
.getLength();
289 for (;pFields
< pFieldsEnd
; ++pFields
)
290 m_pFieldNameCell
->InsertEntry(*pFields
);
292 m_pSortingCell
= new ListBoxControl(&GetDataWindow());
293 m_pSortingCell
->InsertEntry(m_sAscendingText
);
294 m_pSortingCell
->InsertEntry(m_sDescendingText
);
296 m_pFieldNameCell
->SetHelpId( HID_DLGINDEX_INDEXDETAILS_FIELD
);
297 m_pSortingCell
->SetHelpId( HID_DLGINDEX_INDEXDETAILS_SORTORDER
);
300 //------------------------------------------------------------------
301 CellController
* IndexFieldsControl::GetController(long _nRow
, sal_uInt16 _nColumnId
)
306 ConstIndexFieldsIterator aRow
;
307 sal_Bool bNewField
= !implGetFieldDesc(_nRow
, aRow
);
309 DbaMouseDownListBoxController
* pReturn
= NULL
;
312 case COLUMN_ID_ORDER
:
313 if (!bNewField
&& m_pSortingCell
&& 0 != aRow
->sFieldName
.Len())
314 pReturn
= new DbaMouseDownListBoxController(m_pSortingCell
);
317 case COLUMN_ID_FIELDNAME
:
318 pReturn
= new DbaMouseDownListBoxController(m_pFieldNameCell
);
322 OSL_ENSURE(sal_False
, "IndexFieldsControl::GetController: invalid column id!");
326 pReturn
->SetAdditionalModifyHdl(LINK(this, IndexFieldsControl
, OnListEntrySelected
));
331 //------------------------------------------------------------------
332 sal_Bool
IndexFieldsControl::implGetFieldDesc(long _nRow
, ConstIndexFieldsIterator
& _rPos
)
334 _rPos
= m_aFields
.end();
335 if ((_nRow
< 0) || (_nRow
>= (sal_Int32
)m_aFields
.size()))
337 _rPos
= m_aFields
.begin() + _nRow
;
341 //------------------------------------------------------------------
342 sal_Bool
IndexFieldsControl::IsModified() const
344 return EditBrowseBox::IsModified();
347 //------------------------------------------------------------------
348 sal_Bool
IndexFieldsControl::SaveModified()
353 switch (GetCurColumnId())
355 case COLUMN_ID_FIELDNAME
:
357 String sFieldSelected
= m_pFieldNameCell
->GetSelectEntry();
358 sal_Bool bEmptySelected
= 0 == sFieldSelected
.Len();
363 // add a new field to the collection
364 OIndexField aNewField
;
365 aNewField
.sFieldName
= sFieldSelected
;
366 m_aFields
.push_back(aNewField
);
367 RowInserted(GetRowCount(), 1, sal_True
);
372 sal_Int32 nRow
= GetCurRow();
373 OSL_ENSURE(nRow
< (sal_Int32
)m_aFields
.size(), "IndexFieldsControl::SaveModified: invalid current row!");
374 if (nRow
>= 0) // may be -1 in case the control was empty
376 // remove the field from the selection
377 IndexFieldsIterator aPos
= m_aFields
.begin() + nRow
;
381 aPos
->sFieldName
= String();
383 // invalidate the row to force repaint
384 Invalidate(GetRowRectPixel(nRow
));
388 if (sFieldSelected
== aPos
->sFieldName
)
392 aPos
->sFieldName
= sFieldSelected
;
396 Invalidate(GetRowRectPixel(GetCurRow()));
399 case COLUMN_ID_ORDER
:
401 OSL_ENSURE(!isNewField(), "IndexFieldsControl::SaveModified: why the hell ...!!!");
403 sal_uInt16 nPos
= m_pSortingCell
->GetSelectEntryPos();
404 OSL_ENSURE(LISTBOX_ENTRY_NOTFOUND
!= nPos
, "IndexFieldsControl::SaveModified: how did you get this selection??");
405 // adjust the sort flag in the index field description
406 OIndexField
& rCurrentField
= m_aFields
[GetCurRow()];
407 rCurrentField
.bSortAscending
= (0 == nPos
);
412 OSL_ENSURE(sal_False
, "IndexFieldsControl::SaveModified: invalid column id!");
417 //------------------------------------------------------------------
418 void IndexFieldsControl::InitController(CellControllerRef
& /*_rController*/, long _nRow
, sal_uInt16 _nColumnId
)
420 ConstIndexFieldsIterator aFieldDescription
;
421 sal_Bool bNewField
= !implGetFieldDesc(_nRow
, aFieldDescription
);
425 case COLUMN_ID_FIELDNAME
:
426 m_pFieldNameCell
->SelectEntry(bNewField
? String() : aFieldDescription
->sFieldName
);
427 m_pFieldNameCell
->SaveValue();
430 case COLUMN_ID_ORDER
:
431 m_pSortingCell
->SelectEntry(aFieldDescription
->bSortAscending
? m_sAscendingText
: m_sDescendingText
);
432 m_pSortingCell
->SaveValue();
436 OSL_ENSURE(sal_False
, "IndexFieldsControl::InitController: invalid column id!");
440 //------------------------------------------------------------------
441 IMPL_LINK( IndexFieldsControl
, OnListEntrySelected
, ListBox
*, _pBox
)
443 if (!_pBox
->IsTravelSelect() && m_aModifyHdl
.IsSet())
444 m_aModifyHdl
.Call(this);
446 if (_pBox
== m_pFieldNameCell
)
447 { // a field has been selected
448 if (GetCurRow() >= GetRowCount() - 2)
449 { // and we're in one of the last two rows
450 String sSelectedEntry
= m_pFieldNameCell
->GetSelectEntry();
451 sal_Int32 nCurrentRow
= GetCurRow();
452 sal_Int32 rowCount
= GetRowCount();
454 OSL_ENSURE(((sal_Int32
)(m_aFields
.size() + 1)) == rowCount
, "IndexFieldsControl::OnListEntrySelected: inconsistence!");
456 if (sSelectedEntry
.Len() && (nCurrentRow
== rowCount
- 1) /*&& (!m_nMaxColumnsInIndex || rowCount < m_nMaxColumnsInIndex )*/ )
457 { // in the last row, an non-empty string has been selected
458 // -> insert a new row
459 m_aFields
.push_back(OIndexField());
460 RowInserted(GetRowCount(), 1);
461 Invalidate(GetRowRectPixel(nCurrentRow
));
463 else if (!sSelectedEntry
.Len() && (nCurrentRow
== rowCount
- 2))
464 { // in the (last-1)th row, an empty entry has been selected
465 // -> remove the last row
466 m_aFields
.erase(m_aFields
.end() - 1);
467 RowRemoved(GetRowCount() - 1, 1);
468 Invalidate(GetRowRectPixel(nCurrentRow
));
476 //------------------------------------------------------------------
477 String
IndexFieldsControl::GetCellText(long _nRow
,sal_uInt16 nColId
) const
479 ConstIndexFieldsIterator aRow
= m_aFields
.end();
482 aRow
= m_aFields
.begin() + _nRow
;
483 OSL_ENSURE(aRow
<= m_aFields
.end(), "IndexFieldsControl::SeekRow: invalid row!");
485 return GetRowCellText(aRow
,nColId
);
487 //------------------------------------------------------------------
488 String
IndexFieldsControl::GetRowCellText(const ConstIndexFieldsIterator
& _rRow
,sal_uInt16 nColId
) const
490 if (_rRow
< m_aFields
.end())
494 case COLUMN_ID_FIELDNAME
:
495 return _rRow
->sFieldName
;
496 case COLUMN_ID_ORDER
:
497 if (0 == _rRow
->sFieldName
.Len())
500 return _rRow
->bSortAscending
? m_sAscendingText
: m_sDescendingText
;
502 OSL_ENSURE(sal_False
, "IndexFieldsControl::GetCurrentRowCellText: invalid column id!");
507 //------------------------------------------------------------------
508 sal_Bool
IndexFieldsControl::IsTabAllowed(sal_Bool
/*bForward*/) const
512 //------------------------------------------------------------------
514 //......................................................................
516 //......................................................................