Version 3.6.0.2, tag libreoffice-3.6.0.2
[LibreOffice.git] / dbaccess / source / ui / dlg / indexfieldscontrol.cxx
blob7c23d13ce3e7f9fda8c52214aa8ab68b267086d1
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 //......................................................................
36 namespace dbaui
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
54 protected:
55 Link m_aOriginalModifyHdl;
56 Link m_aAdditionalModifyHdl;
58 public:
59 DbaMouseDownListBoxController(ListBoxControl* _pParent)
60 :ListBoxCellController(_pParent)
64 void SetAdditionalModifyHdl(const Link& _rHdl);
66 protected:
67 virtual sal_Bool WantMouseEvent() const { return sal_True; }
68 virtual void SetModifyHdl(const Link& _rHdl);
70 private:
71 void implCheckLinks();
72 DECL_LINK( OnMultiplexModify, void* );
75 //------------------------------------------------------------------
76 void DbaMouseDownListBoxController::SetAdditionalModifyHdl(const Link& _rHdl)
78 m_aAdditionalModifyHdl = _rHdl;
79 implCheckLinks();
82 //------------------------------------------------------------------
83 void DbaMouseDownListBoxController::SetModifyHdl(const Link& _rHdl)
85 m_aOriginalModifyHdl = _rHdl;
86 implCheckLinks();
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);
96 return 0L;
99 //------------------------------------------------------------------
100 void DbaMouseDownListBoxController::implCheckLinks()
102 if (m_aAdditionalModifyHdl.IsSet() || m_aOriginalModifyHdl.IsSet())
103 ListBoxCellController::SetModifyHdl(LINK(this, DbaMouseDownListBoxController, OnMultiplexModify));
104 else
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))
140 return sal_False;
142 if (nRow < 0)
144 m_aSeekRow = m_aFields.end();
146 else
148 m_aSeekRow = m_aFields.begin() + nRow;
149 OSL_ENSURE(m_aSeekRow <= m_aFields.end(), "IndexFieldsControl::SeekRow: invalid row!");
152 return sal_True;
155 //------------------------------------------------------------------
156 void IndexFieldsControl::PaintCell( OutputDevice& _rDev, const Rectangle& _rRect, sal_uInt16 _nColumnId ) const
158 Point aPos(_rRect.TopLeft());
159 aPos.X() += 1;
161 String aText = GetRowCellText(m_aSeekRow,_nColumnId);
162 Size TxtSize(GetDataWindow().GetTextWidth(aText), GetDataWindow().GetTextHeight());
164 // clipping
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();
172 if (!bEnabled)
173 _rDev.SetTextColor(GetSettings().GetStyleSettings().GetDisableColor());
175 // draw the text
176 _rDev.DrawText(aPos, aText);
178 // reset the color (if necessary)
179 if (!bEnabled)
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);
194 // remove all rows
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())
216 *aDest = *aSource;
217 ++aDest;
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)
239 RemoveColumns();
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)
292 if (!IsEnabled())
293 return NULL;
295 ConstIndexFieldsIterator aRow;
296 sal_Bool bNewField = !implGetFieldDesc(_nRow, aRow);
298 DbaMouseDownListBoxController* pReturn = NULL;
299 switch (_nColumnId)
301 case COLUMN_ID_ORDER:
302 if (!bNewField && m_pSortingCell && 0 != aRow->sFieldName.Len())
303 pReturn = new DbaMouseDownListBoxController(m_pSortingCell);
304 break;
306 case COLUMN_ID_FIELDNAME:
307 pReturn = new DbaMouseDownListBoxController(m_pFieldNameCell);
308 break;
310 default:
311 OSL_FAIL("IndexFieldsControl::GetController: invalid column id!");
314 if (pReturn)
315 pReturn->SetAdditionalModifyHdl(LINK(this, IndexFieldsControl, OnListEntrySelected));
317 return pReturn;
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()))
325 return sal_False;
326 _rPos = m_aFields.begin() + _nRow;
327 return sal_True;
330 //------------------------------------------------------------------
331 sal_Bool IndexFieldsControl::IsModified() const
333 return EditBrowseBox::IsModified();
336 //------------------------------------------------------------------
337 sal_Bool IndexFieldsControl::SaveModified()
339 if (!IsModified())
340 return sal_True;
342 switch (GetCurColumnId())
344 case COLUMN_ID_FIELDNAME:
346 String sFieldSelected = m_pFieldNameCell->GetSelectEntry();
347 sal_Bool bEmptySelected = 0 == sFieldSelected.Len();
348 if (isNewField())
350 if (!bEmptySelected)
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);
359 else
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;
368 if (bEmptySelected)
370 aPos->sFieldName = String();
372 // invalidate the row to force repaint
373 Invalidate(GetRowRectPixel(nRow));
374 return sal_True;
377 if (sFieldSelected == aPos->sFieldName)
378 // nothing changed
379 return sal_True;
381 aPos->sFieldName = sFieldSelected;
385 Invalidate(GetRowRectPixel(GetCurRow()));
387 break;
388 case COLUMN_ID_ORDER:
390 OSL_ENSURE(!isNewField(), "IndexFieldsControl::SaveModified: why the hell ...!!!");
391 // selected entry
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);
399 break;
400 default:
401 OSL_FAIL("IndexFieldsControl::SaveModified: invalid column id!");
403 return sal_True;
406 //------------------------------------------------------------------
407 void IndexFieldsControl::InitController(CellControllerRef& /*_rController*/, long _nRow, sal_uInt16 _nColumnId)
409 ConstIndexFieldsIterator aFieldDescription;
410 sal_Bool bNewField = !implGetFieldDesc(_nRow, aFieldDescription);
412 switch (_nColumnId)
414 case COLUMN_ID_FIELDNAME:
415 m_pFieldNameCell->SelectEntry(bNewField ? String() : aFieldDescription->sFieldName);
416 m_pFieldNameCell->SaveValue();
417 break;
419 case COLUMN_ID_ORDER:
420 m_pSortingCell->SelectEntry(aFieldDescription->bSortAscending ? m_sAscendingText : m_sDescendingText);
421 m_pSortingCell->SaveValue();
422 break;
424 default:
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));
461 SaveModified();
463 return 0L;
465 //------------------------------------------------------------------
466 String IndexFieldsControl::GetCellText(long _nRow,sal_uInt16 nColId) const
468 ConstIndexFieldsIterator aRow = m_aFields.end();
469 if ( _nRow >= 0 )
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())
481 switch (nColId)
483 case COLUMN_ID_FIELDNAME:
484 return _rRow->sFieldName;
485 case COLUMN_ID_ORDER:
486 if (0 == _rRow->sFieldName.Len())
487 return String();
488 else
489 return _rRow->bSortAscending ? m_sAscendingText : m_sDescendingText;
490 default:
491 OSL_FAIL("IndexFieldsControl::GetCurrentRowCellText: invalid column id!");
494 return String();
496 //------------------------------------------------------------------
497 sal_Bool IndexFieldsControl::IsTabAllowed(sal_Bool /*bForward*/) const
499 return sal_False;
501 //------------------------------------------------------------------
503 //......................................................................
504 } // namespace dbaui
505 //......................................................................
507 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */