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 :
21 : #include "indexfieldscontrol.hxx"
22 : #include "dbu_dlg.hrc"
23 : #include <osl/diagnose.h>
24 : #include "dbaccess_helpid.hrc"
25 :
26 : //......................................................................
27 : namespace dbaui
28 : {
29 : //......................................................................
30 :
31 : #define BROWSER_STANDARD_FLAGS BROWSER_COLUMNSELECTION | BROWSER_HLINESFULL | BROWSER_VLINESFULL | \
32 : BROWSER_HIDECURSOR | BROWSER_HIDESELECT | BROWSER_AUTO_HSCROLL | BROWSER_AUTO_VSCROLL
33 :
34 : #define COLUMN_ID_FIELDNAME 1
35 : #define COLUMN_ID_ORDER 2
36 :
37 : using namespace ::com::sun::star::uno;
38 : using namespace ::svt;
39 :
40 : //==================================================================
41 : //= DbaMouseDownListBoxController
42 : //==================================================================
43 0 : class DbaMouseDownListBoxController : public ListBoxCellController
44 : {
45 : protected:
46 : Link m_aOriginalModifyHdl;
47 : Link m_aAdditionalModifyHdl;
48 :
49 : public:
50 0 : DbaMouseDownListBoxController(ListBoxControl* _pParent)
51 0 : :ListBoxCellController(_pParent)
52 : {
53 0 : }
54 :
55 : void SetAdditionalModifyHdl(const Link& _rHdl);
56 :
57 : protected:
58 0 : virtual sal_Bool WantMouseEvent() const { return sal_True; }
59 : virtual void SetModifyHdl(const Link& _rHdl);
60 :
61 : private:
62 : void implCheckLinks();
63 : DECL_LINK( OnMultiplexModify, void* );
64 : };
65 :
66 : //------------------------------------------------------------------
67 0 : void DbaMouseDownListBoxController::SetAdditionalModifyHdl(const Link& _rHdl)
68 : {
69 0 : m_aAdditionalModifyHdl = _rHdl;
70 0 : implCheckLinks();
71 0 : }
72 :
73 : //------------------------------------------------------------------
74 0 : void DbaMouseDownListBoxController::SetModifyHdl(const Link& _rHdl)
75 : {
76 0 : m_aOriginalModifyHdl = _rHdl;
77 0 : implCheckLinks();
78 0 : }
79 :
80 : //------------------------------------------------------------------
81 0 : IMPL_LINK( DbaMouseDownListBoxController, OnMultiplexModify, void*, _pArg )
82 : {
83 0 : if (m_aAdditionalModifyHdl.IsSet())
84 0 : m_aAdditionalModifyHdl.Call(_pArg);
85 0 : if (m_aOriginalModifyHdl.IsSet())
86 0 : m_aOriginalModifyHdl.Call(_pArg);
87 0 : return 0L;
88 : }
89 :
90 : //------------------------------------------------------------------
91 0 : void DbaMouseDownListBoxController::implCheckLinks()
92 : {
93 0 : if (m_aAdditionalModifyHdl.IsSet() || m_aOriginalModifyHdl.IsSet())
94 0 : ListBoxCellController::SetModifyHdl(LINK(this, DbaMouseDownListBoxController, OnMultiplexModify));
95 : else
96 0 : ListBoxCellController::SetModifyHdl(Link());
97 0 : }
98 :
99 : //==================================================================
100 : //= IndexFieldsControl
101 : //==================================================================
102 : DBG_NAME(IndexFieldsControl)
103 : //------------------------------------------------------------------
104 0 : IndexFieldsControl::IndexFieldsControl( Window* _pParent, const ResId& _rId ,sal_Int32 _nMaxColumnsInIndex,sal_Bool _bAddIndexAppendix)
105 : :EditBrowseBox(_pParent, _rId, EBBF_SMART_TAB_TRAVEL | EBBF_ACTIVATE_ON_BUTTONDOWN, BROWSER_STANDARD_FLAGS)
106 0 : ,m_aSeekRow(m_aFields.end())
107 : ,m_pSortingCell(NULL)
108 : ,m_pFieldNameCell(NULL)
109 : ,m_nMaxColumnsInIndex(_nMaxColumnsInIndex)
110 0 : ,m_bAddIndexAppendix(_bAddIndexAppendix)
111 : {
112 : DBG_CTOR(IndexFieldsControl,NULL);
113 :
114 0 : SetUniqueId( UID_DLGINDEX_INDEXDETAILS_BACK );
115 0 : GetDataWindow().SetUniqueId( UID_DLGINDEX_INDEXDETAILS_MAIN );
116 0 : }
117 :
118 : //------------------------------------------------------------------
119 0 : IndexFieldsControl::~IndexFieldsControl()
120 : {
121 0 : delete m_pSortingCell;
122 0 : delete m_pFieldNameCell;
123 :
124 : DBG_DTOR(IndexFieldsControl,NULL);
125 0 : }
126 :
127 : //------------------------------------------------------------------
128 0 : sal_Bool IndexFieldsControl::SeekRow(long nRow)
129 : {
130 0 : if (!EditBrowseBox::SeekRow(nRow))
131 0 : return sal_False;
132 :
133 0 : if (nRow < 0)
134 : {
135 0 : m_aSeekRow = m_aFields.end();
136 : }
137 : else
138 : {
139 0 : m_aSeekRow = m_aFields.begin() + nRow;
140 : OSL_ENSURE(m_aSeekRow <= m_aFields.end(), "IndexFieldsControl::SeekRow: invalid row!");
141 : }
142 :
143 0 : return sal_True;
144 : }
145 :
146 : //------------------------------------------------------------------
147 0 : void IndexFieldsControl::PaintCell( OutputDevice& _rDev, const Rectangle& _rRect, sal_uInt16 _nColumnId ) const
148 : {
149 0 : Point aPos(_rRect.TopLeft());
150 0 : aPos.X() += 1;
151 :
152 0 : String aText = GetRowCellText(m_aSeekRow,_nColumnId);
153 0 : Size TxtSize(GetDataWindow().GetTextWidth(aText), GetDataWindow().GetTextHeight());
154 :
155 : // clipping
156 0 : if (aPos.X() < _rRect.Right() || aPos.X() + TxtSize.Width() > _rRect.Right() ||
157 0 : aPos.Y() < _rRect.Top() || aPos.Y() + TxtSize.Height() > _rRect.Bottom())
158 0 : _rDev.SetClipRegion( _rRect );
159 :
160 : // allow for a disabled control ...
161 0 : sal_Bool bEnabled = IsEnabled();
162 0 : Color aOriginalColor = _rDev.GetTextColor();
163 0 : if (!bEnabled)
164 0 : _rDev.SetTextColor(GetSettings().GetStyleSettings().GetDisableColor());
165 :
166 : // draw the text
167 0 : _rDev.DrawText(aPos, aText);
168 :
169 : // reset the color (if necessary)
170 0 : if (!bEnabled)
171 0 : _rDev.SetTextColor(aOriginalColor);
172 :
173 0 : if (_rDev.IsClipRegion())
174 0 : _rDev.SetClipRegion();
175 0 : }
176 :
177 : //------------------------------------------------------------------
178 0 : void IndexFieldsControl::initializeFrom(const IndexFields& _rFields)
179 : {
180 : // copy the field descriptions
181 0 : m_aFields = _rFields;
182 0 : m_aSeekRow = m_aFields.end();
183 :
184 0 : SetUpdateMode(sal_False);
185 : // remove all rows
186 0 : RowRemoved(1, GetRowCount());
187 : // insert rows for the the fields
188 0 : RowInserted(GetRowCount(), m_aFields.size(), sal_False);
189 : // insert an additional row for a new field for that index
190 0 : RowInserted(GetRowCount(), 1, sal_False);
191 0 : SetUpdateMode(sal_True);
192 :
193 0 : GoToRowColumnId(0, COLUMN_ID_FIELDNAME);
194 0 : }
195 :
196 : //------------------------------------------------------------------
197 0 : void IndexFieldsControl::commitTo(IndexFields& _rFields)
198 : {
199 : // do not just copy the array, we may have empty field names (which should not be copied)
200 0 : _rFields.resize(m_aFields.size());
201 0 : ConstIndexFieldsIterator aSource = m_aFields.begin();
202 0 : ConstIndexFieldsIterator aSourceEnd = m_aFields.end();
203 0 : IndexFieldsIterator aDest = _rFields.begin();
204 0 : for (; aSource < aSourceEnd; ++aSource)
205 0 : if (0 != aSource->sFieldName.Len())
206 : {
207 0 : *aDest = *aSource;
208 0 : ++aDest;
209 : }
210 :
211 0 : _rFields.resize(aDest - _rFields.begin());
212 0 : }
213 :
214 : //------------------------------------------------------------------
215 0 : sal_uInt32 IndexFieldsControl::GetTotalCellWidth(long _nRow, sal_uInt16 _nColId)
216 : {
217 0 : if (COLUMN_ID_ORDER == _nColId)
218 : {
219 0 : sal_Int32 nWidthAsc = GetTextWidth(m_sAscendingText) + GetSettings().GetStyleSettings().GetScrollBarSize();
220 0 : sal_Int32 nWidthDesc = GetTextWidth(m_sDescendingText) + GetSettings().GetStyleSettings().GetScrollBarSize();
221 : // maximum plus some additional space
222 0 : return (nWidthAsc > nWidthDesc ? nWidthAsc : nWidthDesc) + GetTextWidth(rtl::OUString('0')) * 2;
223 : }
224 0 : return EditBrowseBox::GetTotalCellWidth(_nRow, _nColId);
225 : }
226 :
227 : //------------------------------------------------------------------
228 0 : void IndexFieldsControl::Init(const Sequence< ::rtl::OUString >& _rAvailableFields)
229 : {
230 0 : RemoveColumns();
231 :
232 : // for the width: both columns together should be somewhat smaller than the whole window (without the scrollbar)
233 0 : sal_Int32 nFieldNameWidth = GetSizePixel().Width();
234 :
235 0 : if ( m_bAddIndexAppendix )
236 : {
237 0 : m_sAscendingText = String(ModuleRes(STR_ORDER_ASCENDING));
238 0 : m_sDescendingText = String(ModuleRes(STR_ORDER_DESCENDING));
239 :
240 : // the "sort order" column
241 0 : String sColumnName = String(ModuleRes(STR_TAB_INDEX_SORTORDER));
242 : // the width of the order column is the maximum widths of the texts used
243 : // (the title of the column)
244 0 : sal_Int32 nSortOrderColumnWidth = GetTextWidth(sColumnName);
245 : // ("ascending" + scrollbar width)
246 0 : sal_Int32 nOther = GetTextWidth(m_sAscendingText) + GetSettings().GetStyleSettings().GetScrollBarSize();
247 0 : nSortOrderColumnWidth = nSortOrderColumnWidth > nOther ? nSortOrderColumnWidth : nOther;
248 : // ("descending" + scrollbar width)
249 0 : nOther = GetTextWidth(m_sDescendingText) + GetSettings().GetStyleSettings().GetScrollBarSize();
250 0 : nSortOrderColumnWidth = nSortOrderColumnWidth > nOther ? nSortOrderColumnWidth : nOther;
251 : // (plus some additional space)
252 0 : nSortOrderColumnWidth += GetTextWidth(rtl::OUString('0')) * 2;
253 0 : InsertDataColumn(COLUMN_ID_ORDER, sColumnName, nSortOrderColumnWidth, HIB_STDSTYLE, 1);
254 :
255 0 : m_pSortingCell = new ListBoxControl(&GetDataWindow());
256 0 : m_pSortingCell->InsertEntry(m_sAscendingText);
257 0 : m_pSortingCell->InsertEntry(m_sDescendingText);
258 0 : m_pSortingCell->SetHelpId( HID_DLGINDEX_INDEXDETAILS_SORTORDER );
259 :
260 0 : nFieldNameWidth -= nSortOrderColumnWidth;
261 : }
262 0 : StyleSettings aSystemStyle = Application::GetSettings().GetStyleSettings();
263 0 : nFieldNameWidth -= aSystemStyle.GetScrollBarSize();
264 0 : nFieldNameWidth -= 8;
265 : // the "field name" column
266 0 : String sColumnName = String(ModuleRes(STR_TAB_INDEX_FIELD));
267 0 : InsertDataColumn(COLUMN_ID_FIELDNAME, sColumnName, nFieldNameWidth, HIB_STDSTYLE, 0);
268 :
269 : // create the cell controllers
270 : // for the field name cell
271 0 : m_pFieldNameCell = new ListBoxControl(&GetDataWindow());
272 0 : m_pFieldNameCell->InsertEntry(String());
273 0 : m_pFieldNameCell->SetHelpId( HID_DLGINDEX_INDEXDETAILS_FIELD );
274 0 : const ::rtl::OUString* pFields = _rAvailableFields.getConstArray();
275 0 : const ::rtl::OUString* pFieldsEnd = pFields + _rAvailableFields.getLength();
276 0 : for (;pFields < pFieldsEnd; ++pFields)
277 0 : m_pFieldNameCell->InsertEntry(*pFields);
278 0 : }
279 :
280 : //------------------------------------------------------------------
281 0 : CellController* IndexFieldsControl::GetController(long _nRow, sal_uInt16 _nColumnId)
282 : {
283 0 : if (!IsEnabled())
284 0 : return NULL;
285 :
286 0 : ConstIndexFieldsIterator aRow;
287 0 : sal_Bool bNewField = !implGetFieldDesc(_nRow, aRow);
288 :
289 0 : DbaMouseDownListBoxController* pReturn = NULL;
290 0 : switch (_nColumnId)
291 : {
292 : case COLUMN_ID_ORDER:
293 0 : if (!bNewField && m_pSortingCell && 0 != aRow->sFieldName.Len())
294 0 : pReturn = new DbaMouseDownListBoxController(m_pSortingCell);
295 0 : break;
296 :
297 : case COLUMN_ID_FIELDNAME:
298 0 : pReturn = new DbaMouseDownListBoxController(m_pFieldNameCell);
299 0 : break;
300 :
301 : default:
302 : OSL_FAIL("IndexFieldsControl::GetController: invalid column id!");
303 : }
304 :
305 0 : if (pReturn)
306 0 : pReturn->SetAdditionalModifyHdl(LINK(this, IndexFieldsControl, OnListEntrySelected));
307 :
308 0 : return pReturn;
309 : }
310 :
311 : //------------------------------------------------------------------
312 0 : sal_Bool IndexFieldsControl::implGetFieldDesc(long _nRow, ConstIndexFieldsIterator& _rPos)
313 : {
314 0 : _rPos = m_aFields.end();
315 0 : if ((_nRow < 0) || (_nRow >= (sal_Int32)m_aFields.size()))
316 0 : return sal_False;
317 0 : _rPos = m_aFields.begin() + _nRow;
318 0 : return sal_True;
319 : }
320 :
321 : //------------------------------------------------------------------
322 0 : sal_Bool IndexFieldsControl::IsModified() const
323 : {
324 0 : return EditBrowseBox::IsModified();
325 : }
326 :
327 : //------------------------------------------------------------------
328 0 : sal_Bool IndexFieldsControl::SaveModified()
329 : {
330 0 : if (!IsModified())
331 0 : return sal_True;
332 :
333 0 : switch (GetCurColumnId())
334 : {
335 : case COLUMN_ID_FIELDNAME:
336 : {
337 0 : String sFieldSelected = m_pFieldNameCell->GetSelectEntry();
338 0 : sal_Bool bEmptySelected = 0 == sFieldSelected.Len();
339 0 : if (isNewField())
340 : {
341 0 : if (!bEmptySelected)
342 : {
343 : // add a new field to the collection
344 0 : OIndexField aNewField;
345 0 : aNewField.sFieldName = sFieldSelected;
346 0 : m_aFields.push_back(aNewField);
347 0 : RowInserted(GetRowCount(), 1, sal_True);
348 : }
349 : }
350 : else
351 : {
352 0 : sal_Int32 nRow = GetCurRow();
353 : OSL_ENSURE(nRow < (sal_Int32)m_aFields.size(), "IndexFieldsControl::SaveModified: invalid current row!");
354 0 : if (nRow >= 0) // may be -1 in case the control was empty
355 : {
356 : // remove the field from the selection
357 0 : IndexFieldsIterator aPos = m_aFields.begin() + nRow;
358 :
359 0 : if (bEmptySelected)
360 : {
361 0 : aPos->sFieldName = String();
362 :
363 : // invalidate the row to force repaint
364 0 : Invalidate(GetRowRectPixel(nRow));
365 0 : return sal_True;
366 : }
367 :
368 0 : if (sFieldSelected == aPos->sFieldName)
369 : // nothing changed
370 0 : return sal_True;
371 :
372 0 : aPos->sFieldName = sFieldSelected;
373 : }
374 : }
375 :
376 0 : Invalidate(GetRowRectPixel(GetCurRow()));
377 : }
378 0 : break;
379 : case COLUMN_ID_ORDER:
380 : {
381 : OSL_ENSURE(!isNewField(), "IndexFieldsControl::SaveModified: why the hell ...!!!");
382 : // selected entry
383 0 : sal_uInt16 nPos = m_pSortingCell->GetSelectEntryPos();
384 : OSL_ENSURE(LISTBOX_ENTRY_NOTFOUND != nPos, "IndexFieldsControl::SaveModified: how did you get this selection??");
385 : // adjust the sort flag in the index field description
386 0 : OIndexField& rCurrentField = m_aFields[GetCurRow()];
387 0 : rCurrentField.bSortAscending = (0 == nPos);
388 :
389 : }
390 0 : break;
391 : default:
392 : OSL_FAIL("IndexFieldsControl::SaveModified: invalid column id!");
393 : }
394 0 : return sal_True;
395 : }
396 :
397 : //------------------------------------------------------------------
398 0 : void IndexFieldsControl::InitController(CellControllerRef& /*_rController*/, long _nRow, sal_uInt16 _nColumnId)
399 : {
400 0 : ConstIndexFieldsIterator aFieldDescription;
401 0 : sal_Bool bNewField = !implGetFieldDesc(_nRow, aFieldDescription);
402 :
403 0 : switch (_nColumnId)
404 : {
405 : case COLUMN_ID_FIELDNAME:
406 0 : m_pFieldNameCell->SelectEntry(bNewField ? String() : aFieldDescription->sFieldName);
407 0 : m_pFieldNameCell->SaveValue();
408 0 : break;
409 :
410 : case COLUMN_ID_ORDER:
411 0 : m_pSortingCell->SelectEntry(aFieldDescription->bSortAscending ? m_sAscendingText : m_sDescendingText);
412 0 : m_pSortingCell->SaveValue();
413 0 : break;
414 :
415 : default:
416 : OSL_FAIL("IndexFieldsControl::InitController: invalid column id!");
417 : }
418 0 : }
419 :
420 : //------------------------------------------------------------------
421 0 : IMPL_LINK( IndexFieldsControl, OnListEntrySelected, ListBox*, _pBox )
422 : {
423 0 : if (!_pBox->IsTravelSelect() && m_aModifyHdl.IsSet())
424 0 : m_aModifyHdl.Call(this);
425 :
426 0 : if (_pBox == m_pFieldNameCell)
427 : { // a field has been selected
428 0 : if (GetCurRow() >= GetRowCount() - 2)
429 : { // and we're in one of the last two rows
430 0 : String sSelectedEntry = m_pFieldNameCell->GetSelectEntry();
431 0 : sal_Int32 nCurrentRow = GetCurRow();
432 0 : sal_Int32 rowCount = GetRowCount();
433 :
434 : OSL_ENSURE(((sal_Int32)(m_aFields.size() + 1)) == rowCount, "IndexFieldsControl::OnListEntrySelected: inconsistence!");
435 :
436 0 : if (sSelectedEntry.Len() && (nCurrentRow == rowCount - 1) /*&& (!m_nMaxColumnsInIndex || rowCount < m_nMaxColumnsInIndex )*/ )
437 : { // in the last row, an non-empty string has been selected
438 : // -> insert a new row
439 0 : m_aFields.push_back(OIndexField());
440 0 : RowInserted(GetRowCount(), 1);
441 0 : Invalidate(GetRowRectPixel(nCurrentRow));
442 : }
443 0 : else if (!sSelectedEntry.Len() && (nCurrentRow == rowCount - 2))
444 : { // in the (last-1)th row, an empty entry has been selected
445 : // -> remove the last row
446 0 : m_aFields.erase(m_aFields.end() - 1);
447 0 : RowRemoved(GetRowCount() - 1, 1);
448 0 : Invalidate(GetRowRectPixel(nCurrentRow));
449 0 : }
450 : }
451 :
452 0 : SaveModified();
453 : }
454 0 : return 0L;
455 : }
456 : //------------------------------------------------------------------
457 0 : String IndexFieldsControl::GetCellText(long _nRow,sal_uInt16 nColId) const
458 : {
459 0 : ConstIndexFieldsIterator aRow = m_aFields.end();
460 0 : if ( _nRow >= 0 )
461 : {
462 0 : aRow = m_aFields.begin() + _nRow;
463 : OSL_ENSURE(aRow <= m_aFields.end(), "IndexFieldsControl::SeekRow: invalid row!");
464 : }
465 0 : return GetRowCellText(aRow,nColId);
466 : }
467 : //------------------------------------------------------------------
468 0 : String IndexFieldsControl::GetRowCellText(const ConstIndexFieldsIterator& _rRow,sal_uInt16 nColId) const
469 : {
470 0 : if (_rRow < m_aFields.end())
471 : {
472 0 : switch (nColId)
473 : {
474 : case COLUMN_ID_FIELDNAME:
475 0 : return _rRow->sFieldName;
476 : case COLUMN_ID_ORDER:
477 0 : if (0 == _rRow->sFieldName.Len())
478 0 : return String();
479 : else
480 0 : return _rRow->bSortAscending ? m_sAscendingText : m_sDescendingText;
481 : default:
482 : OSL_FAIL("IndexFieldsControl::GetCurrentRowCellText: invalid column id!");
483 : }
484 : }
485 0 : return String();
486 : }
487 : //------------------------------------------------------------------
488 0 : sal_Bool IndexFieldsControl::IsTabAllowed(sal_Bool /*bForward*/) const
489 : {
490 0 : return sal_False;
491 : }
492 : //------------------------------------------------------------------
493 :
494 : //......................................................................
495 : } // namespace dbaui
496 : //......................................................................
497 :
498 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|