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