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 <vcl/waitobj.hxx>
21 : #include <com/sun/star/util/URL.hpp>
22 : #include <vcl/msgbox.hxx>
23 : #include <vcl/stdtext.hxx>
24 : #include <comphelper/types.hxx>
25 : #include <comphelper/sequence.hxx>
26 : #include "framectr.hxx"
27 : #include "datman.hxx"
28 : #include "bibview.hxx"
29 : #include "bibresid.hxx"
30 : #include "bib.hrc"
31 : #include <toolkit/helper/vclunohelper.hxx>
32 : #include "bibconfig.hxx"
33 : #include <cppuhelper/implbase1.hxx>
34 : #include <vcl/svapp.hxx>
35 : #include "bibliography.hrc"
36 : #include <comphelper/processfactory.hxx>
37 : #include <com/sun/star/form/XConfirmDeleteListener.hpp>
38 : #include <com/sun/star/form/runtime/XFormController.hpp>
39 : #include <com/sun/star/beans/PropertyState.hpp>
40 : #include <com/sun/star/beans/PropertyValue.hpp>
41 : #include <com/sun/star/ui/dialogs/XExecutableDialog.hpp>
42 : #include <com/sun/star/sdbcx/Privilege.hpp>
43 : #include <com/sun/star/sdbc/XResultSetUpdate.hpp>
44 : #include <com/sun/star/sdb/FilterDialog.hpp>
45 : #include <com/sun/star/sdb/RowChangeAction.hpp>
46 : #include <com/sun/star/frame/CommandGroup.hpp>
47 : #include <com/sun/star/datatransfer/clipboard/XClipboard.hpp>
48 : #include <cppuhelper/interfacecontainer.hxx>
49 : #include <cppuhelper/supportsservice.hxx>
50 : #include <sot/exchange.hxx>
51 : #include <sot/formats.hxx>
52 : #include <vcl/edit.hxx>
53 : #include <osl/mutex.hxx>
54 :
55 : #include <unordered_map>
56 :
57 : using namespace osl;
58 : using namespace cppu;
59 : using namespace com::sun::star::sdbc;
60 : using namespace com::sun::star::frame;
61 : using namespace com::sun::star::uno;
62 : using namespace com::sun::star;
63 :
64 :
65 : struct DispatchInfo
66 : {
67 : const char* pCommand;
68 : sal_Int16 nGroupId;
69 : bool bActiveConnection;
70 : };
71 :
72 : struct CacheDispatchInfo
73 : {
74 : sal_Int16 nGroupId;
75 : bool bActiveConnection;
76 : };
77 :
78 : // Attention: commands must be sorted by command groups. Implementation is dependent
79 : // on this!!
80 : static const DispatchInfo SupportedCommandsArray[] =
81 : {
82 : { ".uno:Undo" , frame::CommandGroup::EDIT , false },
83 : { ".uno:Cut" , frame::CommandGroup::EDIT , false },
84 : { ".uno:Copy" , frame::CommandGroup::EDIT , false },
85 : { ".uno:Paste" , frame::CommandGroup::EDIT , false },
86 : { ".uno:SelectAll" , frame::CommandGroup::EDIT , false },
87 : { ".uno:CloseDoc" , frame::CommandGroup::DOCUMENT , false },
88 : { ".uno:StatusBarVisible" , frame::CommandGroup::VIEW , false },
89 : { ".uno:AvailableToolbars" , frame::CommandGroup::VIEW , false },
90 : { ".uno:Bib/standardFilter" , frame::CommandGroup::DATA , true },
91 : { ".uno:Bib/DeleteRecord" , frame::CommandGroup::DATA , true },
92 : { ".uno:Bib/InsertRecord" , frame::CommandGroup::DATA , true },
93 : { ".uno:Bib/query" , frame::CommandGroup::DATA , true },
94 : { ".uno:Bib/autoFilter" , frame::CommandGroup::DATA , true },
95 : { ".uno:Bib/source" , frame::CommandGroup::DATA , true },
96 : { ".uno:Bib/removeFilter" , frame::CommandGroup::DATA , true },
97 : { ".uno:Bib/sdbsource" , frame::CommandGroup::DATA , true },
98 : { ".uno:Bib/Mapping" , frame::CommandGroup::DATA , true },
99 : { 0 , 0 , false }
100 : };
101 :
102 : typedef std::unordered_map< OUString, CacheDispatchInfo, OUStringHash, ::std::equal_to< OUString > > CmdToInfoCache;
103 :
104 0 : const CmdToInfoCache& GetCommandToInfoCache()
105 : {
106 : static bool bCacheInitialized = false;
107 0 : static CmdToInfoCache aCmdToInfoCache;
108 :
109 0 : if ( !bCacheInitialized )
110 : {
111 0 : ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
112 0 : if ( !bCacheInitialized )
113 : {
114 0 : sal_Int32 i( 0 );
115 0 : while ( SupportedCommandsArray[i].pCommand != 0 )
116 : {
117 0 : OUString aCommand( OUString::createFromAscii( SupportedCommandsArray[i].pCommand ));
118 :
119 : CacheDispatchInfo aDispatchInfo;
120 0 : aDispatchInfo.nGroupId = SupportedCommandsArray[i].nGroupId;
121 0 : aDispatchInfo.bActiveConnection = SupportedCommandsArray[i].bActiveConnection;
122 0 : aCmdToInfoCache.insert( CmdToInfoCache::value_type( aCommand, aDispatchInfo ));
123 0 : ++i;
124 0 : }
125 0 : bCacheInitialized = true;
126 0 : }
127 : }
128 :
129 0 : return aCmdToInfoCache;
130 : }
131 :
132 :
133 : class BibFrameCtrl_Impl : public cppu::WeakImplHelper1 < XFrameActionListener >
134 : {
135 : public:
136 : Mutex aMutex;
137 : OMultiTypeInterfaceContainerHelper aLC;
138 :
139 : BibFrameController_Impl* pController;
140 :
141 0 : BibFrameCtrl_Impl()
142 : : aLC( aMutex )
143 0 : , pController(0)
144 0 : {}
145 :
146 : virtual ~BibFrameCtrl_Impl();
147 :
148 : virtual void SAL_CALL frameAction(const FrameActionEvent& aEvent) throw( RuntimeException, std::exception ) SAL_OVERRIDE;
149 : virtual void SAL_CALL disposing( const lang::EventObject& Source ) throw (::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
150 : };
151 :
152 :
153 0 : BibFrameCtrl_Impl::~BibFrameCtrl_Impl()
154 : {
155 0 : }
156 :
157 0 : void BibFrameCtrl_Impl::frameAction(const FrameActionEvent& ) throw( uno::RuntimeException, std::exception )
158 : {
159 0 : }
160 :
161 0 : void BibFrameCtrl_Impl::disposing( const lang::EventObject& /*Source*/ )
162 : throw (::com::sun::star::uno::RuntimeException, std::exception)
163 : {
164 0 : ::SolarMutexGuard aGuard;
165 0 : if ( pController )
166 0 : pController->getFrame()->removeFrameActionListener( this );
167 0 : }
168 :
169 0 : BibFrameController_Impl::BibFrameController_Impl( const uno::Reference< awt::XWindow > & xComponent,
170 : BibDataManager* pDataManager)
171 : :xWindow( xComponent )
172 : ,m_xDatMan( pDataManager )
173 : ,pDatMan( pDataManager )
174 0 : ,pBibMod(NULL)
175 : {
176 0 : vcl::Window* pParent = VCLUnoHelper::GetWindow( xWindow );
177 0 : pParent->SetUniqueId(UID_BIB_FRAME_WINDOW);
178 0 : bDisposing=false;
179 0 : bHierarchical=true;
180 0 : pImp = new BibFrameCtrl_Impl;
181 0 : pImp->pController = this;
182 0 : pImp->acquire();
183 0 : }
184 :
185 0 : BibFrameController_Impl::~BibFrameController_Impl()
186 : {
187 0 : pImp->pController = NULL;
188 0 : pImp->release();
189 0 : delete pDatMan;
190 0 : if(pBibMod)
191 0 : CloseBibModul(pBibMod);
192 0 : }
193 :
194 0 : OUString SAL_CALL BibFrameController_Impl::getImplementationName() throw (::com::sun::star::uno::RuntimeException, std::exception)
195 : {
196 0 : return OUString("com.sun.star.comp.extensions.Bibliography");
197 : }
198 :
199 0 : sal_Bool SAL_CALL BibFrameController_Impl::supportsService( const OUString& sServiceName ) throw (::com::sun::star::uno::RuntimeException, std::exception)
200 : {
201 0 : return cppu::supportsService( this, sServiceName );
202 : }
203 :
204 0 : ::com::sun::star::uno::Sequence< OUString > SAL_CALL BibFrameController_Impl::getSupportedServiceNames() throw (::com::sun::star::uno::RuntimeException, std::exception)
205 : {
206 : // return only top level services ...
207 : // base services are included there and should be asked by uno-rtti.
208 0 : ::com::sun::star::uno::Sequence< OUString > lNames(1);
209 0 : lNames[0] = "com.sun.star.frame.Bibliography";
210 0 : return lNames;
211 : }
212 :
213 0 : void BibFrameController_Impl::attachFrame( const uno::Reference< XFrame > & xArg ) throw (::com::sun::star::uno::RuntimeException, std::exception)
214 : {
215 0 : xFrame = xArg;
216 0 : xFrame->addFrameActionListener( pImp );
217 0 : }
218 :
219 0 : sal_Bool BibFrameController_Impl::attachModel( const uno::Reference< XModel > & /*xModel*/ ) throw (::com::sun::star::uno::RuntimeException, std::exception)
220 : {
221 0 : return sal_False;
222 : }
223 :
224 0 : sal_Bool BibFrameController_Impl::suspend( sal_Bool bSuspend ) throw (::com::sun::star::uno::RuntimeException, std::exception)
225 : {
226 0 : if ( bSuspend )
227 0 : getFrame()->removeFrameActionListener( pImp );
228 : else
229 0 : getFrame()->addFrameActionListener( pImp );
230 0 : return sal_True;
231 : }
232 :
233 0 : uno::Any BibFrameController_Impl::getViewData() throw (::com::sun::star::uno::RuntimeException, std::exception)
234 : {
235 0 : return uno::Any();
236 : }
237 :
238 0 : void BibFrameController_Impl::restoreViewData( const uno::Any& /*Value*/ ) throw (::com::sun::star::uno::RuntimeException, std::exception)
239 : {
240 0 : }
241 :
242 0 : uno::Reference< XFrame > BibFrameController_Impl::getFrame() throw (::com::sun::star::uno::RuntimeException, std::exception)
243 : {
244 0 : return xFrame;
245 : }
246 :
247 0 : uno::Reference< XModel > BibFrameController_Impl::getModel() throw (::com::sun::star::uno::RuntimeException, std::exception)
248 : {
249 0 : return uno::Reference< XModel > ();
250 : }
251 :
252 0 : void BibFrameController_Impl::dispose() throw (::com::sun::star::uno::RuntimeException, std::exception)
253 : {
254 0 : bDisposing = true;
255 0 : lang::EventObject aObject;
256 0 : aObject.Source = static_cast<XController*>(this);
257 0 : pImp->aLC.disposeAndClear(aObject);
258 0 : m_xDatMan = 0;
259 0 : pDatMan = 0;
260 0 : aStatusListeners.clear();
261 0 : }
262 :
263 0 : void BibFrameController_Impl::addEventListener( const uno::Reference< lang::XEventListener > & aListener ) throw (::com::sun::star::uno::RuntimeException, std::exception)
264 : {
265 0 : pImp->aLC.addInterface( cppu::UnoType<lang::XEventListener>::get(), aListener );
266 0 : }
267 :
268 0 : void BibFrameController_Impl::removeEventListener( const uno::Reference< lang::XEventListener > & aListener ) throw (::com::sun::star::uno::RuntimeException, std::exception)
269 : {
270 0 : pImp->aLC.removeInterface( cppu::UnoType<lang::XEventListener>::get(), aListener );
271 0 : }
272 :
273 0 : uno::Reference< frame::XDispatch > BibFrameController_Impl::queryDispatch( const util::URL& aURL, const OUString& /*aTarget*/, sal_Int32 /*nSearchFlags*/ ) throw (::com::sun::star::uno::RuntimeException, std::exception)
274 : {
275 0 : if ( !bDisposing )
276 : {
277 0 : const CmdToInfoCache& rCmdCache = GetCommandToInfoCache();
278 0 : CmdToInfoCache::const_iterator pIter = rCmdCache.find( aURL.Complete );
279 0 : if ( pIter != rCmdCache.end() )
280 : {
281 0 : if (( pDatMan->HasActiveConnection() ) ||
282 0 : ( !pIter->second.bActiveConnection ))
283 0 : return static_cast<frame::XDispatch*>(this);
284 : }
285 : }
286 :
287 0 : return uno::Reference< frame::XDispatch > ();
288 : }
289 :
290 0 : uno::Sequence<uno::Reference< XDispatch > > BibFrameController_Impl::queryDispatches( const uno::Sequence<DispatchDescriptor>& aDescripts ) throw (::com::sun::star::uno::RuntimeException, std::exception)
291 : {
292 0 : uno::Sequence< uno::Reference< XDispatch > > aDispatches( aDescripts.getLength() );
293 0 : for ( sal_Int32 i=0; i<aDescripts.getLength(); ++i )
294 0 : aDispatches[i] = queryDispatch( aDescripts[i].FeatureURL, aDescripts[i].FrameName, aDescripts[i].SearchFlags );
295 0 : return aDispatches;
296 : }
297 :
298 0 : uno::Sequence< ::sal_Int16 > SAL_CALL BibFrameController_Impl::getSupportedCommandGroups()
299 : throw (::com::sun::star::uno::RuntimeException, std::exception)
300 : {
301 0 : uno::Sequence< ::sal_Int16 > aDispatchInfo( 4 );
302 :
303 0 : aDispatchInfo[0] = frame::CommandGroup::EDIT;
304 0 : aDispatchInfo[1] = frame::CommandGroup::DOCUMENT;
305 0 : aDispatchInfo[2] = frame::CommandGroup::DATA;
306 0 : aDispatchInfo[3] = frame::CommandGroup::VIEW;
307 :
308 0 : return aDispatchInfo;
309 : }
310 :
311 0 : uno::Sequence< frame::DispatchInformation > SAL_CALL BibFrameController_Impl::getConfigurableDispatchInformation( ::sal_Int16 nCommandGroup )
312 : throw (::com::sun::star::uno::RuntimeException, std::exception)
313 : {
314 0 : const CmdToInfoCache& rCmdCache = GetCommandToInfoCache();
315 :
316 0 : frame::DispatchInformation aDispatchInfo;
317 0 : std::list< frame::DispatchInformation > aDispatchInfoList;
318 :
319 0 : if (( nCommandGroup == frame::CommandGroup::EDIT ) ||
320 0 : ( nCommandGroup == frame::CommandGroup::DOCUMENT ) ||
321 0 : ( nCommandGroup == frame::CommandGroup::DATA ) ||
322 : ( nCommandGroup == frame::CommandGroup::VIEW ))
323 : {
324 0 : bool bGroupFound = false;
325 0 : CmdToInfoCache::const_iterator pIter = rCmdCache.begin();
326 0 : while ( pIter != rCmdCache.end() )
327 : {
328 0 : if ( pIter->second.nGroupId == nCommandGroup )
329 : {
330 0 : bGroupFound = true;
331 0 : aDispatchInfo.Command = pIter->first;
332 0 : aDispatchInfo.GroupId = pIter->second.nGroupId;
333 0 : aDispatchInfoList.push_back( aDispatchInfo );
334 : }
335 0 : else if ( bGroupFound )
336 0 : break;
337 :
338 0 : ++pIter;
339 : }
340 : }
341 :
342 : ::com::sun::star::uno::Sequence< ::com::sun::star::frame::DispatchInformation > aSeq =
343 0 : comphelper::containerToSequence< ::com::sun::star::frame::DispatchInformation, std::list< ::com::sun::star::frame::DispatchInformation > >( aDispatchInfoList );
344 :
345 0 : return aSeq;
346 : }
347 :
348 0 : bool canInsertRecords(const Reference< beans::XPropertySet>& _rxCursorSet)
349 : {
350 0 : sal_Int32 nPriv = 0;
351 0 : _rxCursorSet->getPropertyValue("Privileges") >>= nPriv;
352 0 : return ((_rxCursorSet.is() && (nPriv & sdbcx::Privilege::INSERT) != 0));
353 : }
354 :
355 0 : bool BibFrameController_Impl::SaveModified(const Reference< form::runtime::XFormController>& xController)
356 : {
357 0 : if (!xController.is())
358 0 : return false;
359 :
360 0 : Reference< XResultSetUpdate> _xCursor = Reference< XResultSetUpdate>(xController->getModel(), UNO_QUERY);
361 :
362 0 : if (!_xCursor.is())
363 0 : return false;
364 :
365 0 : Reference< beans::XPropertySet> _xSet = Reference< beans::XPropertySet>(_xCursor, UNO_QUERY);
366 0 : if (!_xSet.is())
367 0 : return false;
368 :
369 : // need to save?
370 0 : bool bIsNew = ::comphelper::getBOOL(_xSet->getPropertyValue("IsNew"));
371 0 : bool bIsModified = ::comphelper::getBOOL(_xSet->getPropertyValue("IsModified"));
372 0 : bool bResult = !bIsModified;
373 0 : if (bIsModified)
374 : {
375 : try
376 : {
377 0 : if (bIsNew)
378 0 : _xCursor->insertRow();
379 : else
380 0 : _xCursor->updateRow();
381 0 : bResult = true;
382 : }
383 0 : catch(const Exception&)
384 : {
385 : OSL_FAIL("SaveModified: Exception occurred!");
386 : }
387 : }
388 0 : return bResult;
389 : }
390 :
391 0 : static vcl::Window* lcl_GetFocusChild( vcl::Window* pParent )
392 : {
393 0 : sal_uInt16 nChildren = pParent->GetChildCount();
394 0 : for( sal_uInt16 nChild = 0; nChild < nChildren; ++nChild)
395 : {
396 0 : vcl::Window* pChild = pParent->GetChild( nChild );
397 0 : if(pChild->HasFocus())
398 0 : return pChild;
399 0 : vcl::Window* pSubChild = lcl_GetFocusChild( pChild );
400 0 : if(pSubChild)
401 0 : return pSubChild;
402 : }
403 0 : return 0;
404 : }
405 :
406 : //class XDispatch
407 0 : void BibFrameController_Impl::dispatch(const util::URL& _rURL, const uno::Sequence< beans::PropertyValue >& aArgs)
408 : throw (::com::sun::star::uno::RuntimeException,
409 : std::exception)
410 : {
411 0 : if ( !bDisposing )
412 : {
413 0 : ::SolarMutexGuard aGuard;
414 0 : vcl::Window* pParent = VCLUnoHelper::GetWindow( xWindow );
415 0 : WaitObject aWaitObject( pParent );
416 :
417 0 : OUString aCommand( _rURL.Path);
418 0 : if(aCommand == "Bib/Mapping")
419 : {
420 0 : pDatMan->CreateMappingDialog(pParent);
421 : }
422 0 : else if(aCommand == "Bib/source")
423 : {
424 0 : ChangeDataSource(aArgs);
425 : }
426 0 : else if(aCommand == "Bib/sdbsource")
427 : {
428 0 : OUString aURL = pDatMan->CreateDBChangeDialog(pParent);
429 0 : if(!aURL.isEmpty())
430 : {
431 : try
432 : {
433 0 : uno::Sequence< beans::PropertyValue > aNewDataSource(2);
434 0 : beans::PropertyValue* pProps = aNewDataSource.getArray();
435 0 : pProps[0].Value <<= OUString();
436 0 : pProps[1].Value <<= aURL;
437 0 : ChangeDataSource(aNewDataSource);
438 : }
439 0 : catch(const Exception&)
440 : {
441 : OSL_FAIL("Exception catched while changing the data source");
442 : }
443 0 : }
444 : }
445 0 : else if(aCommand == "Bib/autoFilter")
446 : {
447 0 : sal_uInt16 nCount = aStatusListeners.size();
448 0 : for ( sal_uInt16 n=0; n<nCount; n++ )
449 : {
450 0 : BibStatusDispatch *pObj = &aStatusListeners[n];
451 0 : if ( pObj->aURL.Path == "Bib/removeFilter" )
452 : {
453 0 : FeatureStateEvent aEvent;
454 0 : aEvent.FeatureURL = pObj->aURL;
455 0 : aEvent.IsEnabled = sal_True;
456 0 : aEvent.Requery = sal_False;
457 0 : aEvent.Source = static_cast<XDispatch *>(this);
458 0 : pObj->xListener->statusChanged( aEvent );
459 : //break; because there are more than one
460 : }
461 : }
462 :
463 0 : const beans::PropertyValue* pPropertyValue = aArgs.getConstArray();
464 0 : uno::Any aValue=pPropertyValue[0].Value;
465 0 : OUString aQuery;
466 0 : aValue >>= aQuery;
467 :
468 0 : aValue=pPropertyValue[1].Value;
469 0 : OUString aQueryField;
470 0 : aValue >>= aQueryField;
471 0 : BibConfig* pConfig = BibModul::GetConfig();
472 0 : pConfig->setQueryField(aQueryField);
473 0 : pDatMan->startQueryWith(aQuery);
474 : }
475 0 : else if(aCommand == "Bib/standardFilter")
476 : {
477 : try
478 : {
479 0 : uno::Reference< uno::XComponentContext > xContext = ::comphelper::getProcessComponentContext();
480 :
481 : // create the dialog object
482 0 : uno::Reference< ui::dialogs::XExecutableDialog > xDialog = sdb::FilterDialog::createWithQuery(xContext, pDatMan->getParser(),
483 0 : Reference<sdbc::XRowSet>(pDatMan->getForm(), uno::UNO_QUERY_THROW), xWindow);
484 : // execute it
485 0 : if ( xDialog->execute( ) )
486 : {
487 : // the dialog has been executed successfully, and the filter on the query composer
488 : // has been changed
489 0 : OUString sNewFilter = pDatMan->getParser()->getFilter();
490 0 : pDatMan->setFilter( sNewFilter );
491 0 : }
492 : }
493 0 : catch( const uno::Exception& )
494 : {
495 : OSL_FAIL( "BibFrameController_Impl::dispatch: caught an exception!" );
496 : }
497 :
498 0 : sal_uInt16 nCount = aStatusListeners.size();
499 0 : for ( sal_uInt16 n=0; n<nCount; n++ )
500 : {
501 0 : BibStatusDispatch *pObj = &aStatusListeners[n];
502 0 : if ( pObj->aURL.Path == "Bib/removeFilter" && pDatMan->getParser().is())
503 : {
504 0 : FeatureStateEvent aEvent;
505 0 : aEvent.FeatureURL = pObj->aURL;
506 0 : aEvent.IsEnabled = !pDatMan->getParser()->getFilter().isEmpty();
507 0 : aEvent.Requery = sal_False;
508 0 : aEvent.Source = static_cast<XDispatch *>(this);
509 0 : pObj->xListener->statusChanged( aEvent );
510 : }
511 : }
512 : }
513 0 : else if(aCommand == "Bib/removeFilter")
514 : {
515 0 : RemoveFilter();
516 : }
517 0 : else if( _rURL.Complete == "slot:5503" || aCommand == "CloseDoc" )
518 : {
519 : Application::PostUserEvent( LINK( this, BibFrameController_Impl,
520 0 : DisposeHdl ), 0 );
521 :
522 : }
523 0 : else if(aCommand == "Bib/InsertRecord")
524 : {
525 0 : Reference<form::runtime::XFormController > xFormCtrl = pDatMan->GetFormController();
526 0 : if(SaveModified(xFormCtrl))
527 : {
528 : try
529 : {
530 0 : Reference< sdbc::XResultSet > xCursor( pDatMan->getForm(), UNO_QUERY );
531 0 : xCursor->last();
532 :
533 0 : Reference< XResultSetUpdate > xUpdateCursor( pDatMan->getForm(), UNO_QUERY );
534 0 : xUpdateCursor->moveToInsertRow();
535 : }
536 0 : catch(const Exception&)
537 : {
538 : OSL_FAIL("Exception in last() or moveToInsertRow()");
539 : }
540 0 : }
541 : }
542 0 : else if(aCommand == "Bib/DeleteRecord")
543 : {
544 0 : Reference< ::com::sun::star::sdbc::XResultSet > xCursor(pDatMan->getForm(), UNO_QUERY);
545 0 : Reference< XResultSetUpdate > xUpdateCursor(xCursor, UNO_QUERY);
546 0 : Reference< beans::XPropertySet > xSet(pDatMan->getForm(), UNO_QUERY);
547 0 : bool bIsNew = ::comphelper::getBOOL(xSet->getPropertyValue("IsNew"));
548 0 : if(!bIsNew)
549 : {
550 0 : sal_uInt32 nCount = 0;
551 0 : xSet->getPropertyValue("RowCount") >>= nCount;
552 : // determine next position
553 0 : bool bSuccess = false;
554 0 : bool bLeft = false;
555 0 : bool bRight = false;
556 : try
557 : {
558 0 : bLeft = xCursor->isLast() && nCount > 1;
559 0 : bRight= !xCursor->isLast();
560 : // ask for confirmation
561 0 : Reference< frame::XController > xCtrl = pImp->pController;
562 0 : Reference< form::XConfirmDeleteListener > xConfirm(pDatMan->GetFormController(),UNO_QUERY);
563 0 : if (xConfirm.is())
564 : {
565 0 : sdb::RowChangeEvent aEvent;
566 0 : aEvent.Source = Reference< XInterface > (xCursor, UNO_QUERY);
567 0 : aEvent.Action = sdb::RowChangeAction::DELETE;
568 0 : aEvent.Rows = 1;
569 0 : bSuccess = xConfirm->confirmDelete(aEvent);
570 : }
571 :
572 : // delete it
573 0 : if (bSuccess)
574 0 : xUpdateCursor->deleteRow();
575 : }
576 0 : catch(const Exception&)
577 : {
578 0 : bSuccess = false;
579 : }
580 0 : if (bSuccess)
581 : {
582 0 : if (bLeft || bRight)
583 0 : xCursor->relative(bRight ? 1 : -1);
584 : else
585 : {
586 0 : bool bCanInsert = canInsertRecords(xSet);
587 : // can another entry be inserted?
588 : try
589 : {
590 0 : if (bCanInsert)
591 0 : xUpdateCursor->moveToInsertRow();
592 : else
593 : // move data entry to reset state
594 0 : xCursor->first();
595 : }
596 0 : catch(const Exception&)
597 : {
598 : OSL_FAIL("DeleteRecord: exception caught!");
599 : }
600 : }
601 : }
602 0 : }
603 : }
604 0 : else if(aCommand == "Cut")
605 : {
606 0 : vcl::Window* pChild = lcl_GetFocusChild( VCLUnoHelper::GetWindow( xWindow ) );
607 0 : if(pChild)
608 : {
609 0 : KeyEvent aEvent( 0, KeyFuncType::CUT );
610 0 : pChild->KeyInput( aEvent );
611 : }
612 : }
613 0 : else if(aCommand == "Copy")
614 : {
615 0 : vcl::Window* pChild = lcl_GetFocusChild( VCLUnoHelper::GetWindow( xWindow ) );
616 0 : if(pChild)
617 : {
618 0 : KeyEvent aEvent( 0, KeyFuncType::COPY );
619 0 : pChild->KeyInput( aEvent );
620 : }
621 : }
622 0 : else if(aCommand == "Paste")
623 : {
624 0 : vcl::Window* pChild = lcl_GetFocusChild( VCLUnoHelper::GetWindow( xWindow ) );
625 0 : if(pChild)
626 : {
627 0 : KeyEvent aEvent( 0, KeyFuncType::PASTE );
628 0 : pChild->KeyInput( aEvent );
629 : }
630 0 : }
631 : }
632 0 : }
633 0 : IMPL_LINK_NOARG( BibFrameController_Impl, DisposeHdl )
634 : {
635 0 : xFrame->dispose();
636 0 : return 0;
637 : };
638 :
639 0 : void BibFrameController_Impl::addStatusListener(
640 : const uno::Reference< frame::XStatusListener > & aListener,
641 : const util::URL& aURL)
642 : throw (::com::sun::star::uno::RuntimeException,
643 : std::exception)
644 : {
645 0 : BibConfig* pConfig = BibModul::GetConfig();
646 : // create a new Reference and insert into listener array
647 0 : aStatusListeners.push_back( new BibStatusDispatch( aURL, aListener ) );
648 :
649 : // send first status synchronously
650 0 : FeatureStateEvent aEvent;
651 0 : aEvent.FeatureURL = aURL;
652 0 : aEvent.Requery = sal_False;
653 0 : aEvent.Source = static_cast<XDispatch *>(this);
654 0 : if ( aURL.Path == "StatusBarVisible" )
655 : {
656 0 : aEvent.IsEnabled = sal_False;
657 0 : aEvent.State <<= false;
658 : }
659 0 : else if ( aURL.Path == "Bib/hierarchical" )
660 : {
661 0 : aEvent.IsEnabled = sal_True;
662 0 : const char* pHier = bHierarchical? "" : "*" ;
663 0 : aEvent.State <<= OUString::createFromAscii(pHier);
664 : }
665 0 : else if(aURL.Path == "Bib/MenuFilter")
666 : {
667 0 : aEvent.IsEnabled = sal_True;
668 0 : aEvent.FeatureDescriptor=pDatMan->getQueryField();
669 :
670 0 : uno::Sequence<OUString> aStringSeq=pDatMan->getQueryFields();
671 0 : aEvent.State.setValue(&aStringSeq,cppu::UnoType<uno::Sequence<OUString>>::get());
672 :
673 : }
674 0 : else if ( aURL.Path == "Bib/source")
675 : {
676 0 : aEvent.IsEnabled = sal_True;
677 0 : aEvent.FeatureDescriptor=pDatMan->getActiveDataTable();
678 :
679 0 : uno::Sequence<OUString> aStringSeq=pDatMan->getDataSources();
680 0 : aEvent.State.setValue(&aStringSeq,cppu::UnoType<uno::Sequence<OUString>>::get());
681 : }
682 0 : else if( aURL.Path == "Bib/sdbsource" ||
683 0 : aURL.Path == "Bib/Mapping" ||
684 0 : aURL.Path == "Bib/autoFilter" ||
685 0 : aURL.Path == "Bib/standardFilter" )
686 : {
687 0 : aEvent.IsEnabled = sal_True;
688 : }
689 0 : else if(aURL.Path == "Bib/query")
690 : {
691 0 : aEvent.IsEnabled = sal_True;
692 0 : aEvent.State <<= pConfig->getQueryText();
693 : }
694 0 : else if (aURL.Path == "Bib/removeFilter" )
695 : {
696 0 : OUString aFilterStr=pDatMan->getFilter();
697 0 : aEvent.IsEnabled = !aFilterStr.isEmpty();
698 : }
699 0 : else if(aURL.Path == "Cut")
700 : {
701 0 : vcl::Window* pChild = lcl_GetFocusChild( VCLUnoHelper::GetWindow( xWindow ) );
702 0 : Edit* pEdit = dynamic_cast<Edit*>( pChild );
703 0 : if( pEdit )
704 0 : aEvent.IsEnabled = !pEdit->IsReadOnly() && pEdit->GetSelection().Len();
705 : }
706 0 : if(aURL.Path == "Copy")
707 : {
708 0 : vcl::Window* pChild = lcl_GetFocusChild( VCLUnoHelper::GetWindow( xWindow ) );
709 0 : Edit* pEdit = dynamic_cast<Edit*>( pChild );
710 0 : if( pEdit )
711 0 : aEvent.IsEnabled = pEdit->GetSelection().Len() > 0;
712 : }
713 0 : else if(aURL.Path == "Paste" )
714 : {
715 0 : aEvent.IsEnabled = sal_False;
716 0 : vcl::Window* pChild = lcl_GetFocusChild( VCLUnoHelper::GetWindow( xWindow ) );
717 0 : if(pChild)
718 : {
719 0 : uno::Reference< datatransfer::clipboard::XClipboard > xClip = pChild->GetClipboard();
720 0 : if(xClip.is())
721 : {
722 0 : uno::Reference< datatransfer::XTransferable > xDataObj;
723 :
724 : try
725 : {
726 0 : SolarMutexReleaser aReleaser;
727 0 : xDataObj = xClip->getContents();
728 : }
729 0 : catch( const uno::Exception& )
730 : {
731 : }
732 :
733 0 : if ( xDataObj.is() )
734 : {
735 0 : datatransfer::DataFlavor aFlavor;
736 0 : SotExchange::GetFormatDataFlavor( SotClipboardFormatId::STRING, aFlavor );
737 : try
738 : {
739 0 : uno::Any aData = xDataObj->getTransferData( aFlavor );
740 0 : OUString aText;
741 0 : aData >>= aText;
742 0 : aEvent.IsEnabled = !aText.isEmpty();
743 : }
744 0 : catch( const uno::Exception& )
745 : {
746 0 : }
747 0 : }
748 : }
749 0 : uno::Reference< datatransfer::XTransferable > xContents = xClip->getContents( );
750 : }
751 : }
752 0 : else if(aURL.Path == "Bib/DeleteRecord")
753 : {
754 0 : Reference< ::com::sun::star::sdbc::XResultSet > xCursor(pDatMan->getForm(), UNO_QUERY);
755 0 : Reference< XResultSetUpdate > xUpdateCursor(xCursor, UNO_QUERY);
756 0 : Reference< beans::XPropertySet > xSet(pDatMan->getForm(), UNO_QUERY);
757 0 : bool bIsNew = ::comphelper::getBOOL(xSet->getPropertyValue("IsNew"));
758 0 : if(!bIsNew)
759 : {
760 0 : sal_uInt32 nCount = 0;
761 0 : xSet->getPropertyValue("RowCount") >>= nCount;
762 0 : aEvent.IsEnabled = nCount > 0;
763 0 : }
764 : }
765 0 : else if (aURL.Path == "Bib/InsertRecord")
766 : {
767 0 : Reference< beans::XPropertySet > xSet(pDatMan->getForm(), UNO_QUERY);
768 0 : aEvent.IsEnabled = canInsertRecords(xSet);
769 : }
770 0 : aListener->statusChanged( aEvent );
771 0 : }
772 :
773 0 : void BibFrameController_Impl::removeStatusListener(
774 : const uno::Reference< frame::XStatusListener > & aObject, const util::URL& aURL)
775 : throw (::com::sun::star::uno::RuntimeException, std::exception)
776 : {
777 : // search listener array for given listener
778 : // for checking equality always "cast" to XInterface
779 0 : if ( !bDisposing )
780 : {
781 0 : sal_uInt16 nCount = aStatusListeners.size();
782 0 : for ( sal_uInt16 n=0; n<nCount; n++ )
783 : {
784 0 : BibStatusDispatch *pObj = &aStatusListeners[n];
785 0 : bool bFlag=pObj->xListener.is();
786 0 : if (!bFlag || (pObj->xListener == aObject &&
787 0 : ( aURL.Complete.isEmpty() || pObj->aURL.Path == aURL.Path )))
788 : {
789 0 : aStatusListeners.erase( aStatusListeners.begin() + n );
790 0 : break;
791 : }
792 : }
793 : }
794 0 : }
795 :
796 0 : void BibFrameController_Impl::RemoveFilter()
797 : {
798 0 : OUString aQuery;
799 0 : pDatMan->startQueryWith(aQuery);
800 :
801 0 : sal_uInt16 nCount = aStatusListeners.size();
802 :
803 0 : bool bRemoveFilter=false;
804 0 : bool bQueryText=false;
805 :
806 0 : for ( sal_uInt16 n=0; n<nCount; n++ )
807 : {
808 0 : BibStatusDispatch *pObj = &aStatusListeners[n];
809 0 : if ( pObj->aURL.Path == "Bib/removeFilter" )
810 : {
811 0 : FeatureStateEvent aEvent;
812 0 : aEvent.FeatureURL = pObj->aURL;
813 0 : aEvent.IsEnabled = sal_False;
814 0 : aEvent.Requery = sal_False;
815 0 : aEvent.Source = static_cast<XDispatch *>(this);
816 0 : pObj->xListener->statusChanged( aEvent );
817 0 : bRemoveFilter=true;
818 : }
819 0 : else if(pObj->aURL.Path == "Bib/query")
820 : {
821 0 : FeatureStateEvent aEvent;
822 0 : aEvent.FeatureURL = pObj->aURL;
823 0 : aEvent.IsEnabled = sal_True;
824 0 : aEvent.Requery = sal_False;
825 0 : aEvent.Source = static_cast<XDispatch *>(this);
826 0 : aEvent.State <<= aQuery;
827 0 : pObj->xListener->statusChanged( aEvent );
828 0 : bQueryText=true;
829 : }
830 :
831 0 : if(bRemoveFilter && bQueryText)
832 0 : break;
833 :
834 0 : }
835 0 : }
836 :
837 0 : void BibFrameController_Impl::ChangeDataSource(const uno::Sequence< beans::PropertyValue >& aArgs)
838 : {
839 0 : const beans::PropertyValue* pPropertyValue = aArgs.getConstArray();
840 0 : uno::Any aValue=pPropertyValue[0].Value;
841 0 : OUString aDBTableName;
842 0 : aValue >>= aDBTableName;
843 :
844 :
845 0 : if(aArgs.getLength() > 1)
846 : {
847 0 : uno::Any aDB = pPropertyValue[1].Value;
848 0 : OUString aURL;
849 0 : aDB >>= aURL;
850 0 : pDatMan->setActiveDataSource(aURL);
851 0 : aDBTableName = pDatMan->getActiveDataTable();
852 : }
853 : else
854 : {
855 0 : m_xDatMan->unload();
856 0 : pDatMan->setActiveDataTable(aDBTableName);
857 0 : pDatMan->updateGridModel();
858 0 : m_xDatMan->load();
859 : }
860 :
861 :
862 0 : sal_uInt16 nCount = aStatusListeners.size();
863 :
864 0 : bool bMenuFilter=false;
865 0 : bool bQueryText=false;
866 0 : for ( sal_uInt16 n=0; n<nCount; n++ )
867 : {
868 0 : BibStatusDispatch *pObj = &aStatusListeners[n];
869 0 : if (pObj->aURL.Path == "Bib/MenuFilter")
870 : {
871 0 : FeatureStateEvent aEvent;
872 0 : aEvent.FeatureURL = pObj->aURL;
873 0 : aEvent.IsEnabled = sal_True;
874 0 : aEvent.Requery = sal_False;
875 0 : aEvent.Source = static_cast<XDispatch *>(this);
876 0 : aEvent.FeatureDescriptor=pDatMan->getQueryField();
877 :
878 0 : uno::Sequence<OUString> aStringSeq=pDatMan->getQueryFields();
879 0 : aEvent.State = makeAny( aStringSeq );
880 :
881 0 : pObj->xListener->statusChanged( aEvent );
882 0 : bMenuFilter=true;
883 : }
884 0 : else if (pObj->aURL.Path == "Bib/query")
885 : {
886 0 : FeatureStateEvent aEvent;
887 0 : aEvent.FeatureURL = pObj->aURL;
888 0 : aEvent.IsEnabled = sal_True;
889 0 : aEvent.Requery = sal_False;
890 0 : aEvent.Source = static_cast<XDispatch *>(this);
891 0 : BibConfig* pConfig = BibModul::GetConfig();
892 0 : aEvent.State <<= pConfig->getQueryText();
893 0 : pObj->xListener->statusChanged( aEvent );
894 0 : bQueryText=true;
895 : }
896 :
897 0 : if (bMenuFilter && bQueryText)
898 0 : break;
899 :
900 0 : }
901 6 : }
902 :
903 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|