1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * Copyright 2000, 2010 Oracle and/or its affiliates.
8 * OpenOffice.org - a multi-platform office productivity suite
10 * This file is part of OpenOffice.org.
12 * OpenOffice.org is free software: you can redistribute it and/or modify
13 * it under the terms of the GNU Lesser General Public License version 3
14 * only, as published by the Free Software Foundation.
16 * OpenOffice.org is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser General Public License version 3 for more details
20 * (a copy is included in the LICENSE file that accompanied this code).
22 * You should have received a copy of the GNU Lesser General Public License
23 * version 3 along with OpenOffice.org. If not, see
24 * <http://www.openoffice.org/license.html>
25 * for a copy of the LGPLv3 License.
27 ************************************************************************/
30 #include "indexfieldscontrol.hxx"
31 #include "dbu_dlg.hrc"
32 #include <osl/diagnose.h>
33 #include "dbaccess_helpid.hrc"
35 //......................................................................
38 //......................................................................
40 #define BROWSER_STANDARD_FLAGS BROWSER_COLUMNSELECTION | BROWSER_HLINESFULL | BROWSER_VLINESFULL | \
41 BROWSER_HIDECURSOR | BROWSER_HIDESELECT | BROWSER_AUTO_HSCROLL | BROWSER_AUTO_VSCROLL
43 #define COLUMN_ID_FIELDNAME 1
44 #define COLUMN_ID_ORDER 2
46 using namespace ::com::sun::star::uno
;
47 using namespace ::svt
;
49 //==================================================================
50 //= DbaMouseDownListBoxController
51 //==================================================================
52 class DbaMouseDownListBoxController
: public ListBoxCellController
55 Link m_aOriginalModifyHdl
;
56 Link m_aAdditionalModifyHdl
;
59 DbaMouseDownListBoxController(ListBoxControl
* _pParent
)
60 :ListBoxCellController(_pParent
)
64 void SetAdditionalModifyHdl(const Link
& _rHdl
);
67 virtual sal_Bool
WantMouseEvent() const { return sal_True
; }
68 virtual void SetModifyHdl(const Link
& _rHdl
);
71 void implCheckLinks();
72 DECL_LINK( OnMultiplexModify
, void* );
75 //------------------------------------------------------------------
76 void DbaMouseDownListBoxController::SetAdditionalModifyHdl(const Link
& _rHdl
)
78 m_aAdditionalModifyHdl
= _rHdl
;
82 //------------------------------------------------------------------
83 void DbaMouseDownListBoxController::SetModifyHdl(const Link
& _rHdl
)
85 m_aOriginalModifyHdl
= _rHdl
;
89 //------------------------------------------------------------------
90 IMPL_LINK( DbaMouseDownListBoxController
, OnMultiplexModify
, void*, _pArg
)
92 if (m_aAdditionalModifyHdl
.IsSet())
93 m_aAdditionalModifyHdl
.Call(_pArg
);
94 if (m_aOriginalModifyHdl
.IsSet())
95 m_aOriginalModifyHdl
.Call(_pArg
);
99 //------------------------------------------------------------------
100 void DbaMouseDownListBoxController::implCheckLinks()
102 if (m_aAdditionalModifyHdl
.IsSet() || m_aOriginalModifyHdl
.IsSet())
103 ListBoxCellController::SetModifyHdl(LINK(this, DbaMouseDownListBoxController
, OnMultiplexModify
));
105 ListBoxCellController::SetModifyHdl(Link());
108 //==================================================================
109 //= IndexFieldsControl
110 //==================================================================
111 DBG_NAME(IndexFieldsControl
)
112 //------------------------------------------------------------------
113 IndexFieldsControl::IndexFieldsControl( Window
* _pParent
, const ResId
& _rId
,sal_Int32 _nMaxColumnsInIndex
,sal_Bool _bAddIndexAppendix
)
114 :EditBrowseBox(_pParent
, _rId
, EBBF_SMART_TAB_TRAVEL
| EBBF_ACTIVATE_ON_BUTTONDOWN
, BROWSER_STANDARD_FLAGS
)
115 ,m_aSeekRow(m_aFields
.end())
116 ,m_pSortingCell(NULL
)
117 ,m_pFieldNameCell(NULL
)
118 ,m_nMaxColumnsInIndex(_nMaxColumnsInIndex
)
119 ,m_bAddIndexAppendix(_bAddIndexAppendix
)
121 DBG_CTOR(IndexFieldsControl
,NULL
);
123 SetUniqueId( UID_DLGINDEX_INDEXDETAILS_BACK
);
124 GetDataWindow().SetUniqueId( UID_DLGINDEX_INDEXDETAILS_MAIN
);
127 //------------------------------------------------------------------
128 IndexFieldsControl::~IndexFieldsControl()
130 delete m_pSortingCell
;
131 delete m_pFieldNameCell
;
133 DBG_DTOR(IndexFieldsControl
,NULL
);
136 //------------------------------------------------------------------
137 sal_Bool
IndexFieldsControl::SeekRow(long nRow
)
139 if (!EditBrowseBox::SeekRow(nRow
))
144 m_aSeekRow
= m_aFields
.end();
148 m_aSeekRow
= m_aFields
.begin() + nRow
;
149 OSL_ENSURE(m_aSeekRow
<= m_aFields
.end(), "IndexFieldsControl::SeekRow: invalid row!");
155 //------------------------------------------------------------------
156 void IndexFieldsControl::PaintCell( OutputDevice
& _rDev
, const Rectangle
& _rRect
, sal_uInt16 _nColumnId
) const
158 Point
aPos(_rRect
.TopLeft());
161 String aText
= GetRowCellText(m_aSeekRow
,_nColumnId
);
162 Size
TxtSize(GetDataWindow().GetTextWidth(aText
), GetDataWindow().GetTextHeight());
165 if (aPos
.X() < _rRect
.Right() || aPos
.X() + TxtSize
.Width() > _rRect
.Right() ||
166 aPos
.Y() < _rRect
.Top() || aPos
.Y() + TxtSize
.Height() > _rRect
.Bottom())
167 _rDev
.SetClipRegion( _rRect
);
169 // allow for a disabled control ...
170 sal_Bool bEnabled
= IsEnabled();
171 Color aOriginalColor
= _rDev
.GetTextColor();
173 _rDev
.SetTextColor(GetSettings().GetStyleSettings().GetDisableColor());
176 _rDev
.DrawText(aPos
, aText
);
178 // reset the color (if necessary)
180 _rDev
.SetTextColor(aOriginalColor
);
182 if (_rDev
.IsClipRegion())
183 _rDev
.SetClipRegion();
186 //------------------------------------------------------------------
187 void IndexFieldsControl::initializeFrom(const IndexFields
& _rFields
)
189 // copy the field descriptions
190 m_aFields
= _rFields
;
191 m_aSeekRow
= m_aFields
.end();
193 SetUpdateMode(sal_False
);
195 RowRemoved(1, GetRowCount());
196 // insert rows for the the fields
197 RowInserted(GetRowCount(), m_aFields
.size(), sal_False
);
198 // insert an additional row for a new field for that index
199 RowInserted(GetRowCount(), 1, sal_False
);
200 SetUpdateMode(sal_True
);
202 GoToRowColumnId(0, COLUMN_ID_FIELDNAME
);
205 //------------------------------------------------------------------
206 void IndexFieldsControl::commitTo(IndexFields
& _rFields
)
208 // do not just copy the array, we may have empty field names (which should not be copied)
209 _rFields
.resize(m_aFields
.size());
210 ConstIndexFieldsIterator aSource
= m_aFields
.begin();
211 ConstIndexFieldsIterator aSourceEnd
= m_aFields
.end();
212 IndexFieldsIterator aDest
= _rFields
.begin();
213 for (; aSource
< aSourceEnd
; ++aSource
)
214 if (0 != aSource
->sFieldName
.Len())
220 _rFields
.resize(aDest
- _rFields
.begin());
223 //------------------------------------------------------------------
224 sal_uInt32
IndexFieldsControl::GetTotalCellWidth(long _nRow
, sal_uInt16 _nColId
)
226 if (COLUMN_ID_ORDER
== _nColId
)
228 sal_Int32 nWidthAsc
= GetTextWidth(m_sAscendingText
) + GetSettings().GetStyleSettings().GetScrollBarSize();
229 sal_Int32 nWidthDesc
= GetTextWidth(m_sDescendingText
) + GetSettings().GetStyleSettings().GetScrollBarSize();
230 // maximum plus some additional space
231 return (nWidthAsc
> nWidthDesc
? nWidthAsc
: nWidthDesc
) + GetTextWidth('0') * 2;
233 return EditBrowseBox::GetTotalCellWidth(_nRow
, _nColId
);
236 //------------------------------------------------------------------
237 void IndexFieldsControl::Init(const Sequence
< ::rtl::OUString
>& _rAvailableFields
)
241 // for the width: both columns together should be somewhat smaller than the whole window (without the scrollbar)
242 sal_Int32 nFieldNameWidth
= GetSizePixel().Width();
244 if ( m_bAddIndexAppendix
)
246 m_sAscendingText
= String(ModuleRes(STR_ORDER_ASCENDING
));
247 m_sDescendingText
= String(ModuleRes(STR_ORDER_DESCENDING
));
249 // the "sort order" column
250 String sColumnName
= String(ModuleRes(STR_TAB_INDEX_SORTORDER
));
251 // the width of the order column is the maximum widths of the texts used
252 // (the title of the column)
253 sal_Int32 nSortOrderColumnWidth
= GetTextWidth(sColumnName
);
254 // ("ascending" + scrollbar width)
255 sal_Int32 nOther
= GetTextWidth(m_sAscendingText
) + GetSettings().GetStyleSettings().GetScrollBarSize();
256 nSortOrderColumnWidth
= nSortOrderColumnWidth
> nOther
? nSortOrderColumnWidth
: nOther
;
257 // ("descending" + scrollbar width)
258 nOther
= GetTextWidth(m_sDescendingText
) + GetSettings().GetStyleSettings().GetScrollBarSize();
259 nSortOrderColumnWidth
= nSortOrderColumnWidth
> nOther
? nSortOrderColumnWidth
: nOther
;
260 // (plus some additional space)
261 nSortOrderColumnWidth
+= GetTextWidth('0') * 2;
262 InsertDataColumn(COLUMN_ID_ORDER
, sColumnName
, nSortOrderColumnWidth
, HIB_STDSTYLE
, 1);
264 m_pSortingCell
= new ListBoxControl(&GetDataWindow());
265 m_pSortingCell
->InsertEntry(m_sAscendingText
);
266 m_pSortingCell
->InsertEntry(m_sDescendingText
);
267 m_pSortingCell
->SetHelpId( HID_DLGINDEX_INDEXDETAILS_SORTORDER
);
269 nFieldNameWidth
-= nSortOrderColumnWidth
;
271 StyleSettings aSystemStyle
= Application::GetSettings().GetStyleSettings();
272 nFieldNameWidth
-= aSystemStyle
.GetScrollBarSize();
273 nFieldNameWidth
-= 8;
274 // the "field name" column
275 String sColumnName
= String(ModuleRes(STR_TAB_INDEX_FIELD
));
276 InsertDataColumn(COLUMN_ID_FIELDNAME
, sColumnName
, nFieldNameWidth
, HIB_STDSTYLE
, 0);
278 // create the cell controllers
279 // for the field name cell
280 m_pFieldNameCell
= new ListBoxControl(&GetDataWindow());
281 m_pFieldNameCell
->InsertEntry(String());
282 m_pFieldNameCell
->SetHelpId( HID_DLGINDEX_INDEXDETAILS_FIELD
);
283 const ::rtl::OUString
* pFields
= _rAvailableFields
.getConstArray();
284 const ::rtl::OUString
* pFieldsEnd
= pFields
+ _rAvailableFields
.getLength();
285 for (;pFields
< pFieldsEnd
; ++pFields
)
286 m_pFieldNameCell
->InsertEntry(*pFields
);
289 //------------------------------------------------------------------
290 CellController
* IndexFieldsControl::GetController(long _nRow
, sal_uInt16 _nColumnId
)
295 ConstIndexFieldsIterator aRow
;
296 sal_Bool bNewField
= !implGetFieldDesc(_nRow
, aRow
);
298 DbaMouseDownListBoxController
* pReturn
= NULL
;
301 case COLUMN_ID_ORDER
:
302 if (!bNewField
&& m_pSortingCell
&& 0 != aRow
->sFieldName
.Len())
303 pReturn
= new DbaMouseDownListBoxController(m_pSortingCell
);
306 case COLUMN_ID_FIELDNAME
:
307 pReturn
= new DbaMouseDownListBoxController(m_pFieldNameCell
);
311 OSL_FAIL("IndexFieldsControl::GetController: invalid column id!");
315 pReturn
->SetAdditionalModifyHdl(LINK(this, IndexFieldsControl
, OnListEntrySelected
));
320 //------------------------------------------------------------------
321 sal_Bool
IndexFieldsControl::implGetFieldDesc(long _nRow
, ConstIndexFieldsIterator
& _rPos
)
323 _rPos
= m_aFields
.end();
324 if ((_nRow
< 0) || (_nRow
>= (sal_Int32
)m_aFields
.size()))
326 _rPos
= m_aFields
.begin() + _nRow
;
330 //------------------------------------------------------------------
331 sal_Bool
IndexFieldsControl::IsModified() const
333 return EditBrowseBox::IsModified();
336 //------------------------------------------------------------------
337 sal_Bool
IndexFieldsControl::SaveModified()
342 switch (GetCurColumnId())
344 case COLUMN_ID_FIELDNAME
:
346 String sFieldSelected
= m_pFieldNameCell
->GetSelectEntry();
347 sal_Bool bEmptySelected
= 0 == sFieldSelected
.Len();
352 // add a new field to the collection
353 OIndexField aNewField
;
354 aNewField
.sFieldName
= sFieldSelected
;
355 m_aFields
.push_back(aNewField
);
356 RowInserted(GetRowCount(), 1, sal_True
);
361 sal_Int32 nRow
= GetCurRow();
362 OSL_ENSURE(nRow
< (sal_Int32
)m_aFields
.size(), "IndexFieldsControl::SaveModified: invalid current row!");
363 if (nRow
>= 0) // may be -1 in case the control was empty
365 // remove the field from the selection
366 IndexFieldsIterator aPos
= m_aFields
.begin() + nRow
;
370 aPos
->sFieldName
= String();
372 // invalidate the row to force repaint
373 Invalidate(GetRowRectPixel(nRow
));
377 if (sFieldSelected
== aPos
->sFieldName
)
381 aPos
->sFieldName
= sFieldSelected
;
385 Invalidate(GetRowRectPixel(GetCurRow()));
388 case COLUMN_ID_ORDER
:
390 OSL_ENSURE(!isNewField(), "IndexFieldsControl::SaveModified: why the hell ...!!!");
392 sal_uInt16 nPos
= m_pSortingCell
->GetSelectEntryPos();
393 OSL_ENSURE(LISTBOX_ENTRY_NOTFOUND
!= nPos
, "IndexFieldsControl::SaveModified: how did you get this selection??");
394 // adjust the sort flag in the index field description
395 OIndexField
& rCurrentField
= m_aFields
[GetCurRow()];
396 rCurrentField
.bSortAscending
= (0 == nPos
);
401 OSL_FAIL("IndexFieldsControl::SaveModified: invalid column id!");
406 //------------------------------------------------------------------
407 void IndexFieldsControl::InitController(CellControllerRef
& /*_rController*/, long _nRow
, sal_uInt16 _nColumnId
)
409 ConstIndexFieldsIterator aFieldDescription
;
410 sal_Bool bNewField
= !implGetFieldDesc(_nRow
, aFieldDescription
);
414 case COLUMN_ID_FIELDNAME
:
415 m_pFieldNameCell
->SelectEntry(bNewField
? String() : aFieldDescription
->sFieldName
);
416 m_pFieldNameCell
->SaveValue();
419 case COLUMN_ID_ORDER
:
420 m_pSortingCell
->SelectEntry(aFieldDescription
->bSortAscending
? m_sAscendingText
: m_sDescendingText
);
421 m_pSortingCell
->SaveValue();
425 OSL_FAIL("IndexFieldsControl::InitController: invalid column id!");
429 //------------------------------------------------------------------
430 IMPL_LINK( IndexFieldsControl
, OnListEntrySelected
, ListBox
*, _pBox
)
432 if (!_pBox
->IsTravelSelect() && m_aModifyHdl
.IsSet())
433 m_aModifyHdl
.Call(this);
435 if (_pBox
== m_pFieldNameCell
)
436 { // a field has been selected
437 if (GetCurRow() >= GetRowCount() - 2)
438 { // and we're in one of the last two rows
439 String sSelectedEntry
= m_pFieldNameCell
->GetSelectEntry();
440 sal_Int32 nCurrentRow
= GetCurRow();
441 sal_Int32 rowCount
= GetRowCount();
443 OSL_ENSURE(((sal_Int32
)(m_aFields
.size() + 1)) == rowCount
, "IndexFieldsControl::OnListEntrySelected: inconsistence!");
445 if (sSelectedEntry
.Len() && (nCurrentRow
== rowCount
- 1) /*&& (!m_nMaxColumnsInIndex || rowCount < m_nMaxColumnsInIndex )*/ )
446 { // in the last row, an non-empty string has been selected
447 // -> insert a new row
448 m_aFields
.push_back(OIndexField());
449 RowInserted(GetRowCount(), 1);
450 Invalidate(GetRowRectPixel(nCurrentRow
));
452 else if (!sSelectedEntry
.Len() && (nCurrentRow
== rowCount
- 2))
453 { // in the (last-1)th row, an empty entry has been selected
454 // -> remove the last row
455 m_aFields
.erase(m_aFields
.end() - 1);
456 RowRemoved(GetRowCount() - 1, 1);
457 Invalidate(GetRowRectPixel(nCurrentRow
));
465 //------------------------------------------------------------------
466 String
IndexFieldsControl::GetCellText(long _nRow
,sal_uInt16 nColId
) const
468 ConstIndexFieldsIterator aRow
= m_aFields
.end();
471 aRow
= m_aFields
.begin() + _nRow
;
472 OSL_ENSURE(aRow
<= m_aFields
.end(), "IndexFieldsControl::SeekRow: invalid row!");
474 return GetRowCellText(aRow
,nColId
);
476 //------------------------------------------------------------------
477 String
IndexFieldsControl::GetRowCellText(const ConstIndexFieldsIterator
& _rRow
,sal_uInt16 nColId
) const
479 if (_rRow
< m_aFields
.end())
483 case COLUMN_ID_FIELDNAME
:
484 return _rRow
->sFieldName
;
485 case COLUMN_ID_ORDER
:
486 if (0 == _rRow
->sFieldName
.Len())
489 return _rRow
->bSortAscending
? m_sAscendingText
: m_sDescendingText
;
491 OSL_FAIL("IndexFieldsControl::GetCurrentRowCellText: invalid column id!");
496 //------------------------------------------------------------------
497 sal_Bool
IndexFieldsControl::IsTabAllowed(sal_Bool
/*bForward*/) const
501 //------------------------------------------------------------------
503 //......................................................................
505 //......................................................................
507 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */