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 : #include "svx/fmgridif.hxx"
21 : #include "fmitems.hxx"
22 : #include "fmprop.hrc"
23 : #include "svx/fmtools.hxx"
24 : #include "svx/fmresids.hrc"
25 : #include "fmservs.hxx"
26 : #include "fmurl.hxx"
27 : #include "formcontrolfactory.hxx"
28 : #include "gridcell.hxx"
29 : #include "gridcols.hxx"
30 : #include "svx/dbaexchange.hxx"
31 : #include "svx/dialmgr.hxx"
32 : #include "svx/dialogs.hrc"
33 : #include "svx/fmgridcl.hxx"
34 : #include "svx/svxdlg.hxx"
35 : #include "svx/svxids.hrc"
36 : #include "trace.hxx"
37 :
38 : #include <com/sun/star/form/XConfirmDeleteListener.hpp>
39 : #include <com/sun/star/form/XFormComponent.hpp>
40 : #include <com/sun/star/form/XGridColumnFactory.hpp>
41 : #include <com/sun/star/io/XPersistObject.hpp>
42 : #include <com/sun/star/sdb/CommandType.hpp>
43 : #include <com/sun/star/sdb/RowChangeAction.hpp>
44 : #include <com/sun/star/sdb/XQueriesSupplier.hpp>
45 : #include <com/sun/star/sdbc/DataType.hpp>
46 : #include <com/sun/star/sdbc/XPreparedStatement.hpp>
47 : #include <com/sun/star/sdbcx/XColumnsSupplier.hpp>
48 : #include <com/sun/star/sdbcx/XDeleteRows.hpp>
49 : #include <com/sun/star/sdbcx/XTablesSupplier.hpp>
50 : #include <com/sun/star/uno/XNamingService.hpp>
51 : #include <com/sun/star/util/XNumberFormats.hpp>
52 : #include <com/sun/star/util/XNumberFormatsSupplier.hpp>
53 : #include <com/sun/star/util/URLTransformer.hpp>
54 : #include <com/sun/star/util/XURLTransformer.hpp>
55 : #include <com/sun/star/view/XSelectionSupplier.hpp>
56 : #include <comphelper/extract.hxx>
57 : #include <comphelper/numbers.hxx>
58 : #include <comphelper/processfactory.hxx>
59 : #include <comphelper/property.hxx>
60 : #include <comphelper/string.hxx>
61 : #include <connectivity/dbtools.hxx>
62 : #include <sfx2/dispatch.hxx>
63 : #include <sfx2/viewfrm.hxx>
64 : #include <svl/eitem.hxx>
65 : #include <svtools/fmtfield.hxx>
66 : #include <svl/numuno.hxx>
67 : #include <tools/multisel.hxx>
68 : #include <tools/shl.hxx>
69 : #include <tools/diagnose_ex.h>
70 : #include <vcl/help.hxx>
71 : #include <vcl/image.hxx>
72 : #include <vcl/longcurr.hxx>
73 : #include <vcl/menu.hxx>
74 :
75 : #include <math.h>
76 :
77 : using namespace ::com::sun::star::uno;
78 : using namespace ::com::sun::star::view;
79 : using namespace ::com::sun::star::beans;
80 : using namespace ::com::sun::star::lang;
81 : using namespace ::com::sun::star::sdbcx;
82 : using namespace ::com::sun::star::sdbc;
83 : using namespace ::com::sun::star::sdb;
84 : using namespace ::com::sun::star::form;
85 : using namespace ::com::sun::star::util;
86 : using namespace ::com::sun::star::container;
87 : using namespace ::cppu;
88 : using namespace ::svxform;
89 : using namespace ::svx;
90 :
91 : //==============================================================================
92 : //------------------------------------------------------------------------------
93 0 : ::rtl::OUString FieldServiceFromId(sal_Int32 nID)
94 : {
95 0 : switch (nID)
96 : {
97 0 : case SID_FM_EDIT : return FM_COL_TEXTFIELD;
98 0 : case SID_FM_COMBOBOX : return FM_COL_COMBOBOX;
99 0 : case SID_FM_LISTBOX : return FM_COL_LISTBOX;
100 0 : case SID_FM_CHECKBOX : return FM_COL_CHECKBOX;
101 0 : case SID_FM_DATEFIELD : return FM_COL_DATEFIELD;
102 0 : case SID_FM_TIMEFIELD : return FM_COL_TIMEFIELD;
103 0 : case SID_FM_NUMERICFIELD : return FM_COL_NUMERICFIELD;
104 0 : case SID_FM_CURRENCYFIELD : return FM_COL_CURRENCYFIELD;
105 0 : case SID_FM_PATTERNFIELD : return FM_COL_PATTERNFIELD;
106 0 : case SID_FM_FORMATTEDFIELD : return FM_COL_FORMATTEDFIELD;
107 : }
108 0 : return ::rtl::OUString();
109 : }
110 :
111 : //==============================================================================
112 0 : struct FmGridHeaderData
113 : {
114 : ODataAccessDescriptor aDropData;
115 : Point aDropPosPixel;
116 : sal_Int8 nDropAction;
117 : Reference< XInterface > xDroppedStatement;
118 : Reference< XInterface > xDroppedResultSet;
119 : };
120 :
121 : //==============================================================================
122 : //------------------------------------------------------------------------------
123 : const sal_Int16 nChangeTypeOffset = 1000;
124 0 : void SetMenuItem(const ImageList& rList, sal_uInt16 nID, Menu* pMenu, Menu& rNewMenu, sal_Bool bDesignMode = sal_True, sal_Int16 nOffset = nChangeTypeOffset)
125 : {
126 0 : pMenu->SetItemImage(nID, rList.GetImage(nID));
127 0 : pMenu->EnableItem(nID, bDesignMode);
128 0 : rNewMenu.InsertItem(nID + nOffset, pMenu->GetItemText(nID));
129 0 : rNewMenu.SetItemImage(nID + nOffset, rList.GetImage(nID));
130 0 : rNewMenu.SetHelpId(nID + nOffset, pMenu->GetHelpId(nID));
131 0 : rNewMenu.EnableItem(nID + nOffset, bDesignMode);
132 0 : }
133 :
134 : //------------------------------------------------------------------------------
135 0 : FmGridHeader::FmGridHeader( BrowseBox* pParent, WinBits nWinBits)
136 : :EditBrowserHeader(pParent, nWinBits)
137 : ,DropTargetHelper(this)
138 0 : ,m_pImpl(new FmGridHeaderData)
139 : {
140 0 : }
141 :
142 : //------------------------------------------------------------------------------
143 0 : FmGridHeader::~FmGridHeader()
144 : {
145 0 : delete m_pImpl;
146 0 : }
147 :
148 : //------------------------------------------------------------------------------
149 0 : sal_uInt16 FmGridHeader::GetModelColumnPos(sal_uInt16 nId) const
150 : {
151 0 : return static_cast<FmGridControl*>(GetParent())->GetModelColumnPos(nId);
152 : }
153 : //---------------------------------------------------------------------------------------
154 0 : void FmGridHeader::notifyColumnSelect(sal_uInt16 nColumnId)
155 : {
156 0 : sal_uInt16 nPos = GetModelColumnPos(nColumnId);
157 0 : Reference< XIndexAccess > xColumns(((FmGridControl*)GetParent())->GetPeer()->getColumns(), UNO_QUERY);
158 0 : if ( nPos < xColumns->getCount() )
159 : {
160 0 : Reference< XSelectionSupplier > xSelSupplier(xColumns, UNO_QUERY);
161 0 : if ( xSelSupplier.is() )
162 : {
163 0 : Reference< XPropertySet > xColumn;
164 0 : xColumns->getByIndex(nPos) >>= xColumn;
165 0 : xSelSupplier->select(makeAny(xColumn));
166 0 : }
167 0 : }
168 0 : }
169 : //------------------------------------------------------------------------------
170 0 : void FmGridHeader::Select()
171 : {
172 0 : EditBrowserHeader::Select();
173 0 : notifyColumnSelect(GetCurItemId());
174 0 : }
175 :
176 : //------------------------------------------------------------------------------
177 0 : void FmGridHeader::RequestHelp( const HelpEvent& rHEvt )
178 : {
179 0 : sal_uInt16 nItemId = GetItemId( ScreenToOutputPixel( rHEvt.GetMousePosPixel() ) );
180 0 : if ( nItemId )
181 : {
182 0 : if ( rHEvt.GetMode() & (HELPMODE_QUICK | HELPMODE_BALLOON) )
183 : {
184 0 : Rectangle aItemRect = GetItemRect( nItemId );
185 0 : Point aPt = OutputToScreenPixel( aItemRect.TopLeft() );
186 0 : aItemRect.Left() = aPt.X();
187 0 : aItemRect.Top() = aPt.Y();
188 0 : aPt = OutputToScreenPixel( aItemRect.BottomRight() );
189 0 : aItemRect.Right() = aPt.X();
190 0 : aItemRect.Bottom() = aPt.Y();
191 :
192 0 : sal_uInt16 nPos = GetModelColumnPos(nItemId);
193 0 : Reference< ::com::sun::star::container::XIndexContainer > xColumns(static_cast<FmGridControl*>(GetParent())->GetPeer()->getColumns());
194 : try
195 : {
196 0 : Reference< ::com::sun::star::beans::XPropertySet > xColumn(xColumns->getByIndex(nPos),UNO_QUERY);
197 0 : ::rtl::OUString aHelpText;
198 0 : xColumn->getPropertyValue(FM_PROP_HELPTEXT) >>= aHelpText;
199 0 : if ( aHelpText.isEmpty() )
200 0 : xColumn->getPropertyValue(FM_PROP_DESCRIPTION) >>= aHelpText;
201 0 : if ( !aHelpText.isEmpty() )
202 : {
203 0 : if ( rHEvt.GetMode() & HELPMODE_BALLOON )
204 0 : Help::ShowBalloon( this, aItemRect.Center(), aItemRect, aHelpText );
205 : else
206 0 : Help::ShowQuickHelp( this, aItemRect, aHelpText );
207 : return;
208 0 : }
209 : }
210 0 : catch(Exception&)
211 : {
212 : return;
213 0 : }
214 : }
215 : }
216 0 : EditBrowserHeader::RequestHelp( rHEvt );
217 : }
218 :
219 : //------------------------------------------------------------------------------
220 0 : sal_Int8 FmGridHeader::AcceptDrop( const AcceptDropEvent& rEvt )
221 : {
222 : // drop allowed in design mode only
223 0 : if (!static_cast<FmGridControl*>(GetParent())->IsDesignMode())
224 0 : return DND_ACTION_NONE;
225 :
226 : // search for recognized formats
227 0 : const DataFlavorExVector& rFlavors = GetDataFlavorExVector();
228 0 : if (OColumnTransferable::canExtractColumnDescriptor(rFlavors, CTF_COLUMN_DESCRIPTOR | CTF_FIELD_DESCRIPTOR))
229 0 : return rEvt.mnAction;
230 :
231 0 : return DND_ACTION_NONE;
232 : }
233 :
234 : //------------------------------------------------------------------------------
235 0 : sal_Int8 FmGridHeader::ExecuteDrop( const ExecuteDropEvent& _rEvt )
236 : {
237 0 : if (!static_cast<FmGridControl*>(GetParent())->IsDesignMode())
238 0 : return DND_ACTION_NONE;
239 :
240 0 : TransferableDataHelper aDroppedData(_rEvt.maDropEvent.Transferable);
241 :
242 : // check the formats
243 0 : sal_Bool bColumnDescriptor = OColumnTransferable::canExtractColumnDescriptor(aDroppedData.GetDataFlavorExVector(), CTF_COLUMN_DESCRIPTOR);
244 0 : sal_Bool bFieldDescriptor = OColumnTransferable::canExtractColumnDescriptor(aDroppedData.GetDataFlavorExVector(), CTF_FIELD_DESCRIPTOR);
245 0 : if (!bColumnDescriptor && !bFieldDescriptor)
246 : {
247 : OSL_FAIL("FmGridHeader::ExecuteDrop: should never have reached this (no extractable format)!");
248 0 : return DND_ACTION_NONE;
249 : }
250 :
251 : // extract the descriptor
252 0 : ::rtl::OUString sDatasouce, sCommand, sFieldName,sDatabaseLocation,sConnnectionResource;
253 0 : sal_Int32 nCommandType = CommandType::COMMAND;
254 0 : Reference< XPreparedStatement > xStatement;
255 0 : Reference< XResultSet > xResultSet;
256 0 : Reference< XPropertySet > xField;
257 0 : Reference< XConnection > xConnection;
258 :
259 0 : ODataAccessDescriptor aColumn = OColumnTransferable::extractColumnDescriptor(aDroppedData);
260 0 : if (aColumn.has(daDataSource)) aColumn[daDataSource] >>= sDatasouce;
261 0 : if (aColumn.has(daDatabaseLocation)) aColumn[daDatabaseLocation] >>= sDatabaseLocation;
262 0 : if (aColumn.has(daConnectionResource)) aColumn[daConnectionResource] >>= sConnnectionResource;
263 0 : if (aColumn.has(daCommand)) aColumn[daCommand] >>= sCommand;
264 0 : if (aColumn.has(daCommandType)) aColumn[daCommandType] >>= nCommandType;
265 0 : if (aColumn.has(daColumnName)) aColumn[daColumnName] >>= sFieldName;
266 0 : if (aColumn.has(daColumnObject))aColumn[daColumnObject] >>= xField;
267 0 : if (aColumn.has(daConnection)) aColumn[daConnection] >>= xConnection;
268 :
269 0 : if ( sFieldName.isEmpty()
270 0 : || sCommand.isEmpty()
271 0 : || ( sDatasouce.isEmpty()
272 0 : && sDatabaseLocation.isEmpty()
273 0 : && !xConnection.is()
274 : )
275 : )
276 : {
277 : OSL_FAIL( "FmGridHeader::ExecuteDrop: somebody started a nonsense drag operation!!" );
278 0 : return DND_ACTION_NONE;
279 : }
280 :
281 : try
282 : {
283 : // need a connection
284 0 : if (!xConnection.is())
285 : { // the transferable did not contain the connection -> build an own one
286 : try
287 : {
288 0 : ::rtl::OUString sSignificantSource( sDatasouce.isEmpty() ? sDatabaseLocation : sDatasouce );
289 : xConnection = OStaticDataAccessTools().getConnection_withFeedback(sSignificantSource, ::rtl::OUString(),::rtl::OUString(),
290 0 : comphelper::getComponentContext( static_cast<FmGridControl*>(GetParent())->getServiceManager() ));
291 : }
292 0 : catch(NoSuchElementException&)
293 : { // allowed, means sDatasouce isn't a valid data source name ....
294 : }
295 0 : catch(Exception&)
296 : {
297 : OSL_FAIL("FmGridHeader::ExecuteDrop: could not retrieve the database access object !");
298 : }
299 :
300 0 : if (!xConnection.is())
301 : {
302 : OSL_FAIL("FmGridHeader::ExecuteDrop: could not retrieve the database access object !");
303 0 : return DND_ACTION_NONE;
304 : }
305 : }
306 :
307 : // try to obtain the column object
308 0 : if (!xField.is())
309 : {
310 : #ifdef DBG_UTIL
311 : Reference< XServiceInfo > xServiceInfo(xConnection, UNO_QUERY);
312 : DBG_ASSERT(xServiceInfo.is() && xServiceInfo->supportsService(SRV_SDB_CONNECTION), "FmGridHeader::ExecuteDrop: invalid connection (no database access connection !)");
313 : #endif
314 :
315 0 : Reference< XNameAccess > xFields;
316 0 : switch (nCommandType)
317 : {
318 : case CommandType::TABLE:
319 : {
320 0 : Reference< XTablesSupplier > xSupplyTables(xConnection, UNO_QUERY);
321 0 : Reference< XColumnsSupplier > xSupplyColumns;
322 0 : xSupplyTables->getTables()->getByName(sCommand) >>= xSupplyColumns;
323 0 : xFields = xSupplyColumns->getColumns();
324 : }
325 0 : break;
326 : case CommandType::QUERY:
327 : {
328 0 : Reference< XQueriesSupplier > xSupplyQueries(xConnection, UNO_QUERY);
329 0 : Reference< XColumnsSupplier > xSupplyColumns;
330 0 : xSupplyQueries->getQueries()->getByName(sCommand) >>= xSupplyColumns;
331 0 : xFields = xSupplyColumns->getColumns();
332 : }
333 0 : break;
334 : default:
335 : {
336 0 : xStatement = xConnection->prepareStatement(sCommand);
337 : // not interested in any results
338 :
339 0 : Reference< XPropertySet > xStatProps(xStatement,UNO_QUERY);
340 0 : xStatProps->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("MaxRows")), makeAny(sal_Int32(0)));
341 :
342 0 : xResultSet = xStatement->executeQuery();
343 0 : Reference< XColumnsSupplier > xSupplyCols(xResultSet, UNO_QUERY);
344 0 : if (xSupplyCols.is())
345 0 : xFields = xSupplyCols->getColumns();
346 : }
347 : }
348 :
349 0 : if (xFields.is() && xFields->hasByName(sFieldName))
350 0 : xFields->getByName(sFieldName) >>= xField;
351 :
352 0 : if (!xField.is())
353 : {
354 0 : ::comphelper::disposeComponent(xStatement);
355 0 : return DND_ACTION_NONE;
356 0 : }
357 : }
358 :
359 : // do the drop asynchronously
360 : // (85957 - UI actions within the drop are not allowed, but we want to open a popup menu)
361 0 : m_pImpl->aDropData = aColumn;
362 0 : m_pImpl->aDropData[daConnection] <<= xConnection;
363 0 : m_pImpl->aDropData[daColumnObject] <<= xField;
364 :
365 0 : m_pImpl->nDropAction = _rEvt.mnAction;
366 0 : m_pImpl->aDropPosPixel = _rEvt.maPosPixel;
367 0 : m_pImpl->xDroppedStatement = xStatement;
368 0 : m_pImpl->xDroppedResultSet = xResultSet;
369 :
370 0 : PostUserEvent(LINK(this, FmGridHeader, OnAsyncExecuteDrop));
371 : }
372 0 : catch (Exception&)
373 : {
374 : OSL_FAIL("FmGridHeader::ExecuteDrop: caught an exception while creatin' the column !");
375 0 : ::comphelper::disposeComponent(xStatement);
376 0 : return sal_False;
377 : }
378 :
379 0 : return DND_ACTION_LINK;
380 : }
381 :
382 : //------------------------------------------------------------------------------
383 0 : IMPL_LINK( FmGridHeader, OnAsyncExecuteDrop, void*, /*NOTINTERESTEDIN*/ )
384 : {
385 0 : ::rtl::OUString sCommand, sFieldName,sURL;
386 0 : sal_Int32 nCommandType = CommandType::COMMAND;
387 0 : Reference< XPropertySet > xField;
388 0 : Reference< XConnection > xConnection;
389 :
390 0 : ::rtl::OUString sDatasouce = m_pImpl->aDropData.getDataSource();
391 0 : if ( sDatasouce.isEmpty() && m_pImpl->aDropData.has(daConnectionResource) )
392 0 : m_pImpl->aDropData[daConnectionResource] >>= sURL;
393 0 : m_pImpl->aDropData[daCommand] >>= sCommand;
394 0 : m_pImpl->aDropData[daCommandType] >>= nCommandType;
395 0 : m_pImpl->aDropData[daColumnName] >>= sFieldName;
396 0 : m_pImpl->aDropData[daConnection] >>= xConnection;
397 0 : m_pImpl->aDropData[daColumnObject] >>= xField;
398 :
399 : try
400 : {
401 : // need number formats
402 0 : Reference< XNumberFormatsSupplier > xSupplier = OStaticDataAccessTools().getNumberFormats(xConnection, sal_True);
403 0 : Reference< XNumberFormats > xNumberFormats;
404 0 : if (xSupplier.is())
405 0 : xNumberFormats = xSupplier->getNumberFormats();
406 0 : if (!xNumberFormats.is())
407 : {
408 0 : ::comphelper::disposeComponent(m_pImpl->xDroppedResultSet);
409 0 : ::comphelper::disposeComponent(m_pImpl->xDroppedStatement);
410 0 : return 0L;
411 : }
412 :
413 : // Vom Feld werden nun zwei Informationen benoetigt:
414 : // a.) Name des Feldes fuer Label und ControlSource
415 : // b.) FormatKey, um festzustellen, welches Feld erzeugt werden soll
416 0 : sal_Int32 nDataType = 0;
417 0 : xField->getPropertyValue(FM_PROP_FIELDTYPE) >>= nDataType;
418 : // diese Datentypen koennen im Gridcontrol nicht verarbeitet werden
419 0 : switch (nDataType)
420 : {
421 : case DataType::BLOB:
422 : case DataType::LONGVARBINARY:
423 : case DataType::BINARY:
424 : case DataType::VARBINARY:
425 : case DataType::OTHER:
426 0 : ::comphelper::disposeComponent(m_pImpl->xDroppedResultSet);
427 0 : ::comphelper::disposeComponent(m_pImpl->xDroppedStatement);
428 0 : return 0L;
429 : }
430 :
431 : // Erstellen der Column
432 0 : Reference< XIndexContainer > xCols(static_cast<FmGridControl*>(GetParent())->GetPeer()->getColumns());
433 0 : Reference< XGridColumnFactory > xFactory(xCols, UNO_QUERY);
434 :
435 0 : sal_uInt16 nColId = GetItemId(m_pImpl->aDropPosPixel);
436 : // EinfuegePosition, immer vor der aktuellen Spalte
437 0 : sal_uInt16 nPos = GetModelColumnPos(nColId);
438 0 : Reference< XPropertySet > xCol, xSecondCol;
439 :
440 : // Create Column based on type, default textfield
441 0 : std::vector<sal_uInt16> aPossibleTypes;
442 0 : switch (nDataType)
443 : {
444 : case DataType::BIT:
445 : case DataType::BOOLEAN:
446 0 : aPossibleTypes.push_back(SID_FM_CHECKBOX);
447 0 : break;
448 : case DataType::TINYINT:
449 : case DataType::SMALLINT:
450 : case DataType::INTEGER:
451 0 : aPossibleTypes.push_back(SID_FM_NUMERICFIELD);
452 0 : aPossibleTypes.push_back(SID_FM_FORMATTEDFIELD);
453 0 : break;
454 : case DataType::REAL:
455 : case DataType::DOUBLE:
456 : case DataType::NUMERIC:
457 : case DataType::DECIMAL:
458 0 : aPossibleTypes.push_back(SID_FM_FORMATTEDFIELD);
459 0 : aPossibleTypes.push_back(SID_FM_NUMERICFIELD);
460 0 : break;
461 : case DataType::TIMESTAMP:
462 0 : aPossibleTypes.push_back(SID_FM_TWOFIELDS_DATE_N_TIME);
463 0 : aPossibleTypes.push_back(SID_FM_DATEFIELD);
464 0 : aPossibleTypes.push_back(SID_FM_TIMEFIELD);
465 0 : aPossibleTypes.push_back(SID_FM_FORMATTEDFIELD);
466 0 : break;
467 : case DataType::DATE:
468 0 : aPossibleTypes.push_back(SID_FM_DATEFIELD);
469 0 : aPossibleTypes.push_back(SID_FM_FORMATTEDFIELD);
470 0 : break;
471 : case DataType::TIME:
472 0 : aPossibleTypes.push_back(SID_FM_TIMEFIELD);
473 0 : aPossibleTypes.push_back(SID_FM_FORMATTEDFIELD);
474 0 : break;
475 : case DataType::CHAR:
476 : case DataType::VARCHAR:
477 : case DataType::LONGVARCHAR:
478 : default:
479 0 : aPossibleTypes.push_back(SID_FM_EDIT);
480 0 : aPossibleTypes.push_back(SID_FM_FORMATTEDFIELD);
481 0 : break;
482 : }
483 : // if it's a currency field, a a "currency field" option
484 : try
485 : {
486 0 : if ( ::comphelper::hasProperty(FM_PROP_ISCURRENCY, xField)
487 0 : && ::comphelper::getBOOL(xField->getPropertyValue(FM_PROP_ISCURRENCY)))
488 0 : aPossibleTypes.insert(aPossibleTypes.begin(), SID_FM_CURRENCYFIELD);
489 : }
490 0 : catch(Exception&)
491 : {
492 : OSL_FAIL("FmGridHeader::ExecuteDrop: Exception occurred!");
493 : }
494 :
495 0 : sal_Bool bDateNTimeCol = sal_False;
496 0 : if (!aPossibleTypes.empty())
497 : {
498 0 : sal_Int32 nPreferedType = aPossibleTypes[0];
499 0 : if ((m_pImpl->nDropAction == DND_ACTION_LINK) && (aPossibleTypes.size() > 1))
500 : {
501 0 : ImageList aImageList( SVX_RES(RID_SVXIMGLIST_FMEXPL) );
502 :
503 0 : PopupMenu aInsertMenu(SVX_RES(RID_SVXMNU_COLS));
504 0 : PopupMenu aTypeMenu;
505 0 : PopupMenu* pMenu = aInsertMenu.GetPopupMenu(SID_FM_INSERTCOL);
506 0 : for (std::vector<sal_uInt16>::const_iterator iter = aPossibleTypes.begin(); iter != aPossibleTypes.end(); ++iter)
507 0 : SetMenuItem(aImageList, *iter, pMenu, aTypeMenu, sal_True, 0);
508 0 : nPreferedType = aTypeMenu.Execute(this, m_pImpl->aDropPosPixel);
509 : }
510 :
511 0 : bDateNTimeCol = nPreferedType == SID_FM_TWOFIELDS_DATE_N_TIME;
512 0 : sal_uInt16 nColCount = bDateNTimeCol ? 2 : 1;
513 0 : ::rtl::OUString sFieldService;
514 0 : while (nColCount--)
515 : {
516 0 : if (bDateNTimeCol)
517 0 : nPreferedType = nColCount ? SID_FM_DATEFIELD : SID_FM_TIMEFIELD;
518 :
519 0 : sFieldService = FieldServiceFromId(nPreferedType);
520 0 : Reference< XPropertySet > xThisRoundCol;
521 0 : if ( !sFieldService.isEmpty() )
522 0 : xThisRoundCol = xFactory->createColumn(sFieldService);
523 0 : if (nColCount)
524 0 : xSecondCol = xThisRoundCol;
525 : else
526 0 : xCol = xThisRoundCol;
527 0 : }
528 : }
529 :
530 0 : if (!xCol.is() || (bDateNTimeCol && !xSecondCol.is()))
531 : {
532 0 : ::comphelper::disposeComponent(xCol); // in case only the creation of the second column failed
533 0 : ::comphelper::disposeComponent(m_pImpl->xDroppedResultSet);
534 0 : ::comphelper::disposeComponent(m_pImpl->xDroppedStatement);
535 0 : return 0L;
536 : }
537 :
538 0 : if (bDateNTimeCol)
539 : {
540 0 : String sTimePostfix( SVX_RES( RID_STR_POSTFIX_TIME ) );
541 0 : xCol->setPropertyValue(FM_PROP_LABEL, makeAny( ::rtl::OUString( sFieldName + sTimePostfix ) ) );
542 :
543 0 : String sDatePostfix( SVX_RES( RID_STR_POSTFIX_DATE ) );
544 0 : xSecondCol->setPropertyValue(FM_PROP_LABEL, makeAny( ::rtl::OUString( sFieldName + sDatePostfix ) ) );
545 : }
546 : else
547 0 : xCol->setPropertyValue(FM_PROP_LABEL, makeAny(sFieldName));
548 :
549 0 : FormControlFactory aControlFactory( ::comphelper::getProcessServiceFactory() );
550 0 : aControlFactory.initializeControlModel( DocumentClassification::classifyHostDocument( xCols ), xCol );
551 0 : aControlFactory.initializeFieldDependentProperties( xField, xCol, xNumberFormats );
552 :
553 0 : xCol->setPropertyValue(FM_PROP_CONTROLSOURCE, makeAny(sFieldName));
554 0 : if ( xSecondCol.is() )
555 0 : xSecondCol->setPropertyValue(FM_PROP_CONTROLSOURCE, makeAny(sFieldName));
556 :
557 0 : if (bDateNTimeCol)
558 : {
559 0 : String sRealName,sPurePostfix;
560 :
561 : String aPostfix[] = {
562 0 : String( SVX_RES( RID_STR_POSTFIX_DATE ) ),
563 0 : String( SVX_RES( RID_STR_POSTFIX_TIME ) )
564 0 : };
565 :
566 0 : for ( size_t i=0; i<2; ++i )
567 : {
568 0 : sPurePostfix = comphelper::string::stripStart(aPostfix[i], ' ');
569 0 : sPurePostfix = comphelper::string::stripStart(sPurePostfix, '(');
570 0 : sPurePostfix = comphelper::string::stripEnd(sPurePostfix, ')');
571 0 : sRealName = sFieldName;
572 0 : sRealName += '_';
573 0 : sRealName += sPurePostfix;
574 0 : if (i)
575 0 : xSecondCol->setPropertyValue(FM_PROP_NAME, makeAny(::rtl::OUString(sRealName)));
576 : else
577 0 : xCol->setPropertyValue(FM_PROP_NAME, makeAny(::rtl::OUString(sRealName)));
578 0 : }
579 : }
580 : else
581 0 : xCol->setPropertyValue(FM_PROP_NAME, makeAny(sFieldName));
582 :
583 : // jetzt einfuegen
584 0 : Any aElement;
585 0 : aElement <<= xCol;
586 0 : xCols->insertByIndex(nPos, aElement);
587 :
588 0 : if (bDateNTimeCol)
589 : {
590 0 : aElement <<= xSecondCol;
591 0 : xCols->insertByIndex(nPos == (sal_uInt16)-1 ? nPos : ++nPos, aElement);
592 : }
593 :
594 : // ist die component::Form an die Datenbankangebunden?
595 0 : Reference< XFormComponent > xFormCp(xCols, UNO_QUERY);
596 0 : Reference< XPropertySet > xForm(xFormCp->getParent(), UNO_QUERY);
597 0 : if (xForm.is())
598 : {
599 0 : if (::comphelper::getString(xForm->getPropertyValue(FM_PROP_DATASOURCE)).isEmpty())
600 : {
601 0 : if ( !sDatasouce.isEmpty() )
602 0 : xForm->setPropertyValue(FM_PROP_DATASOURCE, makeAny(sDatasouce));
603 : else
604 0 : xForm->setPropertyValue(FM_PROP_URL, makeAny(sURL));
605 : }
606 :
607 0 : if (::comphelper::getString(xForm->getPropertyValue(FM_PROP_COMMAND)).isEmpty())
608 : {
609 0 : xForm->setPropertyValue(FM_PROP_COMMAND, makeAny(sCommand));
610 0 : Any aCommandType;
611 0 : switch (nCommandType)
612 : {
613 : case CommandType::TABLE:
614 0 : aCommandType <<= (sal_Int32)CommandType::TABLE;
615 0 : break;
616 : case CommandType::QUERY:
617 0 : aCommandType <<= (sal_Int32)CommandType::QUERY;
618 0 : break;
619 : default:
620 0 : aCommandType <<= (sal_Int32)CommandType::COMMAND;
621 0 : xForm->setPropertyValue(FM_PROP_ESCAPE_PROCESSING, bool2any((sal_Bool)(2 == nCommandType)));
622 0 : break;
623 : }
624 0 : xForm->setPropertyValue(FM_PROP_COMMANDTYPE, aCommandType);
625 : }
626 0 : }
627 : }
628 0 : catch (Exception&)
629 : {
630 : OSL_FAIL("FmGridHeader::OnAsyncExecuteDrop: caught an exception while creatin' the column !");
631 0 : ::comphelper::disposeComponent(m_pImpl->xDroppedResultSet);
632 0 : ::comphelper::disposeComponent(m_pImpl->xDroppedStatement);
633 0 : return 0L;
634 : }
635 :
636 0 : ::comphelper::disposeComponent(m_pImpl->xDroppedResultSet);
637 0 : ::comphelper::disposeComponent(m_pImpl->xDroppedStatement);
638 0 : return 1L;
639 : }
640 :
641 : //------------------------------------------------------------------------------
642 0 : void FmGridHeader::PreExecuteColumnContextMenu(sal_uInt16 nColId, PopupMenu& rMenu)
643 : {
644 0 : sal_Bool bDesignMode = static_cast<FmGridControl*>(GetParent())->IsDesignMode();
645 :
646 0 : Reference< ::com::sun::star::container::XIndexContainer > xCols(static_cast<FmGridControl*>(GetParent())->GetPeer()->getColumns());
647 : // Aufbau des Insert Menues
648 : // mark the column if nColId != HEADERBAR_ITEM_NOTFOUND
649 0 : if(nColId > 0)
650 : {
651 0 : sal_uInt16 nPos2 = GetModelColumnPos(nColId);
652 :
653 0 : Reference< ::com::sun::star::container::XIndexContainer > xColumns(static_cast<FmGridControl*>(GetParent())->GetPeer()->getColumns());
654 0 : Reference< ::com::sun::star::beans::XPropertySet> xColumn;
655 0 : ::cppu::extractInterface(xColumn, xColumns->getByIndex(nPos2));
656 0 : Reference< ::com::sun::star::view::XSelectionSupplier > xSelSupplier(xColumns, UNO_QUERY);
657 0 : if (xSelSupplier.is())
658 0 : xSelSupplier->select(makeAny(xColumn));
659 : }
660 :
661 : // EinfuegePosition, immer vor der aktuellen Spalte
662 0 : sal_uInt16 nPos = GetModelColumnPos(nColId);
663 0 : sal_Bool bMarked = nColId && static_cast<FmGridControl*>(GetParent())->isColumnMarked(nColId);
664 :
665 0 : ImageList aImageList( SVX_RES(RID_SVXIMGLIST_FMEXPL) );
666 0 : PopupMenu* pControlMenu = new PopupMenu;
667 :
668 0 : PopupMenu* pMenu = rMenu.GetPopupMenu(SID_FM_INSERTCOL);
669 0 : if (pMenu)
670 : {
671 0 : SetMenuItem(aImageList, SID_FM_EDIT, pMenu, *pControlMenu, bDesignMode);
672 0 : SetMenuItem(aImageList, SID_FM_CHECKBOX, pMenu, *pControlMenu, bDesignMode);
673 0 : SetMenuItem(aImageList, SID_FM_COMBOBOX, pMenu, *pControlMenu, bDesignMode);
674 0 : SetMenuItem(aImageList, SID_FM_LISTBOX, pMenu, *pControlMenu, bDesignMode);
675 0 : SetMenuItem(aImageList, SID_FM_DATEFIELD, pMenu, *pControlMenu, bDesignMode);
676 0 : SetMenuItem(aImageList, SID_FM_TIMEFIELD, pMenu, *pControlMenu, bDesignMode);
677 0 : SetMenuItem(aImageList, SID_FM_NUMERICFIELD, pMenu, *pControlMenu, bDesignMode);
678 0 : SetMenuItem(aImageList, SID_FM_CURRENCYFIELD, pMenu, *pControlMenu, bDesignMode);
679 0 : SetMenuItem(aImageList, SID_FM_PATTERNFIELD, pMenu, *pControlMenu, bDesignMode);
680 0 : SetMenuItem(aImageList, SID_FM_FORMATTEDFIELD, pMenu, *pControlMenu, bDesignMode);
681 : }
682 :
683 0 : if (pMenu && xCols.is() && nColId)
684 : {
685 0 : Reference< ::com::sun::star::beans::XPropertySet > xSet;
686 0 : ::cppu::extractInterface(xSet, xCols->getByIndex(nPos));
687 : sal_Int16 nClassId;
688 0 : xSet->getPropertyValue(FM_PROP_CLASSID) >>= nClassId;
689 :
690 0 : Reference< ::com::sun::star::io::XPersistObject > xServiceQuestion(xSet, UNO_QUERY);
691 0 : sal_Int32 nColType = xServiceQuestion.is() ? getColumnTypeByModelName(xServiceQuestion->getServiceName()) : 0;
692 0 : if (nColType == TYPE_TEXTFIELD)
693 : { // edit fields and formatted fields have the same service name, thus getColumnTypeByModelName returns TYPE_TEXTFIELD
694 : // in both cases. And as columns don't have an ::com::sun::star::lang::XServiceInfo interface, we have to distinguish both
695 : // types via the existence of special properties
696 0 : Reference< ::com::sun::star::beans::XPropertySet > xProps(xSet, UNO_QUERY);
697 0 : if (xProps.is())
698 : {
699 0 : Reference< ::com::sun::star::beans::XPropertySetInfo > xPropsInfo = xProps->getPropertySetInfo();
700 0 : if (xPropsInfo.is() && xPropsInfo->hasPropertyByName(FM_PROP_FORMATSSUPPLIER))
701 0 : nColType = TYPE_FORMATTEDFIELD;
702 0 : }
703 : }
704 :
705 0 : pControlMenu->EnableItem(SID_FM_EDIT + nChangeTypeOffset, bDesignMode && (nColType != TYPE_TEXTFIELD));
706 0 : pControlMenu->EnableItem(SID_FM_COMBOBOX + nChangeTypeOffset, bDesignMode && (nColType != TYPE_COMBOBOX));
707 0 : pControlMenu->EnableItem(SID_FM_LISTBOX + nChangeTypeOffset, bDesignMode && (nColType != TYPE_LISTBOX));
708 0 : pControlMenu->EnableItem(SID_FM_CHECKBOX + nChangeTypeOffset, bDesignMode && (nColType != TYPE_CHECKBOX));
709 0 : pControlMenu->EnableItem(SID_FM_DATEFIELD + nChangeTypeOffset, bDesignMode && (nColType != TYPE_DATEFIELD));
710 0 : pControlMenu->EnableItem(SID_FM_NUMERICFIELD + nChangeTypeOffset, bDesignMode && (nColType != TYPE_NUMERICFIELD));
711 0 : pControlMenu->EnableItem(SID_FM_TIMEFIELD + nChangeTypeOffset, bDesignMode && (nColType != TYPE_TIMEFIELD));
712 0 : pControlMenu->EnableItem(SID_FM_CURRENCYFIELD + nChangeTypeOffset, bDesignMode && (nColType != TYPE_CURRENCYFIELD));
713 0 : pControlMenu->EnableItem(SID_FM_PATTERNFIELD + nChangeTypeOffset, bDesignMode && (nColType != TYPE_PATTERNFIELD));
714 0 : pControlMenu->EnableItem(SID_FM_FORMATTEDFIELD + nChangeTypeOffset, bDesignMode && (nColType != TYPE_FORMATTEDFIELD));
715 0 : rMenu.SetPopupMenu(SID_FM_CHANGECOL, pControlMenu);
716 : }
717 :
718 0 : rMenu.EnableItem(SID_FM_INSERTCOL, bDesignMode && xCols.is());
719 0 : rMenu.EnableItem(SID_FM_DELETECOL, bDesignMode && bMarked && xCols.is());
720 0 : rMenu.EnableItem(SID_FM_CHANGECOL, bDesignMode && bMarked && xCols.is());
721 0 : rMenu.EnableItem(SID_FM_SHOW_PROPERTY_BROWSER, bDesignMode && bMarked && xCols.is());
722 :
723 0 : PopupMenu* pShowColsMenu = rMenu.GetPopupMenu(SID_FM_SHOWCOLS);
724 0 : sal_uInt16 nHiddenCols = 0;
725 0 : if (pShowColsMenu)
726 : {
727 0 : if (xCols.is())
728 : {
729 : // check for hidden cols
730 0 : Reference< ::com::sun::star::beans::XPropertySet > xCurCol;
731 0 : Any aHidden,aName;
732 0 : for (sal_uInt16 i=0; i<xCols->getCount(); ++i)
733 : {
734 0 : ::cppu::extractInterface(xCurCol, xCols->getByIndex(i));
735 : DBG_ASSERT(xCurCol.is(), "FmGridHeader::PreExecuteColumnContextMenu : the Peer has invalid columns !");
736 0 : aHidden = xCurCol->getPropertyValue(FM_PROP_HIDDEN);
737 : DBG_ASSERT(aHidden.getValueType().getTypeClass() == TypeClass_BOOLEAN,
738 : "FmGridHeader::PreExecuteColumnContextMenu : the property 'hidden' should be boolean !");
739 0 : if (::comphelper::getBOOL(aHidden))
740 : {
741 : // put the column name into the 'show col' menu
742 0 : if (nHiddenCols < 16)
743 : { // (only the first 16 items to keep the menu rather small)
744 0 : aName = xCurCol->getPropertyValue(FM_PROP_LABEL);
745 0 : pShowColsMenu->InsertItem(nHiddenCols + 1, ::comphelper::getString(aName), 0, nHiddenCols);
746 : // the ID is arbitrary, but should be unique within the whole menu
747 : }
748 0 : ++nHiddenCols;
749 : }
750 0 : }
751 : }
752 0 : pShowColsMenu->EnableItem(SID_FM_SHOWCOLS_MORE, xCols.is() && (nHiddenCols > 16));
753 0 : pShowColsMenu->EnableItem(SID_FM_SHOWALLCOLS, xCols.is() && (nHiddenCols > 0));
754 : }
755 :
756 : // allow the 'hide column' item ?
757 0 : sal_Bool bAllowHide = bMarked; // a column is marked
758 0 : bAllowHide = bAllowHide || (!bDesignMode && (nPos != (sal_uInt16)-1)); // OR we are in alive mode and have hit a column
759 0 : bAllowHide = bAllowHide && xCols.is(); // AND we have a column container
760 0 : bAllowHide = bAllowHide && (xCols->getCount()-nHiddenCols > 1); // AND there are at least two visible columns
761 0 : rMenu.EnableItem(SID_FM_HIDECOL, bAllowHide);
762 :
763 0 : sal_Bool bChecked = sal_False;
764 0 : if (bMarked)
765 : {
766 :
767 0 : SfxViewFrame* pCurrentFrame = SfxViewFrame::Current();
768 0 : SfxItemState eState = SFX_ITEM_UNKNOWN;
769 : // ask the bindings of the current view frame (which should be the one we're residing in) for the state
770 0 : if (pCurrentFrame)
771 : {
772 0 : SfxPoolItem* pItem = NULL;
773 0 : eState = pCurrentFrame->GetBindings().QueryState(SID_FM_CTL_PROPERTIES, pItem);
774 :
775 0 : if (eState >= SFX_ITEM_AVAILABLE && pItem )
776 : {
777 0 : bChecked = pItem->ISA(SfxBoolItem) && ((SfxBoolItem*)pItem)->GetValue();
778 0 : rMenu.CheckItem(SID_FM_SHOW_PROPERTY_BROWSER,bChecked);
779 : }
780 0 : delete pItem;
781 : }
782 0 : }
783 0 : }
784 :
785 : enum InspectorAction { eOpenInspector, eCloseInspector, eUpdateInspector, eNone };
786 :
787 : //------------------------------------------------------------------------------
788 0 : void FmGridHeader::PostExecuteColumnContextMenu(sal_uInt16 nColId, const PopupMenu& rMenu, sal_uInt16 nExecutionResult)
789 : {
790 0 : Reference< ::com::sun::star::container::XIndexContainer > xCols(static_cast<FmGridControl*>(GetParent())->GetPeer()->getColumns());
791 0 : sal_uInt16 nPos = GetModelColumnPos(nColId);
792 :
793 : // remove and delet the menu we inserted in PreExecuteColumnContextMenu
794 0 : PopupMenu* pControlMenu = rMenu.GetPopupMenu(SID_FM_CHANGECOL);
795 0 : delete pControlMenu;
796 :
797 0 : ::rtl::OUString aFieldType;
798 0 : sal_Bool bReplace = sal_False;
799 0 : InspectorAction eInspectorAction = eNone;
800 0 : Reference< XPropertySet > xColumnToInspect;
801 0 : switch (nExecutionResult)
802 : {
803 : case SID_FM_DELETECOL:
804 : {
805 0 : Reference< XInterface > xCol;
806 0 : ::cppu::extractInterface(xCol, xCols->getByIndex(nPos));
807 0 : xCols->removeByIndex(nPos);
808 0 : ::comphelper::disposeComponent(xCol);
809 0 : } break;
810 : case SID_FM_SHOW_PROPERTY_BROWSER:
811 0 : eInspectorAction = rMenu.IsItemChecked( SID_FM_SHOW_PROPERTY_BROWSER ) ? eOpenInspector : eCloseInspector;
812 0 : xColumnToInspect.set( xCols->getByIndex( nPos ), UNO_QUERY );
813 0 : break;
814 : case SID_FM_EDIT + nChangeTypeOffset:
815 0 : bReplace = sal_True;
816 : case SID_FM_EDIT:
817 0 : aFieldType = FM_COL_TEXTFIELD;
818 0 : break;
819 : case SID_FM_COMBOBOX + nChangeTypeOffset:
820 0 : bReplace = sal_True;
821 : case SID_FM_COMBOBOX:
822 0 : aFieldType = FM_COL_COMBOBOX;
823 0 : break;
824 : case SID_FM_LISTBOX + nChangeTypeOffset:
825 0 : bReplace = sal_True;
826 : case SID_FM_LISTBOX:
827 0 : aFieldType = FM_COL_LISTBOX;
828 0 : break;
829 : case SID_FM_CHECKBOX + nChangeTypeOffset:
830 0 : bReplace = sal_True;
831 : case SID_FM_CHECKBOX:
832 0 : aFieldType = FM_COL_CHECKBOX;
833 0 : break;
834 : case SID_FM_DATEFIELD + nChangeTypeOffset:
835 0 : bReplace = sal_True;
836 : case SID_FM_DATEFIELD:
837 0 : aFieldType = FM_COL_DATEFIELD;
838 0 : break;
839 : case SID_FM_TIMEFIELD + nChangeTypeOffset:
840 0 : bReplace = sal_True;
841 : case SID_FM_TIMEFIELD:
842 0 : aFieldType = FM_COL_TIMEFIELD;
843 0 : break;
844 : case SID_FM_NUMERICFIELD + nChangeTypeOffset:
845 0 : bReplace = sal_True;
846 : case SID_FM_NUMERICFIELD:
847 0 : aFieldType = FM_COL_NUMERICFIELD;
848 0 : break;
849 : case SID_FM_CURRENCYFIELD + nChangeTypeOffset:
850 0 : bReplace = sal_True;
851 : case SID_FM_CURRENCYFIELD:
852 0 : aFieldType = FM_COL_CURRENCYFIELD;
853 0 : break;
854 : case SID_FM_PATTERNFIELD + nChangeTypeOffset:
855 0 : bReplace = sal_True;
856 : case SID_FM_PATTERNFIELD:
857 0 : aFieldType = FM_COL_PATTERNFIELD;
858 0 : break;
859 : case SID_FM_FORMATTEDFIELD + nChangeTypeOffset:
860 0 : bReplace = sal_True;
861 : case SID_FM_FORMATTEDFIELD:
862 0 : aFieldType = FM_COL_FORMATTEDFIELD;
863 0 : break;
864 : case SID_FM_HIDECOL:
865 : {
866 0 : Reference< ::com::sun::star::beans::XPropertySet > xCurCol;
867 0 : ::cppu::extractInterface(xCurCol, xCols->getByIndex(nPos));
868 0 : xCurCol->setPropertyValue(FM_PROP_HIDDEN, makeAny((sal_Bool)sal_True));
869 : }
870 0 : break;
871 : case SID_FM_SHOWCOLS_MORE:
872 : {
873 0 : SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
874 0 : if(pFact)
875 : {
876 0 : AbstractFmShowColsDialog* pDlg = pFact->CreateFmShowColsDialog(NULL);
877 : DBG_ASSERT(pDlg, "Dialogdiet fail!");
878 0 : pDlg->SetColumns(xCols);
879 0 : pDlg->Execute();
880 0 : delete pDlg;
881 : }
882 :
883 : }
884 0 : break;
885 : case SID_FM_SHOWALLCOLS:
886 : {
887 : // just iterate through all the cols ...
888 0 : Reference< ::com::sun::star::beans::XPropertySet > xCurCol;
889 0 : for (sal_uInt16 i=0; i<xCols->getCount(); ++i)
890 : {
891 0 : ::cppu::extractInterface(xCurCol, xCols->getByIndex(i));
892 0 : xCurCol->setPropertyValue(FM_PROP_HIDDEN, makeAny((sal_Bool)sal_False));
893 0 : }
894 : // TODO : there must be a more clever way to do this ....
895 : // with the above the view is updated after every single model update ...
896 : }
897 0 : break;
898 : default:
899 0 : if (nExecutionResult>0 && nExecutionResult<=16)
900 : { // it was a "show column/<colname>" command (there are at most 16 such items)
901 : // search the nExecutionResult'th hidden col
902 0 : Reference< ::com::sun::star::beans::XPropertySet > xCurCol;
903 0 : for (sal_uInt16 i=0; i<xCols->getCount() && nExecutionResult; ++i)
904 : {
905 0 : ::cppu::extractInterface(xCurCol, xCols->getByIndex(i));
906 0 : Any aHidden = xCurCol->getPropertyValue(FM_PROP_HIDDEN);
907 0 : if (::comphelper::getBOOL(aHidden))
908 0 : if (!--nExecutionResult)
909 : {
910 0 : xCurCol->setPropertyValue(FM_PROP_HIDDEN, makeAny((sal_Bool)sal_False));
911 : break;
912 : }
913 0 : }
914 : }
915 0 : break;
916 : }
917 :
918 0 : if ( !aFieldType.isEmpty() )
919 : {
920 : try
921 : {
922 0 : Reference< XGridColumnFactory > xFactory( xCols, UNO_QUERY_THROW );
923 0 : Reference< XPropertySet > xNewCol( xFactory->createColumn( aFieldType ), UNO_SET_THROW );
924 :
925 0 : if ( bReplace )
926 : {
927 : // ein paar Properties hinueberretten
928 0 : Reference< XPropertySet > xReplaced( xCols->getByIndex( nPos ), UNO_QUERY );
929 :
930 : OStaticDataAccessTools().TransferFormComponentProperties(
931 0 : xReplaced, xNewCol, Application::GetSettings().GetUILanguageTag().getLocale() );
932 :
933 0 : xCols->replaceByIndex( nPos, makeAny( xNewCol ) );
934 0 : ::comphelper::disposeComponent( xReplaced );
935 :
936 0 : eInspectorAction = eUpdateInspector;
937 0 : xColumnToInspect = xNewCol;
938 : }
939 : else
940 : {
941 0 : FormControlFactory factory( ::comphelper::getProcessServiceFactory() );
942 :
943 : ::rtl::OUString sLabel = factory.getDefaultUniqueName_ByComponentType(
944 0 : Reference< XNameAccess >( xCols, UNO_QUERY_THROW ), xNewCol );
945 0 : xNewCol->setPropertyValue( FM_PROP_LABEL, makeAny( sLabel ) );
946 0 : xNewCol->setPropertyValue( FM_PROP_NAME, makeAny( sLabel ) );
947 :
948 0 : factory.initializeControlModel( DocumentClassification::classifyHostDocument( xCols ), xNewCol );
949 :
950 0 : xCols->insertByIndex( nPos, makeAny( xNewCol ) );
951 0 : }
952 : }
953 0 : catch( const Exception& )
954 : {
955 : DBG_UNHANDLED_EXCEPTION();
956 : }
957 : }
958 :
959 0 : SfxViewFrame* pCurrentFrame = SfxViewFrame::Current();
960 : OSL_ENSURE( pCurrentFrame, "FmGridHeader::PostExecuteColumnContextMenu: no view frame -> no bindings -> no property browser!" );
961 0 : if ( pCurrentFrame )
962 : {
963 0 : if ( eInspectorAction == eUpdateInspector )
964 : {
965 0 : if ( !pCurrentFrame->HasChildWindow( SID_FM_SHOW_PROPERTIES ) )
966 0 : eInspectorAction = eNone;
967 : }
968 :
969 0 : if ( eInspectorAction != eNone )
970 : {
971 0 : FmInterfaceItem aIFaceItem( SID_FM_SHOW_PROPERTY_BROWSER, xColumnToInspect );
972 0 : SfxBoolItem aShowItem( SID_FM_SHOW_PROPERTIES, eInspectorAction == eCloseInspector ? sal_False : sal_True );
973 :
974 0 : pCurrentFrame->GetBindings().GetDispatcher()->Execute( SID_FM_SHOW_PROPERTY_BROWSER, SFX_CALLMODE_ASYNCHRON,
975 0 : &aIFaceItem, &aShowItem, 0L );
976 : }
977 0 : }
978 0 : }
979 :
980 : //------------------------------------------------------------------------------
981 0 : void FmGridHeader::triggerColumnContextMenu( const ::Point& _rPreferredPos )
982 : {
983 : // the affected col
984 0 : sal_uInt16 nColId = GetItemId( _rPreferredPos );
985 :
986 : // the menu
987 0 : PopupMenu aContextMenu( SVX_RES( RID_SVXMNU_COLS ) );
988 :
989 : // let derivees modify the menu
990 0 : PreExecuteColumnContextMenu( nColId, aContextMenu );
991 0 : aContextMenu.RemoveDisabledEntries( sal_True, sal_True );
992 :
993 : // execute the menu
994 0 : sal_uInt16 nResult = aContextMenu.Execute( this, _rPreferredPos );
995 :
996 : // let derivees handle the result
997 0 : PostExecuteColumnContextMenu( nColId, aContextMenu, nResult );
998 0 : }
999 :
1000 : //------------------------------------------------------------------------------
1001 0 : void FmGridHeader::Command(const CommandEvent& rEvt)
1002 : {
1003 0 : switch (rEvt.GetCommand())
1004 : {
1005 : case COMMAND_CONTEXTMENU:
1006 : {
1007 0 : if (!rEvt.IsMouseEvent())
1008 0 : return;
1009 :
1010 0 : triggerColumnContextMenu( rEvt.GetMousePosPixel() );
1011 : }
1012 0 : break;
1013 : default:
1014 0 : EditBrowserHeader::Command(rEvt);
1015 : }
1016 : }
1017 :
1018 : //------------------------------------------------------------------------------
1019 0 : FmGridControl::FmGridControl(
1020 : Reference< ::com::sun::star::lang::XMultiServiceFactory > _rxFactory,
1021 : Window* pParent,
1022 : FmXGridPeer* _pPeer,
1023 : WinBits nBits)
1024 : :DbGridControl(_rxFactory, pParent, nBits)
1025 : ,m_pPeer(_pPeer)
1026 : ,m_nCurrentSelectedColumn(-1)
1027 : ,m_nMarkedColumnId(BROWSER_INVALIDID)
1028 : ,m_bSelecting(sal_False)
1029 0 : ,m_bInColumnMove(sal_False)
1030 : {
1031 0 : EnableInteractiveRowHeight( );
1032 0 : }
1033 :
1034 : //------------------------------------------------------------------------------
1035 0 : void FmGridControl::Command(const CommandEvent& _rEvt)
1036 : {
1037 0 : if ( COMMAND_CONTEXTMENU == _rEvt.GetCommand() )
1038 : {
1039 0 : FmGridHeader* pMyHeader = static_cast< FmGridHeader* >( GetHeaderBar() );
1040 0 : if ( pMyHeader && !_rEvt.IsMouseEvent() )
1041 : { // context menu requested by keyboard
1042 0 : if ( 1 == GetSelectColumnCount() || IsDesignMode() )
1043 : {
1044 : sal_uInt16 nSelId = GetColumnId(
1045 0 : sal::static_int_cast< sal_uInt16 >( FirstSelectedColumn() ) );
1046 0 : ::Rectangle aColRect( GetFieldRectPixel( 0, nSelId, sal_False ) );
1047 :
1048 0 : Point aRelativePos( pMyHeader->ScreenToOutputPixel( OutputToScreenPixel( aColRect.TopCenter() ) ) );
1049 0 : pMyHeader->triggerColumnContextMenu( aRelativePos, FmGridHeader::AccessControl() );
1050 :
1051 : // handled
1052 0 : return;
1053 : }
1054 : }
1055 : }
1056 :
1057 0 : DbGridControl::Command( _rEvt );
1058 : }
1059 :
1060 : // ::com::sun::star::beans::XPropertyChangeListener
1061 : //------------------------------------------------------------------------------
1062 0 : void FmGridControl::propertyChange(const ::com::sun::star::beans::PropertyChangeEvent& evt)
1063 : {
1064 0 : if (evt.PropertyName == FM_PROP_ROWCOUNT)
1065 : {
1066 : // if we're not in the main thread call AdjustRows asynchronously
1067 0 : implAdjustInSolarThread(sal_True);
1068 0 : return;
1069 : }
1070 :
1071 0 : const DbGridRowRef& xRow = GetCurrentRow();
1072 : // waehrend Positionierung wird kein abgleich der Properties vorgenommen
1073 0 : Reference<XPropertySet> xSet(evt.Source,UNO_QUERY);
1074 0 : if (xRow.Is() && (::cppu::any2bool(xSet->getPropertyValue(FM_PROP_ISNEW))|| CompareBookmark(getDataSource()->getBookmark(), xRow->GetBookmark())))
1075 : {
1076 0 : if (evt.PropertyName == FM_PROP_ISMODIFIED)
1077 : {
1078 : // modified or clean ?
1079 0 : GridRowStatus eStatus = ::comphelper::getBOOL(evt.NewValue) ? GRS_MODIFIED : GRS_CLEAN;
1080 0 : if (eStatus != xRow->GetStatus())
1081 : {
1082 0 : xRow->SetStatus(eStatus);
1083 0 : SolarMutexGuard aGuard;
1084 0 : RowModified(GetCurrentPos());
1085 : }
1086 : }
1087 0 : }
1088 : }
1089 :
1090 : //------------------------------------------------------------------------------
1091 0 : void FmGridControl::SetDesignMode(sal_Bool bMode)
1092 : {
1093 0 : sal_Bool bOldMode = IsDesignMode();
1094 0 : DbGridControl::SetDesignMode(bMode);
1095 0 : if (bOldMode != bMode)
1096 : {
1097 0 : if (!bMode)
1098 : {
1099 : // selection aufheben
1100 0 : markColumn(USHRT_MAX);
1101 : }
1102 : else
1103 : {
1104 0 : Reference< ::com::sun::star::container::XIndexContainer > xColumns(GetPeer()->getColumns());
1105 0 : Reference< ::com::sun::star::view::XSelectionSupplier > xSelSupplier(xColumns, UNO_QUERY);
1106 0 : if (xSelSupplier.is())
1107 : {
1108 0 : Any aSelection = xSelSupplier->getSelection();
1109 0 : Reference< ::com::sun::star::beans::XPropertySet > xColumn;
1110 0 : if (aSelection.getValueType().getTypeClass() == TypeClass_INTERFACE)
1111 0 : ::cppu::extractInterface(xColumn, aSelection);
1112 0 : Reference< XInterface > xCurrent;
1113 0 : for (sal_uInt16 i=0; i<xColumns->getCount(); ++i)
1114 : {
1115 0 : ::cppu::extractInterface(xCurrent, xColumns->getByIndex(i));
1116 0 : if (xCurrent == xColumn)
1117 : {
1118 0 : markColumn(GetColumnIdFromModelPos(i));
1119 0 : break;
1120 : }
1121 0 : }
1122 0 : }
1123 : }
1124 : }
1125 0 : }
1126 :
1127 : //------------------------------------------------------------------------------
1128 0 : void FmGridControl::DeleteSelectedRows()
1129 : {
1130 0 : if (!m_pSeekCursor)
1131 : return;
1132 :
1133 : // how many rows are selected?
1134 0 : sal_Int32 nSelectedRows = GetSelectRowCount();
1135 :
1136 : // the current line should be deleted but it is currently in edit mode
1137 0 : if ( IsCurrentAppending() )
1138 : return;
1139 : // is the insert row selected
1140 0 : if (GetEmptyRow().Is() && IsRowSelected(GetRowCount() - 1))
1141 0 : nSelectedRows -= 1;
1142 :
1143 : // nothing to do
1144 0 : if (nSelectedRows <= 0)
1145 : return;
1146 :
1147 : // try to confirm the delete
1148 0 : Reference< ::com::sun::star::frame::XDispatchProvider > xDispatcher = (::com::sun::star::frame::XDispatchProvider*)GetPeer();
1149 0 : if (xDispatcher.is())
1150 : {
1151 0 : ::com::sun::star::util::URL aUrl;
1152 0 : aUrl.Complete = FMURL_CONFIRM_DELETION;
1153 : // #100312# ------------
1154 : Reference< ::com::sun::star::util::XURLTransformer > xTransformer(
1155 0 : ::com::sun::star::util::URLTransformer::create(::comphelper::getProcessComponentContext()) );
1156 0 : xTransformer->parseStrict( aUrl );
1157 :
1158 0 : Reference< ::com::sun::star::frame::XDispatch > xDispatch = xDispatcher->queryDispatch(aUrl, rtl::OUString(), 0);
1159 0 : Reference< ::com::sun::star::form::XConfirmDeleteListener > xConfirm(xDispatch, UNO_QUERY);
1160 0 : if (xConfirm.is())
1161 : {
1162 0 : ::com::sun::star::sdb::RowChangeEvent aEvent;
1163 0 : aEvent.Source = (Reference< XInterface > )(*getDataSource());
1164 0 : aEvent.Rows = nSelectedRows;
1165 0 : aEvent.Action = ::com::sun::star::sdb::RowChangeAction::DELETE;
1166 0 : if (!xConfirm->confirmDelete(aEvent))
1167 0 : return;
1168 0 : }
1169 : }
1170 :
1171 0 : const MultiSelection* pRowSelection = GetSelection();
1172 0 : if ( pRowSelection && pRowSelection->IsAllSelected() )
1173 : {
1174 0 : BeginCursorAction();
1175 0 : CursorWrapper* pCursor = getDataSource();
1176 0 : Reference< XResultSetUpdate > xUpdateCursor((Reference< XInterface >)*pCursor, UNO_QUERY);
1177 : try
1178 : {
1179 0 : pCursor->beforeFirst();
1180 0 : while( pCursor->next() )
1181 0 : xUpdateCursor->deleteRow();
1182 :
1183 0 : SetUpdateMode(sal_False);
1184 0 : SetNoSelection();
1185 :
1186 0 : xUpdateCursor->moveToInsertRow();
1187 : }
1188 0 : catch(const Exception&)
1189 : {
1190 : OSL_FAIL("Exception caught while deleting rows!");
1191 : }
1192 : // An den DatenCursor anpassen
1193 0 : AdjustDataSource(sal_True);
1194 0 : EndCursorAction();
1195 0 : SetUpdateMode(sal_True);
1196 : }
1197 : else
1198 : {
1199 0 : Reference< ::com::sun::star::sdbcx::XDeleteRows > xDeleteThem((Reference< XInterface >)*getDataSource(), UNO_QUERY);
1200 :
1201 : // colect the bookmarks of the selected rows
1202 0 : Sequence < Any> aBookmarks = getSelectionBookmarks();
1203 :
1204 : // determine the next row to position after deletion
1205 0 : Any aBookmark;
1206 0 : sal_Bool bNewPos = sal_False;
1207 : // if the current row isn't selected we take the row as row after deletion
1208 : OSL_ENSURE( GetCurrentRow().Is(), "FmGridControl::DeleteSelectedRows: no current row here?" );
1209 : // crash reports suggest it can happen we don't have a current row - how?
1210 : // #154303# / 2008-04-23 / frank.schoenheit@sun.com
1211 0 : if ( !IsRowSelected( GetCurrentPos() ) && !IsCurrentAppending() && GetCurrentRow().Is() )
1212 : {
1213 0 : aBookmark = GetCurrentRow()->GetBookmark();
1214 0 : bNewPos = sal_True;
1215 : }
1216 : else
1217 : {
1218 : // we look for the first row after the selected block for selection
1219 0 : long nIdx = LastSelectedRow() + 1;
1220 0 : if (nIdx < GetRowCount() - 1)
1221 : {
1222 : // there is a next row to position on
1223 0 : if (SeekCursor(nIdx))
1224 : {
1225 0 : GetSeekRow()->SetState(m_pSeekCursor, sal_True);
1226 :
1227 0 : bNewPos = sal_True;
1228 : // if it's not the row for inserting we keep the bookmark
1229 0 : if (!IsInsertionRow(nIdx))
1230 0 : aBookmark = m_pSeekCursor->getBookmark();
1231 : }
1232 : }
1233 : else
1234 : {
1235 : // we look for the first row before the selected block for selection after deletion
1236 0 : nIdx = FirstSelectedRow() - 1;
1237 0 : if (nIdx >= 0 && SeekCursor(nIdx))
1238 : {
1239 0 : GetSeekRow()->SetState(m_pSeekCursor, sal_True);
1240 :
1241 0 : bNewPos = sal_True;
1242 0 : aBookmark = m_pSeekCursor->getBookmark();
1243 : }
1244 : }
1245 : }
1246 :
1247 : // Sind alle Zeilen Selectiert
1248 : // Zweite bedingung falls keine einguegeZeile existiert
1249 0 : sal_Bool bAllSelected = GetTotalCount() == nSelectedRows || GetRowCount() == nSelectedRows;
1250 :
1251 0 : BeginCursorAction();
1252 :
1253 : // now delete the row
1254 0 : Sequence <sal_Int32> aDeletedRows;
1255 0 : SetUpdateMode( sal_False );
1256 : try
1257 : {
1258 0 : aDeletedRows = xDeleteThem->deleteRows(aBookmarks);
1259 : }
1260 0 : catch(SQLException&)
1261 : {
1262 : }
1263 0 : SetUpdateMode( sal_True );
1264 :
1265 : // how many rows are deleted?
1266 0 : sal_Int32 nDeletedRows = 0;
1267 0 : const sal_Int32* pSuccess = aDeletedRows.getConstArray();
1268 0 : for (sal_Int32 i = 0; i < aDeletedRows.getLength(); i++)
1269 : {
1270 0 : if (pSuccess[i])
1271 0 : ++nDeletedRows;
1272 : }
1273 :
1274 : // sind Zeilen geloescht worden?
1275 0 : if (nDeletedRows)
1276 : {
1277 0 : SetUpdateMode(sal_False);
1278 0 : SetNoSelection();
1279 : try
1280 : {
1281 : // did we delete all the rows than try to move to the next possible row
1282 0 : if (nDeletedRows == aDeletedRows.getLength())
1283 : {
1284 : // there exists a new position to move on
1285 0 : if (bNewPos)
1286 : {
1287 0 : if (aBookmark.hasValue())
1288 0 : getDataSource()->moveToBookmark(aBookmark);
1289 : // no valid bookmark so move to the insert row
1290 : else
1291 : {
1292 0 : Reference< XResultSetUpdate > xUpdateCursor((Reference< XInterface >)*m_pDataCursor, UNO_QUERY);
1293 0 : xUpdateCursor->moveToInsertRow();
1294 : }
1295 : }
1296 : else
1297 : {
1298 0 : Reference< ::com::sun::star::beans::XPropertySet > xSet((Reference< XInterface >)*m_pDataCursor, UNO_QUERY);
1299 :
1300 0 : sal_Int32 nRecordCount(0);
1301 0 : xSet->getPropertyValue(FM_PROP_ROWCOUNT) >>= nRecordCount;
1302 0 : if ( m_pDataCursor->rowDeleted() )
1303 0 : --nRecordCount;
1304 :
1305 : // there are no rows left and we have an insert row
1306 0 : if (!nRecordCount && GetEmptyRow().Is())
1307 : {
1308 0 : Reference< XResultSetUpdate > xUpdateCursor((Reference< XInterface >)*m_pDataCursor, UNO_QUERY);
1309 0 : xUpdateCursor->moveToInsertRow();
1310 : }
1311 0 : else if (nRecordCount)
1312 : // move to the first row
1313 0 : getDataSource()->first();
1314 : }
1315 : }
1316 : // not all the rows where deleted, so move to the first row which remained in the resultset
1317 : else
1318 : {
1319 0 : for (sal_Int32 i = 0; i < aDeletedRows.getLength(); i++)
1320 : {
1321 0 : if (!pSuccess[i])
1322 : {
1323 0 : getDataSource()->moveToBookmark(aBookmarks.getConstArray()[i]);
1324 0 : break;
1325 : }
1326 : }
1327 : }
1328 : }
1329 0 : catch(const Exception&)
1330 : {
1331 : try
1332 : {
1333 : // positioning went wrong so try to move to the first row
1334 0 : getDataSource()->first();
1335 : }
1336 0 : catch(const Exception&)
1337 : {
1338 : }
1339 : }
1340 :
1341 : // An den DatenCursor anpassen
1342 0 : AdjustDataSource(sal_True);
1343 :
1344 : // es konnten nicht alle Zeilen geloescht werden
1345 : // da nie nicht geloeschten wieder selektieren
1346 0 : if (nDeletedRows < nSelectedRows)
1347 : {
1348 : // waren alle selektiert
1349 0 : if (bAllSelected)
1350 : {
1351 0 : SelectAll();
1352 0 : if (IsInsertionRow(GetRowCount() - 1)) // einfuegeZeile nicht
1353 0 : SelectRow(GetRowCount() - 1, sal_False);
1354 : }
1355 : else
1356 : {
1357 : // select the remaining rows
1358 0 : for (sal_Int32 i = 0; i < aDeletedRows.getLength(); i++)
1359 : {
1360 : try
1361 : {
1362 0 : if (!pSuccess[i])
1363 : {
1364 0 : m_pSeekCursor->moveToBookmark(m_pDataCursor->getBookmark());
1365 0 : SetSeekPos(m_pSeekCursor->getRow() - 1);
1366 0 : SelectRow(GetSeekPos());
1367 : }
1368 : }
1369 0 : catch(const Exception&)
1370 : {
1371 : // keep the seekpos in all cases
1372 0 : SetSeekPos(m_pSeekCursor->getRow() - 1);
1373 : }
1374 : }
1375 : }
1376 : }
1377 :
1378 0 : EndCursorAction();
1379 0 : SetUpdateMode(sal_True);
1380 : }
1381 : else // Zeile konnte nicht geloescht werden
1382 : {
1383 0 : EndCursorAction();
1384 : try
1385 : {
1386 : // currentrow is the insert row?
1387 0 : if (!IsCurrentAppending())
1388 0 : getDataSource()->refreshRow();
1389 : }
1390 0 : catch(const Exception&)
1391 : {
1392 : }
1393 0 : }
1394 : }
1395 :
1396 : // if there is no selection anymore we can start editing
1397 0 : if (!GetSelectRowCount())
1398 0 : ActivateCell();
1399 : }
1400 :
1401 :
1402 : // XCurrentRecordListener
1403 : //------------------------------------------------------------------------------
1404 0 : void FmGridControl::positioned(const ::com::sun::star::lang::EventObject& /*rEvent*/)
1405 : {
1406 : TRACE_RANGE("FmGridControl::positioned");
1407 : // position on the data source (force it to be done in the main thread)
1408 0 : implAdjustInSolarThread(sal_False);
1409 0 : }
1410 :
1411 : //------------------------------------------------------------------------------
1412 0 : sal_Bool FmGridControl::commit()
1413 : {
1414 : // Commit nur ausfuehren, wenn nicht bereits ein Update vom ::com::sun::star::form::component::GridControl ausgefuehrt
1415 : // wird
1416 0 : if (!IsUpdating())
1417 : {
1418 0 : if (Controller().Is() && Controller()->IsModified())
1419 : {
1420 0 : if (!SaveModified())
1421 0 : return sal_False;
1422 : }
1423 : }
1424 0 : return sal_True;
1425 : }
1426 :
1427 : //------------------------------------------------------------------------------
1428 0 : void FmGridControl::inserted(const ::com::sun::star::lang::EventObject& /*rEvent*/)
1429 : {
1430 0 : const DbGridRowRef& xRow = GetCurrentRow();
1431 0 : if (!xRow.Is())
1432 0 : return;
1433 :
1434 : // Zeile ist eingefuegt worden, dann den status und mode zuruecksetzen
1435 0 : xRow->SetState(m_pDataCursor, sal_False);
1436 0 : xRow->SetNew(sal_False);
1437 :
1438 : }
1439 :
1440 : //------------------------------------------------------------------------------
1441 0 : BrowserHeader* FmGridControl::imp_CreateHeaderBar(BrowseBox* pParent)
1442 : {
1443 : DBG_ASSERT( pParent == this, "FmGridControl::imp_CreateHeaderBar: parent?" );
1444 0 : return new FmGridHeader( pParent );
1445 : }
1446 :
1447 : //------------------------------------------------------------------------------
1448 0 : void FmGridControl::markColumn(sal_uInt16 nId)
1449 : {
1450 0 : if (GetHeaderBar() && m_nMarkedColumnId != nId)
1451 : {
1452 : // deselektieren
1453 0 : if (m_nMarkedColumnId != BROWSER_INVALIDID)
1454 : {
1455 0 : HeaderBarItemBits aBits = GetHeaderBar()->GetItemBits(m_nMarkedColumnId) & ~HIB_FLAT;
1456 0 : GetHeaderBar()->SetItemBits(m_nMarkedColumnId, aBits);
1457 : }
1458 :
1459 :
1460 0 : if (nId != BROWSER_INVALIDID)
1461 : {
1462 0 : HeaderBarItemBits aBits = GetHeaderBar()->GetItemBits(nId) | HIB_FLAT;
1463 0 : GetHeaderBar()->SetItemBits(nId, aBits);
1464 : }
1465 0 : m_nMarkedColumnId = nId;
1466 : }
1467 0 : }
1468 :
1469 : //------------------------------------------------------------------------------
1470 0 : sal_Bool FmGridControl::isColumnMarked(sal_uInt16 nId) const
1471 : {
1472 0 : return m_nMarkedColumnId == nId;
1473 : }
1474 :
1475 : //------------------------------------------------------------------------------
1476 0 : long FmGridControl::QueryMinimumRowHeight()
1477 : {
1478 0 : long nMinimalLogicHeight = 20; // 0.2 cm
1479 0 : long nMinimalPixelHeight = LogicToPixel( Point( 0, nMinimalLogicHeight ), MAP_10TH_MM ).Y();
1480 0 : return CalcZoom( nMinimalPixelHeight );
1481 : }
1482 :
1483 : //------------------------------------------------------------------------------
1484 0 : void FmGridControl::RowHeightChanged()
1485 : {
1486 0 : DbGridControl::RowHeightChanged();
1487 :
1488 0 : Reference< XPropertySet > xModel( GetPeer()->getColumns(), UNO_QUERY );
1489 : DBG_ASSERT( xModel.is(), "FmGridControl::RowHeightChanged: no model!" );
1490 0 : if ( xModel.is() )
1491 : {
1492 : try
1493 : {
1494 0 : sal_Int32 nUnzoomedPixelHeight = CalcReverseZoom( GetDataRowHeight() );
1495 0 : Any aProperty = makeAny( (sal_Int32)PixelToLogic( Point( 0, nUnzoomedPixelHeight ), MAP_10TH_MM ).Y() );
1496 0 : xModel->setPropertyValue( FM_PROP_ROWHEIGHT, aProperty );
1497 : }
1498 0 : catch( const Exception& )
1499 : {
1500 : OSL_FAIL( "FmGridControl::RowHeightChanged: caught an exception!" );
1501 : }
1502 0 : }
1503 0 : }
1504 :
1505 : //------------------------------------------------------------------------------
1506 0 : void FmGridControl::ColumnResized(sal_uInt16 nId)
1507 : {
1508 0 : DbGridControl::ColumnResized(nId);
1509 :
1510 : // Wert ans model uebergeben
1511 0 : DbGridColumn* pCol = DbGridControl::GetColumns().at( GetModelColumnPos(nId) );
1512 0 : Reference< ::com::sun::star::beans::XPropertySet > xColModel(pCol->getModel());
1513 0 : if (xColModel.is())
1514 : {
1515 0 : Any aWidth;
1516 0 : sal_Int32 nColumnWidth = GetColumnWidth(nId);
1517 0 : nColumnWidth = CalcReverseZoom(nColumnWidth);
1518 : // Umrechnen in 10THMM
1519 0 : aWidth <<= (sal_Int32)PixelToLogic(Point(nColumnWidth,0),MAP_10TH_MM).X();
1520 0 : xColModel->setPropertyValue(FM_PROP_WIDTH, aWidth);
1521 0 : }
1522 0 : }
1523 :
1524 : //------------------------------------------------------------------------------
1525 0 : void FmGridControl::CellModified()
1526 : {
1527 0 : DbGridControl::CellModified();
1528 0 : GetPeer()->CellModified();
1529 0 : }
1530 :
1531 : //------------------------------------------------------------------------------
1532 0 : void FmGridControl::BeginCursorAction()
1533 : {
1534 0 : DbGridControl::BeginCursorAction();
1535 0 : m_pPeer->stopCursorListening();
1536 0 : }
1537 :
1538 : //------------------------------------------------------------------------------
1539 0 : void FmGridControl::EndCursorAction()
1540 : {
1541 0 : m_pPeer->startCursorListening();
1542 0 : DbGridControl::EndCursorAction();
1543 0 : }
1544 :
1545 : //------------------------------------------------------------------------------
1546 0 : void FmGridControl::ColumnMoved(sal_uInt16 nId)
1547 : {
1548 0 : m_bInColumnMove = sal_True;
1549 :
1550 0 : DbGridControl::ColumnMoved(nId);
1551 0 : Reference< ::com::sun::star::container::XIndexContainer > xColumns(GetPeer()->getColumns());
1552 :
1553 0 : if (xColumns.is())
1554 : {
1555 : // suchen der Spalte und verschieben im Model
1556 : // ColumnPos holen
1557 0 : DbGridColumn* pCol = DbGridControl::GetColumns().at( GetModelColumnPos(nId) );
1558 0 : Reference< ::com::sun::star::beans::XPropertySet > xCol;
1559 :
1560 : // Einfuegen muß sich an den Column Positionen orientieren
1561 : sal_Int32 i;
1562 0 : Reference< XInterface > xCurrent;
1563 0 : for (i = 0; !xCol.is() && i < xColumns->getCount(); i++)
1564 : {
1565 0 : ::cppu::extractInterface(xCurrent, xColumns->getByIndex(i));
1566 0 : if (xCurrent == pCol->getModel())
1567 : {
1568 0 : xCol = pCol->getModel();
1569 0 : break;
1570 : }
1571 : }
1572 :
1573 : DBG_ASSERT(i < xColumns->getCount(), "Falscher ::com::sun::star::sdbcx::Index");
1574 0 : xColumns->removeByIndex(i);
1575 0 : Any aElement;
1576 0 : aElement <<= xCol;
1577 0 : xColumns->insertByIndex(GetModelColumnPos(nId), aElement);
1578 0 : pCol->setModel(xCol);
1579 : // if the column which is shown here is selected ...
1580 0 : if ( isColumnSelected(nId,pCol) )
1581 0 : markColumn(nId); // ... -> mark it
1582 : }
1583 :
1584 0 : m_bInColumnMove = sal_False;
1585 0 : }
1586 :
1587 : //------------------------------------------------------------------------------
1588 0 : void FmGridControl::InitColumnsByModels(const Reference< ::com::sun::star::container::XIndexContainer >& xColumns)
1589 : {
1590 : // Spalten wieder neu setzen
1591 : // wenn es nur eine HandleColumn gibt, dann nicht
1592 0 : if (GetModelColCount())
1593 : {
1594 0 : RemoveColumns();
1595 0 : InsertHandleColumn();
1596 : }
1597 :
1598 0 : if (!xColumns.is())
1599 0 : return;
1600 :
1601 0 : SetUpdateMode(sal_False);
1602 :
1603 : // Einfuegen mu� sich an den Column Positionen orientieren
1604 : sal_Int32 i;
1605 0 : Any aWidth;
1606 0 : for (i = 0; i < xColumns->getCount(); ++i)
1607 : {
1608 0 : Reference< ::com::sun::star::beans::XPropertySet > xCol;
1609 0 : ::cppu::extractInterface(xCol, xColumns->getByIndex(i));
1610 :
1611 : rtl::OUString aName(
1612 0 : comphelper::getString(xCol->getPropertyValue(FM_PROP_LABEL)));
1613 :
1614 0 : aWidth = xCol->getPropertyValue(FM_PROP_WIDTH);
1615 0 : sal_Int32 nWidth = 0;
1616 0 : if (aWidth >>= nWidth)
1617 0 : nWidth = LogicToPixel(Point(nWidth,0),MAP_10TH_MM).X();
1618 :
1619 0 : AppendColumn(aName, (sal_uInt16)nWidth);
1620 0 : DbGridColumn* pCol = DbGridControl::GetColumns().at( i );
1621 0 : pCol->setModel(xCol);
1622 0 : }
1623 :
1624 : // und jetzt noch die hidden columns rausnehmen
1625 : // (wir haben das nicht gleich in der oberen Schleife gemacht, da wir dann Probleme mit den
1626 : // IDs der Spalten bekommen haetten : AppendColumn vergibt die automatisch, die Spalte _nach_
1627 : // einer versteckten braucht aber eine um eine erhoehte ID ....
1628 0 : Any aHidden;
1629 0 : for (i = 0; i < xColumns->getCount(); ++i)
1630 : {
1631 0 : Reference< ::com::sun::star::beans::XPropertySet > xCol;
1632 0 : ::cppu::extractInterface(xCol, xColumns->getByIndex(i));
1633 0 : aHidden = xCol->getPropertyValue(FM_PROP_HIDDEN);
1634 0 : if (::comphelper::getBOOL(aHidden))
1635 0 : HideColumn(GetColumnIdFromModelPos((sal_uInt16)i));
1636 0 : }
1637 :
1638 0 : SetUpdateMode(sal_True);
1639 : }
1640 :
1641 : //------------------------------------------------------------------------------
1642 0 : void FmGridControl::InitColumnByField(
1643 : DbGridColumn* _pColumn, const Reference< XPropertySet >& _rxColumnModel,
1644 : const Reference< XNameAccess >& _rxFieldsByNames, const Reference< XIndexAccess >& _rxFieldsByIndex )
1645 : {
1646 : DBG_ASSERT( _rxFieldsByNames == _rxFieldsByIndex, "FmGridControl::InitColumnByField: invalid container interfaces!" );
1647 :
1648 : // lookup the column which belongs to the control source
1649 0 : ::rtl::OUString sFieldName;
1650 0 : _rxColumnModel->getPropertyValue( FM_PROP_CONTROLSOURCE ) >>= sFieldName;
1651 0 : Reference< XPropertySet > xField;
1652 0 : _rxColumnModel->getPropertyValue( FM_PROP_BOUNDFIELD ) >>= xField;
1653 :
1654 :
1655 0 : if ( !xField.is() && /*sFieldName.getLength() && */_rxFieldsByNames->hasByName( sFieldName ) ) // #i93452# do not check for name length
1656 0 : _rxFieldsByNames->getByName( sFieldName ) >>= xField;
1657 :
1658 : // determine the position of this column
1659 0 : sal_Int32 nFieldPos = -1;
1660 0 : if ( xField.is() )
1661 : {
1662 0 : Reference< XPropertySet > xCheck;
1663 0 : sal_Int32 nFieldCount = _rxFieldsByIndex->getCount();
1664 0 : for ( sal_Int32 i = 0; i < nFieldCount; ++i)
1665 : {
1666 0 : _rxFieldsByIndex->getByIndex( i ) >>= xCheck;
1667 0 : if ( xField.get() == xCheck.get() )
1668 : {
1669 0 : nFieldPos = i;
1670 0 : break;
1671 : }
1672 0 : }
1673 : }
1674 :
1675 0 : if ( xField.is() && ( nFieldPos >= 0 ) )
1676 : {
1677 : // some data types are not allowed
1678 0 : sal_Int32 nDataType = DataType::OTHER;
1679 0 : xField->getPropertyValue( FM_PROP_FIELDTYPE ) >>= nDataType;
1680 :
1681 0 : sal_Bool bIllegalType = sal_False;
1682 0 : switch ( nDataType )
1683 : {
1684 : case DataType::BLOB:
1685 : case DataType::LONGVARBINARY:
1686 : case DataType::BINARY:
1687 : case DataType::VARBINARY:
1688 : case DataType::OTHER:
1689 0 : bIllegalType = sal_True;
1690 0 : break;
1691 : }
1692 :
1693 0 : if ( bIllegalType )
1694 : {
1695 0 : _pColumn->SetObject( (sal_Int16)nFieldPos );
1696 : return;
1697 : }
1698 : }
1699 :
1700 : // the control type is determined by the ColumnServiceName
1701 0 : static ::rtl::OUString s_sPropColumnServiceName( RTL_CONSTASCII_USTRINGPARAM( "ColumnServiceName" ) );
1702 0 : if ( !::comphelper::hasProperty( s_sPropColumnServiceName, _rxColumnModel ) )
1703 : return;
1704 :
1705 0 : _pColumn->setModel( _rxColumnModel );
1706 :
1707 0 : ::rtl::OUString sColumnServiceName;
1708 0 : _rxColumnModel->getPropertyValue( s_sPropColumnServiceName ) >>= sColumnServiceName;
1709 :
1710 0 : sal_Int32 nTypeId = getColumnTypeByModelName( sColumnServiceName );
1711 0 : _pColumn->CreateControl( nFieldPos, xField, nTypeId );
1712 : }
1713 :
1714 : //------------------------------------------------------------------------------
1715 0 : void FmGridControl::InitColumnsByFields(const Reference< ::com::sun::star::container::XIndexAccess >& _rxFields)
1716 : {
1717 0 : if ( !_rxFields.is() )
1718 0 : return;
1719 :
1720 : // Spalten initialisieren
1721 0 : Reference< XIndexContainer > xColumns( GetPeer()->getColumns() );
1722 0 : Reference< XNameAccess > xFieldsAsNames( _rxFields, UNO_QUERY );
1723 :
1724 : // Einfuegen muss sich an den Column Positionen orientieren
1725 0 : for (sal_Int32 i = 0; i < xColumns->getCount(); i++)
1726 : {
1727 0 : DbGridColumn* pCol = GetColumns().at( i );
1728 : OSL_ENSURE(pCol,"No grid column!");
1729 0 : if ( pCol )
1730 : {
1731 0 : Reference< XPropertySet > xColumnModel;
1732 0 : ::cppu::extractInterface( xColumnModel, xColumns->getByIndex( i ) );
1733 :
1734 0 : InitColumnByField( pCol, xColumnModel, xFieldsAsNames, _rxFields );
1735 : }
1736 0 : }
1737 : }
1738 :
1739 : //------------------------------------------------------------------------------
1740 0 : void FmGridControl::HideColumn(sal_uInt16 nId)
1741 : {
1742 0 : DbGridControl::HideColumn(nId);
1743 :
1744 0 : sal_uInt16 nPos = GetModelColumnPos(nId);
1745 0 : if (nPos == (sal_uInt16)-1)
1746 0 : return;
1747 :
1748 0 : DbGridColumn* pColumn = GetColumns().at( nPos );
1749 0 : if (pColumn->IsHidden())
1750 0 : GetPeer()->columnHidden(pColumn);
1751 :
1752 0 : if (nId == m_nMarkedColumnId)
1753 0 : m_nMarkedColumnId = (sal_uInt16)-1;
1754 : }
1755 : // -----------------------------------------------------------------------------
1756 0 : sal_Bool FmGridControl::isColumnSelected(sal_uInt16 /*nId*/,DbGridColumn* _pColumn)
1757 : {
1758 : OSL_ENSURE(_pColumn,"Column can not be null!");
1759 0 : sal_Bool bSelected = sal_False;
1760 : // if the column which is shown here is selected ...
1761 0 : Reference< ::com::sun::star::view::XSelectionSupplier > xSelSupplier(GetPeer()->getColumns(), UNO_QUERY);
1762 0 : if ( xSelSupplier.is() )
1763 : {
1764 0 : Reference< ::com::sun::star::beans::XPropertySet > xColumn;
1765 0 : xSelSupplier->getSelection() >>= xColumn;
1766 0 : bSelected = (xColumn.get() == _pColumn->getModel().get());
1767 : }
1768 0 : return bSelected;
1769 : }
1770 :
1771 : //------------------------------------------------------------------------------
1772 0 : void FmGridControl::ShowColumn(sal_uInt16 nId)
1773 : {
1774 0 : DbGridControl::ShowColumn(nId);
1775 :
1776 0 : sal_uInt16 nPos = GetModelColumnPos(nId);
1777 0 : if (nPos == (sal_uInt16)-1)
1778 0 : return;
1779 :
1780 0 : DbGridColumn* pColumn = GetColumns().at( nPos );
1781 0 : if (!pColumn->IsHidden())
1782 0 : GetPeer()->columnVisible(pColumn);
1783 :
1784 : // if the column which is shown here is selected ...
1785 0 : if ( isColumnSelected(nId,pColumn) )
1786 0 : markColumn(nId); // ... -> mark it
1787 : }
1788 :
1789 : //------------------------------------------------------------------------------
1790 0 : sal_Bool FmGridControl::selectBookmarks(const Sequence< Any >& _rBookmarks)
1791 : {
1792 0 : SolarMutexGuard aGuard;
1793 : // need to lock the SolarMutex so that no paint call disturbs us ...
1794 :
1795 0 : if ( !m_pSeekCursor )
1796 : {
1797 : OSL_FAIL( "FmGridControl::selectBookmarks: no seek cursor!" );
1798 0 : return sal_False;
1799 : }
1800 :
1801 0 : const Any* pBookmark = _rBookmarks.getConstArray();
1802 0 : const Any* pBookmarkEnd = pBookmark + _rBookmarks.getLength();
1803 :
1804 0 : SetNoSelection();
1805 :
1806 0 : sal_Bool bAllSuccessfull = sal_True;
1807 : try
1808 : {
1809 0 : for (; pBookmark != pBookmarkEnd; ++pBookmark)
1810 : {
1811 : // move the seek cursor to the row given
1812 0 : if (m_pSeekCursor->moveToBookmark(*pBookmark))
1813 0 : SelectRow( m_pSeekCursor->getRow() - 1);
1814 : else
1815 0 : bAllSuccessfull = sal_False;
1816 : }
1817 : }
1818 0 : catch(Exception&)
1819 : {
1820 : OSL_FAIL("FmGridControl::selectBookmarks: could not move to one of the bookmarks!");
1821 0 : return sal_False;
1822 : }
1823 :
1824 0 : return bAllSuccessfull;
1825 : }
1826 :
1827 : //------------------------------------------------------------------------------
1828 0 : Sequence< Any> FmGridControl::getSelectionBookmarks()
1829 : {
1830 : // lock our update so no paint-triggered seeks interfere ...
1831 0 : SetUpdateMode(sal_False);
1832 :
1833 0 : sal_Int32 nSelectedRows = GetSelectRowCount(), i = 0;
1834 0 : Sequence< Any> aBookmarks(nSelectedRows);
1835 0 : if ( nSelectedRows )
1836 : {
1837 0 : Any* pBookmarks = (Any*)aBookmarks.getArray();
1838 :
1839 : // (I'm not sure if the problem isn't deeper : The szenario : a large table displayed by a grid with a
1840 : // thread-safe cursor (dBase). On loading the sdb-cursor started a counting thread. While this counting progress
1841 : // was running, I tried do delete 3 records from within the grid. Deletion caused a SeekCursor, which did a
1842 : // m_pSeekCursor->moveRelative and a m_pSeekCursor->getPosition.
1843 : // Unfortunally the first call caused a propertyChanged(RECORDCOUNT) which resulted in a repaint of the
1844 : // navigation bar and the grid. The latter itself will result in SeekRow calls. So after (successfully) returning
1845 : // from the moveRelative the getPosition returns an invalid value. And so the SeekCursor fails.
1846 : // In the consequence ALL parts of code where two calls to the seek cursor are done, while the second call _relys_ on
1847 : // the first one, should be secured against recursion, with a broad-minded interpretion of "recursion" : if any of these
1848 : // code parts is executed, no other should be accessible. But this sounds very difficult to achieve ....
1849 : // )
1850 :
1851 : // The next problem caused by the same behaviuor (SeekCursor causes a propertyChanged) : when adjusting rows we implicitly
1852 : // change our selection. So a "FirstSelected(); SeekCursor(); NextSelected();" may produce unpredictable results.
1853 : // That's why we _first_ collect the indicies of the selected rows and _then_ their bookmarks.
1854 0 : long nIdx = FirstSelectedRow();
1855 0 : while (nIdx >= 0)
1856 : {
1857 : // (we misuse the bookmarks array for this ...)
1858 0 : pBookmarks[i++] <<= (sal_Int32)nIdx;
1859 0 : nIdx = NextSelectedRow();
1860 : }
1861 : DBG_ASSERT(i == nSelectedRows, "FmGridControl::DeleteSelectedRows : could not collect the row indicies !");
1862 :
1863 0 : for (i=0; i<nSelectedRows; ++i)
1864 : {
1865 0 : nIdx = ::comphelper::getINT32(pBookmarks[i]);
1866 0 : if (IsInsertionRow(nIdx))
1867 : {
1868 : // leerzeile nicht loeschen
1869 0 : aBookmarks.realloc(--nSelectedRows);
1870 0 : SelectRow(nIdx,sal_False); // selection aufheben fuer leerzeile
1871 0 : break;
1872 : }
1873 :
1874 : // Zunaechst den DatenCursor auf den selektierten Satz pos.
1875 0 : if (SeekCursor(nIdx))
1876 : {
1877 0 : GetSeekRow()->SetState(m_pSeekCursor, sal_True);
1878 :
1879 0 : pBookmarks[i] = m_pSeekCursor->getBookmark();
1880 : }
1881 : #ifdef DBG_UTIL
1882 : else
1883 : OSL_FAIL("FmGridControl::DeleteSelectedRows : a bookmark could not be determined !");
1884 : #endif
1885 : }
1886 : }
1887 0 : SetUpdateMode(sal_True);
1888 :
1889 : // if one of the SeekCursor-calls failed ....
1890 0 : aBookmarks.realloc(i);
1891 :
1892 : // (the alternative : while collecting the bookmarks lock our propertyChanged, this should resolve both our problems.
1893 : // but this would be incompatible as we need a locking flag, then ...)
1894 :
1895 0 : return aBookmarks;
1896 : }
1897 : // -----------------------------------------------------------------------------
1898 : namespace
1899 : {
1900 0 : ::rtl::OUString getColumnPropertyFromPeer(FmXGridPeer* _pPeer,sal_Int32 _nPosition,const ::rtl::OUString& _sPropName)
1901 : {
1902 0 : ::rtl::OUString sRetText;
1903 0 : if ( _pPeer && _nPosition != -1)
1904 : {
1905 0 : Reference<XIndexContainer> xIndex = _pPeer->getColumns();
1906 0 : if ( xIndex.is() && xIndex->getCount() > _nPosition )
1907 : {
1908 0 : Reference<XPropertySet> xProp;
1909 0 : xIndex->getByIndex( _nPosition ) >>= xProp;
1910 0 : if ( xProp.is() )
1911 0 : xProp->getPropertyValue( _sPropName ) >>= sRetText;
1912 0 : }
1913 : }
1914 0 : return sRetText;
1915 : }
1916 : }
1917 : // Object data and state ------------------------------------------------------
1918 0 : ::rtl::OUString FmGridControl::GetAccessibleObjectName( ::svt::AccessibleBrowseBoxObjType _eObjType,sal_Int32 _nPosition ) const
1919 : {
1920 0 : ::rtl::OUString sRetText;
1921 0 : switch( _eObjType )
1922 : {
1923 : case ::svt::BBTYPE_BROWSEBOX:
1924 0 : if ( GetPeer() )
1925 : {
1926 0 : Reference<XPropertySet> xProp(GetPeer()->getColumns(),UNO_QUERY);
1927 0 : if ( xProp.is() )
1928 0 : xProp->getPropertyValue(FM_PROP_NAME) >>= sRetText;
1929 : }
1930 0 : break;
1931 : case ::svt::BBTYPE_COLUMNHEADERCELL:
1932 : sRetText = getColumnPropertyFromPeer(
1933 : GetPeer(),
1934 : GetModelColumnPos(
1935 0 : sal::static_int_cast< sal_uInt16 >(_nPosition)),
1936 0 : FM_PROP_LABEL);
1937 0 : break;
1938 : default:
1939 0 : sRetText = DbGridControl::GetAccessibleObjectName(_eObjType,_nPosition);
1940 : }
1941 0 : return sRetText;
1942 : }
1943 : // -----------------------------------------------------------------------------
1944 :
1945 0 : ::rtl::OUString FmGridControl::GetAccessibleObjectDescription( ::svt::AccessibleBrowseBoxObjType _eObjType,sal_Int32 _nPosition ) const
1946 : {
1947 0 : ::rtl::OUString sRetText;
1948 0 : switch( _eObjType )
1949 : {
1950 : case ::svt::BBTYPE_BROWSEBOX:
1951 0 : if ( GetPeer() )
1952 : {
1953 0 : Reference<XPropertySet> xProp(GetPeer()->getColumns(),UNO_QUERY);
1954 0 : if ( xProp.is() )
1955 : {
1956 0 : xProp->getPropertyValue(FM_PROP_HELPTEXT) >>= sRetText;
1957 0 : if ( sRetText.isEmpty() )
1958 0 : xProp->getPropertyValue(FM_PROP_DESCRIPTION) >>= sRetText;
1959 0 : }
1960 : }
1961 0 : break;
1962 : case ::svt::BBTYPE_COLUMNHEADERCELL:
1963 : sRetText = getColumnPropertyFromPeer(
1964 : GetPeer(),
1965 : GetModelColumnPos(
1966 0 : sal::static_int_cast< sal_uInt16 >(_nPosition)),
1967 0 : FM_PROP_HELPTEXT);
1968 0 : if ( sRetText.isEmpty() )
1969 : sRetText = getColumnPropertyFromPeer(
1970 : GetPeer(),
1971 : GetModelColumnPos(
1972 0 : sal::static_int_cast< sal_uInt16 >(_nPosition)),
1973 0 : FM_PROP_DESCRIPTION);
1974 :
1975 0 : break;
1976 : default:
1977 0 : sRetText = DbGridControl::GetAccessibleObjectDescription(_eObjType,_nPosition);
1978 : }
1979 0 : return sRetText;
1980 : }
1981 : // -----------------------------------------------------------------------------
1982 0 : void FmGridControl::Select()
1983 : {
1984 0 : DbGridControl::Select();
1985 : // ... betrifft das unsere Spalten ?
1986 0 : const MultiSelection* pColumnSelection = GetColumnSelection();
1987 :
1988 : sal_uInt16 nSelectedColumn =
1989 0 : pColumnSelection && pColumnSelection->GetSelectCount()
1990 : ? sal::static_int_cast< sal_uInt16 >(
1991 0 : ((MultiSelection*)pColumnSelection)->FirstSelected())
1992 0 : : SAL_MAX_UINT16;
1993 : // die HandleColumn wird nicht selektiert
1994 0 : switch (nSelectedColumn)
1995 : {
1996 0 : case SAL_MAX_UINT16: break; // no selection
1997 0 : case 0 : nSelectedColumn = SAL_MAX_UINT16; break;
1998 : // handle col can't be seledted
1999 : default :
2000 : // get the model col pos instead of the view col pos
2001 0 : nSelectedColumn = GetModelColumnPos(GetColumnIdFromViewPos(nSelectedColumn - 1));
2002 0 : break;
2003 : }
2004 :
2005 0 : if (nSelectedColumn != m_nCurrentSelectedColumn)
2006 : {
2007 : // VOR dem Aufruf des select am SelectionSupplier !
2008 0 : m_nCurrentSelectedColumn = nSelectedColumn;
2009 :
2010 0 : if (!m_bSelecting)
2011 : {
2012 0 : m_bSelecting = sal_True;
2013 :
2014 : try
2015 : {
2016 0 : Reference< XIndexAccess > xColumns(GetPeer()->getColumns(), UNO_QUERY);
2017 0 : Reference< XSelectionSupplier > xSelSupplier(xColumns, UNO_QUERY);
2018 0 : if (xSelSupplier.is())
2019 : {
2020 0 : if (nSelectedColumn != SAL_MAX_UINT16)
2021 : {
2022 0 : Reference< XPropertySet > xColumn;
2023 0 : ::cppu::extractInterface(xColumn,xColumns->getByIndex(nSelectedColumn));
2024 0 : xSelSupplier->select(makeAny(xColumn));
2025 : }
2026 : else
2027 : {
2028 0 : xSelSupplier->select(Any());
2029 : }
2030 0 : }
2031 : }
2032 0 : catch(Exception&)
2033 : {
2034 : }
2035 :
2036 :
2037 0 : m_bSelecting = sal_False;
2038 : }
2039 : }
2040 0 : }
2041 : // -----------------------------------------------------------------------------
2042 0 : sal_Int32 FmGridControl::GetSelectedColumn() const
2043 : {
2044 0 : return m_nCurrentSelectedColumn;
2045 : }
2046 : // -----------------------------------------------------------------------------
2047 0 : void FmGridControl::KeyInput( const KeyEvent& rKEvt )
2048 : {
2049 0 : sal_Bool bDone = sal_False;
2050 0 : const KeyCode& rKeyCode = rKEvt.GetKeyCode();
2051 0 : if ( IsDesignMode()
2052 0 : && !rKeyCode.IsShift()
2053 0 : && !rKeyCode.IsMod1()
2054 0 : && !rKeyCode.IsMod2()
2055 0 : && GetParent() )
2056 : {
2057 0 : switch ( rKeyCode.GetCode() )
2058 : {
2059 : case KEY_ESCAPE:
2060 0 : GetParent()->GrabFocus();
2061 0 : bDone = sal_True;
2062 0 : break;
2063 : case KEY_DELETE:
2064 0 : if ( GetSelectColumnCount() && GetPeer() && m_nCurrentSelectedColumn >= 0 )
2065 : {
2066 0 : Reference< ::com::sun::star::container::XIndexContainer > xCols(GetPeer()->getColumns());
2067 0 : if ( xCols.is() )
2068 : {
2069 : try
2070 : {
2071 0 : if ( m_nCurrentSelectedColumn < xCols->getCount() )
2072 : {
2073 0 : Reference< XInterface > xCol;
2074 0 : xCols->getByIndex(m_nCurrentSelectedColumn) >>= xCol;
2075 0 : xCols->removeByIndex(m_nCurrentSelectedColumn);
2076 0 : ::comphelper::disposeComponent(xCol);
2077 : }
2078 : }
2079 0 : catch(const Exception&)
2080 : {
2081 : OSL_FAIL("exception occurred while deleting a column");
2082 : }
2083 0 : }
2084 : }
2085 0 : bDone = sal_True;
2086 0 : break;
2087 : }
2088 : }
2089 0 : if ( !bDone )
2090 0 : DbGridControl::KeyInput( rKEvt );
2091 63 : }
2092 : // -----------------------------------------------------------------------------
2093 :
2094 :
2095 :
2096 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|