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