merge the formfield patch from ooo-build
[ooovba.git] / dbaccess / source / ui / dlg / indexfieldscontrol.cxx
blob4bf0131bf91847cdf67570e082b821299dffbe31
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: indexfieldscontrol.cxx,v $
10 * $Revision: 1.18 $
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"
36 #endif
37 #ifndef _DBU_DLG_HRC_
38 #include "dbu_dlg.hrc"
39 #endif
40 #ifndef _OSL_DIAGNOSE_H_
41 #include <osl/diagnose.h>
42 #endif
43 #ifndef _DBA_DBACCESS_HELPID_HRC_
44 #include "dbaccess_helpid.hrc"
45 #endif
47 //......................................................................
48 namespace dbaui
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
66 protected:
67 Link m_aOriginalModifyHdl;
68 Link m_aAdditionalModifyHdl;
70 public:
71 DbaMouseDownListBoxController(ListBoxControl* _pParent)
72 :ListBoxCellController(_pParent)
76 void SetAdditionalModifyHdl(const Link& _rHdl);
78 protected:
79 virtual sal_Bool WantMouseEvent() const { return sal_True; }
80 virtual void SetModifyHdl(const Link& _rHdl);
82 private:
83 void implCheckLinks();
84 DECL_LINK( OnMultiplexModify, void* );
87 //------------------------------------------------------------------
88 void DbaMouseDownListBoxController::SetAdditionalModifyHdl(const Link& _rHdl)
90 m_aAdditionalModifyHdl = _rHdl;
91 implCheckLinks();
94 //------------------------------------------------------------------
95 void DbaMouseDownListBoxController::SetModifyHdl(const Link& _rHdl)
97 m_aOriginalModifyHdl = _rHdl;
98 implCheckLinks();
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);
108 return 0L;
111 //------------------------------------------------------------------
112 void DbaMouseDownListBoxController::implCheckLinks()
114 if (m_aAdditionalModifyHdl.IsSet() || m_aOriginalModifyHdl.IsSet())
115 ListBoxCellController::SetModifyHdl(LINK(this, DbaMouseDownListBoxController, OnMultiplexModify));
116 else
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))
151 return sal_False;
153 if (nRow < 0)
155 m_aSeekRow = m_aFields.end();
157 else
159 m_aSeekRow = m_aFields.begin() + nRow;
160 OSL_ENSURE(m_aSeekRow <= m_aFields.end(), "IndexFieldsControl::SeekRow: invalid row!");
163 return sal_True;
166 //------------------------------------------------------------------
167 void IndexFieldsControl::PaintCell( OutputDevice& _rDev, const Rectangle& _rRect, sal_uInt16 _nColumnId ) const
169 Point aPos(_rRect.TopLeft());
170 aPos.X() += 1;
172 String aText = GetRowCellText(m_aSeekRow,_nColumnId);
173 Size TxtSize(GetDataWindow().GetTextWidth(aText), GetDataWindow().GetTextHeight());
175 // clipping
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();
183 if (!bEnabled)
184 _rDev.SetTextColor(GetSettings().GetStyleSettings().GetDisableColor());
186 // draw the text
187 _rDev.DrawText(aPos, aText);
189 // reset the color (if necessary)
190 if (!bEnabled)
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);
205 // remove all rows
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())
228 *aDest = *aSource;
229 ++aDest;
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)
251 RemoveColumns();
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);
291 // for the sort cell
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)
303 if (!IsEnabled())
304 return NULL;
306 ConstIndexFieldsIterator aRow;
307 sal_Bool bNewField = !implGetFieldDesc(_nRow, aRow);
309 DbaMouseDownListBoxController* pReturn = NULL;
310 switch (_nColumnId)
312 case COLUMN_ID_ORDER:
313 if (!bNewField && m_pSortingCell && 0 != aRow->sFieldName.Len())
314 pReturn = new DbaMouseDownListBoxController(m_pSortingCell);
315 break;
317 case COLUMN_ID_FIELDNAME:
318 pReturn = new DbaMouseDownListBoxController(m_pFieldNameCell);
319 break;
321 default:
322 OSL_ENSURE(sal_False, "IndexFieldsControl::GetController: invalid column id!");
325 if (pReturn)
326 pReturn->SetAdditionalModifyHdl(LINK(this, IndexFieldsControl, OnListEntrySelected));
328 return pReturn;
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()))
336 return sal_False;
337 _rPos = m_aFields.begin() + _nRow;
338 return sal_True;
341 //------------------------------------------------------------------
342 sal_Bool IndexFieldsControl::IsModified() const
344 return EditBrowseBox::IsModified();
347 //------------------------------------------------------------------
348 sal_Bool IndexFieldsControl::SaveModified()
350 if (!IsModified())
351 return sal_True;
353 switch (GetCurColumnId())
355 case COLUMN_ID_FIELDNAME:
357 String sFieldSelected = m_pFieldNameCell->GetSelectEntry();
358 sal_Bool bEmptySelected = 0 == sFieldSelected.Len();
359 if (isNewField())
361 if (!bEmptySelected)
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);
370 else
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;
379 if (bEmptySelected)
381 aPos->sFieldName = String();
383 // invalidate the row to force repaint
384 Invalidate(GetRowRectPixel(nRow));
385 return sal_True;
388 if (sFieldSelected == aPos->sFieldName)
389 // nothing changed
390 return sal_True;
392 aPos->sFieldName = sFieldSelected;
396 Invalidate(GetRowRectPixel(GetCurRow()));
398 break;
399 case COLUMN_ID_ORDER:
401 OSL_ENSURE(!isNewField(), "IndexFieldsControl::SaveModified: why the hell ...!!!");
402 // selected entry
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);
410 break;
411 default:
412 OSL_ENSURE(sal_False, "IndexFieldsControl::SaveModified: invalid column id!");
414 return sal_True;
417 //------------------------------------------------------------------
418 void IndexFieldsControl::InitController(CellControllerRef& /*_rController*/, long _nRow, sal_uInt16 _nColumnId)
420 ConstIndexFieldsIterator aFieldDescription;
421 sal_Bool bNewField = !implGetFieldDesc(_nRow, aFieldDescription);
423 switch (_nColumnId)
425 case COLUMN_ID_FIELDNAME:
426 m_pFieldNameCell->SelectEntry(bNewField ? String() : aFieldDescription->sFieldName);
427 m_pFieldNameCell->SaveValue();
428 break;
430 case COLUMN_ID_ORDER:
431 m_pSortingCell->SelectEntry(aFieldDescription->bSortAscending ? m_sAscendingText : m_sDescendingText);
432 m_pSortingCell->SaveValue();
433 break;
435 default:
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));
472 SaveModified();
474 return 0L;
476 //------------------------------------------------------------------
477 String IndexFieldsControl::GetCellText(long _nRow,sal_uInt16 nColId) const
479 ConstIndexFieldsIterator aRow = m_aFields.end();
480 if ( _nRow >= 0 )
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())
492 switch (nColId)
494 case COLUMN_ID_FIELDNAME:
495 return _rRow->sFieldName;
496 case COLUMN_ID_ORDER:
497 if (0 == _rRow->sFieldName.Len())
498 return String();
499 else
500 return _rRow->bSortAscending ? m_sAscendingText : m_sDescendingText;
501 default:
502 OSL_ENSURE(sal_False, "IndexFieldsControl::GetCurrentRowCellText: invalid column id!");
505 return String();
507 //------------------------------------------------------------------
508 sal_Bool IndexFieldsControl::IsTabAllowed(sal_Bool /*bForward*/) const
510 return sal_False;
512 //------------------------------------------------------------------
514 //......................................................................
515 } // namespace dbaui
516 //......................................................................