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_basctl.hxx" 26 27 #include "documentenumeration.hxx" 28 29 /** === begin UNO includes === **/ 30 #include <com/sun/star/frame/XDesktop.hpp> 31 #include <com/sun/star/frame/XModel2.hpp> 32 #include <com/sun/star/frame/FrameSearchFlag.hpp> 33 #include <com/sun/star/lang/XServiceInfo.hpp> 34 #include <com/sun/star/frame/XFramesSupplier.hpp> 35 /** === end UNO includes === **/ 36 37 #include <tools/diagnose_ex.h> 38 39 #include <comphelper/stl_types.hxx> 40 41 //........................................................................ 42 namespace basctl { namespace docs { 43 //........................................................................ 44 45 /** === begin UNO using === **/ 46 using ::com::sun::star::uno::Exception; 47 using ::com::sun::star::uno::Reference; 48 using ::com::sun::star::uno::UNO_QUERY_THROW; 49 using ::com::sun::star::uno::UNO_SET_THROW; 50 using ::com::sun::star::frame::XDesktop; 51 using ::com::sun::star::container::XEnumerationAccess; 52 using ::com::sun::star::container::XEnumeration; 53 using ::com::sun::star::uno::Any; 54 using ::com::sun::star::frame::XModel; 55 using ::com::sun::star::frame::XFramesSupplier; 56 using ::com::sun::star::frame::XFrames; 57 using ::com::sun::star::frame::XController; 58 using ::com::sun::star::frame::XModel2; 59 using ::com::sun::star::uno::UNO_QUERY; 60 using ::com::sun::star::lang::XServiceInfo; 61 using ::com::sun::star::uno::Sequence; 62 using ::com::sun::star::frame::XFrame; 63 /** === end UNO using === **/ 64 namespace FrameSearchFlag = ::com::sun::star::frame::FrameSearchFlag; 65 66 //==================================================================== 67 //= DocumentEnumeration_Data 68 //==================================================================== 69 struct DocumentEnumeration_Data 70 { 71 ::comphelper::ComponentContext aContext; 72 const IDocumentDescriptorFilter* pFilter; 73 DocumentEnumeration_Databasctl::docs::DocumentEnumeration_Data74 DocumentEnumeration_Data( const ::comphelper::ComponentContext& _rContext, const IDocumentDescriptorFilter* _pFilter ) 75 :aContext( _rContext ) 76 ,pFilter( _pFilter ) 77 { 78 } 79 }; 80 81 //==================================================================== 82 //= DocumentEnumeration 83 //==================================================================== 84 //-------------------------------------------------------------------- DocumentEnumeration(const::comphelper::ComponentContext & _rContext,const IDocumentDescriptorFilter * _pFilter)85 DocumentEnumeration::DocumentEnumeration( const ::comphelper::ComponentContext& _rContext, const IDocumentDescriptorFilter* _pFilter ) 86 :m_pData( new DocumentEnumeration_Data( _rContext, _pFilter ) ) 87 { 88 } 89 90 //-------------------------------------------------------------------- ~DocumentEnumeration()91 DocumentEnumeration::~DocumentEnumeration() 92 { 93 } 94 95 //-------------------------------------------------------------------- 96 namespace 97 { 98 //................................................................ lcl_getDocumentControllers_nothrow(DocumentDescriptor & _io_rDocDesc)99 void lcl_getDocumentControllers_nothrow( DocumentDescriptor& _io_rDocDesc ) 100 { 101 OSL_PRECOND( _io_rDocDesc.xModel.is(), "lcl_getDocumentControllers_nothrow: illegal model!" ); 102 103 _io_rDocDesc.aControllers.clear(); 104 try 105 { 106 Reference< XModel2 > xModel2( _io_rDocDesc.xModel, UNO_QUERY ); 107 if ( xModel2.is() ) 108 { 109 Reference< XEnumeration > xEnum( xModel2->getControllers(), UNO_SET_THROW ); 110 while ( xEnum->hasMoreElements() ) 111 { 112 Reference< XController > xController( xEnum->nextElement(), UNO_QUERY_THROW ); 113 _io_rDocDesc.aControllers.push_back( xController ); 114 } 115 } 116 else if ( _io_rDocDesc.xModel.is() ) 117 _io_rDocDesc.aControllers.push_back( _io_rDocDesc.xModel->getCurrentController() ); 118 } 119 catch( const Exception& ) 120 { 121 DBG_UNHANDLED_EXCEPTION(); 122 } 123 } 124 125 //................................................................ lcl_getDocuments_nothrow(const Sequence<Reference<XFrame>> & _rFrames,Documents & _out_rDocuments,const IDocumentDescriptorFilter * _pFilter)126 void lcl_getDocuments_nothrow( const Sequence< Reference< XFrame > >& _rFrames, Documents& _out_rDocuments, 127 const IDocumentDescriptorFilter* _pFilter ) 128 { 129 // ensure we don't encounter some models multiple times 130 ::std::set< Reference< XModel >, ::comphelper::OInterfaceCompare< XModel > > aEncounteredModels; 131 132 for ( const Reference< XFrame >* pFrame = _rFrames.getConstArray(); 133 pFrame != _rFrames.getConstArray() + _rFrames.getLength(); 134 ++pFrame 135 ) 136 { 137 try 138 { 139 OSL_ENSURE( pFrame->is(), "lcl_getDocuments_nothrow: illegal frame!" ); 140 if ( !pFrame->is() ) 141 continue; 142 Reference< XController > xController( (*pFrame)->getController() ); 143 if ( !xController.is() ) 144 continue; 145 146 Reference< XModel > xModel( xController->getModel() ); 147 if ( !xModel.is() ) 148 // though it's legal for a controller to not have a model, we're not interested in 149 // those 150 continue; 151 152 if ( aEncounteredModels.find( xModel ) != aEncounteredModels.end() ) 153 // there might be multiple frames for the same model 154 // handle it only once 155 continue; 156 aEncounteredModels.insert( xModel ); 157 158 // create a DocumentDescriptor 159 DocumentDescriptor aDescriptor; 160 aDescriptor.xModel = xModel; 161 lcl_getDocumentControllers_nothrow( aDescriptor ); 162 163 // consult filter, if there is one 164 if ( _pFilter && !_pFilter->includeDocument( aDescriptor ) ) 165 continue; 166 167 _out_rDocuments.push_back( aDescriptor ); 168 } 169 catch( const Exception& ) 170 { 171 DBG_UNHANDLED_EXCEPTION(); 172 } 173 } 174 } 175 } 176 177 //-------------------------------------------------------------------- getDocuments(Documents & _out_rDocuments) const178 void DocumentEnumeration::getDocuments( Documents& _out_rDocuments ) const 179 { 180 _out_rDocuments.clear(); 181 182 try 183 { 184 const Reference< XDesktop > xDesktop( m_pData->aContext.createComponent( "com.sun.star.frame.Desktop" ), UNO_QUERY_THROW ); 185 const Reference< XFramesSupplier > xSuppFrames( xDesktop, UNO_QUERY_THROW ); 186 const Reference< XFrames > xFrames( xSuppFrames->getFrames(), UNO_SET_THROW ); 187 const Sequence< Reference< XFrame > > aFrames( xFrames->queryFrames( FrameSearchFlag::ALL ) ); 188 189 lcl_getDocuments_nothrow( aFrames, _out_rDocuments, m_pData->pFilter ); 190 } 191 catch( const Exception& ) 192 { 193 DBG_UNHANDLED_EXCEPTION(); 194 } 195 } 196 197 //........................................................................ 198 } } // namespace basctl::docs 199 //........................................................................ 200