1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 #ifndef __FRAMEWORK_SERVICES_DESKTOP_HXX_ 29 #define __FRAMEWORK_SERVICES_DESKTOP_HXX_ 30 31 //_________________________________________________________________________________________________________________ 32 // my own includes 33 //_________________________________________________________________________________________________________________ 34 35 #include <classes/framecontainer.hxx> 36 #include <threadhelp/threadhelpbase.hxx> 37 #include <helper/oframes.hxx> 38 #include <macros/generic.hxx> 39 #include <macros/debug.hxx> 40 #include <macros/xinterface.hxx> 41 #include <macros/xtypeprovider.hxx> 42 #include <macros/xserviceinfo.hxx> 43 44 //_________________________________________________________________________________________________________________ 45 // interface includes 46 //_________________________________________________________________________________________________________________ 47 48 #include <com/sun/star/frame/XUntitledNumbers.hpp> 49 50 #include <com/sun/star/frame/XController.hpp> 51 #include <com/sun/star/frame/XDesktop.hpp> 52 #include <com/sun/star/frame/WindowArrange.hpp> 53 #include <com/sun/star/frame/TerminationVetoException.hpp> 54 #include <com/sun/star/frame/XTerminateListener.hpp> 55 #include <com/sun/star/frame/XWindowArranger.hpp> 56 #include <com/sun/star/frame/XTask.hpp> 57 #include <com/sun/star/frame/XStorable.hpp> 58 #include <com/sun/star/frame/XModel.hpp> 59 #include <com/sun/star/frame/XFramesSupplier.hpp> 60 #include <com/sun/star/frame/XFrames.hpp> 61 #include <com/sun/star/lang/XServiceName.hpp> 62 #include <com/sun/star/frame/XDispatchProvider.hpp> 63 #include <com/sun/star/frame/XDispatchProviderInterception.hpp> 64 #include <com/sun/star/frame/XComponentLoader.hpp> 65 #include <com/sun/star/frame/FrameAction.hpp> 66 #include <com/sun/star/task/XStatusIndicatorFactory.hpp> 67 #include <com/sun/star/frame/XTasksSupplier.hpp> 68 #include <com/sun/star/container/XEnumerationAccess.hpp> 69 #include <com/sun/star/lang/Locale.hpp> 70 #include <com/sun/star/frame/XDispatchResultListener.hpp> 71 #include <com/sun/star/lang/XEventListener.hpp> 72 #include <com/sun/star/frame/FeatureStateEvent.hpp> 73 #include <com/sun/star/task/XInteractionHandler.hpp> 74 #include <com/sun/star/frame/XDispatchRecorderSupplier.hpp> 75 76 //_________________________________________________________________________________________________________________ 77 // other includes 78 //_________________________________________________________________________________________________________________ 79 #include <unotools/cmdoptions.hxx> 80 #include <cppuhelper/propshlp.hxx> 81 #include <cppuhelper/interfacecontainer.hxx> 82 #include <cppuhelper/weak.hxx> 83 84 #include <comphelper/numberedcollection.hxx> 85 86 //_________________________________________________________________________________________________________________ 87 // namespace 88 //_________________________________________________________________________________________________________________ 89 90 namespace framework{ 91 92 //_________________________________________________________________________________________________________________ 93 // exported const 94 //_________________________________________________________________________________________________________________ 95 96 //_________________________________________________________________________________________________________________ 97 // exported definitions 98 //_________________________________________________________________________________________________________________ 99 100 enum ELoadState 101 { 102 E_NOTSET , 103 E_SUCCESSFUL , 104 E_FAILED , 105 E_INTERACTION 106 }; 107 108 /*-************************************************************************************************************//** 109 @short implement the topframe of frame tree 110 @descr This is the root of the frame tree. The desktop has no window, is not visible but he is the logical 111 "masternode" to build the hierarchy. 112 113 @implements XInterface 114 XTypeProvider 115 XServiceInfo 116 XDesktop 117 XComponentLoader 118 XTasksSupplier 119 XDispatchProvider 120 XFramesSupplier 121 XFrame 122 XComponent 123 XPropertySet 124 XFastPropertySet 125 XMultiPropertySet 126 XDispatchResultListener 127 XEventListener 128 XInteractionHandler 129 130 @base ThreadHelpBase 131 TransactionBase 132 OBroadcastHelper 133 OPropertySetHelper 134 135 @devstatus ready to use 136 @threadsafe yes 137 *//*-*************************************************************************************************************/ 138 class Desktop : // interfaces 139 public css::lang::XTypeProvider , 140 public css::lang::XServiceInfo , 141 public css::frame::XDesktop , 142 public css::frame::XComponentLoader , 143 public css::frame::XTasksSupplier , 144 public css::frame::XDispatchProvider , 145 public css::frame::XDispatchProviderInterception, 146 public css::frame::XFramesSupplier , // => XFrame => XComponent 147 public css::frame::XDispatchResultListener , // => XEventListener 148 public css::task::XInteractionHandler , 149 public css::frame::XUntitledNumbers , 150 // base classes 151 // Order is neccessary for right initialization! 152 private ThreadHelpBase , 153 private TransactionBase , 154 public ::cppu::OBroadcastHelper , 155 public ::cppu::OPropertySetHelper , 156 public ::cppu::OWeakObject 157 { 158 // internal used types, const etcpp. 159 private: 160 161 //--------------------------------------------------------------------- 162 /** used temporary to know which listener was already called or not. */ 163 typedef ::std::vector< css::uno::Reference< css::frame::XTerminateListener > > TTerminateListenerList; 164 165 // public methods 166 public: 167 168 // constructor / destructor 169 Desktop( const css::uno::Reference< css::lang::XMultiServiceFactory >& xFactory ); 170 virtual ~Desktop( ); 171 172 // XInterface, XTypeProvider, XServiceInfo 173 FWK_DECLARE_XINTERFACE 174 FWK_DECLARE_XTYPEPROVIDER 175 DECLARE_XSERVICEINFO 176 177 //--------------------------------------------------------------------- 178 /** 179 @interface XDesktop 180 181 @short try to shutdown these desktop environment. 182 183 @descr Will try to close all frames. If at least one frame could 184 not be closed successfully termination will be stopped. 185 186 Registered termination listener will be taken into account 187 also. As special feature some of our registered listener 188 are well known by it's UNO implementation name. They are handled 189 different to all other listener. 190 191 Btw: Desktop.terminate() was designed in the past to be used 192 within an UI based envrionment. So it's allowed e.g. to 193 call XController.suspend() here. If UI isnt an option ... please 194 use XCloseable.close() at these desktop implementation. 195 ... if it will be supported in the future .-)) 196 197 @seealso XTerminateListener 198 @seealso XTerminateListener2 199 200 @return true if all open frames could be closed and no listener throwed 201 a veto exception; false otherwise. 202 203 @onerror False will be returned. 204 @threadsafe yes 205 */ 206 virtual ::sal_Bool SAL_CALL terminate() 207 throw( css::uno::RuntimeException ); 208 209 //--------------------------------------------------------------------- 210 /** 211 @interface XDesktop 212 213 @short add a listener for termination events 214 215 @descr Additional to adding normal listener these method was implemented special. 216 Every listener will be asked for it's uno implementation name. 217 Some of them are well known ... and the corresponding listener wont be added 218 to the container of "normal listener". Those listener will be set as special 219 member. 220 see e.g. member m_xSfxTerminator 221 222 @seealso terminate() 223 224 @param xListener 225 the listener for registration. 226 227 @threadsafe yes 228 */ 229 virtual void SAL_CALL addTerminateListener( const css::uno::Reference< css::frame::XTerminateListener >& xListener ) 230 throw( css::uno::RuntimeException ); 231 232 //--------------------------------------------------------------------- 233 /** 234 @interface XDesktop 235 236 @short remove a listener from this container. 237 238 @descr Additional to removing normal listener these method was implemented special. 239 Every listener will be asked for it's uno implementation name. 240 Some of them are well known ... and the corresponding listener was set as special member. 241 Now those special member will be reseted also. 242 see e.g. member m_xSfxTerminator 243 244 @seealso terminate() 245 246 @param xListener 247 the listener for deregistration. 248 249 @threadsafe yes 250 */ 251 virtual void SAL_CALL removeTerminateListener( const css::uno::Reference< css::frame::XTerminateListener >& xListener ) 252 throw( css::uno::RuntimeException ); 253 254 virtual css::uno::Reference< css::container::XEnumerationAccess > SAL_CALL getComponents ( ) throw( css::uno::RuntimeException ); 255 virtual css::uno::Reference< css::lang::XComponent > SAL_CALL getCurrentComponent ( ) throw( css::uno::RuntimeException ); 256 virtual css::uno::Reference< css::frame::XFrame > SAL_CALL getCurrentFrame ( ) throw( css::uno::RuntimeException ); 257 258 // XComponentLoader 259 virtual css::uno::Reference< css::lang::XComponent > SAL_CALL loadComponentFromURL ( const ::rtl::OUString& sURL , 260 const ::rtl::OUString& sTargetFrameName , 261 sal_Int32 nSearchFlags , 262 const css::uno::Sequence< css::beans::PropertyValue >& lArguments ) throw( css::io::IOException , 263 css::lang::IllegalArgumentException , 264 css::uno::RuntimeException ); 265 266 // XTasksSupplier 267 virtual css::uno::Reference< css::container::XEnumerationAccess > SAL_CALL getTasks ( ) throw( css::uno::RuntimeException ); 268 virtual css::uno::Reference< css::frame::XTask > SAL_CALL getActiveTask ( ) throw( css::uno::RuntimeException ); 269 270 // XDispatchProvider 271 virtual css::uno::Reference< css::frame::XDispatch > SAL_CALL queryDispatch ( const css::util::URL& aURL , 272 const ::rtl::OUString& sTargetFrameName , 273 sal_Int32 nSearchFlags ) throw( css::uno::RuntimeException ); 274 virtual css::uno::Sequence< css::uno::Reference< css::frame::XDispatch > > SAL_CALL queryDispatches ( const css::uno::Sequence< css::frame::DispatchDescriptor >& lQueries ) throw( css::uno::RuntimeException ); 275 276 // XDispatchProviderInterception 277 virtual void SAL_CALL registerDispatchProviderInterceptor( const css::uno::Reference< css::frame::XDispatchProviderInterceptor >& xInterceptor) throw( css::uno::RuntimeException); 278 virtual void SAL_CALL releaseDispatchProviderInterceptor ( const css::uno::Reference< css::frame::XDispatchProviderInterceptor >& xInterceptor) throw( css::uno::RuntimeException); 279 280 // XFramesSupplier 281 virtual css::uno::Reference< css::frame::XFrames > SAL_CALL getFrames ( ) throw( css::uno::RuntimeException ); 282 virtual css::uno::Reference< css::frame::XFrame > SAL_CALL getActiveFrame ( ) throw( css::uno::RuntimeException ); 283 virtual void SAL_CALL setActiveFrame ( const css::uno::Reference< css::frame::XFrame >& xFrame ) throw( css::uno::RuntimeException ); 284 285 // XFrame 286 // Attention: findFrame() is implemented only! Other methods make no sense for our desktop! 287 virtual css::uno::Reference< css::frame::XFrame > SAL_CALL findFrame ( const ::rtl::OUString& sTargetFrameName , 288 sal_Int32 nSearchFlags ) throw( css::uno::RuntimeException ); 289 virtual void SAL_CALL initialize ( const css::uno::Reference< css::awt::XWindow >& xWindow ) throw( css::uno::RuntimeException ); 290 virtual css::uno::Reference< css::awt::XWindow > SAL_CALL getContainerWindow ( ) throw( css::uno::RuntimeException ); 291 virtual void SAL_CALL setCreator ( const css::uno::Reference< css::frame::XFramesSupplier >& xCreator ) throw( css::uno::RuntimeException ); 292 virtual css::uno::Reference< css::frame::XFramesSupplier > SAL_CALL getCreator ( ) throw( css::uno::RuntimeException ); 293 virtual ::rtl::OUString SAL_CALL getName ( ) throw( css::uno::RuntimeException ); 294 virtual void SAL_CALL setName ( const ::rtl::OUString& sName ) throw( css::uno::RuntimeException ); 295 virtual sal_Bool SAL_CALL isTop ( ) throw( css::uno::RuntimeException ); 296 virtual void SAL_CALL activate ( ) throw( css::uno::RuntimeException ); 297 virtual void SAL_CALL deactivate ( ) throw( css::uno::RuntimeException ); 298 virtual sal_Bool SAL_CALL isActive ( ) throw( css::uno::RuntimeException ); 299 virtual sal_Bool SAL_CALL setComponent ( const css::uno::Reference< css::awt::XWindow >& xComponentWindow , 300 const css::uno::Reference< css::frame::XController >& xController ) throw( css::uno::RuntimeException ); 301 virtual css::uno::Reference< css::awt::XWindow > SAL_CALL getComponentWindow ( ) throw( css::uno::RuntimeException ); 302 virtual css::uno::Reference< css::frame::XController > SAL_CALL getController ( ) throw( css::uno::RuntimeException ); 303 virtual void SAL_CALL contextChanged ( ) throw( css::uno::RuntimeException ); 304 virtual void SAL_CALL addFrameActionListener ( const css::uno::Reference< css::frame::XFrameActionListener >& xListener ) throw( css::uno::RuntimeException ); 305 virtual void SAL_CALL removeFrameActionListener ( const css::uno::Reference< css::frame::XFrameActionListener >& xListener ) throw( css::uno::RuntimeException ); 306 307 // XComponent 308 using cppu::OPropertySetHelper::disposing; 309 virtual void SAL_CALL dispose ( ) throw( css::uno::RuntimeException ); 310 virtual void SAL_CALL addEventListener ( const css::uno::Reference< css::lang::XEventListener >& xListener ) throw( css::uno::RuntimeException ); 311 virtual void SAL_CALL removeEventListener ( const css::uno::Reference< css::lang::XEventListener >& xListener ) throw( css::uno::RuntimeException ); 312 313 // XDispatchResultListener 314 virtual void SAL_CALL dispatchFinished ( const css::frame::DispatchResultEvent& aEvent ) throw( css::uno::RuntimeException ); 315 316 // XEventListener 317 virtual void SAL_CALL disposing ( const css::lang::EventObject& aSource ) throw( css::uno::RuntimeException ); 318 319 // XInteractionHandler 320 virtual void SAL_CALL handle ( const css::uno::Reference< css::task::XInteractionRequest >& xRequest ) throw( css::uno::RuntimeException ); 321 322 // css.frame.XUntitledNumbers 323 virtual ::sal_Int32 SAL_CALL leaseNumber( const css::uno::Reference< css::uno::XInterface >& xComponent ) 324 throw (css::lang::IllegalArgumentException, 325 css::uno::RuntimeException ); 326 327 // css.frame.XUntitledNumbers 328 virtual void SAL_CALL releaseNumber( ::sal_Int32 nNumber ) 329 throw (css::lang::IllegalArgumentException, 330 css::uno::RuntimeException ); 331 332 // css.frame.XUntitledNumbers 333 virtual void SAL_CALL releaseNumberForComponent( const css::uno::Reference< css::uno::XInterface >& xComponent ) 334 throw (css::lang::IllegalArgumentException, 335 css::uno::RuntimeException ); 336 337 // css.frame.XUntitledNumbers 338 virtual ::rtl::OUString SAL_CALL getUntitledPrefix() 339 throw (css::uno::RuntimeException); 340 341 //------------------------------------------------------------------------------------------------------------- 342 // protected methods 343 //------------------------------------------------------------------------------------------------------------- 344 protected: 345 346 // OPropertySetHelper 347 virtual sal_Bool SAL_CALL convertFastPropertyValue ( css::uno::Any& aConvertedValue , 348 css::uno::Any& aOldValue , 349 sal_Int32 nHandle , 350 const css::uno::Any& aValue ) throw( css::lang::IllegalArgumentException ); 351 virtual void SAL_CALL setFastPropertyValue_NoBroadcast( sal_Int32 nHandle , 352 const css::uno::Any& aValue ) throw( css::uno::Exception ); 353 using cppu::OPropertySetHelper::getFastPropertyValue; 354 virtual void SAL_CALL getFastPropertyValue ( css::uno::Any& aValue , 355 sal_Int32 nHandle ) const; 356 virtual ::cppu::IPropertyArrayHelper& SAL_CALL getInfoHelper ( ); 357 virtual css::uno::Reference< css::beans::XPropertySetInfo > SAL_CALL getPropertySetInfo ( ) throw (css::uno::RuntimeException); 358 359 //------------------------------------------------------------------------------------------------------------- 360 // private methods 361 //------------------------------------------------------------------------------------------------------------- 362 private: 363 364 css::uno::Reference< css::lang::XComponent > impl_getFrameComponent ( const css::uno::Reference< css::frame::XFrame >& xFrame ) const; 365 static const css::uno::Sequence< css::beans::Property > impl_getStaticPropertyDescriptor( ); 366 367 //--------------------------------------------------------------------- 368 /** calls queryTermination() on every registered termination listener. 369 * 370 * Note: Only normal termination listener (registered in list m_aListenerContainer 371 * will be recognized here. Special listener like quick starter, pipe or others 372 * has to be handled explicitly ! 373 * 374 * @param [out] lCalledListener 375 * every called listener will be returned here. 376 * Those list will be used to informa all called listener 377 * about cancel this termination request. 378 * 379 * @param [out] bVeto 380 * will be true if at least one listener throwed a veto exception; 381 * false otherwise. 382 * 383 * @see impl_sendCancelTerminationEvent() 384 */ 385 void impl_sendQueryTerminationEvent(TTerminateListenerList& lCalledListener, 386 ::sal_Bool& bVeto ); 387 388 //--------------------------------------------------------------------- 389 /** calls cancelTermination() on every termination listener 390 * where queryTermination() was called before. 391 * 392 * Note: Only normal termination listener (registered in list m_aListenerContainer 393 * will be recognized here. Special listener like quick starter, pipe or others 394 * has to be handled explicitly ! 395 * 396 * @param [in] lCalledListener 397 * every listener in this list was called within its method 398 * queryTermination() before. 399 * 400 * @see impl_sendQueryTerminationEvent() 401 */ 402 void impl_sendCancelTerminationEvent(const TTerminateListenerList& lCalledListener); 403 404 //--------------------------------------------------------------------- 405 /** calls notifyTermination() on every registered termination listener. 406 * 407 * Note: Only normal termination listener (registered in list m_aListenerContainer 408 * will be recognized here. Special listener like quick starter, pipe or others 409 * has to be handled explicitly ! 410 */ 411 void impl_sendNotifyTerminationEvent(); 412 413 //--------------------------------------------------------------------- 414 /** try to close all open frames. 415 * 416 * Iterates over all child frames and try to close them. 417 * Given parameter bAllowUI enable/disable showing any UI 418 * (which mostly occure on calling XController->suspend()). 419 * 420 * These method doesnt stop if one frame could not be closed. 421 * It will ignore such frames and try all other ones. 422 * But it returns false in such case - true otherwise. 423 * 424 * @param bAllowUI 425 * enable/disable showing of UI. 426 * 427 * @return true if all frames could be closed; false otherwise. 428 */ 429 ::sal_Bool impl_closeFrames(::sal_Bool bAllowUI); 430 431 //------------------------------------------------------------------------------------------------------------- 432 // debug methods 433 // (should be private everytime!) 434 //------------------------------------------------------------------------------------------------------------- 435 #ifdef ENABLE_ASSERTIONS 436 private: 437 438 static sal_Bool implcp_ctor ( const css::uno::Reference< css::lang::XMultiServiceFactory >& xFactory ); 439 static sal_Bool implcp_addEventListener ( const css::uno::Reference< css::lang::XEventListener >& xListener ); 440 static sal_Bool implcp_removeEventListener ( const css::uno::Reference< css::lang::XEventListener >& xListener ); 441 442 sal_Bool m_bIsTerminated ; /// check flag to protect us against dispose before terminate! 443 /// see dispose() for further informations! 444 445 #endif // #ifdef ENABLE_ASSERTIONS 446 447 //------------------------------------------------------------------------------------------------------------- 448 // variables 449 // (should be private everytime!) 450 //------------------------------------------------------------------------------------------------------------- 451 private: 452 453 css::uno::Reference< css::lang::XMultiServiceFactory > m_xFactory ; /// reference to factory, which has create this instance 454 FrameContainer m_aChildTaskContainer ; /// array of child tasks (childs of desktop are tasks; and tasks are also frames - But pure frames are not accepted!) 455 ::cppu::OMultiTypeInterfaceContainerHelper m_aListenerContainer ; /// container for ALL Listener 456 css::uno::Reference< css::frame::XFrames > m_xFramesHelper ; /// helper for XFrames, XIndexAccess, XElementAccess and implementation of a childcontainer! 457 css::uno::Reference< css::frame::XDispatchProvider > m_xDispatchHelper ; /// helper to dispatch something for new tasks, created by "_blank"! 458 ELoadState m_eLoadState ; /// hold information about state of asynchron loading of component for loadComponentFromURL()! 459 css::uno::Reference< css::frame::XFrame > m_xLastFrame ; /// last target of "loadComponentFromURL()"! 460 css::uno::Any m_aInteractionRequest ; 461 sal_Bool m_bSuspendQuickstartVeto ; /// don't ask quickstart for a veto 462 SvtCommandOptions m_aCommandOptions ; /// ref counted class to support disabling commands defined by configuration file 463 ::rtl::OUString m_sName ; 464 ::rtl::OUString m_sTitle ; 465 css::uno::Reference< css::frame::XDispatchRecorderSupplier > m_xDispatchRecorderSupplier ; 466 467 //--------------------------------------------------------------------- 468 /** special terminate listener to close pipe and block external requests 469 * during/after termination process is/was running 470 */ 471 css::uno::Reference< css::frame::XTerminateListener > m_xPipeTerminator; 472 473 //--------------------------------------------------------------------- 474 /** special terminate listener shown inside system tray (quick starter) 475 * Will hinder the office on shutdown ... but wish to allow closing 476 * of open documents. And because thats different to a normal terminate listener 477 * it has to be handled special .-) 478 */ 479 css::uno::Reference< css::frame::XTerminateListener > m_xQuickLauncher; 480 481 //--------------------------------------------------------------------- 482 /** special terminate listener which loads images asynchronous for current open documents. 483 * Because internaly it uses blocking system APIs ... it cant be guaranteed that 484 * running jobs can be cancelled successfully if the corressponding document will be closed ... 485 * it will not hinder those documents on closing. Instead it let all jobs running ... 486 * but at least on terminate we have to wait for all those blocked requests. 487 * So these implementation must be a special terminate listener too .-( 488 */ 489 css::uno::Reference< css::frame::XTerminateListener > m_xSWThreadManager; 490 491 //--------------------------------------------------------------------- 492 /** special terminate listener shuting down the SfxApplication. 493 * Because these desktop instance closes documents and informs listener 494 * only ... it does not realy shutdown the whole application. 495 * 496 * Btw: That wouldnt be possible by design ... because Desktop.terminate() 497 * has to return a boolean value about success ... it cant realy shutdown the 498 * process .-) 499 * 500 * So we uses a trick: A special listener (exactly these one here) listen for notifyTermination() 501 * and shutdown the process asynchronous. But desktop has to make this special 502 * notification as realy last one ... Otherwhise it can happen that asynchronous 503 * shutdown will be faster then all other code around Desktop.terminate() .-)) 504 */ 505 css::uno::Reference< css::frame::XTerminateListener > m_xSfxTerminator; 506 507 css::uno::Reference< css::frame::XUntitledNumbers > m_xTitleNumberGenerator; 508 509 }; // class Desktop 510 511 } // namespace framework 512 513 #endif // #ifndef __FRAMEWORK_SERVICES_DESKTOP_HXX_ 514